Merge "Add stopservice command to am"
diff --git a/api/current.txt b/api/current.txt
index 3318e06..a5f05fa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2697,7 +2697,8 @@
     method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void closeContextMenu();
     method public void closeOptionsMenu();
-    method public void convertToOpaque();
+    method public void convertFromTranslucent();
+    method public void convertToTranslucent(android.app.Activity.TranslucentConversionListener);
     method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
     method public final deprecated void dismissDialog(int);
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
@@ -2883,6 +2884,10 @@
     field public static final int RESULT_OK = -1; // 0xffffffff
   }
 
+  public static abstract interface Activity.TranslucentConversionListener {
+    method public abstract void onTranslucentConversionComplete(boolean);
+  }
+
   public deprecated class ActivityGroup extends android.app.Activity {
     ctor public ActivityGroup();
     ctor public ActivityGroup(boolean);
@@ -3134,6 +3139,32 @@
     ctor public AliasActivity();
   }
 
+  public class AppOpsManager {
+    method public int checkOp(int, int, java.lang.String);
+    method public int checkOpNoThrow(int, int, java.lang.String);
+    method public void finishOp(int, int, java.lang.String);
+    method public void finishOp(int);
+    method public int noteOp(int, int, java.lang.String);
+    method public int noteOpNoThrow(int, int, java.lang.String);
+    method public static java.lang.String opToName(int);
+    method public int startOp(int, int, java.lang.String);
+    method public int startOpNoThrow(int, int, java.lang.String);
+    method public void startWatchingMode(int, java.lang.String, android.app.AppOpsManager.Callback);
+    method public void stopWatchingMode(android.app.AppOpsManager.Callback);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_ERRORED = 2; // 0x2
+    field public static final int MODE_IGNORED = 1; // 0x1
+    field public static final int OP_COARSE_LOCATION = 0; // 0x0
+    field public static final int OP_FINE_LOCATION = 1; // 0x1
+    field public static final int OP_GPS = 2; // 0x2
+    field public static final int OP_MONITOR_LOCATION = 41; // 0x29
+    field public static final int OP_NONE = -1; // 0xffffffff
+  }
+
+  public static abstract interface AppOpsManager.Callback {
+    method public abstract void opChanged(int, java.lang.String);
+  }
+
   public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
     ctor public Application();
     method public void onConfigurationChanged(android.content.res.Configuration);
@@ -10729,7 +10760,7 @@
   }
 
   public static class CameraMetadata.Key {
-    ctor public CameraMetadata.Key(java.lang.String);
+    ctor public CameraMetadata.Key(java.lang.String, java.lang.Class<T>);
     method public final boolean equals(java.lang.Object);
     method public final java.lang.String getName();
     method public final int hashCode();
@@ -10781,6 +10812,12 @@
     method public int getScore();
   }
 
+  public final class Rational {
+    ctor public Rational(int, int);
+    method public int getDenominator();
+    method public int getNumerator();
+  }
+
   public final class Size {
     method public final int getHeight();
     method public final int getWidth();
@@ -26510,6 +26547,9 @@
     method public void buildDrawingCache(boolean);
     method public void buildLayer();
     method public boolean callOnClick();
+    method public boolean canResolveLayoutDirection();
+    method public boolean canResolveTextAlignment();
+    method public boolean canResolveTextDirection();
     method public boolean canScrollHorizontally(int);
     method public boolean canScrollVertically(int);
     method public void cancelLongPress();
@@ -26714,6 +26754,7 @@
     method public boolean isInEditMode();
     method public boolean isInLayout();
     method public boolean isInTouchMode();
+    method public boolean isLayoutDirectionResolved();
     method public boolean isLayoutRequested();
     method public boolean isLongClickable();
     method public boolean isOpaque();
@@ -26727,6 +26768,8 @@
     method public boolean isSelected();
     method public boolean isShown();
     method public boolean isSoundEffectsEnabled();
+    method public boolean isTextAlignmentResolved();
+    method public boolean isTextDirectionResolved();
     method public boolean isVerticalFadingEdgeEnabled();
     method public boolean isVerticalScrollBarEnabled();
     method public void jumpDrawablesToCurrentState();
@@ -27230,7 +27273,9 @@
     method public void bringChildToFront(android.view.View);
     method protected boolean canAnimate();
     method protected boolean checkLayoutParams(android.view.ViewGroup.LayoutParams);
+    method public void childAccessibilityStateChanged(android.view.View);
     method public void childDrawableStateChanged(android.view.View);
+    method public void childHasTransientStateChanged(android.view.View, boolean);
     method protected void cleanupLayoutState(android.view.View);
     method public void clearChildFocus(android.view.View);
     method public void clearDisappearingChildren();
@@ -27391,17 +27436,28 @@
 
   public abstract interface ViewParent {
     method public abstract void bringChildToFront(android.view.View);
+    method public abstract boolean canResolveLayoutDirection();
+    method public abstract boolean canResolveTextAlignment();
+    method public abstract boolean canResolveTextDirection();
+    method public abstract void childAccessibilityStateChanged(android.view.View);
     method public abstract void childDrawableStateChanged(android.view.View);
+    method public abstract void childHasTransientStateChanged(android.view.View, boolean);
     method public abstract void clearChildFocus(android.view.View);
     method public abstract void createContextMenu(android.view.ContextMenu);
     method public abstract android.view.View focusSearch(android.view.View, int);
     method public abstract void focusableViewAvailable(android.view.View);
     method public abstract boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
+    method public abstract int getLayoutDirection();
     method public abstract android.view.ViewParent getParent();
     method public abstract android.view.ViewParent getParentForAccessibility();
+    method public abstract int getTextAlignment();
+    method public abstract int getTextDirection();
     method public abstract void invalidateChild(android.view.View, android.graphics.Rect);
     method public abstract android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+    method public abstract boolean isLayoutDirectionResolved();
     method public abstract boolean isLayoutRequested();
+    method public abstract boolean isTextAlignmentResolved();
+    method public abstract boolean isTextDirectionResolved();
     method public abstract void recomputeViewAttributes(android.view.View);
     method public abstract void requestChildFocus(android.view.View, android.view.View);
     method public abstract boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
@@ -49918,6 +49974,7 @@
     ctor public JSONArray(java.util.Collection);
     ctor public JSONArray(org.json.JSONTokener) throws org.json.JSONException;
     ctor public JSONArray(java.lang.String) throws org.json.JSONException;
+    ctor public JSONArray(java.lang.Object) throws org.json.JSONException;
     method public java.lang.Object get(int) throws org.json.JSONException;
     method public boolean getBoolean(int) throws org.json.JSONException;
     method public double getDouble(int) throws org.json.JSONException;
@@ -49952,6 +50009,7 @@
     method public org.json.JSONArray put(int, int) throws org.json.JSONException;
     method public org.json.JSONArray put(int, long) throws org.json.JSONException;
     method public org.json.JSONArray put(int, java.lang.Object) throws org.json.JSONException;
+    method public java.lang.Object remove(int);
     method public org.json.JSONObject toJSONObject(org.json.JSONArray) throws org.json.JSONException;
     method public java.lang.String toString(int) throws org.json.JSONException;
   }
@@ -50004,6 +50062,7 @@
     method public java.lang.Object remove(java.lang.String);
     method public org.json.JSONArray toJSONArray(org.json.JSONArray) throws org.json.JSONException;
     method public java.lang.String toString(int) throws org.json.JSONException;
+    method public static java.lang.Object wrap(java.lang.Object);
     field public static final java.lang.Object NULL;
   }
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d1efd0d1..fa746ba 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -745,6 +745,7 @@
     // protected by synchronized (this) 
     int mResultCode = RESULT_CANCELED;
     Intent mResultData = null;
+    private TranslucentConversionListener mTranslucentCallback;
 
     private boolean mTitleReady = false;
 
@@ -1382,6 +1383,7 @@
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
         if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
         getApplication().dispatchActivityStopped(this);
+        mTranslucentCallback = null;
         mCalled = true;
     }
 
@@ -4886,23 +4888,62 @@
     /**
      * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a
      * fullscreen opaque Activity.
-     *
+     * <p>
      * Call this whenever the background of a translucent Activity has changed to become opaque.
-     * Doing so will allow the previously visible Activity behind this one to be stopped. Stopped
-     * apps consume no CPU cycles and are eligible for removal when reclaiming memory.
-     *
+     * Doing so will allow the {@link android.view.Surface} of the Activity behind to be released.
+     * <p>
      * This call has no effect on non-translucent activities or on activities with the
      * {@link android.R.attr#windowIsFloating} attribute.
+     *
+     * @see #convertToTranslucent(TranslucentConversionListener)
+     * @see TranslucentConversionListener
      */
-    public void convertToOpaque() {
+    public void convertFromTranslucent() {
         try {
-            ActivityManagerNative.getDefault().convertToOpaque(mToken);
+            mTranslucentCallback = null;
+            ActivityManagerNative.getDefault().convertFromTranslucent(mToken);
         } catch (RemoteException e) {
             // pass
         }
     }
 
     /**
+     * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} back from
+     * opaque to translucent following a call to {@link #convertFromTranslucent()}.
+     * <p>
+     * Calling this allows the Activity behind this one to be seen again. Once all such Activities
+     * have been redrawn {@link TranslucentConversionListener#onTranslucentConversionComplete} will
+     * be called indicating that it is safe to make this activity translucent again. Until
+     * {@link TranslucentConversionListener#onTranslucentConversionComplete} is called the image
+     * behind the frontmost Activity will be indeterminate.
+     * <p>
+     * This call has no effect on non-translucent activities or on activities with the
+     * {@link android.R.attr#windowIsFloating} attribute.
+     *
+     * @param callback the method to call when all visible Activities behind this one have been
+     * drawn and it is safe to make this Activity translucent again.
+     *
+     * @see #convertFromTranslucent()
+     * @see TranslucentConversionListener
+     */
+    public void convertToTranslucent(TranslucentConversionListener callback) {
+        try {
+            mTranslucentCallback = callback;
+            ActivityManagerNative.getDefault().convertToTranslucent(mToken);
+        } catch (RemoteException e) {
+            // pass
+        }
+    }
+
+    /** @hide */
+    void onTranslucentConversionComplete(boolean drawComplete) {
+        if (mTranslucentCallback != null) {
+            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
+            mTranslucentCallback = null;
+        }
+    }
+
+    /**
      * Adjust the current immersive mode setting.
      *
      * Note that changing this value will have no effect on the activity's
@@ -4947,6 +4988,7 @@
      * @return The new action mode, or <code>null</code> if the activity does not want to
      *         provide special handling for this action mode. (It will be handled by the system.)
      */
+    @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
         initActionBar();
         if (mActionBar != null) {
@@ -4961,6 +5003,7 @@
      *
      * @param mode The new action mode.
      */
+    @Override
     public void onActionModeStarted(ActionMode mode) {
     }
 
@@ -4970,6 +5013,7 @@
      *
      * @param mode The action mode that just finished.
      */
+    @Override
     public void onActionModeFinished(ActionMode mode) {
     }
 
@@ -5373,4 +5417,26 @@
             }
         }
     }
+
+    /**
+     * Interface for informing a translucent {@link Activity} once all visible activities below it
+     * have completed drawing. This is necessary only after an {@link Activity} has been made
+     * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn
+     * translucent again following a call to {@link
+     * Activity#convertToTranslucent(TranslucentConversionListener)}.
+     */
+    public interface TranslucentConversionListener {
+        /**
+         * Callback made following {@link Activity#convertToTranslucent} once all visible Activities
+         * below the top one have been redrawn. Following this callback it is safe to make the top
+         * Activity translucent because the underlying Activity has been drawn.
+         *
+         * @param drawComplete True if the background Activity has drawn itself. False if a timeout
+         * occurred waiting for the Activity to complete drawing.
+         *
+         * @see Activity#convertFromTranslucent()
+         * @see Activity#convertToTranslucent(TranslucentConversionListener)
+         */
+        public void onTranslucentConversionComplete(boolean drawComplete);
+    }
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index a23611ec..acfcb40 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1499,10 +1499,18 @@
             return true;
         }
 
-        case CONVERT_TO_OPAQUE_TRANSACTION: {
+        case CONVERT_FROM_TRANSLUCENT_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
-            convertToOpaque(token);
+            convertFromTranslucent(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case CONVERT_TO_TRANSLUCENT_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            convertToTranslucent(token);
             reply.writeNoException();
             return true;
         }
@@ -1957,6 +1965,13 @@
             return true;
         }
 
+        case NOTIFY_ACTIVITY_DRAWN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            notifyActivityDrawn(token);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3840,13 +3855,25 @@
         reply.recycle();
     }
 
-    public void convertToOpaque(IBinder token)
+    public void convertFromTranslucent(IBinder token)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
-        mRemote.transact(CONVERT_TO_OPAQUE_TRANSACTION, data, reply, 0);
+        mRemote.transact(CONVERT_FROM_TRANSLUCENT_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public void convertToTranslucent(IBinder token)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
         reply.recycle();
@@ -4482,5 +4509,16 @@
         reply.recycle();
     }
 
+    public void notifyActivityDrawn(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(NOTIFY_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4568525..b24aeb0 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -16,8 +16,6 @@
 
 package android.app;
 
-import static android.view.DisplayAdjustments.DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN;
-
 import android.app.backup.BackupAgent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks2;
@@ -77,7 +75,6 @@
 import android.util.LogPrinter;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
-import android.view.DisplayAdjustments;
 import android.view.Display;
 import android.view.HardwareRenderer;
 import android.view.View;
@@ -150,7 +147,7 @@
     public static final boolean DEBUG_BROADCAST = false;
     private static final boolean DEBUG_RESULTS = false;
     private static final boolean DEBUG_BACKUP = false;
-    private static final boolean DEBUG_CONFIGURATION = false;
+    public static final boolean DEBUG_CONFIGURATION = false;
     private static final boolean DEBUG_SERVICE = false;
     private static final boolean DEBUG_MEMORY_TRIM = false;
     private static final boolean DEBUG_PROVIDER = false;
@@ -182,8 +179,6 @@
     boolean mDensityCompatMode;
     Configuration mConfiguration;
     Configuration mCompatConfiguration;
-    Configuration mResConfiguration;
-    CompatibilityInfo mResCompatibilityInfo;
     Application mInitialApplication;
     final ArrayList<Application> mAllApplications
             = new ArrayList<Application>();
@@ -212,14 +207,12 @@
             = new HashMap<String, WeakReference<LoadedApk>>();
     final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
             = new HashMap<String, WeakReference<LoadedApk>>();
-    final HashMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics
-            = new HashMap<DisplayAdjustments, DisplayMetrics>();
-    final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
-            = new HashMap<ResourcesKey, WeakReference<Resources> >();
     final ArrayList<ActivityClientRecord> mRelaunchingActivities
             = new ArrayList<ActivityClientRecord>();
     Configuration mPendingConfiguration = null;
 
+    private final ResourcesManager mResourcesManager;
+
     private static final class ProviderKey {
         final String authority;
         final int userId;
@@ -555,7 +548,7 @@
         private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
 
         private void updatePendingConfiguration(Configuration config) {
-            synchronized (mPackages) {
+            synchronized (mResourcesManager) {
                 if (mPendingConfiguration == null ||
                         mPendingConfiguration.isOtherSeqNewer(config)) {
                     mPendingConfiguration = config;
@@ -1222,6 +1215,9 @@
             queueOrSendMessage(H.TRIM_MEMORY, null, level);
         }
 
+        public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
+            queueOrSendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
+        }
     }
 
     private class H extends Handler {
@@ -1269,6 +1265,7 @@
         public static final int DUMP_PROVIDER           = 141;
         public static final int UNSTABLE_PROVIDER_DIED  = 142;
         public static final int REQUEST_ACTIVITY_EXTRAS = 143;
+        public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
                 switch (code) {
@@ -1316,6 +1313,7 @@
                     case DUMP_PROVIDER: return "DUMP_PROVIDER";
                     case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
                     case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS";
+                    case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
                 }
             }
             return Integer.toString(code);
@@ -1530,6 +1528,9 @@
                 case REQUEST_ACTIVITY_EXTRAS:
                     handleRequestActivityExtras((RequestActivityExtras)msg.obj);
                     break;
+                case TRANSLUCENT_CONVERSION_COMPLETE:
+                    handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
+                    break;
             }
             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
         }
@@ -1608,72 +1609,6 @@
         }
     }
 
-    private static class ResourcesKey {
-        final private String mResDir;
-        final private int mDisplayId;
-        final private Configuration mOverrideConfiguration;
-        final private float mScale;
-        final private int mHash;
-        final private IBinder mToken;
-
-        ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
-                float scale, IBinder token) {
-            mResDir = resDir;
-            mDisplayId = displayId;
-            if (overrideConfiguration != null) {
-                if (Configuration.EMPTY.equals(overrideConfiguration)) {
-                    overrideConfiguration = null;
-                }
-            }
-            mOverrideConfiguration = overrideConfiguration;
-            mScale = scale;
-            int hash = 17;
-            hash = 31 * hash + mResDir.hashCode();
-            hash = 31 * hash + mDisplayId;
-            hash = 31 * hash + (mOverrideConfiguration != null
-                    ? mOverrideConfiguration.hashCode() : 0);
-            hash = 31 * hash + Float.floatToIntBits(mScale);
-            if (DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN) {
-                mToken = token;
-                hash = 31 * hash + (mToken == null ? 0 : mToken.hashCode());
-            } else {
-                mToken = null;
-            }
-            mHash = hash;
-        }
-
-        @Override
-        public int hashCode() {
-            return mHash;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof ResourcesKey)) {
-                return false;
-            }
-            ResourcesKey peer = (ResourcesKey) obj;
-            if (!mResDir.equals(peer.mResDir)) {
-                return false;
-            }
-            if (mDisplayId != peer.mDisplayId) {
-                return false;
-            }
-            if (mOverrideConfiguration != peer.mOverrideConfiguration) {
-                if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
-                    return false;
-                }
-                if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
-                    return false;
-                }
-            }
-            if (mScale != peer.mScale) {
-                return false;
-            }
-            return true;
-        }
-    }
-
     public static ActivityThread currentActivityThread() {
         return sCurrentActivityThread;
     }
@@ -1707,49 +1642,6 @@
         return sPackageManager;
     }
 
-    private void flushDisplayMetricsLocked() {
-        mDefaultDisplayMetrics.clear();
-    }
-
-    DisplayMetrics getDisplayMetricsLocked(int displayId) {
-        return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-    }
-
-    DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) {
-        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-        DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null;
-        if (dm != null) {
-            return dm;
-        }
-        dm = new DisplayMetrics();
-
-        DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
-        if (displayManager == null) {
-            // may be null early in system startup
-            dm.setToDefaults();
-            return dm;
-        }
-
-        if (isDefaultDisplay) {
-            mDefaultDisplayMetrics.put(daj, dm);
-        }
-
-        Display d = displayManager.getCompatibleDisplay(displayId, daj);
-        if (d != null) {
-            d.getMetrics(dm);
-        } else {
-            // Display no longer exists
-            // FIXME: This would not be a problem if we kept the Display object around
-            // instead of using the raw display id everywhere.  The Display object caches
-            // its information even after the display has been removed.
-            dm.setToDefaults();
-        }
-        //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
-        //        + metrics.heightPixels + " den=" + metrics.density
-        //        + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
-        return dm;
-    }
-
     private Configuration mMainThreadConfig = new Configuration();
     Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
             CompatibilityInfo compat) {
@@ -1765,90 +1657,12 @@
     }
 
     /**
-     * Creates the top level Resources for applications with the given compatibility info.
-     *
-     * @param resDir the resource directory.
-     * @param compatInfo the compability info. Must not be null.
-     * @param token the application token for determining stack bounds.
-     */
-    Resources getTopLevelResources(String resDir, int displayId,
-            Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
-        final float scale = compatInfo.applicationScale;
-        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
-                token);
-        Resources r;
-        synchronized (mPackages) {
-            // Resources is app scale dependent.
-            if (false) {
-                Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale);
-            }
-            WeakReference<Resources> wr = mActiveResources.get(key);
-            r = wr != null ? wr.get() : null;
-            //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
-            if (r != null && r.getAssets().isUpToDate()) {
-                if (false) {
-                    Slog.w(TAG, "Returning cached resources " + r + " " + resDir
-                            + ": appScale=" + r.getCompatibilityInfo().applicationScale);
-                }
-                return r;
-            }
-        }
-
-        //if (r != null) {
-        //    Slog.w(TAG, "Throwing away out-of-date resources!!!! "
-        //            + r + " " + resDir);
-        //}
-
-        AssetManager assets = new AssetManager();
-        if (assets.addAssetPath(resDir) == 0) {
-            return null;
-        }
-
-        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
-        DisplayMetrics dm = getDisplayMetricsLocked(displayId);
-        Configuration config;
-        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-        if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
-            config = new Configuration(getConfiguration());
-            if (!isDefaultDisplay) {
-                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
-            }
-            if (key.mOverrideConfiguration != null) {
-                config.updateFrom(key.mOverrideConfiguration);
-            }
-        } else {
-            config = getConfiguration();
-        }
-        r = new Resources(assets, dm, config, compatInfo, token);
-        if (false) {
-            Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
-                    + r.getConfiguration() + " appScale="
-                    + r.getCompatibilityInfo().applicationScale);
-        }
-
-        synchronized (mPackages) {
-            WeakReference<Resources> wr = mActiveResources.get(key);
-            Resources existing = wr != null ? wr.get() : null;
-            if (existing != null && existing.getAssets().isUpToDate()) {
-                // Someone else already created the resources while we were
-                // unlocked; go ahead and use theirs.
-                r.getAssets().close();
-                return existing;
-            }
-
-            // XXX need to remove entries when weak references go away
-            mActiveResources.put(key, new WeakReference<Resources>(r));
-            return r;
-        }
-    }
-
-    /**
      * Creates the top level resources for the given package.
      */
     Resources getTopLevelResources(String resDir,
             int displayId, Configuration overrideConfiguration,
             LoadedApk pkgInfo) {
-        return getTopLevelResources(resDir, displayId, overrideConfiguration,
+        return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration,
                 pkgInfo.getCompatibilityInfo(), null);
     }
 
@@ -1863,7 +1677,7 @@
 
     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
             int flags, int userId) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
                 ref = mPackages.get(packageName);
@@ -1933,7 +1747,7 @@
     }
 
     public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if (includeCode) {
                 ref = mPackages.get(packageName);
@@ -1946,7 +1760,7 @@
 
     private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
             ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if (includeCode) {
                 ref = mPackages.get(aInfo.packageName);
@@ -1978,6 +1792,7 @@
     }
 
     ActivityThread() {
+        mResourcesManager = ResourcesManager.getInstance();
     }
 
     public ApplicationThread getApplicationThread()
@@ -1990,10 +1805,6 @@
         return mInstrumentation;
     }
 
-    public Configuration getConfiguration() {
-        return mResConfiguration;
-    }
-
     public boolean isProfiling() {
         return mProfiler != null && mProfiler.profileFile != null
                 && mProfiler.profileFd == null;
@@ -2023,8 +1834,8 @@
                 LoadedApk info = new LoadedApk(this, "android", context, null,
                         CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
                 context.init(info, null, this);
-                context.getResources().updateConfiguration(getConfiguration(),
-                        getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
+                context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),
+                        mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
                 mSystemContext = context;
                 //Slog.i(TAG, "Created system resources " + context.getResources()
                 //        + ": " + context.getResources().getConfiguration());
@@ -2452,7 +2263,14 @@
         } catch (RemoteException e) {
         }
     }
-    
+
+    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.activity.onTranslucentConversionComplete(drawComplete);
+        }
+    }
+
     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
 
     /**
@@ -3419,7 +3237,7 @@
     }
 
     private void handleSetCoreSettings(Bundle coreSettings) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             mCoreSettings = coreSettings;
         }
     }
@@ -3509,7 +3327,7 @@
     private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
             int configChanges, boolean getNonConfigInstance) {
         ActivityClientRecord r = mActivities.get(token);
-        Class activityClass = null;
+        Class<? extends Activity> activityClass = null;
         if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
         if (r != null) {
             activityClass = r.activity.getClass();
@@ -3664,7 +3482,7 @@
             boolean fromServer) {
         ActivityClientRecord target = null;
 
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             for (int i=0; i<mRelaunchingActivities.size(); i++) {
                 ActivityClientRecord r = mRelaunchingActivities.get(i);
                 if (r.token == token) {
@@ -3725,7 +3543,7 @@
         // First: make sure we have the most recent configuration and most
         // recent version of the activity, or skip it if some previous call
         // had taken a more recent version.
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             int N = mRelaunchingActivities.size();
             IBinder token = tmp.token;
             tmp = null;
@@ -3854,7 +3672,7 @@
         ArrayList<ComponentCallbacks2> callbacks
                 = new ArrayList<ComponentCallbacks2>();
 
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             final int N = mAllApplications.size();
             for (int i=0; i<N; i++) {
                 callbacks.add(mAllApplications.get(i));
@@ -3948,114 +3766,18 @@
     }
 
     public final void applyConfigurationToResources(Configuration config) {
-        synchronized (mPackages) {
-            applyConfigurationToResourcesLocked(config, null);
+        synchronized (mResourcesManager) {
+            mResourcesManager.applyConfigurationToResourcesLocked(config, null);
         }
     }
 
-    final boolean applyConfigurationToResourcesLocked(Configuration config,
-            CompatibilityInfo compat) {
-        if (mResConfiguration == null) {
-            mResConfiguration = new Configuration();
-        }
-        if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
-            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
-                    + mResConfiguration.seq + ", newSeq=" + config.seq);
-            return false;
-        }
-        int changes = mResConfiguration.updateFrom(config);
-        flushDisplayMetricsLocked();
-        DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
-
-        if (compat != null && (mResCompatibilityInfo == null ||
-                !mResCompatibilityInfo.equals(compat))) {
-            mResCompatibilityInfo = compat;
-            changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
-                    | ActivityInfo.CONFIG_SCREEN_SIZE
-                    | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
-        }
-
-        // set it for java, this also affects newly created Resources
-        if (config.locale != null) {
-            Locale.setDefault(config.locale);
-        }
-
-        Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
-
-        ApplicationPackageManager.configurationChanged();
-        //Slog.i(TAG, "Configuration changed in " + currentPackageName());
-
-        Configuration tmpConfig = null;
-
-        Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
-                mActiveResources.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
-            Resources r = entry.getValue().get();
-            if (r != null) {
-                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
-                        + r + " config to: " + config);
-                int displayId = entry.getKey().mDisplayId;
-                boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-                DisplayMetrics dm = defaultDisplayMetrics;
-                Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
-                if (!isDefaultDisplay || overrideConfig != null) {
-                    if (tmpConfig == null) {
-                        tmpConfig = new Configuration();
-                    }
-                    tmpConfig.setTo(config);
-                    if (!isDefaultDisplay) {
-                        dm = getDisplayMetricsLocked(displayId);
-                        applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
-                    }
-                    if (overrideConfig != null) {
-                        tmpConfig.updateFrom(overrideConfig);
-                    }
-                    r.updateConfiguration(tmpConfig, dm, compat);
-                } else {
-                    r.updateConfiguration(config, dm, compat);
-                }
-                //Slog.i(TAG, "Updated app resources " + v.getKey()
-                //        + " " + r + ": " + r.getConfiguration());
-            } else {
-                //Slog.i(TAG, "Removing old resources " + v.getKey());
-                it.remove();
-            }
-        }
-        
-        return changes != 0;
-    }
-
-    final void applyNonDefaultDisplayMetricsToConfigurationLocked(
-            DisplayMetrics dm, Configuration config) {
-        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
-        config.densityDpi = dm.densityDpi;
-        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
-        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
-        int sl = Configuration.resetScreenLayout(config.screenLayout);
-        if (dm.widthPixels > dm.heightPixels) {
-            config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-            config.screenLayout = Configuration.reduceScreenLayout(sl,
-                    config.screenWidthDp, config.screenHeightDp);
-        } else {
-            config.orientation = Configuration.ORIENTATION_PORTRAIT;
-            config.screenLayout = Configuration.reduceScreenLayout(sl,
-                    config.screenHeightDp, config.screenWidthDp);
-        }
-        config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-        config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
-    }
-
     final Configuration applyCompatConfiguration(int displayDensity) {
         Configuration config = mConfiguration;
         if (mCompatConfiguration == null) {
             mCompatConfiguration = new Configuration();
         }
         mCompatConfiguration.setTo(mConfiguration);
-        if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
-            mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
+        if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
             config = mCompatConfiguration;
         }
         return config;
@@ -4065,7 +3787,7 @@
 
         int configDiff = 0;
 
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             if (mPendingConfiguration != null) {
                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
                     config = mPendingConfiguration;
@@ -4081,9 +3803,9 @@
             
             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
                     + config);
-        
-            applyConfigurationToResourcesLocked(config, compat);
-            
+
+            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
+
             if (mConfiguration == null) {
                 mConfiguration = new Configuration();
             }
@@ -4333,7 +4055,7 @@
          * reflect configuration changes. The configuration object passed
          * in AppBindData can be safely assumed to be up to date
          */
-        applyConfigurationToResourcesLocked(data.config, data.compatInfo);
+        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
         mCurDefaultDisplayDpi = data.config.densityDpi;
         applyCompatConfiguration(mCurDefaultDisplayDpi);
 
@@ -5045,6 +4767,7 @@
         mSystemThread = system;
         if (!system) {
             ViewRootImpl.addFirstDrawHandler(new Runnable() {
+                @Override
                 public void run() {
                     ensureJitEnabled();
                 }
@@ -5081,12 +4804,13 @@
         DropBox.setReporter(new DropBoxReporter());
 
         ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
+            @Override
             public void onConfigurationChanged(Configuration newConfig) {
-                synchronized (mPackages) {
+                synchronized (mResourcesManager) {
                     // We need to apply this change to the resources
                     // immediately, because upon returning the view
                     // hierarchy will be informed about it.
-                    if (applyConfigurationToResourcesLocked(newConfig, null)) {
+                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                         // This actually changed the resources!  Tell
                         // everyone about it.
                         if (mPendingConfiguration == null ||
@@ -5098,8 +4822,10 @@
                     }
                 }
             }
+            @Override
             public void onLowMemory() {
             }
+            @Override
             public void onTrimMemory(int level) {
             }
         });
@@ -5119,12 +4845,11 @@
     }
 
     public int getIntCoreSetting(String key, int defaultValue) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             if (mCoreSettings != null) {
                 return mCoreSettings.getInt(key, defaultValue);
-            } else {
-                return defaultValue;
             }
+            return defaultValue;
         }
     }
 
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 32bb71e..de94bb7 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -33,21 +33,22 @@
 /**
  * API for interacting with "application operation" tracking.  Allows you to:
  *
- * - Note when operations are happening, and find out if they are allowed for the current caller.
- * - Disallow specific apps from doing specific operations.
- * - Collect all of the current information about operations that have been executed or are not
- * being allowed.
- * - Monitor for changes in whether an operation is allowed.
+ * <ul>
+ * <li> Note when operations are happening, and find out if they are allowed for the current
+ * caller.</li>
+ * <li> Disallow specific apps from doing specific operations.</li>
+ * <li> Collect all of the current information about operations that have been executed or are not
+ * being allowed.</li>
+ * <li> Monitor for changes in whether an operation is allowed.</li>
+ * </ul>
  *
- * Each operation is identified by a single integer; these integers are a fixed set of
+ * <p>Each operation is identified by a single integer; these integers are a fixed set of
  * operations, enumerated by the OP_* constants.
  *
- * When checking operations, the result is a "mode" integer indicating the current setting
+ * <p></p>When checking operations, the result is a "mode" integer indicating the current setting
  * for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute the operation but
  * fake its behavior enough so that the caller doesn't crash), MODE_ERRORED (through a
  * SecurityException back to the caller; the normal operation calls will do this for you).
- *
- * @hide
  */
 public class AppOpsManager {
     final Context mContext;
@@ -63,50 +64,95 @@
     //  - increment _NUM_OP
     //  - add rows to sOpToSwitch, sOpNames, sOpPerms
     //  - add descriptive strings to Settings/res/values/arrays.xml
+
+    /** No operation specified. */
     public static final int OP_NONE = -1;
+    /** Access to coarse location information. */
     public static final int OP_COARSE_LOCATION = 0;
+    /** Access to fine location information. */
     public static final int OP_FINE_LOCATION = 1;
+    /** Causing GPS to run. */
     public static final int OP_GPS = 2;
-    public static final int OP_VIBRATE = 3;
-    public static final int OP_READ_CONTACTS = 4;
-    public static final int OP_WRITE_CONTACTS = 5;
-    public static final int OP_READ_CALL_LOG = 6;
-    public static final int OP_WRITE_CALL_LOG = 7;
-    public static final int OP_READ_CALENDAR = 8;
-    public static final int OP_WRITE_CALENDAR = 9;
-    public static final int OP_WIFI_SCAN = 10;
-    public static final int OP_POST_NOTIFICATION = 11;
-    public static final int OP_NEIGHBORING_CELLS = 12;
-    public static final int OP_CALL_PHONE = 13;
-    public static final int OP_READ_SMS = 14;
-    public static final int OP_WRITE_SMS = 15;
-    public static final int OP_RECEIVE_SMS = 16;
-    public static final int OP_RECEIVE_EMERGECY_SMS = 17;
-    public static final int OP_RECEIVE_MMS = 18;
-    public static final int OP_RECEIVE_WAP_PUSH = 19;
-    public static final int OP_SEND_SMS = 20;
-    public static final int OP_READ_ICC_SMS = 21;
-    public static final int OP_WRITE_ICC_SMS = 22;
-    public static final int OP_WRITE_SETTINGS = 23;
-    public static final int OP_SYSTEM_ALERT_WINDOW = 24;
-    public static final int OP_ACCESS_NOTIFICATIONS = 25;
-    public static final int OP_CAMERA = 26;
-    public static final int OP_RECORD_AUDIO = 27;
-    public static final int OP_PLAY_AUDIO = 28;
-    public static final int OP_READ_CLIPBOARD = 29;
-    public static final int OP_WRITE_CLIPBOARD = 30;
-    public static final int OP_TAKE_MEDIA_BUTTONS = 31;
-    public static final int OP_TAKE_AUDIO_FOCUS = 32;
-    public static final int OP_AUDIO_MASTER_VOLUME = 33;
-    public static final int OP_AUDIO_VOICE_VOLUME = 34;
-    public static final int OP_AUDIO_RING_VOLUME = 35;
-    public static final int OP_AUDIO_MEDIA_VOLUME = 36;
-    public static final int OP_AUDIO_ALARM_VOLUME = 37;
-    public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
-    public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
-    public static final int OP_WAKE_LOCK = 40;
     /** @hide */
-    public static final int _NUM_OP = 41;
+    public static final int OP_VIBRATE = 3;
+    /** @hide */
+    public static final int OP_READ_CONTACTS = 4;
+    /** @hide */
+    public static final int OP_WRITE_CONTACTS = 5;
+    /** @hide */
+    public static final int OP_READ_CALL_LOG = 6;
+    /** @hide */
+    public static final int OP_WRITE_CALL_LOG = 7;
+    /** @hide */
+    public static final int OP_READ_CALENDAR = 8;
+    /** @hide */
+    public static final int OP_WRITE_CALENDAR = 9;
+    /** @hide */
+    public static final int OP_WIFI_SCAN = 10;
+    /** @hide */
+    public static final int OP_POST_NOTIFICATION = 11;
+    /** @hide */
+    public static final int OP_NEIGHBORING_CELLS = 12;
+    /** @hide */
+    public static final int OP_CALL_PHONE = 13;
+    /** @hide */
+    public static final int OP_READ_SMS = 14;
+    /** @hide */
+    public static final int OP_WRITE_SMS = 15;
+    /** @hide */
+    public static final int OP_RECEIVE_SMS = 16;
+    /** @hide */
+    public static final int OP_RECEIVE_EMERGECY_SMS = 17;
+    /** @hide */
+    public static final int OP_RECEIVE_MMS = 18;
+    /** @hide */
+    public static final int OP_RECEIVE_WAP_PUSH = 19;
+    /** @hide */
+    public static final int OP_SEND_SMS = 20;
+    /** @hide */
+    public static final int OP_READ_ICC_SMS = 21;
+    /** @hide */
+    public static final int OP_WRITE_ICC_SMS = 22;
+    /** @hide */
+    public static final int OP_WRITE_SETTINGS = 23;
+    /** @hide */
+    public static final int OP_SYSTEM_ALERT_WINDOW = 24;
+    /** @hide */
+    public static final int OP_ACCESS_NOTIFICATIONS = 25;
+    /** @hide */
+    public static final int OP_CAMERA = 26;
+    /** @hide */
+    public static final int OP_RECORD_AUDIO = 27;
+    /** @hide */
+    public static final int OP_PLAY_AUDIO = 28;
+    /** @hide */
+    public static final int OP_READ_CLIPBOARD = 29;
+    /** @hide */
+    public static final int OP_WRITE_CLIPBOARD = 30;
+    /** @hide */
+    public static final int OP_TAKE_MEDIA_BUTTONS = 31;
+    /** @hide */
+    public static final int OP_TAKE_AUDIO_FOCUS = 32;
+    /** @hide */
+    public static final int OP_AUDIO_MASTER_VOLUME = 33;
+    /** @hide */
+    public static final int OP_AUDIO_VOICE_VOLUME = 34;
+    /** @hide */
+    public static final int OP_AUDIO_RING_VOLUME = 35;
+    /** @hide */
+    public static final int OP_AUDIO_MEDIA_VOLUME = 36;
+    /** @hide */
+    public static final int OP_AUDIO_ALARM_VOLUME = 37;
+    /** @hide */
+    public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
+    /** @hide */
+    public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
+    /** @hide */
+    public static final int OP_WAKE_LOCK = 40;
+    /** Continually monitoring location data. */
+    public static final int OP_MONITOR_LOCATION = 41;
+    /** @hide */
+    public static final int _NUM_OP = 42;
 
     /**
      * This maps each operation to the operation that serves as the
@@ -158,6 +204,7 @@
             OP_AUDIO_NOTIFICATION_VOLUME,
             OP_AUDIO_BLUETOOTH_VOLUME,
             OP_WAKE_LOCK,
+            OP_COARSE_LOCATION,
     };
 
     /**
@@ -206,6 +253,7 @@
             "AUDIO_NOTIFICATION_VOLUME",
             "AUDIO_BLUETOOTH_VOLUME",
             "WAKE_LOCK",
+            "MONITOR_LOCATION",
     };
 
     /**
@@ -254,10 +302,12 @@
             null, // no permission for changing notification volume
             null, // no permission for changing bluetooth volume
             android.Manifest.permission.WAKE_LOCK,
+            null, // no permission for generic location monitoring
     };
 
     /**
      * Retrieve the op switch that controls the given operation.
+     * @hide
      */
     public static int opToSwitch(int op) {
         return sOpToSwitch[op];
@@ -273,6 +323,7 @@
 
     /**
      * Retrieve the permission associated with an operation, or null if there is not one.
+     * @hide
      */
     public static String opToPermission(int op) {
         return sOpPerms[op];
@@ -280,6 +331,7 @@
 
     /**
      * Class holding all of the operation information associated with an app.
+     * @hide
      */
     public static class PackageOps implements Parcelable {
         private final String mPackageName;
@@ -342,6 +394,7 @@
 
     /**
      * Class holding the information about one unique operation of an application.
+     * @hide
      */
     public static class OpEntry implements Parcelable {
         private final int mOp;
@@ -422,7 +475,7 @@
         public void opChanged(int op, String packageName);
     }
 
-    public AppOpsManager(Context context, IAppOpsService service) {
+    AppOpsManager(Context context, IAppOpsService service) {
         mContext = context;
         mService = service;
     }
@@ -431,6 +484,7 @@
      * Retrieve current operation state for all applications.
      *
      * @param ops The set of operations you are interested in, or null if you want all of them.
+     * @hide
      */
     public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
         try {
@@ -446,6 +500,7 @@
      * @param uid The uid of the application of interest.
      * @param packageName The name of the application of interest.
      * @param ops The set of operations you are interested in, or null if you want all of them.
+     * @hide
      */
     public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
         try {
@@ -455,6 +510,7 @@
         return null;
     }
 
+    /** @hide */
     public void setMode(int code, int uid, String packageName, int mode) {
         try {
             mService.setMode(code, uid, packageName, mode);
@@ -462,6 +518,12 @@
         }
     }
 
+    /**
+     * Monitor for changes to the operating mode for the given op in the given app package.
+     * @param op The operation to monitor, one of OP_*.
+     * @param packageName The name of the application to monitor.
+     * @param callback Where to report changes.
+     */
     public void startWatchingMode(int op, String packageName, final Callback callback) {
         synchronized (mModeWatchers) {
             IAppOpsCallback cb = mModeWatchers.get(callback);
@@ -480,6 +542,10 @@
         }
     }
 
+    /**
+     * Stop monitoring that was previously started with {@link #startWatchingMode}.  All
+     * monitoring associated with this callback will be removed.
+     */
     public void stopWatchingMode(Callback callback) {
         synchronized (mModeWatchers) {
             IAppOpsCallback cb = mModeWatchers.get(callback);
@@ -492,6 +558,22 @@
         }
     }
 
+    /**
+     * Do a quick check for whether an application might be able to perform an operation.
+     * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
+     * or {@link #startOp(int, int, String)} for your actual security checks, which also
+     * ensure that the given uid and package name are consistent.  This function can just be
+     * used for a quick check to see if an operation has been disabled for the application,
+     * as an early reject of some work.  This does not modify the time stamp or other data
+     * about the operation.
+     * @param op The operation to check.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
     public int checkOp(int op, int uid, String packageName) {
         try {
             int mode = mService.checkOperation(op, uid, packageName);
@@ -504,6 +586,10 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     */
     public int checkOpNoThrow(int op, int uid, String packageName) {
         try {
             return mService.checkOperation(op, uid, packageName);
@@ -512,6 +598,20 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Make note of an application performing an operation.  Note that you must pass
+     * in both the uid and name of the application to be checked; this function will verify
+     * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
+     * succeeds, the last execution time of the operation for this app will be updated to
+     * the current time.
+     * @param op The operation to note.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
     public int noteOp(int op, int uid, String packageName) {
         try {
             int mode = mService.noteOperation(op, uid, packageName);
@@ -524,6 +624,10 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     */
     public int noteOpNoThrow(int op, int uid, String packageName) {
         try {
             return mService.noteOperation(op, uid, packageName);
@@ -532,10 +636,27 @@
         return MODE_IGNORED;
     }
 
+    /** @hide */
     public int noteOp(int op) {
         return noteOp(op, Process.myUid(), mContext.getBasePackageName());
     }
 
+    /**
+     * Report that an application has started executing a long-running operation.  Note that you
+     * must pass in both the uid and name of the application to be checked; this function will
+     * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
+     * succeeds, the last execution time of the operation for this app will be updated to
+     * the current time and the operation will be marked as "running".  In this case you must
+     * later call {@link #finishOp(int, int, String)} to report when the application is no
+     * longer performing the operation.
+     * @param op The operation to start.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
     public int startOp(int op, int uid, String packageName) {
         try {
             int mode = mService.startOperation(op, uid, packageName);
@@ -548,6 +669,10 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     */
     public int startOpNoThrow(int op, int uid, String packageName) {
         try {
             return mService.startOperation(op, uid, packageName);
@@ -556,10 +681,17 @@
         return MODE_IGNORED;
     }
 
+    /** @hide */
     public int startOp(int op) {
         return startOp(op, Process.myUid(), mContext.getBasePackageName());
     }
 
+    /**
+     * Report that an application is no longer performing an operation that had previously
+     * been started with {@link #startOp(int, int, String)}.  There is no validation of input
+     * or result; the parameters supplied here must be the exact same ones previously passed
+     * in when starting the operation.
+     */
     public void finishOp(int op, int uid, String packageName) {
         try {
             mService.finishOperation(op, uid, packageName);
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index e903447..cc495aa 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -603,6 +603,16 @@
             reply.writeNoException();
             return true;
         }
+
+        case SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean timeout = data.readInt() == 1;
+            scheduleTranslucentConversionComplete(token, timeout);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -1197,6 +1207,7 @@
         data.recycle();
     }
 
+    @Override
     public void unstableProviderDied(IBinder provider) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1205,6 +1216,7 @@
         data.recycle();
     }
 
+    @Override
     public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -1215,4 +1227,15 @@
         mRemote.transact(REQUEST_ACTIVITY_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
+
+    @Override
+    public void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        data.writeInt(timeout ? 1 : 0);
+        mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a5106e4..6a0fbd5 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -192,6 +192,7 @@
     private Context mReceiverRestrictedContext = null;
     private boolean mRestricted;
     private UserHandle mUser;
+    private ResourcesManager mResourcesManager;
 
     private final Object mSync = new Object();
 
@@ -1832,8 +1833,9 @@
 
         ContextImpl c = new ContextImpl();
         c.init(mPackageInfo, null, mMainThread);
-        c.mResources = mMainThread.getTopLevelResources(mPackageInfo.getResDir(), getDisplayId(),
-                overrideConfiguration, mResources.getCompatibilityInfo(), mActivityToken);
+        c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
+                getDisplayId(), overrideConfiguration, mResources.getCompatibilityInfo(),
+                mActivityToken);
         return c;
     }
 
@@ -1849,8 +1851,8 @@
         context.init(mPackageInfo, null, mMainThread);
         context.mDisplay = display;
         DisplayAdjustments daj = getDisplayAdjustments(displayId);
-        context.mResources = mMainThread.getTopLevelResources(mPackageInfo.getResDir(), displayId,
-                null, daj.getCompatibilityInfo(), null);
+        context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
+                displayId, null, daj.getCompatibilityInfo(), null);
         return context;
     }
 
@@ -1929,6 +1931,7 @@
         mPackageInfo = packageInfo;
         mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
         mResources = mPackageInfo.getResources(mainThread);
+        mResourcesManager = ResourcesManager.getInstance();
 
         CompatibilityInfo compatInfo =
                 container == null ? null : container.getCompatibilityInfo();
@@ -1945,7 +1948,7 @@
             }
             mDisplayAdjustments.setCompatibilityInfo(compatInfo);
             mDisplayAdjustments.setActivityToken(activityToken);
-            mResources = mainThread.getTopLevelResources(mPackageInfo.getResDir(),
+            mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
                     Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
         } else {
             mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 3793c73..19858dc 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -258,7 +258,7 @@
             StrictMode.ViolationInfo crashInfo) throws RemoteException;
 
     /*
-     * This will deliver the specified signal to all the persistent processes. Currently only 
+     * This will deliver the specified signal to all the persistent processes. Currently only
      * SIGUSR1 is delivered. All others are ignored.
      */
     public void signalPersistentProcesses(int signal) throws RemoteException;
@@ -301,7 +301,9 @@
 
     public void finishHeavyWeightApp() throws RemoteException;
 
-    public void convertToOpaque(IBinder token) throws RemoteException;
+    public void convertFromTranslucent(IBinder token) throws RemoteException;
+    public void convertToTranslucent(IBinder token) throws RemoteException;
+    public void notifyActivityDrawn(IBinder token) throws RemoteException;
 
     public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
     public boolean isImmersive(IBinder token) throws RemoteException;
@@ -494,7 +496,7 @@
             thisTime = source.readLong();
             totalTime = source.readLong();
         }
-    };
+    }
 
     String descriptor = "android.app.IActivityManager";
 
@@ -670,6 +672,8 @@
     int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
     int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
     int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
-    int CONVERT_TO_OPAQUE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
-    int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
+    int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
+    int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
+    int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
+    int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index a009bd3..286566d 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -133,6 +133,8 @@
     void unstableProviderDied(IBinder provider) throws RemoteException;
     void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
             throws RemoteException;
+    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
+            throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -183,4 +185,5 @@
     int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
     int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
     int REQUEST_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
+    int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
 }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 573a6aa..05d3a47 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -138,11 +138,11 @@
             if (ActivityThread.mSystemContext == null) {
                 ActivityThread.mSystemContext =
                     ContextImpl.createSystemContext(mainThread);
+                ResourcesManager resourcesManager = ResourcesManager.getInstance();
                 ActivityThread.mSystemContext.getResources().updateConfiguration(
-                         mainThread.getConfiguration(),
-                         mainThread.getDisplayMetricsLocked(
-                                 Display.DEFAULT_DISPLAY, mDisplayAdjustments),
-                         compatInfo);
+                        resourcesManager.getConfiguration(),
+                        resourcesManager.getDisplayMetricsLocked(
+                                 Display.DEFAULT_DISPLAY, mDisplayAdjustments), compatInfo);
                 //Slog.i(TAG, "Created system resources "
                 //        + mSystemContext.getResources() + ": "
                 //        + mSystemContext.getResources().getConfiguration());
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
new file mode 100644
index 0000000..e9693dd
--- /dev/null
+++ b/core/java/android/app/ResourcesManager.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import static android.app.ActivityThread.DEBUG_CONFIGURATION;
+
+import android.app.ApplicationPackageManager;
+import android.content.pm.ActivityInfo;
+import android.content.res.AssetManager;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.ResourcesKey;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.IBinder;
+import android.util.ArrayMap;
+import android.util.DisplayMetrics;
+import android.util.Slog;
+import android.view.Display;
+import android.view.DisplayAdjustments;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+/** @hide */
+public class ResourcesManager {
+    static final String TAG = "ResourcesManager";
+    static final boolean DEBUG_CACHE = false;
+    static final boolean DEBUG_STATS = true;
+
+    private static ResourcesManager sResourcesManager;
+    final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
+            = new HashMap<ResourcesKey, WeakReference<Resources> >();
+
+    final ArrayMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics
+            = new ArrayMap<DisplayAdjustments, DisplayMetrics>();
+
+    CompatibilityInfo mResCompatibilityInfo;
+
+    Configuration mResConfiguration;
+    final Configuration mTmpConfig = new Configuration();
+
+    public static ResourcesManager getInstance() {
+        synchronized (ResourcesManager.class) {
+            if (sResourcesManager == null) {
+                sResourcesManager = new ResourcesManager();
+            }
+            return sResourcesManager;
+        }
+    }
+
+    public Configuration getConfiguration() {
+        return mResConfiguration;
+    }
+
+    public void flushDisplayMetricsLocked() {
+        mDefaultDisplayMetrics.clear();
+    }
+
+    public DisplayMetrics getDisplayMetricsLocked(int displayId) {
+        return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+    }
+
+    public DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) {
+        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+        DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null;
+        if (dm != null) {
+            return dm;
+        }
+        dm = new DisplayMetrics();
+
+        DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
+        if (displayManager == null) {
+            // may be null early in system startup
+            dm.setToDefaults();
+            return dm;
+        }
+
+        if (isDefaultDisplay) {
+            mDefaultDisplayMetrics.put(daj, dm);
+        }
+
+        Display d = displayManager.getCompatibleDisplay(displayId, daj);
+        if (d != null) {
+            d.getMetrics(dm);
+        } else {
+            // Display no longer exists
+            // FIXME: This would not be a problem if we kept the Display object around
+            // instead of using the raw display id everywhere.  The Display object caches
+            // its information even after the display has been removed.
+            dm.setToDefaults();
+        }
+        //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
+        //        + metrics.heightPixels + " den=" + metrics.density
+        //        + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
+        return dm;
+    }
+
+    final void applyNonDefaultDisplayMetricsToConfigurationLocked(
+            DisplayMetrics dm, Configuration config) {
+        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
+        config.densityDpi = dm.densityDpi;
+        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
+        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
+        int sl = Configuration.resetScreenLayout(config.screenLayout);
+        if (dm.widthPixels > dm.heightPixels) {
+            config.orientation = Configuration.ORIENTATION_LANDSCAPE;
+            config.screenLayout = Configuration.reduceScreenLayout(sl,
+                    config.screenWidthDp, config.screenHeightDp);
+        } else {
+            config.orientation = Configuration.ORIENTATION_PORTRAIT;
+            config.screenLayout = Configuration.reduceScreenLayout(sl,
+                    config.screenHeightDp, config.screenWidthDp);
+        }
+        config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
+        config.compatScreenWidthDp = config.screenWidthDp;
+        config.compatScreenHeightDp = config.screenHeightDp;
+        config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
+    }
+
+    public boolean applyCompatConfiguration(int displayDensity,
+            Configuration compatConfiguration) {
+        if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
+            mResCompatibilityInfo.applyToConfiguration(displayDensity, compatConfiguration);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Creates the top level Resources for applications with the given compatibility info.
+     *
+     * @param resDir the resource directory.
+     * @param compatInfo the compability info. Must not be null.
+     * @param token the application token for determining stack bounds.
+     */
+    public Resources getTopLevelResources(String resDir, int displayId,
+            Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
+        final float scale = compatInfo.applicationScale;
+        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
+                token);
+        Resources r;
+        synchronized (this) {
+            // Resources is app scale dependent.
+            if (false) {
+                Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale);
+            }
+            WeakReference<Resources> wr = mActiveResources.get(key);
+            r = wr != null ? wr.get() : null;
+            //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
+            if (r != null && r.getAssets().isUpToDate()) {
+                if (false) {
+                    Slog.w(TAG, "Returning cached resources " + r + " " + resDir
+                            + ": appScale=" + r.getCompatibilityInfo().applicationScale);
+                }
+                return r;
+            }
+        }
+
+        //if (r != null) {
+        //    Slog.w(TAG, "Throwing away out-of-date resources!!!! "
+        //            + r + " " + resDir);
+        //}
+
+        AssetManager assets = new AssetManager();
+        if (assets.addAssetPath(resDir) == 0) {
+            return null;
+        }
+
+        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
+        DisplayMetrics dm = getDisplayMetricsLocked(displayId);
+        Configuration config;
+        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+        final boolean hasOverrideConfig = key.hasOverrideConfiguration();
+        if (!isDefaultDisplay || hasOverrideConfig) {
+            config = new Configuration(getConfiguration());
+            if (!isDefaultDisplay) {
+                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
+            }
+            if (hasOverrideConfig) {
+                config.updateFrom(key.mOverrideConfiguration);
+            }
+        } else {
+            config = getConfiguration();
+        }
+        r = new Resources(assets, dm, config, compatInfo, token);
+        if (false) {
+            Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
+                    + r.getConfiguration() + " appScale="
+                    + r.getCompatibilityInfo().applicationScale);
+        }
+
+        synchronized (this) {
+            WeakReference<Resources> wr = mActiveResources.get(key);
+            Resources existing = wr != null ? wr.get() : null;
+            if (existing != null && existing.getAssets().isUpToDate()) {
+                // Someone else already created the resources while we were
+                // unlocked; go ahead and use theirs.
+                r.getAssets().close();
+                return existing;
+            }
+
+            // XXX need to remove entries when weak references go away
+            mActiveResources.put(key, new WeakReference<Resources>(r));
+            return r;
+        }
+    }
+
+    public final boolean applyConfigurationToResourcesLocked(Configuration config,
+            CompatibilityInfo compat) {
+        if (mResConfiguration == null) {
+            mResConfiguration = new Configuration();
+        }
+        if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
+            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
+                    + mResConfiguration.seq + ", newSeq=" + config.seq);
+            return false;
+        }
+        int changes = mResConfiguration.updateFrom(config);
+        flushDisplayMetricsLocked();
+        DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
+
+        if (compat != null && (mResCompatibilityInfo == null ||
+                !mResCompatibilityInfo.equals(compat))) {
+            mResCompatibilityInfo = compat;
+            changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
+                    | ActivityInfo.CONFIG_SCREEN_SIZE
+                    | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+        }
+
+        // set it for java, this also affects newly created Resources
+        if (config.locale != null) {
+            Locale.setDefault(config.locale);
+        }
+
+        Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
+
+        ApplicationPackageManager.configurationChanged();
+        //Slog.i(TAG, "Configuration changed in " + currentPackageName());
+
+        Configuration tmpConfig = null;
+
+        Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
+                mActiveResources.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
+            Resources r = entry.getValue().get();
+            if (r != null) {
+                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
+                        + r + " config to: " + config);
+                int displayId = entry.getKey().mDisplayId;
+                boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+                DisplayMetrics dm = defaultDisplayMetrics;
+                ResourcesKey resourcesKey = entry.getKey();
+                final boolean hasOverrideConfiguration = resourcesKey.hasOverrideConfiguration();
+                if (!isDefaultDisplay || hasOverrideConfiguration) {
+                    if (tmpConfig == null) {
+                        tmpConfig = new Configuration();
+                    }
+                    tmpConfig.setTo(config);
+                    if (!isDefaultDisplay) {
+                        dm = getDisplayMetricsLocked(displayId);
+                        applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
+                    }
+                    if (hasOverrideConfiguration) {
+                        tmpConfig.updateFrom(resourcesKey.mOverrideConfiguration);
+                    }
+                    r.updateConfiguration(tmpConfig, dm, compat);
+                } else {
+                    r.updateConfiguration(config, dm, compat);
+                }
+                //Slog.i(TAG, "Updated app resources " + v.getKey()
+                //        + " " + r + ": " + r.getConfiguration());
+            } else {
+                //Slog.i(TAG, "Removing old resources " + v.getKey());
+                it.remove();
+            }
+        }
+
+        return changes != 0;
+    }
+
+}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 8f0c62d..810a521 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1569,7 +1569,7 @@
                 currentKey = parsePublicKey(encodedKey);
                 definedKeySets.put(currentKey, new HashSet<String>());
                 sa.recycle();
-             } else if (tagname.equals("keyset")) {
+            } else if (tagname.equals("keyset")) {
                 final TypedArray sa = res.obtainAttributes(attrs,
                         com.android.internal.R.styleable.KeySet);
                 final String name = sa.getNonResourceString(
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index c24e0ee..6483cd9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1668,13 +1668,6 @@
     }
 
     /**
-     * @hide
-     */
-    public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics) {
-        updateSystemConfiguration(config, metrics, null);
-    }
-    
-    /**
      * Return the current display metrics that are in effect for this resource 
      * object.  The returned object should be treated as read-only.
      * 
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
new file mode 100644
index 0000000..53e0f2c
--- /dev/null
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import android.os.IBinder;
+
+/** @hide */
+public final class ResourcesKey {
+    final String mResDir;
+    final float mScale;
+    private final int mHash;
+    private final IBinder mToken;
+
+    public final int mDisplayId;
+    public final Configuration mOverrideConfiguration = new Configuration();
+
+    public ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
+            float scale, IBinder token) {
+        mResDir = resDir;
+        mDisplayId = displayId;
+        if (overrideConfiguration != null) {
+            mOverrideConfiguration.setTo(overrideConfiguration);
+        }
+        mScale = scale;
+        mToken = token;
+
+        int hash = 17;
+        hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
+        hash = 31 * hash + mDisplayId;
+        hash = 31 * hash + (mOverrideConfiguration != null
+                ? mOverrideConfiguration.hashCode() : 0);
+        hash = 31 * hash + Float.floatToIntBits(mScale);
+        mHash = hash;
+    }
+
+    public boolean hasOverrideConfiguration() {
+        return !Configuration.EMPTY.equals(mOverrideConfiguration);
+    }
+
+    @Override
+    public int hashCode() {
+        return mHash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ResourcesKey)) {
+            return false;
+        }
+        ResourcesKey peer = (ResourcesKey) obj;
+        if (!mResDir.equals(peer.mResDir)) {
+            return false;
+        }
+        if (mDisplayId != peer.mDisplayId) {
+            return false;
+        }
+        if (mOverrideConfiguration != peer.mOverrideConfiguration) {
+            if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
+                return false;
+            }
+            if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
+                return false;
+            }
+        }
+        if (mScale != peer.mScale) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toHexString(mHash);
+    }
+}
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 5cc1150..c3e9cb7 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -204,37 +204,71 @@
     // TODO(): The following arrays are fragile and error-prone. This needs to be refactored.
 
     // Note: This needs to be updated, whenever a new sensor is added.
-    private static int[] sSensorReportingModes = {
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ONE_SHOT };
-
-    // Note: This needs to be updated, whenever a new sensor is added.
-    // Holds the maximum length of the values array associated with {@link SensorEvent} or
-    // {@link TriggerEvent} for the Sensor
-    private static int[] sMaxLengthValuesArray = {
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3,
-            6, 4, 6, 1 };
+    // Holds the reporting mode and maximum length of the values array
+    // associated with
+    // {@link SensorEvent} or {@link TriggerEvent} for the Sensor
+    private static final int[] sSensorReportingModes = {
+            0, 0, // padding because sensor types start at 1
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ACCELEROMETER
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GEOMAGNETIC_FIELD
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ORIENTATION
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GYROSCOPE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_LIGHT
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_PRESSURE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_TEMPERATURE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_PROXIMITY
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GRAVITY
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_LINEAR_ACCELERATION
+            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_ROTATION_VECTOR
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_RELATIVE_HUMIDITY
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_AMBIENT_TEMPERATURE
+            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
+            REPORTING_MODE_CONTINUOUS, 4, // SENSOR_TYPE_GAME_ROTATION_VECTOR
+            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+            REPORTING_MODE_ONE_SHOT,   1, // SENSOR_TYPE_SIGNIFICANT_MOTION
+            // added post 4.3
+            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_DETECTOR
+            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_COUNTER
+            REPORTING_MODE_CONTINUOUS, 5  // SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+    };
 
     static int getReportingMode(Sensor sensor) {
-        // mType starts from offset 1.
-        return sSensorReportingModes[sensor.mType - 1];
+        int offset = sensor.mType * 2;
+        if (offset >= sSensorReportingModes.length) {
+            // we don't know about this sensor, so this is probably a
+            // vendor-defined sensor, in that case, we figure out the reporting
+            // mode from the sensor meta-data.
+            int minDelay = sensor.mMinDelay;
+            if (minDelay == 0) {
+                return REPORTING_MODE_ON_CHANGE;
+            } else if (minDelay < 0) {
+                return REPORTING_MODE_ONE_SHOT;
+            } else {
+                return REPORTING_MODE_CONTINUOUS;
+            }
+        }
+        return sSensorReportingModes[offset];
     }
 
     static int getMaxLengthValuesArray(Sensor sensor, int sdkLevel) {
-        // mType starts from offset 1.
-        int len = sMaxLengthValuesArray[sensor.mType - 1];
-
+        int type = sensor.mType;
         // RotationVector length has changed to 3 to 5 for API level 18
         // Set it to 3 for backward compatibility.
-        if (sensor.getType() == Sensor.TYPE_ROTATION_VECTOR &&
+        if (type == Sensor.TYPE_ROTATION_VECTOR &&
                 sdkLevel <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            len = 3;
+            return 3;
         }
-        return len;
+        int offset = type * 2 + 1;
+        if (offset >= sSensorReportingModes.length) {
+            // we don't know about this sensor, so this is probably a
+            // vendor-defined sensor, in that case, we don't know how many value
+            // it has
+            // so we return the maximum and assume the app will know.
+            // FIXME: sensor HAL should advertise how much data is returned per
+            // sensor
+            return 16;
+        }
+        return sSensorReportingModes[offset];
     }
 
     /* Some of these fields are set only by the native bindings in
diff --git a/core/java/android/hardware/photography/CameraMetadata.java b/core/java/android/hardware/photography/CameraMetadata.java
index 5488952..1988967 100644
--- a/core/java/android/hardware/photography/CameraMetadata.java
+++ b/core/java/android/hardware/photography/CameraMetadata.java
@@ -20,7 +20,18 @@
 import android.os.Parcel;
 import android.util.Log;
 
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -72,9 +83,19 @@
      * type to the key.
      */
     public <T> void set(Key<T> key, T value) {
-        Log.e(TAG, "Not fully implemented yet");
+        int tag = key.getTag();
 
-        mMetadataMap.put(key, value);
+        int nativeType = getNativeType(tag);
+
+        int size = packSingle(value, null, key.mType, nativeType, /* sizeOnly */true);
+
+        // TODO: Optimization. Cache the byte[] and reuse if the size is big enough.
+        byte[] values = new byte[size];
+
+        ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
+        packSingle(value, buffer, key.mType, nativeType, /*sizeOnly*/false);
+
+        writeValues(tag, values);
     }
 
     /**
@@ -82,14 +103,536 @@
      * found in {@link CameraProperties}, {@link CaptureResult}, and
      * {@link CaptureRequest}.
      *
+     * @throws IllegalArgumentException if the key was not valid
+     *
      * @param key the metadata field to read.
      * @return the value of that key, or {@code null} if the field is not set.
      */
     @SuppressWarnings("unchecked")
     public <T> T get(Key<T> key) {
-        Log.e(TAG, "Not fully implemented yet");
+        int tag = key.getTag();
+        byte[] values = readValues(tag);
+        if (values == null) {
+            return null;
+        }
 
-        return (T) mMetadataMap.get(key);
+        int nativeType = getNativeType(tag);
+
+        ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
+        return unpackSingle(buffer, key.mType, nativeType);
+    }
+
+    // Keep up-to-date with camera_metadata.h
+    /**
+     * @hide
+     */
+    public static final int TYPE_BYTE = 0;
+    /**
+     * @hide
+     */
+    public static final int TYPE_INT32 = 1;
+    /**
+     * @hide
+     */
+    public static final int TYPE_FLOAT = 2;
+    /**
+     * @hide
+     */
+    public static final int TYPE_INT64 = 3;
+    /**
+     * @hide
+     */
+    public static final int TYPE_DOUBLE = 4;
+    /**
+     * @hide
+     */
+    public static final int TYPE_RATIONAL = 5;
+    /**
+     * @hide
+     */
+    public static final int NUM_TYPES = 6;
+
+    private static int getTypeSize(int nativeType) {
+        switch(nativeType) {
+            case TYPE_BYTE:
+                return 1;
+            case TYPE_INT32:
+            case TYPE_FLOAT:
+                return 4;
+            case TYPE_INT64:
+            case TYPE_DOUBLE:
+            case TYPE_RATIONAL:
+                return 8;
+        }
+
+        throw new UnsupportedOperationException("Unknown type, can't get size "
+                + nativeType);
+    }
+
+    private static Class<?> getExpectedType(int nativeType) {
+        switch(nativeType) {
+            case TYPE_BYTE:
+                return Byte.TYPE;
+            case TYPE_INT32:
+                return Integer.TYPE;
+            case TYPE_FLOAT:
+                return Float.TYPE;
+            case TYPE_INT64:
+                return Long.TYPE;
+            case TYPE_DOUBLE:
+                return Double.TYPE;
+            case TYPE_RATIONAL:
+                return Rational.class;
+        }
+
+        throw new UnsupportedOperationException("Unknown type, can't map to Java type "
+                + nativeType);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> int packSingleNative(T value, ByteBuffer buffer, Class<T> type,
+            int nativeType, boolean sizeOnly) {
+
+        if (!sizeOnly) {
+            /**
+             * Rewrite types when the native type doesn't match the managed type
+             *  - Boolean -> Byte
+             *  - Integer -> Byte
+             */
+
+            if (nativeType == TYPE_BYTE && type == Boolean.TYPE) {
+                // Since a boolean can't be cast to byte, and we don't want to use putBoolean
+                boolean asBool = (Boolean) value;
+                byte asByte = (byte) (asBool ? 1 : 0);
+                value = (T) (Byte) asByte;
+            } else if (nativeType == TYPE_BYTE && type == Integer.TYPE) {
+                int asInt = (Integer) value;
+                byte asByte = (byte) asInt;
+                value = (T) (Byte) asByte;
+            } else if (type != getExpectedType(nativeType)) {
+                throw new UnsupportedOperationException("Tried to pack a type of " + type +
+                        " but we expected the type to be " + getExpectedType(nativeType));
+            }
+
+            if (nativeType == TYPE_BYTE) {
+                buffer.put((Byte) value);
+            } else if (nativeType == TYPE_INT32) {
+                buffer.putInt((Integer) value);
+            } else if (nativeType == TYPE_FLOAT) {
+                buffer.putFloat((Float) value);
+            } else if (nativeType == TYPE_INT64) {
+                buffer.putLong((Long) value);
+            } else if (nativeType == TYPE_DOUBLE) {
+                buffer.putDouble((Double) value);
+            } else if (nativeType == TYPE_RATIONAL) {
+                Rational r = (Rational) value;
+                buffer.putInt(r.getNumerator());
+                buffer.putInt(r.getDenominator());
+            }
+
+        }
+
+        return getTypeSize(nativeType);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private static <T> int packSingle(T value, ByteBuffer buffer, Class<T> type, int nativeType,
+            boolean sizeOnly) {
+
+        int size = 0;
+
+        if (type.isPrimitive() || type == Rational.class) {
+            size = packSingleNative(value, buffer, type, nativeType, sizeOnly);
+        } else if (type.isEnum()) {
+            size = packEnum((Enum)value, buffer, (Class<Enum>)type, nativeType, sizeOnly);
+        } else if (type.isArray()) {
+            size = packArray(value, buffer, type, nativeType, sizeOnly);
+        } else {
+            size = packClass(value, buffer, type, nativeType, sizeOnly);
+        }
+
+        return size;
+    }
+
+    private static <T extends Enum<T>> int packEnum(T value, ByteBuffer buffer, Class<T> type,
+            int nativeType, boolean sizeOnly) {
+
+        // TODO: add support for enums with their own values.
+        return packSingleNative(value.ordinal(), buffer, Integer.TYPE, nativeType, sizeOnly);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> int packClass(T value, ByteBuffer buffer, Class<T> type, int nativeType,
+            boolean sizeOnly) {
+
+        /**
+         * FIXME: This doesn't actually work because getFields() returns fields in an unordered
+         * manner. Although we could sort and get the data to come out correctly on the *java* side,
+         * it would not be data-compatible with our strict XML definitions.
+         *
+         * Rewrite this code to use Parcelables instead, they are most likely compatible with
+         * what we are trying to do in general.
+         */
+        List<Field> instanceFields = findInstanceFields(type);
+        if (instanceFields.size() == 0) {
+            throw new UnsupportedOperationException("Class has no instance fields: " + type);
+        }
+
+        int fieldCount = instanceFields.size();
+        int bufferSize = 0;
+
+        HashSet<Class<?>> fieldTypes = new HashSet<Class<?>>();
+        for (Field f : instanceFields) {
+            fieldTypes.add(f.getType());
+        }
+
+        /**
+         * Pack arguments one field at a time. If we can't access field, look for its accessor
+         * method instead.
+         */
+        for (int i = 0; i < fieldCount; ++i) {
+            Object arg;
+
+            Field f = instanceFields.get(i);
+
+            if ((f.getModifiers() & Modifier.PUBLIC) != 0) {
+                try {
+                    arg = f.get(value);
+                } catch (IllegalAccessException e) {
+                    throw new UnsupportedOperationException(
+                            "Failed to access field " + f + " of type " + type, e);
+                } catch (IllegalArgumentException e) {
+                    throw new UnsupportedOperationException(
+                            "Illegal arguments when accessing field " + f + " of type " + type, e);
+                }
+            } else {
+                Method accessor = null;
+                // try to find a public accessor method
+                for(Method m : type.getMethods()) {
+                    Log.v(TAG, String.format("Looking for getter in method %s for field %s", m, f));
+
+                    // Must have 0 arguments
+                    if (m.getParameterTypes().length != 0) {
+                        continue;
+                    }
+
+                    // Return type must be same as field type
+                    if (m.getReturnType() != f.getType()) {
+                        continue;
+                    }
+
+                    // Strip 'm' from variable prefix if the next letter is capitalized
+                    String fieldName = f.getName();
+                    char[] nameChars = f.getName().toCharArray();
+                    if (nameChars.length >= 2 && nameChars[0] == 'm'
+                            && Character.isUpperCase(nameChars[1])) {
+                        fieldName = String.valueOf(nameChars, /*start*/1, nameChars.length - 1);
+                    }
+
+                    Log.v(TAG, String.format("Normalized field name: %s", fieldName));
+
+                    // #getFoo() , getfoo(), foo(), all match.
+                    if (m.getName().toLowerCase().equals(fieldName.toLowerCase()) ||
+                            m.getName().toLowerCase().equals("get" + fieldName.toLowerCase())) {
+                        accessor = m;
+                        break;
+                    }
+                }
+
+                if (accessor == null) {
+                    throw new UnsupportedOperationException(
+                            "Failed to find getter method for field " + f + " in type " + type);
+                }
+
+                try {
+                    arg = accessor.invoke(value);
+                } catch (IllegalAccessException e) {
+                    // Impossible
+                    throw new UnsupportedOperationException("Failed to access method + " + accessor
+                            + " in type " + type, e);
+                } catch (IllegalArgumentException e) {
+                    // Impossible
+                    throw new UnsupportedOperationException("Bad arguments for method + " + accessor
+                            + " in type " + type, e);
+                } catch (InvocationTargetException e) {
+                    // Possibly but extremely unlikely
+                    throw new UnsupportedOperationException("Failed to invoke method + " + accessor
+                            + " in type " + type, e);
+                }
+            }
+
+            bufferSize += packSingle(arg, buffer, (Class<Object>)f.getType(), nativeType, sizeOnly);
+        }
+
+        return bufferSize;
+    }
+
+    private static <T> int packArray(T value, ByteBuffer buffer, Class<T> type, int nativeType,
+            boolean sizeOnly) {
+
+        int size = 0;
+        int arrayLength = Array.getLength(value);
+
+        @SuppressWarnings("unchecked")
+        Class<Object> componentType = (Class<Object>)type.getComponentType();
+
+        for (int i = 0; i < arrayLength; ++i) {
+            size += packSingle(Array.get(value, i), buffer, componentType, nativeType, sizeOnly);
+        }
+
+        return size;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T unpackSingleNative(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        T val;
+
+        if (nativeType == TYPE_BYTE) {
+            val = (T) (Byte) buffer.get();
+        } else if (nativeType == TYPE_INT32) {
+            val = (T) (Integer) buffer.getInt();
+        } else if (nativeType == TYPE_FLOAT) {
+            val = (T) (Float) buffer.getFloat();
+        } else if (nativeType == TYPE_INT64) {
+            val = (T) (Long) buffer.getLong();
+        } else if (nativeType == TYPE_DOUBLE) {
+            val = (T) (Double) buffer.getDouble();
+        } else if (nativeType == TYPE_RATIONAL) {
+            val = (T) new Rational(buffer.getInt(), buffer.getInt());
+        } else {
+            throw new UnsupportedOperationException("Unknown type, can't unpack a native type "
+                + nativeType);
+        }
+
+        /**
+         * Rewrite types when the native type doesn't match the managed type
+         *  - Byte -> Boolean
+         *  - Byte -> Integer
+         */
+
+        if (nativeType == TYPE_BYTE && type == Boolean.TYPE) {
+            // Since a boolean can't be cast to byte, and we don't want to use getBoolean
+            byte asByte = (Byte) val;
+            boolean asBool = asByte != 0;
+            val = (T) (Boolean) asBool;
+        } else if (nativeType == TYPE_BYTE && type == Integer.TYPE) {
+            byte asByte = (Byte) val;
+            int asInt = asByte;
+            val = (T) (Integer) asInt;
+        } else if (type != getExpectedType(nativeType)) {
+            throw new UnsupportedOperationException("Tried to unpack a type of " + type +
+                    " but we expected the type to be " + getExpectedType(nativeType));
+        }
+
+        return val;
+    }
+
+    private static <T> List<Field> findInstanceFields(Class<T> type) {
+        List<Field> fields = new ArrayList<Field>();
+
+        for (Field f : type.getDeclaredFields()) {
+            if (f.isSynthetic()) {
+                throw new UnsupportedOperationException(
+                        "Marshalling synthetic fields not supported in type " + type);
+            }
+
+            // Skip static fields
+            int modifiers = f.getModifiers();
+            if ((modifiers & Modifier.STATIC) == 0) {
+                fields.add(f);
+            }
+
+            Log.v(TAG, String.format("Field %s has modifiers %d", f, modifiers));
+        }
+
+        if (type.getDeclaredFields().length == 0) {
+            Log.w(TAG, String.format("Type %s had 0 fields of any kind", type));
+        }
+        return fields;
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private static <T> T unpackSingle(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        if (type.isPrimitive() || type == Rational.class) {
+            return unpackSingleNative(buffer, type, nativeType);
+        }
+
+        if (type.isEnum()) {
+            return (T) unpackEnum(buffer, (Class<Enum>)type, nativeType);
+        }
+
+        if (type.isArray()) {
+            return unpackArray(buffer, type, nativeType);
+        }
+
+        T instance = unpackClass(buffer, type, nativeType);
+
+        return instance;
+    }
+
+    private static <T> Constructor<T> findApplicableConstructor(Class<T> type) {
+
+        List<Field> instanceFields = findInstanceFields(type);
+        if (instanceFields.size() == 0) {
+            throw new UnsupportedOperationException("Class has no instance fields: " + type);
+        }
+
+        Constructor<T> constructor = null;
+        int fieldCount = instanceFields.size();
+
+        HashSet<Class<?>> fieldTypes = new HashSet<Class<?>>();
+        for (Field f : instanceFields) {
+            fieldTypes.add(f.getType());
+        }
+
+        /**
+         * Find which constructor to use:
+         * - must be public
+         * - same amount of arguments as there are instance fields
+         * - each argument is same type as each field (in any order)
+         */
+        @SuppressWarnings("unchecked")
+        Constructor<T>[] constructors = (Constructor<T>[]) type.getConstructors();
+        for (Constructor<T> ctor : constructors) {
+            Log.v(TAG, String.format("Inspecting constructor '%s'", ctor));
+
+            Class<?>[] parameterTypes = ctor.getParameterTypes();
+            if (parameterTypes.length == fieldCount) {
+                boolean match = true;
+
+                HashSet<Class<?>> argTypes = new HashSet<Class<?>>();
+                for (Class<?> t : parameterTypes) {
+                    argTypes.add(t);
+                }
+
+                // Order does not matter
+                match = argTypes.equals(fieldTypes);
+
+                /*
+                // check if the types are the same
+                for (int i = 0; i < fieldCount; ++i) {
+                    if (parameterTypes[i] != instanceFields.get(i).getType()) {
+
+                        Log.v(TAG, String.format(
+                                "Constructor arg (%d) type %s did not match field type %s", i,
+                                parameterTypes[i], instanceFields.get(i).getType()));
+
+                        match = false;
+                        break;
+                    }
+                }
+                */
+
+                if (match) {
+                    constructor = ctor;
+                    break;
+                } else {
+                    Log.w(TAG, String.format("Constructor args did not have matching types"));
+                }
+            } else {
+                Log.v(TAG, String.format(
+                        "Constructor did not have expected amount of fields (had %d, expected %d)",
+                        parameterTypes.length, fieldCount));
+            }
+        }
+
+        if (constructors.length == 0) {
+            Log.w(TAG, String.format("Type %s had no public constructors", type));
+        }
+
+        if (constructor == null) {
+            throw new UnsupportedOperationException(
+                    "Failed to find any applicable constructors for type " + type);
+        }
+
+        return constructor;
+    }
+
+    private static <T extends Enum<T>> T unpackEnum(ByteBuffer buffer, Class<T> type,
+            int nativeType) {
+
+        // TODO: add support for enums with their own values.
+
+        T[] values = type.getEnumConstants();
+        int ordinal = unpackSingleNative(buffer, Integer.TYPE, nativeType);
+
+        if (ordinal < 0 || ordinal >= values.length) {
+            Log.e(TAG, String.format("Got invalid enum value %d for type %s, assuming it's 0",
+                    ordinal, type));
+            ordinal = 0;
+        }
+
+        return values[ordinal];
+    }
+
+    private static <T> T unpackClass(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        /**
+         * FIXME: This doesn't actually work because getFields() returns fields in an unordered
+         * manner. Although we could sort and get the data to come out correctly on the *java* side,
+         * it would not be data-compatible with our strict XML definitions.
+         *
+         * Rewrite this code to use Parcelables instead, they are most likely compatible with
+         * what we are trying to do in general.
+         */
+
+        List<Field> instanceFields = findInstanceFields(type);
+        if (instanceFields.size() == 0) {
+            throw new UnsupportedOperationException("Class has no instance fields: " + type);
+        }
+        int fieldCount = instanceFields.size();
+
+        Constructor<T> constructor = findApplicableConstructor(type);
+
+        /**
+         * Build the arguments by unpacking one field at a time
+         * (note that while the field type might be different, the native type is the same)
+         */
+        Object[] arguments = new Object[fieldCount];
+        for (int i = 0; i < fieldCount; ++i) {
+            Object o = unpackSingle(buffer, instanceFields.get(i).getType(), nativeType);
+            arguments[i] = o;
+        }
+
+        T instance;
+        try {
+            instance = constructor.newInstance(arguments);
+        } catch (InstantiationException e) {
+            // type is abstract class, interface, etc...
+            throw new UnsupportedOperationException("Failed to instantiate type " + type, e);
+        } catch (IllegalAccessException e) {
+            // This could happen if we have to access a private.
+            throw new UnsupportedOperationException("Failed to access type " + type, e);
+        } catch (IllegalArgumentException e) {
+            throw new UnsupportedOperationException("Illegal arguments for constructor of type "
+                    + type, e);
+        } catch (InvocationTargetException e) {
+            throw new UnsupportedOperationException(
+                    "Underlying constructor threw exception for type " + type, e);
+        }
+
+        return instance;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T unpackArray(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        Class<?> componentType = type.getComponentType();
+        Object array;
+
+        int remaining = buffer.remaining();
+        // FIXME: Assumes that the rest of the ByteBuffer is part of the array.
+        int arraySize = remaining / getTypeSize(nativeType);
+
+        array = Array.newInstance(componentType, arraySize);
+        for (int i = 0; i < arraySize; ++i) {
+           Object elem = unpackSingle(buffer, componentType, nativeType);
+           Array.set(array, i, elem);
+        }
+
+        return (T) array;
     }
 
     @Override
@@ -111,11 +654,22 @@
     }
 
     public static class Key<T> {
-        public Key(String name) {
+
+        private boolean mHasTag;
+        private int mTag;
+        private final Class<T> mType;
+
+        /*
+         * @hide
+         */
+        public Key(String name, Class<T> type) {
             if (name == null) {
                 throw new NullPointerException("Key needs a valid name");
+            } else if (type == null) {
+                throw new NullPointerException("Type needs to be non-null");
             }
             mName = name;
+            mType = type;
         }
 
         public final String getName() {
@@ -144,13 +698,30 @@
         }
 
         private final String mName;
+
+        /**
+         * <p>
+         * Get the tag corresponding to this key. This enables insertion into the
+         * native metadata.
+         * </p>
+         *
+         * <p>This value is looked up the first time, and cached subsequently.</p>
+         *
+         * @return the tag numeric value corresponding to the string
+         *
+         * @hide
+         */
+        public final int getTag() {
+            if (!mHasTag) {
+                mTag = CameraMetadata.getTag(mName);
+                mHasTag = true;
+            }
+            return mTag;
+        }
     }
 
     private final Map<Key<?>, Object> mMetadataMap;
 
-    /**
-     * @hide
-     */
     private long mMetadataPtr; // native CameraMetadata*
 
     private native long nativeAllocate();
@@ -160,6 +731,14 @@
     private native synchronized void nativeClose();
     private native synchronized boolean nativeIsEmpty();
     private native synchronized int nativeGetEntryCount();
+
+    private native synchronized byte[] nativeReadValues(int tag);
+    private native synchronized void nativeWriteValues(int tag, byte[] src);
+
+    private static native int nativeGetTagFromKey(String keyName)
+            throws IllegalArgumentException;
+    private static native int nativeGetTypeFromTag(int tag)
+            throws IllegalArgumentException;
     private static native void nativeClassInit();
 
     /**
@@ -214,6 +793,61 @@
         }
     }
 
+    /**
+     * Convert a key string into the equivalent native tag.
+     *
+     * @throws IllegalArgumentException if the key was not recognized
+     * @throws NullPointerException if the key was null
+     *
+     * @hide
+     */
+    public static int getTag(String key) {
+        return nativeGetTagFromKey(key);
+    }
+
+    /**
+     * Get the underlying native type for a tag.
+     *
+     * @param tag an integer tag, see e.g. {@link #getTag}
+     * @return an int enum for the metadata type, see e.g. {@link #TYPE_BYTE}
+     *
+     * @hide
+     */
+    public static int getNativeType(int tag) {
+        return nativeGetTypeFromTag(tag);
+    }
+
+    /**
+     * <p>Updates the existing entry for tag with the new bytes pointed by src, erasing
+     * the entry if src was null.</p>
+     *
+     * <p>An empty array can be passed in to update the entry to 0 elements.</p>
+     *
+     * @param tag an integer tag, see e.g. {@link #getTag}
+     * @param src an array of bytes, or null to erase the entry
+     *
+     * @hide
+     */
+    public void writeValues(int tag, byte[] src) {
+        nativeWriteValues(tag, src);
+    }
+
+    /**
+     * <p>Returns a byte[] of data corresponding to this tag. Use a wrapped bytebuffer to unserialize
+     * the data properly.</p>
+     *
+     * <p>An empty array can be returned to denote an existing entry with 0 elements.</p>
+     *
+     * @param tag an integer tag, see e.g. {@link #getTag}
+     *
+     * @return null if there were 0 entries for this tag, a byte[] otherwise.
+     * @hide
+     */
+    public byte[] readValues(int tag) {
+     // TODO: Optimization. Native code returns a ByteBuffer instead.
+        return nativeReadValues(tag);
+    }
+
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -230,4 +864,4 @@
         System.loadLibrary("media_jni");
         nativeClassInit();
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/hardware/photography/CameraProperties.java b/core/java/android/hardware/photography/CameraProperties.java
index ad42285..2ed4e3a 100644
--- a/core/java/android/hardware/photography/CameraProperties.java
+++ b/core/java/android/hardware/photography/CameraProperties.java
@@ -40,7 +40,7 @@
      * removable cameras of the same model.
      */
     public static final Key<String> INFO_MODEL =
-            new Key<String>("android.info.model");
+            new Key<String>("android.info.model", String.class);
 
     /**
      * A unique identifier for this camera. For removable cameras, every
@@ -49,7 +49,7 @@
      * identifier is equal to the the device's id.
      */
     public static final Key<String> INFO_IDENTIFIER =
-            new Key<String>("android.info.identifier");
+            new Key<String>("android.info.identifier", String.class);
 
     /**
      * <p>Whether this camera is removable or not.</p>
@@ -59,7 +59,7 @@
      * determine if this camera is a match for a camera device seen earlier.</p>
      */
     public static final Key<Boolean> INFO_REMOVABLE =
-            new Key<Boolean>("android.info.isRemovable");
+            new Key<Boolean>("android.info.isRemovable", Boolean.TYPE);
 
     /**
      * <p>The hardware operational model of this device. One of the
@@ -100,7 +100,7 @@
      * @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
      */
     public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL =
-            new Key<Integer>("android.info.supportedHardwareLevel");
+            new Key<Integer>("android.info.supportedHardwareLevel", Integer.TYPE);
 
     /**
      * <p>The type reported by limited-capability camera devices.</p>
@@ -164,8 +164,8 @@
      * {@link android.graphics.ImageFormat#YUV_420_888} are guaranteed to be
      * supported.</p>
      */
-    public static final Key<Integer[]> SCALER_AVAILABLE_FORMATS =
-            new Key<Integer[]>("android.scaler.availableFormats");
+    public static final Key<int[]> SCALER_AVAILABLE_FORMATS =
+            new Key<int[]>("android.scaler.availableFormats", int[].class);
 
     /**
      * <p>The available output sizes for JPEG buffers from this camera
@@ -174,7 +174,7 @@
      * when using format {@link android.graphics.ImageFormat#JPEG}.</p>
      */
     public static final Key<Size[]> SCALER_AVAILABLE_JPEG_SIZES =
-            new Key<Size[]>("android.scaler.availableJpegSizes");
+            new Key<Size[]>("android.scaler.availableJpegSizes", Size[].class);
 
     /**
      * <p>The available sizes for output buffers from this camera device, when
@@ -194,7 +194,7 @@
      *
      */
     public static final Key<Size[]> SCALER_AVAILABLE_PROCESSED_SIZES =
-            new Key<Size[]>("android.scaler.availableProcessedSizes");
+            new Key<Size[]>("android.scaler.availableProcessedSizes", Size[].class);
 
     /**
      * <p>The available sizes for output buffers from this camera device, when
@@ -207,7 +207,7 @@
      * when using image format {@link android.graphics.ImageFormat#RAW_SENSOR}.</p>
      */
     public static final Key<Size[]> SCALER_AVAILABLE_RAW_SIZES =
-            new Key<Size[]>("android.scaler.availableRawSizes");
+            new Key<Size[]>("android.scaler.availableRawSizes", Size[].class);
 
     /**
      * <p>The coordinates of the sensor's active pixel array, relative to its
@@ -230,7 +230,7 @@
      * being the top-left corner of the active array.</p>
      */
     public static final Key<Rect> SENSOR_ACTIVE_ARRAY_SIZE =
-            new Key<Rect>("android.sensor.activeArraySize");
+            new Key<Rect>("android.sensor.activeArraySize", Rect.class);
 
     /**
      * <p>The size of the sensor's total pixel array available for readout. Some
@@ -240,7 +240,7 @@
      * the supported capture sizes.</p>
      */
     public static final Key<Size> SENSOR_PIXEL_ARRAY_SIZE =
-            new Key<Size>("android.sensor.activeArraySize");
+            new Key<Size>("android.sensor.activeArraySize", Size.class);
 
     // TODO: Many more of these.
 
diff --git a/core/java/android/hardware/photography/CaptureRequest.java b/core/java/android/hardware/photography/CaptureRequest.java
index ac2041b..d4a7a3c 100644
--- a/core/java/android/hardware/photography/CaptureRequest.java
+++ b/core/java/android/hardware/photography/CaptureRequest.java
@@ -58,14 +58,14 @@
      * The exposure time for this capture, in nanoseconds.
      */
     public static final Key<Long> SENSOR_EXPOSURE_TIME =
-            new Key<Long>("android.sensor.exposureTime");
+            new Key<Long>("android.sensor.exposureTime", Long.TYPE);
 
     /**
      * The sensor sensitivity (gain) setting for this camera.
      * This is represented as an ISO sensitivity value
      */
     public static final Key<Integer> SENSOR_SENSITIVITY =
-            new Key<Integer>("android.sensor.sensitivity");
+            new Key<Integer>("android.sensor.sensitivity", Integer.TYPE);
 
     // Many more settings
 
diff --git a/core/java/android/hardware/photography/CaptureResult.java b/core/java/android/hardware/photography/CaptureResult.java
index b502c4c..2fdd466 100644
--- a/core/java/android/hardware/photography/CaptureResult.java
+++ b/core/java/android/hardware/photography/CaptureResult.java
@@ -42,15 +42,15 @@
      * or {@link android.media.Image#getTimestamp Image.getTimestamp()} for this
      * capture's image data.
      */
-    public static final Key SENSOR_TIMESTAMP =
-            new Key<Long>("android.sensor.timestamp");
+    public static final Key<Long> SENSOR_TIMESTAMP =
+            new Key<Long>("android.sensor.timestamp", Long.TYPE);
 
     /**
      * The state of the camera device's auto-exposure algorithm. One of the
      * CONTROL_AE_STATE_* enumerations.
      */
-    public static final Key CONTROL_AE_STATE =
-            new Key<Integer>("android.control.aeState");
+    public static final Key<Integer> CONTROL_AE_STATE =
+            new Key<Integer>("android.control.aeState", Integer.TYPE);
 
     /**
      * The auto-exposure algorithm is inactive.
@@ -96,8 +96,8 @@
      * The list of faces detected in this capture. Available if face detection
      * was enabled for this capture
      */
-    public static final Key STATISTICS_DETECTED_FACES =
-            new Key<Face[]>("android.statistics.faces");
+    public static final Key<Face[]> STATISTICS_DETECTED_FACES =
+            new Key<Face[]>("android.statistics.faces", Face[].class);
 
     // TODO: Many many more
 
diff --git a/core/java/android/hardware/photography/Rational.java b/core/java/android/hardware/photography/Rational.java
new file mode 100644
index 0000000..66e533e
--- /dev/null
+++ b/core/java/android/hardware/photography/Rational.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.photography;
+
+/**
+ * The rational data type used by CameraMetadata keys. Contains a pair of ints representing the
+ * numerator and denominator of a Rational number. This type is immutable.
+ */
+public final class Rational {
+    private final int mNumerator;
+    private final int mDenominator;
+
+    /**
+     * <p>Create a Rational with a given numerator and denominator.</p>
+     *
+     * <p>
+     * The signs of the numerator and the denominator may be flipped such that the denominator
+     * is always 0.
+     * </p>
+     *
+     * @param numerator the numerator of the rational
+     * @param denominator the denominator of the rational
+     *
+     * @throws IllegalArgumentException if the denominator is 0
+     */
+    public Rational(int numerator, int denominator) {
+
+        if (denominator == 0) {
+            throw new IllegalArgumentException("Argument 'denominator' is 0");
+        }
+
+        if (denominator < 0) {
+            numerator = -numerator;
+            denominator = -denominator;
+        }
+
+        mNumerator = numerator;
+        mDenominator = denominator;
+    }
+
+    /**
+     * Gets the numerator of the rational.
+     */
+    public int getNumerator() {
+        return mNumerator;
+    }
+
+    /**
+     * Gets the denominator of the rational
+     */
+    public int getDenominator() {
+        return mDenominator;
+    }
+
+    /**
+     * <p>Compare this Rational to another object and see if they are equal.</p>
+     *
+     * <p>A Rational object can only be equal to another Rational object (comparing against any other
+     * type will return false).</p>
+     *
+     * <p>A Rational object is considered equal to another Rational object if and only if their
+     * reduced forms have the same numerator and denominator.</p>
+     *
+     * <p>A reduced form of a Rational is calculated by dividing both the numerator and the
+     * denominator by their greatest common divisor.</p>
+     *
+     * <pre>
+     *      (new Rational(1, 2)).equals(new Rational(1, 2)) == true  // trivially true
+     *      (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
+     *      (new Rational(1, 2)).equals(new Rational(2, 4)) == true  // true after reduction
+     * </pre>
+     *
+     * @param obj a reference to another object
+     *
+     * @return boolean that determines whether or not the two Rational objects are equal.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Rational) {
+            Rational other = (Rational) obj;
+            if(mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
+                return true;
+            } else {
+                int thisGcd = gcd();
+                int otherGcd = other.gcd();
+
+                int thisNumerator = mNumerator / thisGcd;
+                int thisDenominator = mDenominator / thisGcd;
+
+                int otherNumerator = other.mNumerator / otherGcd;
+                int otherDenominator = other.mDenominator / otherGcd;
+
+                return (thisNumerator == otherNumerator && thisDenominator == otherDenominator);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return mNumerator + "/" + mDenominator;
+    }
+
+    @Override
+    public int hashCode() {
+        final long INT_MASK = 0xffffffffL;
+
+        long asLong = INT_MASK & mNumerator;
+        asLong <<= 32;
+
+        asLong |= (INT_MASK & mDenominator);
+
+        return ((Long)asLong).hashCode();
+    }
+
+    /**
+     * Calculates the greatest common divisor using Euclid's algorithm.
+     *
+     * @return int value representing the gcd. Always positive.
+     * @hide
+     */
+    public int gcd() {
+        /**
+         * Non-recursive implementation of Euclid's algorithm:
+         *
+         *  gcd(a, 0) := a
+         *  gcd(a, b) := gcd(b, a mod b)
+         *
+         */
+
+        int a = mNumerator;
+        int b = mDenominator;
+
+        while (b != 0) {
+            int oldB = b;
+
+            b = a % b;
+            a = oldB;
+        }
+
+        return Math.abs(a);
+    }
+}
diff --git a/core/java/android/hardware/photography/Size.java b/core/java/android/hardware/photography/Size.java
index e1115d3..ee7980e 100644
--- a/core/java/android/hardware/photography/Size.java
+++ b/core/java/android/hardware/photography/Size.java
@@ -24,12 +24,12 @@
     /**
      * Create a new immutable Size instance
      *
-     * @param w The width to store in the Size instance
-     * @param h The height to store in the Size instance
+     * @param width The width to store in the Size instance
+     * @param height The height to store in the Size instance
      */
-    Size(int w, int h) {
-        mWidth = w;
-        mHeight = h;
+    Size(int width, int height) {
+        mWidth = width;
+        mHeight = height;
     }
 
     public final int getWidth() {
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index 382b25e..62d8738 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -639,6 +639,7 @@
         @Deprecated
         public static long[] readFullLongArray(DataInputStream in) throws IOException {
             final int size = in.readInt();
+            if (size < 0) throw new ProtocolException("negative array size");
             final long[] values = new long[size];
             for (int i = 0; i < values.length; i++) {
                 values[i] = in.readLong();
@@ -680,6 +681,7 @@
         public static long[] readVarLongArray(DataInputStream in) throws IOException {
             final int size = in.readInt();
             if (size == -1) return null;
+            if (size < 0) throw new ProtocolException("negative array size");
             final long[] values = new long[size];
             for (int i = 0; i < values.length; i++) {
                 values[i] = readVarLong(in);
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 8e0935d..12646bd 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1803,8 +1803,8 @@
             for (int i=0; i<timers.size(); i++) {
                 TimerEntry timer = timers.get(i);
                 sb.setLength(0);
-                sb.append("  Wake lock #");
-                sb.append(timer.mId);
+                sb.append("  Wake lock ");
+                UserHandle.formatUid(sb, timer.mId);
                 sb.append(" ");
                 sb.append(timer.mName);
                 printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
@@ -1822,8 +1822,11 @@
             }
             
             Uid u = uidStats.valueAt(iu);
-            
-            pw.println(prefix + "  #" + uid + ":");
+
+            pw.print(prefix);
+            pw.print("  ");
+            UserHandle.formatUid(pw, uid);
+            pw.println(":");
             boolean uidActivity = false;
             
             long mobileRxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 2314057..9e9521a 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -18,14 +18,14 @@
 
 import libcore.io.ErrnoException;
 import libcore.io.Libcore;
-import libcore.io.StructStatFs;
+import libcore.io.StructStatVfs;
 
 /**
  * Retrieve overall information about the space on a filesystem. This is a
- * wrapper for Unix statfs().
+ * wrapper for Unix statvfs().
  */
 public class StatFs {
-    private StructStatFs mStat;
+    private StructStatVfs mStat;
 
     /**
      * Construct a new StatFs for looking at the stats of the filesystem at
@@ -39,9 +39,9 @@
         mStat = doStat(path);
     }
 
-    private static StructStatFs doStat(String path) {
+    private static StructStatVfs doStat(String path) {
         try {
-            return Libcore.os.statfs(path);
+            return Libcore.os.statvfs(path);
         } catch (ErrnoException e) {
             throw new IllegalArgumentException("Invalid path: " + path, e);
         }
@@ -66,7 +66,7 @@
 
     /**
      * The size, in bytes, of a block on the file system. This corresponds to
-     * the Unix {@code statfs.f_bsize} field.
+     * the Unix {@code statvfs.f_bsize} field.
      */
     public long getBlockSizeLong() {
         return mStat.f_bsize;
@@ -82,7 +82,7 @@
 
     /**
      * The total number of blocks on the file system. This corresponds to the
-     * Unix {@code statfs.f_blocks} field.
+     * Unix {@code statvfs.f_blocks} field.
      */
     public long getBlockCountLong() {
         return mStat.f_blocks;
@@ -99,7 +99,7 @@
     /**
      * The total number of blocks that are free on the file system, including
      * reserved blocks (that are not available to normal applications). This
-     * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
+     * corresponds to the Unix {@code statvfs.f_bfree} field. Most applications
      * will want to use {@link #getAvailableBlocks()} instead.
      */
     public long getFreeBlocksLong() {
@@ -125,7 +125,7 @@
 
     /**
      * The number of blocks that are free on the file system and available to
-     * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
+     * applications. This corresponds to the Unix {@code statvfs.f_bavail} field.
      */
     public long getAvailableBlocksLong() {
         return mStat.f_bavail;
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index d205253..6e693a4 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -168,8 +168,11 @@
             if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
                 sb.append('i');
                 sb.append(appId - Process.FIRST_ISOLATED_UID);
-            } else {
+            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                 sb.append('a');
+                sb.append(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                sb.append('s');
                 sb.append(appId);
             }
         }
@@ -190,8 +193,11 @@
             if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
                 pw.print('i');
                 pw.print(appId - Process.FIRST_ISOLATED_UID);
-            } else {
+            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                 pw.print('a');
+                pw.print(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                pw.print('s');
                 pw.print(appId);
             }
         }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index a441c39..4adee14 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -781,7 +781,7 @@
         int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
+            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
@@ -796,14 +796,14 @@
         int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
+            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
         }
     }
 
-    private static native void nDrawPatch(int renderer, int bitmap, int chunk,
+    private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, int chunk,
             float left, float top, float right, float bottom, int paint);
 
     @Override
@@ -813,13 +813,13 @@
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap,
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
             float left, float top, int paint);
 
     @Override
@@ -829,13 +829,15 @@
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap,  matrix.native_instance, nativePaint);
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
+                    matrix.native_instance, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint);
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
+            int matrix, int paint);
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
@@ -857,7 +859,7 @@
                 bottom = src.bottom;
             }
 
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
@@ -884,14 +886,14 @@
                 bottom = src.bottom;
             }
     
-            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
+            nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap,
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
             float srcLeft, float srcTop, float srcRight, float srcBottom,
             float left, float top, float right, float bottom, int paint);
 
@@ -960,15 +962,15 @@
 
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
-            final int nativePaint = paint == null ? 0 : paint.mNativePaint;        
-            nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, meshWidth, meshHeight,
+            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+            nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
                     verts, vertOffset, colors, colorOffset, nativePaint);
         } finally {
             if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
         }
     }
 
-    private static native void nDrawBitmapMesh(int renderer, int bitmap,
+    private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
             int meshWidth, int meshHeight, float[] verts, int vertOffset,
             int[] colors, int colorOffset, int paint);
 
diff --git a/core/java/android/view/GraphicBuffer.java b/core/java/android/view/GraphicBuffer.java
index b4576f3..30c077c 100644
--- a/core/java/android/view/GraphicBuffer.java
+++ b/core/java/android/view/GraphicBuffer.java
@@ -62,6 +62,9 @@
     private Canvas mCanvas;
     private int mSaveCount;
 
+    // If set to true, this GraphicBuffer instance cannot be used anymore
+    private boolean mDestroyed;
+
     /**
      * Creates new <code>GraphicBuffer</code> instance. This method will return null
      * if the buffer cannot be created.
@@ -128,10 +131,14 @@
      * <p>The content of the buffer is preserved between unlockCanvas()
      * and lockCanvas().</p>
      *
+     * <p>If this method is called after {@link #destroy()}, the return value will
+     * always be null.</p>
+     *
      * @return A Canvas used to draw into the buffer, or null.
      *
      * @see #lockCanvas(android.graphics.Rect)
      * @see #unlockCanvasAndPost(android.graphics.Canvas)
+     * @see #isDestroyed()
      */
     public Canvas lockCanvas() {
         return lockCanvas(null);
@@ -141,14 +148,22 @@
      * Just like {@link #lockCanvas()} but allows specification of a dirty
      * rectangle.
      *
+     * <p>If this method is called after {@link #destroy()}, the return value will
+     * always be null.</p>
+     *
      * @param dirty Area of the buffer that may be modified.
 
-     * @return A Canvas used to draw into the surface or null
+     * @return A Canvas used to draw into the surface, or null.
      *
      * @see #lockCanvas()
      * @see #unlockCanvasAndPost(android.graphics.Canvas)
+     * @see #isDestroyed()
      */
     public Canvas lockCanvas(Rect dirty) {
+        if (mDestroyed) {
+            return null;
+        }
+
         if (mCanvas == null) {
             mCanvas = new Canvas();
         }
@@ -164,13 +179,17 @@
     /**
      * Finish editing pixels in the buffer.
      *
+     * <p>This method doesn't do anything if {@link #destroy()} was
+     * previously called.</p>
+     *
      * @param canvas The Canvas previously returned by lockCanvas()
      *
      * @see #lockCanvas()
      * @see #lockCanvas(android.graphics.Rect)
+     * @see #isDestroyed()
      */
     public void unlockCanvasAndPost(Canvas canvas) {
-        if (mCanvas != null && canvas == mCanvas) {
+        if (!mDestroyed && mCanvas != null && canvas == mCanvas) {
             canvas.restoreToCount(mSaveCount);
             mSaveCount = 0;
 
@@ -178,10 +197,39 @@
         }
     }
 
+    /**
+     * Destroyes this buffer immediately. Calling this method frees up any
+     * underlying native resources. After calling this method, this buffer
+     * must not be used in any way ({@link #lockCanvas()} must not be called,
+     * etc.)
+     *
+     * @see #isDestroyed()
+     */
+    public void destroy() {
+        if (!mDestroyed) {
+            mDestroyed = true;
+            nDestroyGraphicBuffer(mNativeObject);
+        }
+    }
+
+    /**
+     * Indicates whether this buffer has been destroyed. A destroyed buffer
+     * cannot be used in any way: locking a Canvas will return null, the buffer
+     * cannot be written to a parcel, etc.
+     *
+     * @return True if this <code>GraphicBuffer</code> is in a destroyed state,
+     *         false otherwise.
+     *
+     * @see #destroy()
+     */
+    public boolean isDestroyed() {
+        return mDestroyed;
+    }
+
     @Override
     protected void finalize() throws Throwable {
         try {
-            nDestroyGraphicBuffer(mNativeObject);
+            if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
         } finally {
             super.finalize();
         }
@@ -192,8 +240,23 @@
         return 0;
     }
 
+    /**
+     * Flatten this object in to a Parcel.
+     *
+     * <p>Calling this method will throw an <code>IllegalStateException</code> if
+     * {@link #destroy()} has been previously called.</p>
+     *
+     * @param dest The Parcel in which the object should be written.
+     * @param flags Additional flags about how the object should be written.
+     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+     */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        if (mDestroyed) {
+            throw new IllegalStateException("This GraphicBuffer has been destroyed and cannot be "
+                    + "written to a parcel.");
+        }
+
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeInt(mFormat);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 281bd7e..d9e4600 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1983,6 +1983,7 @@
                         if (map != null) {
                             GLES20Canvas.initAtlas(buffer, map);
                         }
+                        buffer.destroy();
                     }
                 }
             } catch (RemoteException e) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1192390..fddc26c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7051,7 +7051,12 @@
         if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
             mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
             if (mParent != null) {
-                mParent.childAccessibilityStateChanged(this);
+                try {
+                    mParent.childAccessibilityStateChanged(this);
+                } catch (AbstractMethodError e) {
+                    Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                            " does not fully implement ViewParent", e);
+                }
             }
         }
     }
@@ -11944,10 +11949,15 @@
                     if (!canResolveLayoutDirection()) return false;
 
                     // Parent has not yet resolved, LTR is still the default
-                    if (!mParent.isLayoutDirectionResolved()) return false;
+                    try {
+                        if (!mParent.isLayoutDirectionResolved()) return false;
 
-                    if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
-                        mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
+                        if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                            mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
+                        }
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
                     }
                     break;
                 case LAYOUT_DIRECTION_RTL:
@@ -11973,13 +11983,20 @@
      * Check if layout direction resolution can be done.
      *
      * @return true if layout direction resolution can be done otherwise return false.
-     *
-     * @hide
      */
     public boolean canResolveLayoutDirection() {
         switch (getRawLayoutDirection()) {
             case LAYOUT_DIRECTION_INHERIT:
-                return (mParent != null) && mParent.canResolveLayoutDirection();
+                if (mParent != null) {
+                    try {
+                        return mParent.canResolveLayoutDirection();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                    }
+                }
+                return false;
+
             default:
                 return true;
         }
@@ -12007,7 +12024,6 @@
 
     /**
      * @return true if layout direction has been resolved.
-     * @hide
      */
     public boolean isLayoutDirectionResolved() {
         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED;
@@ -17181,14 +17197,26 @@
                     }
 
                     // Parent has not yet resolved, so we still return the default
-                    if (!mParent.isTextDirectionResolved()) {
-                        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
-                        // Resolution will need to happen again later
-                        return false;
+                    try {
+                        if (!mParent.isTextDirectionResolved()) {
+                            mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
+                            // Resolution will need to happen again later
+                            return false;
+                        }
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
                     }
 
                     // Set current resolved direction to the same value as the parent's one
-                    final int parentResolvedDirection = mParent.getTextDirection();
+                    int parentResolvedDirection;
+                    try {
+                        parentResolvedDirection = mParent.getTextDirection();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                        parentResolvedDirection = TEXT_DIRECTION_LTR;
+                    }
                     switch (parentResolvedDirection) {
                         case TEXT_DIRECTION_FIRST_STRONG:
                         case TEXT_DIRECTION_ANY_RTL:
@@ -17229,13 +17257,20 @@
      * Check if text direction resolution can be done.
      *
      * @return true if text direction resolution can be done otherwise return false.
-     *
-     * @hide
      */
     public boolean canResolveTextDirection() {
         switch (getRawTextDirection()) {
             case TEXT_DIRECTION_INHERIT:
-                return (mParent != null) && mParent.canResolveTextDirection();
+                if (mParent != null) {
+                    try {
+                        return mParent.canResolveTextDirection();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                    }
+                }
+                return false;
+
             default:
                 return true;
         }
@@ -17265,8 +17300,6 @@
 
     /**
      * @return true if text direction is resolved.
-     *
-     * @hide
      */
     public boolean isTextDirectionResolved() {
         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED;
@@ -17393,13 +17426,25 @@
                     }
 
                     // Parent has not yet resolved, so we still return the default
-                    if (!mParent.isTextAlignmentResolved()) {
-                        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
-                        // Resolution will need to happen again later
-                        return false;
+                    try {
+                        if (!mParent.isTextAlignmentResolved()) {
+                            mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+                            // Resolution will need to happen again later
+                            return false;
+                        }
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
                     }
 
-                    final int parentResolvedTextAlignment = mParent.getTextAlignment();
+                    int parentResolvedTextAlignment;
+                    try {
+                        parentResolvedTextAlignment = mParent.getTextAlignment();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                        parentResolvedTextAlignment = TEXT_ALIGNMENT_GRAVITY;
+                    }
                     switch (parentResolvedTextAlignment) {
                         case TEXT_ALIGNMENT_GRAVITY:
                         case TEXT_ALIGNMENT_TEXT_START:
@@ -17444,13 +17489,20 @@
      * Check if text alignment resolution can be done.
      *
      * @return true if text alignment resolution can be done otherwise return false.
-     *
-     * @hide
      */
     public boolean canResolveTextAlignment() {
         switch (getRawTextAlignment()) {
             case TEXT_DIRECTION_INHERIT:
-                return (mParent != null) && mParent.canResolveTextAlignment();
+                if (mParent != null) {
+                    try {
+                        return mParent.canResolveTextAlignment();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                    }
+                }
+                return false;
+
             default:
                 return true;
         }
@@ -17480,8 +17532,6 @@
 
     /**
      * @return true if text alignment is resolved.
-     *
-     * @hide
      */
     public boolean isTextAlignmentResolved() {
         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a40582b..f574efa 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -742,8 +742,6 @@
 
     /**
      * Called when a child view has changed whether or not it is tracking transient state.
-     *
-     * @hide
      */
     public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
         final boolean oldHasTransientState = hasTransientState();
@@ -764,9 +762,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     @Override
     public boolean hasTransientState() {
         return mChildCountWithTransientState > 0 || super.hasTransientState();
@@ -2530,13 +2525,15 @@
         event.setClassName(ViewGroup.class.getName());
     }
 
-    /**
-     * @hide
-     */
     @Override
     public void childAccessibilityStateChanged(View root) {
         if (mParent != null) {
-            mParent.childAccessibilityStateChanged(root);
+            try {
+                mParent.childAccessibilityStateChanged(root);
+            } catch (AbstractMethodError e) {
+                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                        " does not fully implement ViewParent", e);
+            }
         }
     }
 
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 2ebc1a1..8ae6996 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -271,8 +271,6 @@
      *
      * @param child Child view whose state has changed
      * @param hasTransientState true if this child has transient state
-     *
-     * @hide
      */
     public void childHasTransientStateChanged(View child, boolean hasTransientState);
 
@@ -295,9 +293,7 @@
      * A child notifies its parent that the accessibility state of a subtree rooted
      * at a given node changed. That is the structure of the subtree is different.
      *
-     * @param The root of the changed subtree.
-     *
-     * @hide
+     * @param root The root of the changed subtree.
      */
     public void childAccessibilityStateChanged(View root);
 
@@ -306,8 +302,6 @@
      * See {@link View#setLayoutDirection(int)}
      *
      * @return True if this view parent can resolve the layout direction.
-     *
-     * @hide
      */
     public boolean canResolveLayoutDirection();
 
@@ -316,8 +310,6 @@
      * See {@link View#setLayoutDirection(int)}
      *
      * @return True if this view parent layout direction is resolved.
-     *
-     * @hide
      */
     public boolean isLayoutDirectionResolved();
 
@@ -326,8 +318,6 @@
      *
      * @return {@link View#LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
      * {@link View#LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
-     *
-     * @hide
      */
     public int getLayoutDirection();
 
@@ -336,8 +326,6 @@
      * See {@link View#setTextDirection(int)}
      *
      * @return True if this view parent can resolve the text direction.
-     *
-     * @hide
      */
     public boolean canResolveTextDirection();
 
@@ -346,8 +334,6 @@
      * See {@link View#setTextDirection(int)}
      *
      * @return True if this view parent text direction is resolved.
-     *
-     * @hide
      */
     public boolean isTextDirectionResolved();
 
@@ -361,8 +347,6 @@
      * {@link View#TEXT_DIRECTION_LTR},
      * {@link View#TEXT_DIRECTION_RTL},
      * {@link View#TEXT_DIRECTION_LOCALE}
-     *
-     * @hide
      */
     public int getTextDirection();
 
@@ -371,8 +355,6 @@
      * See {@link View#setTextAlignment(int)}
      *
      * @return True if this view parent can resolve the text alignment.
-     *
-     * @hide
      */
     public boolean canResolveTextAlignment();
 
@@ -381,8 +363,6 @@
      * See {@link View#setTextAlignment(int)}
      *
      * @return True if this view parent text alignment is resolved.
-     *
-     * @hide
      */
     public boolean isTextAlignmentResolved();
 
@@ -397,8 +377,6 @@
      * {@link View#TEXT_ALIGNMENT_TEXT_END},
      * {@link View#TEXT_ALIGNMENT_VIEW_START},
      * {@link View#TEXT_ALIGNMENT_VIEW_END}
-     *
-     * @hide
      */
     public int getTextAlignment();
 }
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java
index 3c5b6fa..c2aa90b 100644
--- a/core/java/android/view/transition/Fade.java
+++ b/core/java/android/view/transition/Fade.java
@@ -96,12 +96,19 @@
     protected Animator appear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
-        View endView = (endValues != null) ? endValues.view : null;
-        if ((mFadingMode & IN) != IN) {
+        if ((mFadingMode & IN) != IN || endValues == null) {
             return null;
         }
+        final View endView = endValues.view;
         endView.setAlpha(0);
-        return runAnimation(endView, 0, 1, null);
+        final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                // Always end animation with full alpha, in case it's canceled mid-stream
+                endView.setAlpha(1);
+            }
+        };
+        return runAnimation(endView, 0, 1, endListener);
     }
 
     @Override
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
index d0e61ea..313e33e 100644
--- a/core/java/android/view/transition/TransitionGroup.java
+++ b/core/java/android/view/transition/TransitionGroup.java
@@ -104,7 +104,7 @@
                 mTransitions.add(transitions[i]);
                 transitions[i].mParent = this;
                 if (mDuration >= 0) {
-                    transitions[0].setDuration(mDuration);
+                    transitions[i].setDuration(mDuration);
                 }
             }
         }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4998742..0149f03 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -41,6 +41,7 @@
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.widget.AbsoluteLayout;
@@ -2051,6 +2052,13 @@
     }
     */
 
+    @Override
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+        AccessibilityNodeProvider provider =
+                mProvider.getViewDelegate().getAccessibilityNodeProvider();
+        return provider == null ? super.getAccessibilityNodeProvider() : provider;
+    }
+
     @Deprecated
     @Override
     public boolean shouldDelayChildPressedState() {
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 3afab09..5a9e6c9 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -90,6 +90,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.BaseInputConnection;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
@@ -1769,6 +1770,11 @@
     }
 
     @Override
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+      return null;
+    }
+
+    @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         if (!mWebView.isEnabled()) {
             // Only default actions are supported while disabled.
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index fa17ab9..41d6333 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -32,6 +32,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.webkit.WebView.HitTestResult;
@@ -279,6 +280,8 @@
     interface ViewDelegate {
         public boolean shouldDelayChildPressedState();
 
+        public AccessibilityNodeProvider getAccessibilityNodeProvider();
+
         public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
 
         public void onInitializeAccessibilityEvent(AccessibilityEvent event);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1e20ab2..8b51bf3 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -28,6 +28,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.StrictMode;
+import android.os.Trace;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.TextUtils;
@@ -2151,6 +2152,8 @@
      * @return A view displaying the data associated with the specified position
      */
     View obtainView(int position, boolean[] isScrap) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "obtainView");
+
         isScrap[0] = false;
         View scrapView;
 
@@ -2213,6 +2216,8 @@
             }
         }
 
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+
         return child;
     }
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index c4406ac..05a8dc8 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -199,10 +199,8 @@
                 unscheduleDrawable(mButtonDrawable);
             }
             d.setCallback(this);
-            d.setState(getDrawableState());
             d.setVisible(getVisibility() == VISIBLE, false);
             mButtonDrawable = d;
-            mButtonDrawable.setState(null);
             setMinHeight(mButtonDrawable.getIntrinsicHeight());
         }
 
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index d452f58..594b130 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -1037,7 +1037,12 @@
         final int sectionCount = mSections.length;
         final int positionsInSection;
         if (section < sectionCount - 1) {
-            final int nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+            final int nextSectionPos;
+            if (section + 1 < sectionCount) {
+                nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+            } else {
+                nextSectionPos = totalItemCount - 1;
+            }
             positionsInSection = nextSectionPos - sectionPos;
         } else {
             positionsInSection = totalItemCount - sectionPos;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 63147dd..a7d546a 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
+import android.os.Trace;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.KeyEvent;
@@ -1364,6 +1365,8 @@
      */
     private void setupChild(View child, int position, int y, boolean flow, int childrenLeft,
             boolean selected, boolean recycled, int where) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "setupGridItem");
+
         boolean isSelected = selected && shouldShowSelector();
         final boolean updateChildSelected = isSelected != child.isSelected();
         final int mode = mTouchMode;
@@ -1459,6 +1462,8 @@
                 != position) {
             child.jumpDrawablesToCurrentState();
         }
+
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
     }
 
     /**
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index d990a20..c44ac32 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.os.Trace;
 import com.android.internal.R;
 import com.android.internal.util.Predicate;
 import com.google.android.collect.Lists;
@@ -1876,6 +1877,8 @@
      */
     private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
             boolean selected, boolean recycled) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "setupListItem");
+
         final boolean isSelected = selected && shouldShowSelector();
         final boolean updateChildSelected = isSelected != child.isSelected();
         final int mode = mTouchMode;
@@ -1956,6 +1959,8 @@
                 != position) {
             child.jumpDrawablesToCurrentState();
         }
+
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
     }
 
     @Override
diff --git a/core/java/android/widget/SectionIndexer.java b/core/java/android/widget/SectionIndexer.java
index 24f894c..a1c71f4 100644
--- a/core/java/android/widget/SectionIndexer.java
+++ b/core/java/android/widget/SectionIndexer.java
@@ -20,7 +20,9 @@
  * Interface that should be implemented on Adapters to enable fast scrolling 
  * in an {@link AbsListView} between sections of the list. A section is a group of list items
  * to jump to that have something in common. For example, they may begin with the
- * same letter or they may be songs from the same artist. 
+ * same letter or they may be songs from the same artist. ExpandableListAdapters that
+ * consider groups and sections as synonymous should account for collapsed groups and return
+ * an appropriate section/position.
  */
 public interface SectionIndexer {
     /**
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 43a02cf..fe532b0 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -572,7 +572,7 @@
             if (whichButtons == BIT_BUTTON_POSITIVE) {
                 centerButton(mButtonPositive);
             } else if (whichButtons == BIT_BUTTON_NEGATIVE) {
-                centerButton(mButtonNeutral);
+                centerButton(mButtonNegative);
             } else if (whichButtons == BIT_BUTTON_NEUTRAL) {
                 centerButton(mButtonNeutral);
             }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 4e21324..78389c5 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -432,6 +432,17 @@
         }
     }
 
+    public static CharSequence getImeAndSubtypeDisplayName(Context context, InputMethodInfo imi,
+            InputMethodSubtype subtype) {
+        final CharSequence imiLabel = imi.loadLabel(context.getPackageManager());
+        return subtype != null
+                ? TextUtils.concat(subtype.getDisplayName(context,
+                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
+                                (TextUtils.isEmpty(imiLabel) ?
+                                        "" : " - " + imiLabel))
+                : imiLabel;
+    }
+
     /**
      * Utility class for putting and getting settings for InputMethod
      * TODO: Move all putters and getters of settings to this class.
diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java
index fa53cfa..9bec10e 100644
--- a/core/java/com/android/internal/util/FastPrintWriter.java
+++ b/core/java/com/android/internal/util/FastPrintWriter.java
@@ -458,7 +458,7 @@
         if (lnum == 0) {
             println("0");
         } else {
-            super.print(lnum);
+            super.println(lnum);
         }
     }
 
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index 464ae2f..35b76dd 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -242,17 +242,20 @@
 
     private void insertIconView() {
         mIconView = (ImageView) getInflater()
-                .inflate(com.android.internal.R.layout.list_menu_item_icon, this, true);
+                .inflate(com.android.internal.R.layout.list_menu_item_icon, this, false);
+        addView(mIconView);
     }
 
     private void insertRadioButton() {
         mRadioButton = (RadioButton) getInflater()
-                .inflate(com.android.internal.R.layout.list_menu_item_radio, this, true);
+                .inflate(com.android.internal.R.layout.list_menu_item_radio, this, false);
+        addView(mRadioButton);
     }
 
     private void insertCheckBox() {
         mCheckBox = (CheckBox) getInflater()
-                .inflate(com.android.internal.R.layout.list_menu_item_checkbox, this, true);
+                .inflate(com.android.internal.R.layout.list_menu_item_checkbox, this, false);
+        addView(mCheckBox);
     }
 
     private void alignTextToStartOf(View v) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 20e5011..d60fa18 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -196,6 +196,7 @@
 	libgui \
 	libinput \
 	libcamera_client \
+	libcamera_metadata \
 	libskia \
 	libsqlite \
 	libEGL \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 016c11e..3d0c75f 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -116,30 +116,6 @@
     }
 }
 
-static jbyteArray nativeScaleNinePatch(JNIEnv* env, jobject, jbyteArray chunkObject, jfloat scale,
-        jobject padding) {
-
-    jbyte* array = env->GetByteArrayElements(chunkObject, 0);
-    if (array != NULL) {
-        size_t chunkSize = env->GetArrayLength(chunkObject);
-        void* storage = alloca(chunkSize);
-        android::Res_png_9patch* chunk = static_cast<android::Res_png_9patch*>(storage);
-        memcpy(chunk, array, chunkSize);
-        android::Res_png_9patch::deserialize(chunk);
-
-        scaleNinePatchChunk(chunk, scale);
-        memcpy(array, chunk, chunkSize);
-
-        if (padding) {
-            GraphicsJNI::set_jrect(env, padding, chunk->paddingLeft, chunk->paddingTop,
-                    chunk->paddingRight, chunk->paddingBottom);
-        }
-
-        env->ReleaseByteArrayElements(chunkObject, array, 0);
-    }
-    return chunkObject;
-}
-
 static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStream* stream,
         int sampleSize, bool ditherImage) {
 
@@ -624,11 +600,6 @@
         (void*)nativeDecodeByteArray
     },
 
-    {   "nativeScaleNinePatch",
-        "([BFLandroid/graphics/Rect;)[B",
-        (void*)nativeScaleNinePatch
-    },
-
     {   "nativeIsSeekable",
         "(Ljava/io/FileDescriptor;)Z",
         (void*)nativeIsSeekable
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 6374494..ae0113b 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -142,7 +142,13 @@
         while ((n = q->read(buffer, 16)) > 0) {
             for (int i=0 ; i<n ; i++) {
 
-                env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
+                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
+                    // step-counter returns a uint64, but the java API only deals with floats
+                    float value = float(buffer[i].u64.step_counter);
+                    env->SetFloatArrayRegion(mScratch, 0, 1, &value);
+                } else {
+                    env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
+                }
 
                 env->CallVoidMethod(mReceiverObject,
                         gBaseEventQueueClassInfo.dispatchSensorEvent,
diff --git a/core/jni/android_hardware_photography_CameraMetadata.cpp b/core/jni/android_hardware_photography_CameraMetadata.cpp
index fa363f3..5070d2c 100644
--- a/core/jni/android_hardware_photography_CameraMetadata.cpp
+++ b/core/jni/android_hardware_photography_CameraMetadata.cpp
@@ -16,6 +16,7 @@
 */
 
 // #define LOG_NDEBUG 0
+// #define LOG_NNDEBUG 0
 #define LOG_TAG "CameraMetadata-JNI"
 #include <utils/Log.h>
 
@@ -25,6 +26,16 @@
 #include "android_runtime/AndroidRuntime.h"
 
 #include <camera/CameraMetadata.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+
+#if defined(LOG_NNDEBUG)
+#if !LOG_NNDEBUG
+#define ALOGVV ALOGV
+#endif
+#else
+#define ALOGVV(...)
+#endif
 
 // fully-qualified class name
 #define CAMERA_METADATA_CLASS_NAME "android/hardware/photography/CameraMetadata"
@@ -37,9 +48,70 @@
 
 static fields_t fields;
 
+namespace {
+struct Helpers {
+    static size_t getTypeSize(uint8_t type) {
+        if (type >= NUM_TYPES) {
+            ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type);
+            return static_cast<size_t>(-1);
+        }
+
+        return camera_metadata_type_size[type];
+    }
+
+    static status_t updateAny(CameraMetadata *metadata,
+                          uint32_t tag,
+                          uint32_t type,
+                          const void *data,
+                          size_t dataBytes) {
+
+        if (type >= NUM_TYPES) {
+            ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type);
+            return INVALID_OPERATION;
+        }
+
+        size_t typeSize = getTypeSize(type);
+
+        if (dataBytes % typeSize != 0) {
+            ALOGE("%s: Expected dataBytes (%ud) to be divisible by typeSize "
+                  "(%ud)", __FUNCTION__, dataBytes, typeSize);
+            return BAD_VALUE;
+        }
+
+        size_t dataCount = dataBytes / typeSize;
+
+        switch(type) {
+#define METADATA_UPDATE(runtime_type, compile_type)                            \
+            case runtime_type: {                                               \
+                const compile_type *dataPtr =                                  \
+                        static_cast<const compile_type*>(data);                \
+                return metadata->update(tag, dataPtr, dataCount);              \
+            }                                                                  \
+
+            METADATA_UPDATE(TYPE_BYTE,     uint8_t);
+            METADATA_UPDATE(TYPE_INT32,    int32_t);
+            METADATA_UPDATE(TYPE_FLOAT,    float);
+            METADATA_UPDATE(TYPE_INT64,    int64_t);
+            METADATA_UPDATE(TYPE_DOUBLE,   double);
+            METADATA_UPDATE(TYPE_RATIONAL, camera_metadata_rational_t);
+
+            default: {
+                // unreachable
+                ALOGE("%s: Unreachable", __FUNCTION__);
+                return INVALID_OPERATION;
+            }
+        }
+
+#undef METADATA_UPDATE
+    }
+};
+} // namespace {}
+
 extern "C" {
 
 static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
+static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
+static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
 
 // Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
 static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {
@@ -140,6 +212,86 @@
     metadata->swap(*otherMetadata);
 }
 
+static jbyteArray CameraMetadata_readValues(JNIEnv *env, jobject thiz, jint tag) {
+    ALOGV("%s (tag = %d)", __FUNCTION__, tag);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+    if (metadata == NULL) return NULL;
+
+    int tagType = get_camera_metadata_tag_type(tag);
+    if (tagType == -1) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Tag (%d) did not have a type", tag);
+        return NULL;
+    }
+    size_t tagSize = Helpers::getTypeSize(tagType);
+
+    camera_metadata_entry entry = metadata->find(tag);
+    if (entry.count == 0) {
+         if (!metadata->exists(tag)) {
+             ALOGV("%s: Tag %d does not have any entries", __FUNCTION__, tag);
+             return NULL;
+         } else {
+             // OK: we will return a 0-sized array.
+             ALOGV("%s: Tag %d had an entry, but it had 0 data", __FUNCTION__,
+                   tag);
+         }
+    }
+
+    jsize byteCount = entry.count * tagSize;
+    jbyteArray byteArray = env->NewByteArray(byteCount);
+    if (env->ExceptionCheck()) return NULL;
+
+    // Copy into java array from native array
+    ScopedByteArrayRW arrayWriter(env, byteArray);
+    memcpy(arrayWriter.get(), entry.data.u8, byteCount);
+
+    return byteArray;
+}
+
+static void CameraMetadata_writeValues(JNIEnv *env, jobject thiz, jint tag, jbyteArray src) {
+    ALOGV("%s (tag = %d)", __FUNCTION__, tag);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+    if (metadata == NULL) return;
+
+    int tagType = get_camera_metadata_tag_type(tag);
+    if (tagType == -1) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Tag (%d) did not have a type", tag);
+        return;
+    }
+    size_t tagSize = Helpers::getTypeSize(tagType);
+
+    status_t res;
+
+    if (src == NULL) {
+        // If array is NULL, delete the entry
+        res = metadata->erase(tag);
+    } else {
+        // Copy from java array into native array
+        ScopedByteArrayRO arrayReader(env, src);
+        if (arrayReader.get() == NULL) return;
+
+        res = Helpers::updateAny(metadata, static_cast<uint32_t>(tag),
+                                 tagType, arrayReader.get(), arrayReader.size());
+    }
+
+    if (res == OK) {
+        return;
+    } else if (res == BAD_VALUE) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Src byte array was poorly formed");
+    } else if (res == INVALID_OPERATION) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Internal error while trying to update metadata");
+    } else {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Unknown error (%d) while trying to update "
+                            "metadata", res);
+    }
+}
+
 static void CameraMetadata_readFromParcel(JNIEnv *env, jobject thiz, jobject parcel) {
     ALOGV("%s", __FUNCTION__);
     CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
@@ -187,9 +339,17 @@
 //-------------------------------------------------
 
 static JNINativeMethod gCameraMetadataMethods[] = {
+// static methods
   { "nativeClassInit",
     "()V",
     (void *)CameraMetadata_classInit },
+  { "nativeGetTagFromKey",
+    "(Ljava/lang/String;)I",
+    (void *)CameraMetadata_getTagFromKey },
+  { "nativeGetTypeFromTag",
+    "(I)I",
+    (void *)CameraMetadata_getTypeFromTag },
+// instance methods
   { "nativeAllocate",
     "()J",
     (void*)CameraMetadata_allocate },
@@ -205,6 +365,13 @@
   { "nativeSwap",
     "(L" CAMERA_METADATA_CLASS_NAME ";)V",
     (void *)CameraMetadata_swap },
+  { "nativeReadValues",
+    "(I)[B",
+    (void *)CameraMetadata_readValues },
+  { "nativeWriteValues",
+    "(I[B)V",
+    (void *)CameraMetadata_writeValues },
+// Parcelable interface
   { "nativeReadFromParcel",
     "(Landroid/os/Parcel;)V",
     (void *)CameraMetadata_readFromParcel },
@@ -268,4 +435,99 @@
 
     jclass clazz = env->FindClass(CAMERA_METADATA_CLASS_NAME);
 }
+
+static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) {
+
+    ScopedUtfChars keyScoped(env, keyName);
+    const char *key = keyScoped.c_str();
+    if (key == NULL) {
+        // exception thrown by ScopedUtfChars
+        return 0;
+    }
+    size_t keyLength = strlen(key);
+
+    ALOGV("%s (key = '%s')", __FUNCTION__, key);
+
+    // First, find the section by the longest string match
+    const char *section = NULL;
+    size_t sectionIndex = 0;
+    size_t sectionLength = 0;
+    for (size_t i = 0; i < ANDROID_SECTION_COUNT; ++i) {
+        const char *str = camera_metadata_section_names[i];
+        ALOGVV("%s: Trying to match against section '%s'",
+               __FUNCTION__, str);
+        if (strstr(key, str) == key) { // key begins with the section name
+            size_t strLength = strlen(str);
+
+            ALOGVV("%s: Key begins with section name", __FUNCTION__);
+
+            // section name is the longest we've found so far
+            if (section == NULL || sectionLength < strLength) {
+                section = str;
+                sectionIndex = i;
+                sectionLength = strLength;
+
+                ALOGVV("%s: Found new best section (idx %d)", __FUNCTION__, sectionIndex);
+            }
+        }
+    }
+
+    // TODO: vendor ext
+    // TODO: Make above get_camera_metadata_section_from_name ?
+
+    if (section == NULL) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Could not find section name for key '%s')", key);
+        return 0;
+    } else {
+        ALOGV("%s: Found matched section '%s' (%d)",
+              __FUNCTION__, section, sectionIndex);
+    }
+
+    // Get the tag name component of the key
+    const char *keyTagName = key + sectionLength + 1; // x.y.z -> z
+    if (sectionLength + 1 >= keyLength) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Key length too short for key '%s')", key);
+    }
+
+    // Match rest of name against the tag names in that section only
+    uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
+    tagBegin = camera_metadata_section_bounds[sectionIndex][0];
+    tagEnd = camera_metadata_section_bounds[sectionIndex][1];
+
+    uint32_t tag;
+    for (tag = tagBegin; tag < tagEnd; ++tag) {
+        const char *tagName = get_camera_metadata_tag_name(tag);
+
+        if (strcmp(keyTagName, tagName) == 0) {
+            ALOGV("%s: Found matched tag '%s' (%d)",
+                  __FUNCTION__, tagName, tag);
+            break;
+        }
+    }
+
+    // TODO: vendor ext
+    // TODO: Make above get_camera_metadata_tag_from_name ?
+
+    if (tag == tagEnd) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Could not find tag name for key '%s')", key);
+        return 0;
+    }
+
+    return tag;
+}
+
+static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag) {
+    int tagType = get_camera_metadata_tag_type(tag);
+    if (tagType == -1) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Tag (%d) did not have a type", tag);
+        return -1;
+    }
+
+    return tagType;
+}
+
 } // extern "C"
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 87ebbd2..70a4daa 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -377,20 +377,31 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, jfloat left, jfloat top, SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        jfloat left, jfloat top, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawBitmap(bitmap, left, top, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap,
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
         float srcLeft, float srcTop, float srcRight, float srcBottom,
         float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
             dstLeft, dstTop, dstRight, dstBottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        SkMatrix* matrix, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawBitmap(bitmap, matrix, paint);
 }
 
@@ -420,8 +431,12 @@
 }
 
 static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, jint meshWidth, jint meshHeight,
-         jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
+        jint colorOffset, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
     jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
 
@@ -432,8 +447,11 @@
 }
 
 static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, Res_png_9patch* patch,
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, Res_png_9patch* patch,
         float left, float top, float right, float bottom, SkPaint* paint) {
+    // This object allows the renderer to allocate a global JNI ref to the buffer object.
+    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
     renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
 }
 
@@ -1018,14 +1036,14 @@
     { "nGetMatrix",         "(II)V",           (void*) android_view_GLES20Canvas_getMatrix },
     { "nConcatMatrix",      "(II)V",           (void*) android_view_GLES20Canvas_concatMatrix },
 
-    { "nDrawBitmap",        "(IIFFI)V",        (void*) android_view_GLES20Canvas_drawBitmap },
-    { "nDrawBitmap",        "(IIFFFFFFFFI)V",  (void*) android_view_GLES20Canvas_drawBitmapRect },
-    { "nDrawBitmap",        "(IIII)V",         (void*) android_view_GLES20Canvas_drawBitmapMatrix },
+    { "nDrawBitmap",        "(II[BFFI)V",      (void*) android_view_GLES20Canvas_drawBitmap },
+    { "nDrawBitmap",        "(II[BFFFFFFFFI)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
+    { "nDrawBitmap",        "(II[BII)V",       (void*) android_view_GLES20Canvas_drawBitmapMatrix },
     { "nDrawBitmap",        "(I[IIIFFIIZI)V",  (void*) android_view_GLES20Canvas_drawBitmapData },
 
-    { "nDrawBitmapMesh",    "(IIII[FI[III)V",  (void*) android_view_GLES20Canvas_drawBitmapMesh },
+    { "nDrawBitmapMesh",    "(II[BII[FI[III)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
 
-    { "nDrawPatch",         "(IIIFFFFI)V",     (void*) android_view_GLES20Canvas_drawPatch },
+    { "nDrawPatch",         "(II[BIFFFFI)V",   (void*) android_view_GLES20Canvas_drawPatch },
 
     { "nDrawColor",         "(III)V",          (void*) android_view_GLES20Canvas_drawColor },
     { "nDrawRect",          "(IFFFFI)V",       (void*) android_view_GLES20Canvas_drawRect },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7ddb0dc..ea661a9 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2259,6 +2259,16 @@
         android:description="@string/permdesc_modifyNetworkAccounting"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to mark traffic as from another user for per user routing.
+         Used by system wide services like media server that execute delegated network connections
+         for users.
+         @hide
+    -->
+    <permission android:name="android.permission.MARK_NETWORK_SOCKET"
+        android:label="@string/permlab_markNetworkSocket"
+        android:description="@string/permdesc_markNetworkSocket"
+        android:protectionLevel="signature|system" />
+
     <!-- C2DM permission.
          @hide Used internally.
      -->
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8c0da87..3796f73 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -941,8 +941,8 @@
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"ቦታ"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"አሰገባ"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"ሰርዝ"</string>
-    <string name="search_go" msgid="8298016669822141719">" ፈልግ"</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"ፈልግ"</string>
+    <string name="search_go" msgid="8298016669822141719">"ፍለጋ"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"ፍለጋ"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"ጥያቄ ፍለጋ"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"ጥያቄ አጥራ"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"ጥያቄ አስረክብ"</string>
@@ -1394,7 +1394,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ፈልግ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ላለመቆለፍ አንሸራት፡፡"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"የይለፍ ቃል ቁልፎች  ሲነገሩ ለመስማት የጆሮ ማዳመጫ ሰካ።"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ነጥብ."</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0080ad9..42dddb4 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1853,6 +1853,11 @@
     <string name="permdesc_modifyNetworkAccounting">Allows the app to modify how network usage is accounted against apps. Not for use by normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_markNetworkSocket">modify socket marks</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_markNetworkSocket">Allows the app to modify socket marks for routing</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_accessNotifications">access notifications</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_accessNotifications">Allows the app to retrieve, examine, and clear notifications, including those posted by other apps.</string>
diff --git a/docs/html/about/versions/jelly-bean.jd b/docs/html/about/versions/jelly-bean.jd
index 71957be..5812f3d 100644
--- a/docs/html/about/versions/jelly-bean.jd
+++ b/docs/html/about/versions/jelly-bean.jd
@@ -5,7 +5,14 @@
 tab2.link=#android-41
 
 @jd:body
-
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <style>
 #android-41 {display:none;}
diff --git a/docs/html/channels/io2013.jd b/docs/html/channels/io2013.jd
index 977eb2f..b2bde31 100644
--- a/docs/html/channels/io2013.jd
+++ b/docs/html/channels/io2013.jd
@@ -1,7 +1,15 @@
 fullpage=true
 page.title=Google I/O 13
 @jd:body
-    
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
+
 <style>
 #ioplayer-frame {
   z-index:10;
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index 00f4467..ab6bb1b 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -1,5 +1,13 @@
 page.title=Downloads
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <div class="layout-content-row">
   <div class="layout-content-col span-9">
diff --git a/docs/html/design/index.jd b/docs/html/design/index.jd
index 1e6b40c..d4ef07f 100644
--- a/docs/html/design/index.jd
+++ b/docs/html/design/index.jd
@@ -2,6 +2,14 @@
 header.hide=1
 footer.hide=1
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <style>
 #landing-graphic-container {
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 7b5cb4a..f96e868 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -4,6 +4,14 @@
 carousel=1
 tabbedList=1
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <style>
 #noplayer-message {
diff --git a/docs/html/distribute/googleplay/promote/badges.jd b/docs/html/distribute/googleplay/promote/badges.jd
index 9a32921..93092bf 100644
--- a/docs/html/distribute/googleplay/promote/badges.jd
+++ b/docs/html/distribute/googleplay/promote/badges.jd
@@ -1,5 +1,13 @@
 page.title=Google Play Badges
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <p itemprop="description">Google Play badges allow you to promote your app with official branding
 in your online ads, promotional materials, or anywhere else you want a link to your app.</p>
diff --git a/docs/html/distribute/googleplay/promote/brand.jd b/docs/html/distribute/googleplay/promote/brand.jd
index 265584f..a047b1f 100644
--- a/docs/html/distribute/googleplay/promote/brand.jd
+++ b/docs/html/distribute/googleplay/promote/brand.jd
@@ -1,6 +1,13 @@
 page.title=Brand Guidelines
 @jd:body
-
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 
 <p>We encourage you to use the Android and Google Play brands with your Android app
diff --git a/docs/html/distribute/googleplay/promote/index.jd b/docs/html/distribute/googleplay/promote/index.jd
index 6882990..14f37c4 100644
--- a/docs/html/distribute/googleplay/promote/index.jd
+++ b/docs/html/distribute/googleplay/promote/index.jd
@@ -3,6 +3,14 @@
 header.hide=0
 footer.hide=0
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <!--
 <style>
diff --git a/docs/html/distribute/googleplay/promote/linking.jd b/docs/html/distribute/googleplay/promote/linking.jd
index 4fdc5db..014582a 100644
--- a/docs/html/distribute/googleplay/promote/linking.jd
+++ b/docs/html/distribute/googleplay/promote/linking.jd
@@ -1,5 +1,13 @@
 page.title=Linking to Your Products
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
diff --git a/docs/html/distribute/googleplay/publish/preparing.jd b/docs/html/distribute/googleplay/publish/preparing.jd
index 5593f4f..dd35b25 100644
--- a/docs/html/distribute/googleplay/publish/preparing.jd
+++ b/docs/html/distribute/googleplay/publish/preparing.jd
@@ -1,6 +1,14 @@
 page.title=Launch Checklist
 page.tags="publishing","launch","Google Play", "Developer Console"
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <div id="qv-wrapper"><div id="qv">
 <h2>Checklist</h2>
diff --git a/docs/html/distribute/googleplay/quality/core.jd b/docs/html/distribute/googleplay/quality/core.jd
index 9e23bcc..3fd221c 100644
--- a/docs/html/distribute/googleplay/quality/core.jd
+++ b/docs/html/distribute/googleplay/quality/core.jd
@@ -1,5 +1,13 @@
 page.title=Core App Quality Guidelines
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <div id="qv-wrapper"><div id="qv">
 <h2>Quality Criteria</h2>
diff --git a/docs/html/distribute/googleplay/quality/index.jd b/docs/html/distribute/googleplay/quality/index.jd
index ef537b1..def42e5 100644
--- a/docs/html/distribute/googleplay/quality/index.jd
+++ b/docs/html/distribute/googleplay/quality/index.jd
@@ -1,5 +1,13 @@
 page.title=App Quality
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <p>App quality directly influences the long-term success of your app&mdash;in
 terms of installs, user rating and reviews, engagement, and user retention.
diff --git a/docs/html/distribute/googleplay/quality/tablet.jd b/docs/html/distribute/googleplay/quality/tablet.jd
index 03c180b..c80c3cc 100644
--- a/docs/html/distribute/googleplay/quality/tablet.jd
+++ b/docs/html/distribute/googleplay/quality/tablet.jd
@@ -1,5 +1,13 @@
 page.title=Tablet App Quality Checklist
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <div id="qv-wrapper"><div id="qv">
 <h2>Checklist</h2>
@@ -25,9 +33,7 @@
 </ol>
 </div></div>
 
-<p>Before you publish an app on Google Play, it's important to make sure that
-the app meets the basic expectations of tablet users through compelling features
-and an intuitive, well-designed UI. </p>
+<p>Before you publish an app on Google Play, it's important to make sure that the app meets the basic expectations of tablet users through compelling features and an intuitive, well-designed UI. </p>
 
 <p>Tablets are a growing part of the Android installed base that offers new
 opportunities for <a
@@ -258,32 +264,34 @@
 <h2 id="use-tablet-icons">4. Use Icons and other assets that are designed
 for tablet screens</h2>
 
-<p>So that your app looks its best, make sure to use icons and other bitmap
-assets that are created specifically for the densities used by tablet screens.
-Specifically, you should create sets of alternative bitmap drawables for each
-density in the range commonly supported by tablets.</p>
+<p>To ensure your app looks its best, provide icons and other bitmap
+assets for each density in the range commonly supported by tablets. Specifically, you should
+design your icons for the action bar, notifications, and launcher according to the
+<a href="{@docRoot}design/style/iconography.html">Iconography</a> guidelines and
+provide them in multiple densities, so they appear at the appropriate size on all screens
+without blurring or other scaling artifacts.</p>
 
 <p class="table-caption"><strong>Table 1</strong>. Raw asset sizes for icon types.<table>
 <tr>
-<th>Density </th>
-<th colspa>Launcher</th>
+<th>Density</th>
+<th>Launcher</th>
 <th>Action Bar</th>
 <th>Small/Contextual</th>
 <th>Notification</th>
 </tr>
 <tr>
 <td><code>mdpi</code></td>
-<td>48x48px</td>
-<td>32x32px</td>
-<td>16x16px</td>
-<td>24x24px</td>
+<td>48x48 px</td>
+<td>32x32 px</td>
+<td>16x16 px</td>
+<td>24x24 px</td>
 </tr>
 <tr>
 <td><code>hdpi</code></td>
-<td>72x72px</td>
-<td>48x48px</td>
-<td>24x24px</td>
-<td>36x36px</td>
+<td>72x72 px</td>
+<td>48x48 px</td>
+<td>24x24 px</td>
+<td>36x36 px</td>
 </tr>
 <tr>
 <td><code>tvdpi</code></td>
@@ -294,34 +302,42 @@
 </tr>
 <tr>
 <td><code>xhdpi</code></td>
-<td>96x96px</td>
-<td>64x64px</td>
-<td>32x32px</td>
-<td>48x48px</td>
+<td>96x96 px</td>
+<td>64x64 px</td>
+<td>32x32 px</td>
+<td>48x48 px</td>
+</tr>
+<tr>
+<td><code>xxhdpi</code></td>
+<td>144x144 px</td>
+<td>96x96 px</td>
+<td>48x48 px</td>
+<td>74x74 px</td>
 </tr>
 
 </table>
 
-<p>Other points to consider: </p>
+<p>Your app should supply a version of each icon and bitmap asset that's optimized
+for <strong>at least one</strong> the following common tablet screen densities:</p>
 
 <ul>
-<li>Icons in the action bar, notifications, and launcher should be designed
-according to the icon design guidelines and have the same physical size on
-tablets as on phones.</li>
-<li>Use density-specific <a
-href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-resource qualifiers</a> to ensure that the proper set of alternative resources
-gets loaded.</li>
+  <li><code>hdpi</code></li>
+  <li><code>xhdpi</code></li>
+  <li><code>xxhdpi</code></li>
 </ul>
 
-<p style="margin-bottom:.5em;">At a minimum, your app should supply sets of
-  custom drawables and assets for common tablet screen densities,
-  tagged with these qualifiers as appropriate:</p>
+<p>Other tips:</p>
 
 <ul>
-  <li><code>hdpi</code>, OR</li>
-  <li><code>xhdpi</code>, OR</li>
-  <li><code>xxhdpi</code></li>
+<li>When possible, use vector shapes for your icon designs so you can scale them
+without loss of detail and edge crispness.</li>
+<li>Use density-specific <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
+resource qualifiers</a> to ensure that the proper icons are loaded for each screen density.</li>
+<li>Tablets and other large screen devices often request a launcher icon that is one density
+size larger than the device's actual density, so you should provide your launcher
+icon at the highest density possible. For example, if a tablet has an {@code xhdpi} screen,
+it will request the {@code xxhdpi} version of the launcher icon.</li>
 </ul>
 
 <div class="rel-resources">
@@ -331,8 +347,8 @@
 
   <ul>
     <li>
-      <a href="{@docRoot}design/style/iconography.html">Iconography</a>&mdash; Android
-      Design document that shows how to use various types of icons.
+      <a href="{@docRoot}design/style/iconography.html">Iconography</a>&mdash;
+      Design guidelines and tips about how to create various types of icons.
     </li>
 
     <li>
diff --git a/docs/html/distribute/googleplay/spotlight/index.jd b/docs/html/distribute/googleplay/spotlight/index.jd
index b83080e..88cdec4 100644
--- a/docs/html/distribute/googleplay/spotlight/index.jd
+++ b/docs/html/distribute/googleplay/spotlight/index.jd
@@ -3,7 +3,14 @@
 header.hide=0
 
 @jd:body
-
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <p>Android developers, their apps, and their successes with Android and Google Play. </p>
 
diff --git a/docs/html/distribute/index.jd b/docs/html/distribute/index.jd
index 54f9301..8e7c6e1 100644
--- a/docs/html/distribute/index.jd
+++ b/docs/html/distribute/index.jd
@@ -2,6 +2,14 @@
 header.hide=1
 
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
     
     
 <div class="marquee">
diff --git a/docs/html/distribute/promote/device-art.jd b/docs/html/distribute/promote/device-art.jd
index 55b846e..58e183c 100644
--- a/docs/html/distribute/promote/device-art.jd
+++ b/docs/html/distribute/promote/device-art.jd
@@ -1,5 +1,13 @@
 page.title=Device Art Generator
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <p>The device art generator allows you to quickly wrap your app screenshots in real device artwork.
 This provides better visual context for your app screenshots on your web site or in other
diff --git a/docs/html/gms_navtree_data.js b/docs/html/gms_navtree_data.js
index 86f31d9..51c01f6 100644
--- a/docs/html/gms_navtree_data.js
+++ b/docs/html/gms_navtree_data.js
@@ -15,10 +15,10 @@
 , null ], [ "Classes", null, [ [ "DataBuffer", "reference/com/google/android/gms/common/data/DataBuffer.html", null, null ], [ "DataBufferUtils", "reference/com/google/android/gms/common/data/DataBufferUtils.html", null, null ] ]
 , null ] ]
 , null ], [ "com.google.android.gms.common.images", "reference/com/google/android/gms/common/images/package-summary.html", [ [ "Interfaces", null, [ [ "ImageManager.OnImageLoadedListener", "reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html", null, null ] ]
-, null ], [ "Classes", null, [ [ "ImageManager", "reference/com/google/android/gms/common/images/ImageManager.html", null, null ], [ "ImageManager.ImageReceiver", "reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html", null, null ] ]
+, null ], [ "Classes", null, [ [ "ImageManager", "reference/com/google/android/gms/common/images/ImageManager.html", null, null ] ]
 , null ] ]
 , null ], [ "com.google.android.gms.games", "reference/com/google/android/gms/games/package-summary.html", [ [ "Interfaces", null, [ [ "Game", "reference/com/google/android/gms/games/Game.html", null, null ], [ "OnGamesLoadedListener", "reference/com/google/android/gms/games/OnGamesLoadedListener.html", null, null ], [ "OnPlayersLoadedListener", "reference/com/google/android/gms/games/OnPlayersLoadedListener.html", null, null ], [ "OnSignOutCompleteListener", "reference/com/google/android/gms/games/OnSignOutCompleteListener.html", null, null ], [ "Player", "reference/com/google/android/gms/games/Player.html", null, null ], [ "RealTimeSocket", "reference/com/google/android/gms/games/RealTimeSocket.html", null, null ] ]
-, null ], [ "Classes", null, [ [ "GameBuffer", "reference/com/google/android/gms/games/GameBuffer.html", null, null ], [ "GameEntity", "reference/com/google/android/gms/games/GameEntity.html", null, null ], [ "GamesActivityResultCodes", "reference/com/google/android/gms/games/GamesActivityResultCodes.html", null, null ], [ "GamesClient", "reference/com/google/android/gms/games/GamesClient.html", null, null ], [ "GamesClient.Builder", "reference/com/google/android/gms/games/GamesClient.Builder.html", null, null ], [ "GamesClientSettings", "reference/com/google/android/gms/games/GamesClientSettings.html", null, null ], [ "PageDirection", "reference/com/google/android/gms/games/PageDirection.html", null, null ], [ "PlayerBuffer", "reference/com/google/android/gms/games/PlayerBuffer.html", null, null ], [ "PlayerEntity", "reference/com/google/android/gms/games/PlayerEntity.html", null, null ] ]
+, null ], [ "Classes", null, [ [ "GameBuffer", "reference/com/google/android/gms/games/GameBuffer.html", null, null ], [ "GameEntity", "reference/com/google/android/gms/games/GameEntity.html", null, null ], [ "GamesActivityResultCodes", "reference/com/google/android/gms/games/GamesActivityResultCodes.html", null, null ], [ "GamesClient", "reference/com/google/android/gms/games/GamesClient.html", null, null ], [ "GamesClient.Builder", "reference/com/google/android/gms/games/GamesClient.Builder.html", null, null ], [ "PageDirection", "reference/com/google/android/gms/games/PageDirection.html", null, null ], [ "PlayerBuffer", "reference/com/google/android/gms/games/PlayerBuffer.html", null, null ], [ "PlayerEntity", "reference/com/google/android/gms/games/PlayerEntity.html", null, null ] ]
 , null ] ]
 , null ], [ "com.google.android.gms.games.achievement", "reference/com/google/android/gms/games/achievement/package-summary.html", [ [ "Interfaces", null, [ [ "Achievement", "reference/com/google/android/gms/games/achievement/Achievement.html", null, null ], [ "OnAchievementsLoadedListener", "reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html", null, null ], [ "OnAchievementUpdatedListener", "reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html", null, null ] ]
 , null ], [ "Classes", null, [ [ "AchievementBuffer", "reference/com/google/android/gms/games/achievement/AchievementBuffer.html", null, null ] ]
diff --git a/docs/html/google/backup/signup.jd b/docs/html/google/backup/signup.jd
index 550d590..f9ad600 100644
--- a/docs/html/google/backup/signup.jd
+++ b/docs/html/google/backup/signup.jd
@@ -226,7 +226,7 @@
     } else if ($("input#agree").is(':checked')
         && packagename.length
         && packagename != DEFAULT_TEXT) {
-      window.location = "https://play.google.com/apps/publish/v2/GetBackupApiKey?p=" +
+      window.location = "https://play.google.com/apps/publish/GetBackupApiKey?p=" +
                       encodeURIComponent(packagename);
     } else {
       $("label#agreeLabel,label#pnameLabel").parent().stop().animate({color: "#258AAF"}, 200,
diff --git a/docs/html/google/index.jd b/docs/html/google/index.jd
index 4020cf4..095388e 100644
--- a/docs/html/google/index.jd
+++ b/docs/html/google/index.jd
@@ -1,6 +1,14 @@
 page.title=Google Services
 header.hide=1
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <style>
 div.landing-cell,
diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd
index 481a79c..0818514 100644
--- a/docs/html/google/play/billing/index.jd
+++ b/docs/html/google/play/billing/index.jd
@@ -1,5 +1,13 @@
 page.title=Google Play In-app Billing
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <p>In-app Billing is a Google Play service that lets you sell digital content from inside
 your applications. You can use the service to sell a wide range of content, including downloadable
diff --git a/docs/html/guide/components/index.jd b/docs/html/guide/components/index.jd
index 87bae53..6ede873 100644
--- a/docs/html/guide/components/index.jd
+++ b/docs/html/guide/components/index.jd
@@ -4,6 +4,14 @@
 page.landing.image=images/develop/app_components.png
 
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <div class="landing-docs">
 
diff --git a/docs/html/guide/topics/graphics/hardware-accel.jd b/docs/html/guide/topics/graphics/hardware-accel.jd
index 8ba6676..54ef20c 100644
--- a/docs/html/guide/topics/graphics/hardware-accel.jd
+++ b/docs/html/guide/topics/graphics/hardware-accel.jd
@@ -164,7 +164,7 @@
   draws views without hardware acceleration as well. The following sections describe the
   software-based  and hardware-accelerated drawing models.</p>
 
-<h3>Software-based drawing model</h3>
+<h3 id="software-model">Software-based drawing model</h3>
 <p>In the software drawing model, views are drawn with the following two steps:</p>
   <ol>
     <li>Invalidate the hierarchy</li>
@@ -196,7 +196,7 @@
   android.view.View#invalidate invalidate()} when their properties change, such as the background
   color or the text in a {@link android.widget.TextView}.</p>
 
-  <h3>Hardware accelerated drawing model</h3>
+  <h3 id="hardware-model">Hardware accelerated drawing model</h3>
   <p>The Android system still uses {@link android.view.View#invalidate invalidate()} and {@link
   android.view.View#draw draw()} to request screen updates and to render views, but handles the
   actual drawing differently. Instead of executing the drawing commands immediately, the Android
diff --git a/docs/html/images/tools/studio_error_eventlog.png b/docs/html/images/tools/studio_error_eventlog.png
new file mode 100644
index 0000000..909b285
--- /dev/null
+++ b/docs/html/images/tools/studio_error_eventlog.png
Binary files differ
diff --git a/docs/html/images/tools/studio_error_gradle5.png b/docs/html/images/tools/studio_error_gradle5.png
new file mode 100644
index 0000000..13de607
--- /dev/null
+++ b/docs/html/images/tools/studio_error_gradle5.png
Binary files differ
diff --git a/docs/html/images/tools/studio_error_supportlib.png b/docs/html/images/tools/studio_error_supportlib.png
new file mode 100644
index 0000000..603b54c
--- /dev/null
+++ b/docs/html/images/tools/studio_error_supportlib.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index d82deec..a972309 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -3,6 +3,14 @@
 carousel=true
 page.metaDescription=The official site for Android developers. Provides the Android SDK and documentation for app developers and designers.
 @jd:body
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 
 <div class="wrap">
diff --git a/docs/html/reference/com/google/android/gms/R.string.html b/docs/html/reference/com/google/android/gms/R.string.html
index f4fbd3a..9a353cd 100644
--- a/docs/html/reference/com/google/android/gms/R.string.html
+++ b/docs/html/reference/com/google/android/gms/R.string.html
@@ -778,9 +778,33 @@
           static
           
           int</nobr></td>
-          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#auth_client_availability_notification_title">auth_client_availability_notification_title</a></td>
-          <td class="jd-descrcol" width="100%">Title for notification shown when GooglePlayServices is unavailable [CHAR LIMIT=70] 
-</td>
+          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#auth_client_needs_enabling_title">auth_client_needs_enabling_title</a></td>
+          <td class="jd-descrcol" width="100%">Title for notification shown when GooglePlayServices needs to be
+        enabled for a application to work.</td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#auth_client_needs_installation_title">auth_client_needs_installation_title</a></td>
+          <td class="jd-descrcol" width="100%">Title for notification shown when GooglePlayServices needs to be
+        installed for a application to work.</td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#auth_client_needs_update_title">auth_client_needs_update_title</a></td>
+          <td class="jd-descrcol" width="100%">Title for notification shown when GooglePlayServices needs to be
+        udpated for a application to work.</td>
       </tr>
       
     
@@ -813,12 +837,24 @@
           static
           
           int</nobr></td>
+          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#auth_client_using_bad_version_title">auth_client_using_bad_version_title</a></td>
+          <td class="jd-descrcol" width="100%">Title for notification shown when a bad version of GooglePlayServices
+        has been installed and needs correction for an application to work.</td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#common_google_play_services_enable_button">common_google_play_services_enable_button</a></td>
           <td class="jd-descrcol" width="100%">Button in confirmation dialog to enable Google Play services.</td>
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -831,7 +867,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -844,7 +880,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -856,7 +892,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -869,7 +905,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -882,7 +918,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -895,7 +931,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -908,7 +944,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -920,7 +956,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -932,7 +968,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -944,7 +980,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -957,7 +993,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -970,7 +1006,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -982,7 +1018,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -994,44 +1030,6 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
-          
-          int</nobr></td>
-          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#location_client_ulr_inactive_age_under_13">location_client_ulr_inactive_age_under_13</a></td>
-          <td class="jd-descrcol" width="100%">Location client code resources (prefix with location_client) 
-
-        Begin strings for location.reporting
-
-
-        Some InactiveReason names.</td>
-      </tr>
-      
-    
-      <tr class=" api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
-          
-          int</nobr></td>
-          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#location_client_ulr_inactive_age_unknown">location_client_ulr_inactive_age_unknown</a></td>
-          <td class="jd-descrcol" width="100%"></td>
-      </tr>
-      
-    
-      <tr class="alt-color api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
-          
-          int</nobr></td>
-          <td class="jd-linkcol"><a href="/reference/com/google/android/gms/R.string.html#location_client_ulr_inactive_unknown_restriction">location_client_ulr_inactive_unknown_restriction</a></td>
-          <td class="jd-descrcol" width="100%"></td>
-      </tr>
-      
-    
 
 </table>
 
@@ -1314,7 +1312,7 @@
 
 
 
-<A NAME="auth_client_availability_notification_title"></A>
+<A NAME="auth_client_needs_enabling_title"></A>
 
 <div class="jd-details api apilevel-"> 
     <h4 class="jd-details-title">
@@ -1324,7 +1322,7 @@
          
         int
       </span>
-        auth_client_availability_notification_title
+        auth_client_needs_enabling_title
     </h4>
       <div class="api-level">
         
@@ -1334,7 +1332,68 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>Title for notification shown when GooglePlayServices is unavailable [CHAR LIMIT=70] 
+  <div class="jd-tagdata jd-tagdescr"><p>Title for notification shown when GooglePlayServices needs to be
+        enabled for a application to work. [CHAR LIMIT=70] 
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="auth_client_needs_installation_title"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        auth_client_needs_installation_title
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Title for notification shown when GooglePlayServices needs to be
+        installed for a application to work. [CHAR LIMIT=70] 
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="auth_client_needs_update_title"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        auth_client_needs_update_title
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Title for notification shown when GooglePlayServices needs to be
+        udpated for a application to work. [CHAR LIMIT=70] 
 </p></div>
 
     
@@ -1401,6 +1460,37 @@
 
 
 
+<A NAME="auth_client_using_bad_version_title"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        auth_client_using_bad_version_title
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Title for notification shown when a bad version of GooglePlayServices
+        has been installed and needs correction for an application to work.
+        [CHAR LIMIT=70] 
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="common_google_play_services_enable_button"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -1846,97 +1936,6 @@
 
 
 
-<A NAME="location_client_ulr_inactive_age_under_13"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-         
-        int
-      </span>
-        location_client_ulr_inactive_age_under_13
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p>Location client code resources (prefix with location_client) 
-
-        Begin strings for location.reporting
-
-
-        Some InactiveReason names.  See more in OneUp/package/location/res/values/strings.xml
-
-</p></div>
-
-    
-    </div>
-</div>
-
-
-
-<A NAME="location_client_ulr_inactive_age_unknown"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-         
-        int
-      </span>
-        location_client_ulr_inactive_age_unknown
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
-
-    
-    </div>
-</div>
-
-
-
-<A NAME="location_client_ulr_inactive_unknown_restriction"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-         
-        int
-      </span>
-        location_client_ulr_inactive_unknown_restriction
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
-
-    
-    </div>
-</div>
-
-
-
 
 <!-- Public ctors -->
 
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppState.html b/docs/html/reference/com/google/android/gms/appstate/AppState.html
index 287f031..564f1eb 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppState.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppState.html
@@ -995,7 +995,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the conflict data. Only valid if <code><a href="/reference/com/google/android/gms/appstate/AppState.html#hasConflict()">hasConflict()</a></code> is <code>true</code>.
+      <ul class="nolist"><li>The conflict data. Only valid if <code><a href="/reference/com/google/android/gms/appstate/AppState.html#hasConflict()">hasConflict()</a></code> is <code>true</code>.
 </li></ul>
   </div>
 
@@ -1029,7 +1029,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the latest known version of conflicting data from the server.
+      <ul class="nolist"><li>The latest known version of conflicting data from the server.
 </li></ul>
   </div>
 
@@ -1063,7 +1063,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the key associated with this app state blob.
+      <ul class="nolist"><li>The key associated with this app state blob.
 </li></ul>
   </div>
 
@@ -1097,7 +1097,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the local data for this app state blob, or null if none present.
+      <ul class="nolist"><li>The local data for this app state blob, or null if none present.
 </li></ul>
   </div>
 
@@ -1131,7 +1131,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the local version of the app state data.
+      <ul class="nolist"><li>The local version of the app state data.
 </li></ul>
   </div>
 
@@ -1165,7 +1165,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>whether or not this app state has conflict data to resolve.
+      <ul class="nolist"><li>Whether or not this app state has conflict data to resolve.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html b/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html
index f02cb98..785f9e7 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppStateBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html
index 445ca0b..a6e3ed9 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.Builder.html
@@ -1146,16 +1146,16 @@
       <table class="jd-tagtable">
         <tr>
           <th>context</td>
-          <td>the context to use for the connection.</td>
+          <td>The context to use for the connection.</td>
         </tr>
         <tr>
           <th>connectedListener</td>
-          <td>the listener where the results of the asynchronous
+          <td>The listener where the results of the asynchronous
             <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#connect()">connect()</a></code> call are delivered.</td>
         </tr>
         <tr>
           <th>connectionFailedListener</td>
-          <td>the listener which will be notified if the connection
+          <td>The listener which will be notified if the connection
             attempt fails.
 </td>
         </tr>
@@ -1262,11 +1262,15 @@
         <tr>
           <th>accountName</td>
           <td>The account name on the device that should be used by this
-            <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html">AppStateClient</a></code>. Must be non-null.
-</td>
+            <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html">AppStateClient</a></code>. Must be non-null.</td>
         </tr>
       </table>
   </div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Returns</h5>
+      <ul class="nolist"><li>This Builder.
+</li></ul>
+  </div>
 
     </div>
 </div>
diff --git a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html
index 706df18..cf381b3 100644
--- a/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html
+++ b/docs/html/reference/com/google/android/gms/appstate/AppStateClient.html
@@ -817,7 +817,7 @@
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#STATUS_DEVELOPER_ERROR">STATUS_DEVELOPER_ERROR</a></td>
-        <td class="jd-descrcol" width="100%">The developer has configured something incorrectly with their application.</td>
+        <td class="jd-descrcol" width="100%">Your application is incorrectly configured.</td>
     </tr>
     
     
@@ -870,8 +870,8 @@
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#STATUS_STATE_KEY_LIMIT_EXCEEDED">STATUS_STATE_KEY_LIMIT_EXCEEDED</a></td>
-        <td class="jd-descrcol" width="100%">The application already has data in the maximum number of keys and is attempting to create a
- new one.</td>
+        <td class="jd-descrcol" width="100%">The application already has data in the maximum number of keys (data slots) and is attempting
+ to create a new one.</td>
     </tr>
     
     
@@ -1816,8 +1816,8 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>The developer has configured something incorrectly with their application. This is a hard
- error, since retrying will not fix this.
+  <div class="jd-tagdata jd-tagdescr"><p>Your application is incorrectly configured. This is a hard error, since retrying will not fix
+ this.
 </p></div>
 
     
@@ -2095,9 +2095,9 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>The application already has data in the maximum number of keys and is attempting to create a
- new one. This is a hard error. Subsequent writes to this same key will only succeed after
- some number of keys have been deleted.
+  <div class="jd-tagdata jd-tagdescr"><p>The application already has data in the maximum number of keys (data slots) and is attempting
+ to create a new one. This is a hard error. Subsequent writes to this same key will only
+ succeed after some number of keys have been deleted.
 </p></div>
 
     
@@ -2327,7 +2327,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. This listener is
+          <td>The listener that is called when the load is complete. This listener is
             required to be non-null. The listener is called on the main thread.</td>
         </tr>
         <tr>
@@ -2478,7 +2478,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -2512,7 +2512,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -2556,7 +2556,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
 
@@ -2600,7 +2600,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
 
@@ -2640,7 +2640,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. This listener is
+          <td>The listener that is called when the load is complete. This listener is
             required to be non-null. The listener is called on the main thread.
 </td>
         </tr>
@@ -2683,7 +2683,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. This listener is
+          <td>The listener that is called when the load is complete. This listener is
             required to be non-null. The listener is called on the main thread.</td>
         </tr>
         <tr>
@@ -2765,9 +2765,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -2816,11 +2817,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
@@ -2880,7 +2882,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the operation is complete. This listener is
+          <td>The listener that is called when the operation is complete. This listener is
             required to be non-null. The listener is called on the main thread.</td>
         </tr>
         <tr>
@@ -2890,11 +2892,11 @@
         </tr>
         <tr>
           <th>resolvedVersion</td>
-          <td>version code from previous <code>onStateConflict</code> call.</td>
+          <td>Version code from previous <code>onStateConflict</code> call.</td>
         </tr>
         <tr>
           <th>resolvedData</td>
-          <td>data to submit as the current data. <code>null</code> is a valid value here.
+          <td>Data to submit as the current data. <code>null</code> is a valid value here.
             May be a maximum of <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#getMaxStateSize()">getMaxStateSize()</a></code> bytes.
 </td>
         </tr>
@@ -2937,7 +2939,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when sign-out is complete. This listener is
+          <td>The listener that is called when sign-out is complete. This listener is
             required to be non-null. The listener is called on the main thread.
 </td>
         </tr>
@@ -3106,7 +3108,7 @@
         </tr>
         <tr>
           <th>data</td>
-          <td>the data to store. May be a maximum of <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#getMaxStateSize()">getMaxStateSize()</a></code> bytes.
+          <td>The data to store. May be a maximum of <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#getMaxStateSize()">getMaxStateSize()</a></code> bytes.
 </td>
         </tr>
       </table>
@@ -3151,7 +3153,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the write operation is complete. This
+          <td>The listener that is called when the write operation is complete. This
             listener is required to be non-null. The listener is called on the main thread.</td>
         </tr>
         <tr>
@@ -3161,7 +3163,7 @@
         </tr>
         <tr>
           <th>data</td>
-          <td>the data to store. May be a maximum of <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#getMaxStateSize()">getMaxStateSize()</a></code> bytes.
+          <td>The data to store. May be a maximum of <code><a href="/reference/com/google/android/gms/appstate/AppStateClient.html#getMaxStateSize()">getMaxStateSize()</a></code> bytes.
 </td>
         </tr>
       </table>
diff --git a/docs/html/reference/com/google/android/gms/common/AccountPicker.html b/docs/html/reference/com/google/android/gms/common/AccountPicker.html
index f83a2e7..93da937 100644
--- a/docs/html/reference/com/google/android/gms/common/AccountPicker.html
+++ b/docs/html/reference/com/google/android/gms/common/AccountPicker.html
@@ -1130,28 +1130,28 @@
         </tr>
         <tr>
           <th>alwaysPromptForAccount</td>
-          <td>if set the account chooser screen is always shown, otherwise
- it is only shown when there is more than one account from which to choose</td>
+          <td>if set, the account chooser screen is always shown, otherwise
+ it is only shown when there is more than one account from which to choose.</td>
         </tr>
         <tr>
           <th>descriptionOverrideText</td>
           <td>if non-null this string is used as the description in the
- accounts chooser screen rather than the default</td>
+ accounts chooser screen rather than the default.</td>
         </tr>
         <tr>
           <th>addAccountAuthTokenType</td>
           <td>this string is passed as the <code><a href="/reference/android/accounts/AccountManager.html#addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback<Bundle>, Handler)</a></code>
- authTokenType parameter</td>
+ authTokenType parameter.</td>
         </tr>
         <tr>
           <th>addAccountRequiredFeatures</td>
           <td>this string array is passed as the
- <code><a href="/reference/android/accounts/AccountManager.html#addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback<Bundle>, Handler)</a></code> requiredFeatures parameter</td>
+ <code><a href="/reference/android/accounts/AccountManager.html#addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback<Bundle>, Handler)</a></code> requiredFeatures parameter.</td>
         </tr>
         <tr>
           <th>addAccountOptions</td>
           <td>This <code><a href="/reference/android/os/Bundle.html">Bundle</a></code> is passed as the
- <code><a href="/reference/android/accounts/AccountManager.html#addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback<Bundle>, Handler)</a></code> options parameter</td>
+ <code><a href="/reference/android/accounts/AccountManager.html#addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback<Bundle>, Handler)</a></code> options parameter.</td>
         </tr>
       </table>
   </div>
diff --git a/docs/html/reference/com/google/android/gms/common/ConnectionResult.html b/docs/html/reference/com/google/android/gms/common/ConnectionResult.html
index eaed4e5..5ca070d 100644
--- a/docs/html/reference/com/google/android/gms/common/ConnectionResult.html
+++ b/docs/html/reference/com/google/android/gms/common/ConnectionResult.html
@@ -1919,7 +1919,7 @@
  will start any intents requiring user interaction.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If there is a resolution that can be started.
+      <ul class="nolist"><li>true if there is a resolution that can be started.
 </li></ul>
   </div>
 
@@ -1953,7 +1953,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Returns true if the connection was successful.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the connection was successful, false if there was an error.
+      <ul class="nolist"><li>true if the connection was successful, false if there was an error.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html
index 05c531e..e768c22 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesClient.html
@@ -764,7 +764,7 @@
 
 
 <h2>Class Overview</h2>
-<p itemprop="articleBody">
+<p itemprop="articleBody">Base class for clients that connect with Google Play services.
 </p>
 
 
@@ -1186,7 +1186,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -1220,7 +1220,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -1264,7 +1264,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
   <div class="jd-tagdata">
@@ -1313,7 +1313,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
   <div class="jd-tagdata">
@@ -1350,9 +1350,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -1401,11 +1402,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
diff --git a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html
index bb1ee84..a9d9023 100644
--- a/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html
+++ b/docs/html/reference/com/google/android/gms/common/GooglePlayServicesUtil.html
@@ -1296,8 +1296,8 @@
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
             
-                3136000
-                (0x002fda00)
+                3159000
+                (0x003033d8)
             
         </span>
         </div>
diff --git a/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html b/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html
index f9e7220..e5f2ea93 100644
--- a/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html
+++ b/docs/html/reference/com/google/android/gms/common/data/DataBuffer.html
@@ -1362,13 +1362,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html b/docs/html/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html
deleted file mode 100644
index 72edcc3..0000000
--- a/docs/html/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html
+++ /dev/null
@@ -1,1552 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>ImageManager.ImageReceiver | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
-  var toRoot = "/";
-  var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
-  var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-5831155-1']);
-  _gaq.push(['_trackPageview']);
-
-  (function() {
-    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-  })();
-</script>
-</head>
-<body class="gc-documentation google
-  develop" itemscope itemtype="http://schema.org/Article">
-  <div id="doc-api-level" class="" style="display:none"></div>
-  <a name="top"></a>
-
-<a name="top"></a>
-
-    <!-- Header -->
-    <div id="header">
-        <div class="wrap" id="header-wrap">
-          <div class="col-3 logo">
-          <a href="/index.html">
-            <img src="/assets/images/dac_logo.png" width="123" height="25" alt="Android Developers" />
-          </a>
-          <div class="btn-quicknav" id="btn-quicknav">
-          	<a href="#" class="arrow-inactive">Quicknav</a>
-			      <a href="#" class="arrow-active">Quicknav</a>
-          </div>
-          </div>
-            <ul class="nav-x col-9">
-                <li class="design">
-                  <a href="/design/index.html"
-                  zh-tw-lang="設計"
-                  zh-cn-lang="设计"
-                  ru-lang="Проектирование"
-                  ko-lang="디자인"
-                  ja-lang="設計"
-                  es-lang="Diseñar"               
-                  >Design</a></li>
-                <li class="develop"><a href="/develop/index.html"
-                  zh-tw-lang="開發"
-                  zh-cn-lang="开发"
-                  ru-lang="Разработка"
-                  ko-lang="개발"
-                  ja-lang="開発"
-                  es-lang="Desarrollar"               
-                  >Develop</a></li>
-                <li class="distribute last"><a href="/distribute/index.html"
-                  zh-tw-lang="發佈"
-                  zh-cn-lang="分发"
-                  ru-lang="Распространение"
-                  ko-lang="배포"
-                  ja-lang="配布"
-                  es-lang="Distribuir"               
-                  >Distribute</a></li>
-            </ul>
-            
-            <!-- New Search -->
-            <div class="menu-container">
-            <div class="moremenu">
-    <div id="more-btn"></div>
-  </div>
-  <div class="morehover" id="moremenu">
-    <div class="top"></div>
-    <div class="mid">
-      <div class="header">Links</div>
-      <ul>
-        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
-        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
-        <li><a href="/about/index.html">About Android</a></li>
-      </ul>
-      <div class="header">Android Sites</div>
-      <ul>
-        <li><a href="http://www.android.com">Android.com</a></li>
-        <li class="active"><a>Android Developers</a></li>
-        <li><a href="http://source.android.com">Android Open Source Project</a></li>
-      </ul>
-      
-      
-      
-        <div class="header">Language</div>
-          <div id="language" class="locales">
-            <select name="language" onChange="changeLangPref(this.value, true)">
-                <option value="en">English</option>
-                <option value="es">Español</option>
-                <option value="ja">日本語</option>
-                <option value="ko">한국어</option>
-                <option value="ru">Русский</option>
-                <option value="zh-cn">中文 (中国)</option>
-                <option value="zh-tw">中文 (台灣)</option>
-            </select>
-          </div>
-        <script type="text/javascript">
-          <!--
-          loadLangPref();
-            //-->
-        </script>
-      
-      
-
-
-      <br class="clearfix" />
-    </div>
-    <div class="bottom"></div>
-  </div>
-  <div class="search" id="search-container">
-    <div class="search-inner">
-      <div id="search-btn"></div>
-      <div class="left"></div>
-      <form onsubmit="return submit_search()">
-        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')" 
-onkeyup="return search_changed(event, false, '/')" />
-      </form>
-      <div class="right"></div>
-        <a class="close hide">close</a>
-        <div class="left"></div>
-        <div class="right"></div>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper reference">
-    <div class="suggest-card reference no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper docs">
-    <div class="suggest-card dummy no-display">&nbsp;</div>
-    <div class="suggest-card develop no-display">
-      <ul class="search_filtered">
-      </ul>
-      <div class="child-card guides no-display">
-      </div>
-      <div class="child-card training no-display">
-      </div>
-    </div>
-    <div class="suggest-card design no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-    <div class="suggest-card distribute no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  </div>
-  <!-- /New Search>
-          
-          
-          <!-- Expanded quicknav -->
-           <div id="quicknav" class="col-9">
-                <ul>
-                    <li class="design">
-                      <ul>
-                        <li><a href="/design/index.html">Get Started</a></li>
-                        <li><a href="/design/style/index.html">Style</a></li>
-                        <li><a href="/design/patterns/index.html">Patterns</a></li>
-                        <li><a href="/design/building-blocks/index.html">Building Blocks</a></li>
-                        <li><a href="/design/downloads/index.html">Downloads</a></li>
-                        <li><a href="/design/videos/index.html">Videos</a></li>
-                      </ul>
-                    </li>
-                    <li class="develop">
-                      <ul>
-                        <li><a href="/training/index.html"
-                          zh-tw-lang="訓練課程"
-                          zh-cn-lang="培训"
-                          ru-lang="Курсы"
-                          ko-lang="교육"
-                          ja-lang="トレーニング"
-                          es-lang="Capacitación"               
-                          >Training</a></li>
-                        <li><a href="/guide/components/index.html"
-                          zh-tw-lang="API 指南"
-                          zh-cn-lang="API 指南"
-                          ru-lang="Руководства по API"
-                          ko-lang="API 가이드"
-                          ja-lang="API ガイド"
-                          es-lang="Guías de la API"               
-                          >API Guides</a></li>
-                        <li><a href="/reference/packages.html"
-                          zh-tw-lang="參考資源"
-                          zh-cn-lang="参考"
-                          ru-lang="Справочник"
-                          ko-lang="참조문서"
-                          ja-lang="リファレンス"
-                          es-lang="Referencia"               
-                          >Reference</a></li>
-                        <li><a href="/tools/index.html"
-                          zh-tw-lang="相關工具"
-                          zh-cn-lang="工具"
-                          ru-lang="Инструменты"
-                          ko-lang="도구"
-                          ja-lang="ツール"
-                          es-lang="Herramientas"               
-                          >Tools</a>
-                          <ul><li><a href="/sdk/index.html">Get the SDK</a></li></ul>
-                        </li>
-                        <li><a href="/google/index.html">Google Services</a>
-                        </li>
-                      </ul>
-                    </li>
-                    <li class="distribute last">
-                      <ul>
-                        <li><a href="/distribute/index.html">Google Play</a></li>
-                        <li><a href="/distribute/googleplay/publish/index.html">Publishing</a></li>
-                        <li><a href="/distribute/googleplay/promote/index.html">Promoting</a></li>
-                        <li><a href="/distribute/googleplay/quality/index.html">App Quality</a></li>
-                        <li><a href="/distribute/googleplay/spotlight/index.html">Spotlight</a></li>
-                        <li><a href="/distribute/open.html">Open Distribution</a></li>
-                      </ul>
-                    </li>
-                </ul>
-          </div>
-          <!-- /Expanded quicknav -->
-        </div>
-    </div>
-    <!-- /Header -->
-    
-    
-  <div id="searchResults" class="wrap" style="display:none;">
-          <h2 id="searchTitle">Results</h2>
-          <div id="leftSearchControl" class="search-control">Loading...</div>
-  </div>
-    
-    
-  
-    <!-- Secondary x-nav -->
-    <div id="nav-x">
-        <div class="wrap">
-            <ul class="nav-x col-9 develop" style="width:100%">
-                <li class="training"><a href="/training/index.html"
-                  zh-tw-lang="訓練課程"
-                  zh-cn-lang="培训"
-                  ru-lang="Курсы"
-                  ko-lang="교육"
-                  ja-lang="トレーニング"
-                  es-lang="Capacitación"               
-                  >Training</a></li>
-                <li class="guide"><a href="/guide/components/index.html"
-                  zh-tw-lang="API 指南"
-                  zh-cn-lang="API 指南"
-                  ru-lang="Руководства по API"
-                  ko-lang="API 가이드"
-                  ja-lang="API ガイド"
-                  es-lang="Guías de la API"               
-                  >API Guides</a></li>
-                <li class="reference"><a href="/reference/packages.html"
-                  zh-tw-lang="參考資源"
-                  zh-cn-lang="参考"
-                  ru-lang="Справочник"
-                  ko-lang="참조문서"
-                  ja-lang="リファレンス"
-                  es-lang="Referencia"               
-                  >Reference</a></li>
-                <li class="tools"><a href="/tools/index.html"
-                  zh-tw-lang="相關工具"
-                  zh-cn-lang="工具"
-                  ru-lang="Инструменты"
-                  ko-lang="도구"
-                  ja-lang="ツール"
-                  es-lang="Herramientas"
-                  >Tools</a></li>
-                <li class="google"><a href="/google/index.html"
-                  >Google Services</a>
-                </li>
-            </ul>
-        </div>
-        
-    </div>
-    <!-- /Sendondary x-nav -->
-  
-
-
-
-
-  
-
-
-  
-  <div class="wrap clearfix" id="body-content">
-    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
-      <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-
-
-<ul id="nav">
-
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/index.html">
-          <span class="en">Overview</span>
-      </a></div>
-  </li>
-
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/games.html">
-          <span class="en">Games</span>
-      </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/location.html">
-          <span class="en">Location</span>
-      </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/plus.html">
-          <span class="en">Google+</span>
-                </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/maps.html">
-          <span class="en">Google Maps</span>
-      </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/auth.html">
-          <span class="en">Authorization</span>
-      </a></div>
-  </li>
-
-
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/play-services/index.html">
-      <span class="en">Google Play Services</span></a>
-    </div>
-    <ul>
-      <li><a href="/google/play-services/setup.html">
-          <span class="en">Setup</span></a>
-      </li>
-      <li id="gms-tree-list" class="nav-section">
-        <div class="nav-section-header">
-          <a href="/reference/gms-packages.html">
-            <span class="en">Reference</span>
-          </a>
-        <div>
-      </li>
-    </ul>
-  </li>
-
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/play/billing/index.html">
-      <span class="en">Google Play In-app Billing</span></a>
-    </div>
-    <ul>
-      <li><a href="/google/play/billing/billing_overview.html">
-              <span class="en">Overview</span></a>
-      </li>
-      <li class="nav-section"><div class="nav-section-header"><a href="/google/play/billing/api.html">
-              <span class="en">Version 3 API</span></a></div>
-              <ul>
-              <li><a href="/google/play/billing/billing_integrate.html">
-              <span class="en">Implementing the API</span></a></li>
-              <li><a href="/google/play/billing/billing_reference.html">
-              <span class="en">Reference</span></a></li>
-              </ul>
-      </li>
-      <li class="nav-section"><div class="nav-section-header"><a href="/google/play/billing/v2/api.html">
-              <span class="en">Version 2 API</span></a></div>
-              <ul>
-              <li><a href="/google/play/billing/v2/billing_integrate.html">
-              <span class="en">Implementing the API</span></a></li>
-              <li><a href="/google/play/billing/v2/billing_subscriptions.html">
-              <span class="en">Subscriptions</span></a></li>
-              <li><a href="/google/play/billing/v2/billing_reference.html">
-              <span class="en">Reference</span></a></li>
-              </ul>
-      </li>
-      <li><a href="/google/play/billing/billing_subscriptions.html">
-              <span class="en">Subscriptions</span></a>
-      </li>
-      <li><a href="/google/play/billing/billing_best_practices.html">
-              <span class="en">Security and Design</span></a>
-      </li>
-      <li><a href="/google/play/billing/billing_testing.html">
-              <span class="en">Testing In-app Billing</span></a>
-      </li>
-      <li><a href="/google/play/billing/billing_admin.html">
-              <span class="en">Administering In-app Billing</span></a>
-      </li>
-      <li><a href="/google/play/billing/gp-purchase-status-api.html">
-              <span class="en">Purchase Status API</span></a>
-      </li>
-      <li><a href="/google/play/billing/versions.html">
-              <span class="en">Version Notes</span></a>
-      </li>
-    </ul>
-  </li>
-
-
-
-  <li class="nav-section">
-      <div class="nav-section-header"><a href="/google/gcm/index.html">
-        <span class="en">Google Cloud Messaging</span></a>
-      </div>
-      <ul>
-        <li><a href="/google/gcm/gs.html">
-            <span class="en">Getting Started</span></a>
-        </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
-        </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
-        </li>
-        <li><a href="/google/gcm/notifications.html">
-              <span class="en">User Notifications</span></a>
-        </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
-        <li><a href="/google/gcm/adv.html">
-            <span class="en">Advanced Topics</span></a>
-        </li>
-        <li><a href="/google/gcm/c2dm.html">
-            <span class="en">Migration</span></a>
-        </li>
-        <li id="gcm-tree-list" class="nav-section">
-          <div class="nav-section-header">
-            <a href="/reference/gcm-packages.html">
-              <span class="en">Reference</span>
-            </a>
-          <div>
-        </li>
-      </ul>
-  </li>
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/play/dist.html">
-      <span class="en">Google Play Distribution</span></a>
-    </div>
-    <ul>
-      <li><a href="/google/play/filters.html">
-          <span class="en">Filters on Google Play</span></a>
-      </li>
-
-      <li><a href="/google/play/publishing/multiple-apks.html">
-          <span class="en">Multiple APK Support</span></a>
-      </li>
-      <li><a href="/google/play/expansion-files.html">
-          <span class="en">APK Expansion Files</span></a>
-      </li>
-      <li class="nav-section">
-        <div class="nav-section-header"><a href="/google/play/licensing/index.html">
-          <span class="en">Application Licensing</span></a>
-        </div>
-        <ul>
-          <li><a href="/google/play/licensing/overview.html">
-              <span class="en">Licensing Overview</span></a>
-          </li>
-          <li><a href="/google/play/licensing/setting-up.html">
-              <span class="en">Setting Up for Licensing</span></a>
-          </li>
-          <li><a href="/google/play/licensing/adding-licensing.html">
-              <span class="en">Adding Licensing to Your App</span></a>
-          </li>
-          <li><a href="/google/play/licensing/licensing-reference.html">
-              <span class="en">Licensing Reference</span></a>
-          </li>
-        </ul>
-      </li>
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/backup/index.html">
-      Android Backup Service</a>
-    </div>
-    <ul>
-      <li><a href="/google/backup/signup.html">
-          Register</a>
-      </li>
-    </ul>
-  </li>
-
-  </ul>
-
-</li>
-
-
-
-</ul>
-
-<script type="text/javascript">
-<!--
-    buildToggleLists();
-    changeNavLang(getLangPref());
-//-->
-</script>
-
-
-        
-
-      </div>
-      <script type="text/javascript">
-       showGoogleRefTree();
-    
-      </script>
-    </div> <!-- end side-nav -->
-    <script>
-      $(document).ready(function() {
-        scrollIntoView("devdoc-nav");
-        });
-    </script>
-
-
-     
-
-
-
-<div class="col-12"  id="doc-col">
-
-<div id="api-info-block">
-
-
-
-  
-   
-  
-  
-  
-   
-  
-  
-
-  
-   
-  
-  
-  
-  
-
-  
-   
-  
-  
-   
-  
-  
-  
-
-
-<div class="sum-details-links">
-
-Summary:
-
-
-
-
-
-
-  <a href="#inhconstants">Inherited Constants</a>
-  
-
-
-
-  &#124; <a href="#inhfields">Inherited Fields</a>
-  
-
-
-
-
-  &#124; <a href="#pubmethods">Methods</a>
-  
-
-
-
-  &#124; <a href="#inhmethods">Inherited Methods</a>
-
-&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
-
-</div><!-- end sum-details-links -->
-<div class="api-level">
-  
-  
-  
-
-</div>
-</div><!-- end api-info-block -->
-
-
-<!-- ======== START OF CLASS DATA ======== -->
-
-<div id="jd-header">
-    protected
-     
-    final 
-    
-    class
-<h1 itemprop="name">ImageManager.ImageReceiver</h1>
-
-
-
-  
-  
-  
-
-  
-    extends ResultReceiver<br/>
-  
-  
-  
-
-  
-  
-  
-
-
-</div><!-- end header -->
-
-<div id="naMessage"></div>
-
-<div id="jd-content" class="api apilevel-">
-<table class="jd-inheritance-table">
-
-
-    <tr>
-         	
-        <td colspan="3" class="jd-inheritance-class-cell">java.lang.Object</td>
-    </tr>
-    
-
-    <tr>
-        
-            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
-         	
-        <td colspan="2" class="jd-inheritance-class-cell">android.os.ResultReceiver</td>
-    </tr>
-    
-
-    <tr>
-        
-            <td class="jd-inheritance-space">&nbsp;</td>
-        
-            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
-         	
-        <td colspan="1" class="jd-inheritance-class-cell">com.google.android.gms.common.images.ImageManager.ImageReceiver</td>
-    </tr>
-    
-
-</table>
-
-
-
-
-
-
-
-<div class="jd-descr">
-
-
-
-
-
-
-</div><!-- jd-descr -->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div class="jd-descr">
-
-
-<h2>Summary</h2>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<!-- =========== ENUM CONSTANT SUMMARY =========== -->
-<table id="inhconstants" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Constants</div></th></tr>
-
-
-
-
-
-
-<tr class="api apilevel-" >
-<td colspan="12">
-
-  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-constants-android.os.Parcelable" class="jd-expando-trigger closed"
-          ><img id="inherited-constants-android.os.Parcelable-trigger"
-          src="/assets/images/triangle-closed.png"
-          class="jd-expando-trigger-img" /></a>From interface
-android.os.Parcelable
-<div id="inherited-constants-android.os.Parcelable">
-  <div id="inherited-constants-android.os.Parcelable-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-constants-android.os.Parcelable-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    
-
-    
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol">int</td>
-        <td class="jd-linkcol">CONTENTS_FILE_DESCRIPTOR</td>
-        <td class="jd-descrcol" width="100%"></td>
-    </tr>
-    
-    
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol">int</td>
-        <td class="jd-linkcol">PARCELABLE_WRITE_RETURN_VALUE</td>
-        <td class="jd-descrcol" width="100%"></td>
-    </tr>
-    
-    
-</table>
-  </div>
-</div>
-</td></tr>
-
-
-</table>
-
-
-
-
-
-
-
-<!-- =========== FIELD SUMMARY =========== -->
-<table id="inhfields" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Fields</div></th></tr>
-
-
-<tr class="api apilevel-" >
-<td colspan="12">
-
-  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-fields-android.os.ResultReceiver" class="jd-expando-trigger closed"
-          ><img id="inherited-fields-android.os.ResultReceiver-trigger"
-          src="/assets/images/triangle-closed.png"
-          class="jd-expando-trigger-img" /></a>From class
-android.os.ResultReceiver
-<div id="inherited-fields-android.os.ResultReceiver">
-  <div id="inherited-fields-android.os.ResultReceiver-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-fields-android.os.ResultReceiver-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    
-
-    
-      <tr class="alt-color api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
-          final
-          Creator&lt;ResultReceiver&gt;</nobr></td>
-          <td class="jd-linkcol">CREATOR</td>
-          <td class="jd-descrcol" width="100%"></td>
-      </tr>
-      
-    
-</table>
-  </div>
-</div>
-</td></tr>
-
-
-
-
-
-
-</table>
-
-
-
-
-
-
-
-
-<!-- ========== METHOD SUMMARY =========== -->
-<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
-
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html#addOnImageLoadedListenerHolder(com.google.android.gms.common.images.ImageManager.ListenerHolder)">addOnImageLoadedListenerHolder</a></span>(ImageManager.ListenerHolder imageViewLoadListener)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            Uri</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html#getUri()">getUri</a></span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html#onReceiveResult(int, android.os.Bundle)">onReceiveResult</a></span>(int resultCode, Bundle resultData)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html#removeOnImageLoadedListenerHolder(com.google.android.gms.common.images.ImageManager.ListenerHolder)">removeOnImageLoadedListenerHolder</a></span>(ImageManager.ListenerHolder imageViewLoadListener)</nobr>
-        
-  </td></tr>
-
-
-
-</table>
-
-
-
-
-
-
-
-<!-- ========== METHOD SUMMARY =========== -->
-<table id="inhmethods" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Methods</div></th></tr>
-
-
-<tr class="api apilevel-" >
-<td colspan="12">
-  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-android.os.ResultReceiver" class="jd-expando-trigger closed"
-          ><img id="inherited-methods-android.os.ResultReceiver-trigger"
-          src="/assets/images/triangle-closed.png"
-          class="jd-expando-trigger-img" /></a>
-From class
-
-  android.os.ResultReceiver
-
-<div id="inherited-methods-android.os.ResultReceiver">
-  <div id="inherited-methods-android.os.ResultReceiver-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-methods-android.os.ResultReceiver-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            int</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">describeContents</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">onReceiveResult</span>(int arg0, Bundle arg1)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">send</span>(int arg0, Bundle arg1)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">writeToParcel</span>(Parcel arg0, int arg1)</nobr>
-        
-  </td></tr>
-
-
-</table>
-  </div>
-</div>
-</td></tr>
-
-
-
-<tr class="api apilevel-" >
-<td colspan="12">
-  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
-          ><img id="inherited-methods-java.lang.Object-trigger"
-          src="/assets/images/triangle-closed.png"
-          class="jd-expando-trigger-img" /></a>
-From class
-
-  java.lang.Object
-
-<div id="inherited-methods-java.lang.Object">
-  <div id="inherited-methods-java.lang.Object-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            Object</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">clone</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            boolean</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">equals</span>(Object arg0)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">finalize</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            Class&lt;?&gt;</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">getClass</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            int</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">hashCode</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">notify</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">notifyAll</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            String</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">toString</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">wait</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">wait</span>(long arg0)</nobr>
-        
-  </td></tr>
-
-
-</table>
-  </div>
-</div>
-</td></tr>
-
-
-
-<tr class="api apilevel-" >
-<td colspan="12">
-  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-android.os.Parcelable" class="jd-expando-trigger closed"
-          ><img id="inherited-methods-android.os.Parcelable-trigger"
-          src="/assets/images/triangle-closed.png"
-          class="jd-expando-trigger-img" /></a>
-From interface
-
-  android.os.Parcelable
-
-<div id="inherited-methods-android.os.Parcelable">
-  <div id="inherited-methods-android.os.Parcelable-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-methods-android.os.Parcelable-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            abstract
-            
-            
-            
-            
-            int</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">describeContents</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            abstract
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">writeToParcel</span>(Parcel arg0, int arg1)</nobr>
-        
-  </td></tr>
-
-
-</table>
-  </div>
-</div>
-</td></tr>
-
-
-</table>
-
-
-</div><!-- jd-descr (summary) -->
-
-<!-- Details -->
-
-
-
-
-
-
-
-
-<!-- XML Attributes -->
-
-
-<!-- Enum Values -->
-
-
-<!-- Constants -->
-
-
-<!-- Fields -->
-
-
-<!-- Public ctors -->
-
-
-
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<!-- Protected ctors -->
-
-
-
-<!-- ========= METHOD DETAIL ======== -->
-<!-- Public methdos -->
-
-<h2>Public Methods</h2>
-
-
-
-<A NAME="addOnImageLoadedListenerHolder(com.google.android.gms.common.images.ImageManager.ListenerHolder)"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-         
-         
-         
-         
-        void
-      </span>
-      <span class="sympad">addOnImageLoadedListenerHolder</span>
-      <span class="normal">(ImageManager.ListenerHolder imageViewLoadListener)</span>
-    </h4>
-      <div class="api-level">
-        <div></div>
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
-
-    </div>
-</div>
-
-
-<A NAME="getUri()"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-         
-         
-         
-         
-        Uri
-      </span>
-      <span class="sympad">getUri</span>
-      <span class="normal">()</span>
-    </h4>
-      <div class="api-level">
-        <div></div>
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
-
-    </div>
-</div>
-
-
-<A NAME="onReceiveResult(int, android.os.Bundle)"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-         
-         
-         
-         
-        void
-      </span>
-      <span class="sympad">onReceiveResult</span>
-      <span class="normal">(int resultCode, Bundle resultData)</span>
-    </h4>
-      <div class="api-level">
-        <div></div>
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
-
-    </div>
-</div>
-
-
-<A NAME="removeOnImageLoadedListenerHolder(com.google.android.gms.common.images.ImageManager.ListenerHolder)"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-         
-         
-         
-         
-        void
-      </span>
-      <span class="sympad">removeOnImageLoadedListenerHolder</span>
-      <span class="normal">(ImageManager.ListenerHolder imageViewLoadListener)</span>
-    </h4>
-      <div class="api-level">
-        <div></div>
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
-
-    </div>
-</div>
-
-
-
-
-
-<!-- ========= METHOD DETAIL ======== -->
-
-
-
-<!-- ========= END OF CLASS DATA ========= -->
-<A NAME="navbar_top"></A>
-
-<div id="footer" class="wrap" >
-        
-
-  <div id="copyright">
-    
-  Except as noted, this content is licensed under <a
-  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
-  For details and restrictions, see the <a href="/license.html">
-  Content License</a>.
-  </div>
-  <div id="build_info">
-    
-<script src="/timestamp.js" type="text/javascript"></script>
-<script>document.write(BUILD_TIMESTAMP)</script>
-
-  </div>
-
-
-  <div id="footerlinks">
-    
-  <p>
-    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
-    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
-    <a href="/support.html">Support</a>
-  </p>
-  </div>
-
-</div> <!-- end footer -->
-</div> <!-- jd-content -->
-
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content --> 
-
-
-
-
-
-
-</body>
-</html>
diff --git a/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html b/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html
index efa3a83..c51f59f 100644
--- a/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html
+++ b/docs/html/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html
@@ -679,6 +679,10 @@
 <div class="jd-descr">
 
 
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Listener interface for handling when the image for a particular URI has been loaded.
+</p>
+
 
 
 
@@ -749,6 +753,8 @@
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html#onImageLoaded(android.net.Uri, android.graphics.drawable.Drawable)">onImageLoaded</a></span>(Uri uri, Drawable drawable)</nobr>
         
+        <div class="jd-descrdiv">Listener method invoked when an image has been loaded.</div>
+  
   </td></tr>
 
 
@@ -823,7 +829,21 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+  <div class="jd-tagdata jd-tagdescr"><p>Listener method invoked when an image has been loaded.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>uri</td>
+          <td>The URI of the loaded image.</td>
+        </tr>
+        <tr>
+          <th>drawable</td>
+          <td>Drawable containing the image.
+</td>
+        </tr>
+      </table>
+  </div>
 
     </div>
 </div>
diff --git a/docs/html/reference/com/google/android/gms/common/images/ImageManager.html b/docs/html/reference/com/google/android/gms/common/images/ImageManager.html
index b1d9572..a89fb11 100644
--- a/docs/html/reference/com/google/android/gms/common/images/ImageManager.html
+++ b/docs/html/reference/com/google/android/gms/common/images/ImageManager.html
@@ -767,21 +767,9 @@
          
          
         
-        class</nobr></td>
-      <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html">ImageManager.ImageReceiver</a></td>
-      <td class="jd-descrcol" width="100%">&nbsp;</td>
-    </tr>
-    
-    
-    <tr class=" api apilevel-" >
-      <td class="jd-typecol"><nobr>
-        
-         
-         
-        
         interface</nobr></td>
       <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html">ImageManager.OnImageLoadedListener</a></td>
-      <td class="jd-descrcol" width="100%">&nbsp;</td>
+      <td class="jd-descrcol" width="100%">Listener interface for handling when the image for a particular URI has been loaded.&nbsp;</td>
     </tr>
     
     
@@ -1269,7 +1257,7 @@
         </tr>
         <tr>
           <th>uri</td>
-          <td>Uri to load the image data from.</td>
+          <td>URI to load the image data from.</td>
         </tr>
       </table>
   </div>
@@ -1356,8 +1344,8 @@
  <p>
  The result is delivered to the given listener on the main thread.
  <p>
- If we don't find a result image view will be set to the given default resource if the image
- needs to be loaded asynchronously.</p></div>
+ If a result is not found, the image view will be set to the given default resource if the
+ image needs to be loaded asynchronously.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Parameters</h5>
       <table class="jd-tagtable">
@@ -1367,7 +1355,7 @@
         </tr>
         <tr>
           <th>uri</td>
-          <td>Uri to load the image data from.</td>
+          <td>URI to load the image data from.</td>
         </tr>
         <tr>
           <th>defaultResId</td>
@@ -1417,7 +1405,7 @@
         </tr>
         <tr>
           <th>uri</td>
-          <td>Uri to load the image data from.
+          <td>URI to load the image data from.
 </td>
         </tr>
       </table>
@@ -1471,7 +1459,7 @@
         </tr>
         <tr>
           <th>uri</td>
-          <td>Uri to load the image data from.</td>
+          <td>URI to load the image data from.</td>
         </tr>
         <tr>
           <th>defaultResId</td>
diff --git a/docs/html/reference/com/google/android/gms/common/images/package-summary.html b/docs/html/reference/com/google/android/gms/common/images/package-summary.html
index b5d1582d..b8b6f4a 100644
--- a/docs/html/reference/com/google/android/gms/common/images/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/common/images/package-summary.html
@@ -640,6 +640,11 @@
 <div id="jd-content" class="api apilevel-">
 
 
+  <div class="jd-descr">
+    Contains classes for loading images from Google Play services.
+
+  </div>
+
 
 
 
@@ -651,7 +656,7 @@
   <table class="jd-sumtable-expando">
         <tr class="alt-color api apilevel-" >
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html">ImageManager.OnImageLoadedListener</a></td>
-              <td class="jd-descrcol" width="100%">&nbsp;</td>
+              <td class="jd-descrcol" width="100%">Listener interface for handling when the image for a particular URI has been loaded.&nbsp;</td>
           </tr>
   </table>
     </div>
@@ -667,10 +672,6 @@
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/images/ImageManager.html">ImageManager</a></td>
               <td class="jd-descrcol" width="100%">This class is used to load images from the network and handles local caching for you.&nbsp;</td>
           </tr>
-        <tr class=" api apilevel-" >
-              <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html">ImageManager.ImageReceiver</a></td>
-              <td class="jd-descrcol" width="100%">&nbsp;</td>
-          </tr>
   </table>
     </div>
   
diff --git a/docs/html/reference/com/google/android/gms/common/package-summary.html b/docs/html/reference/com/google/android/gms/common/package-summary.html
index 2e43027..b8877eb 100644
--- a/docs/html/reference/com/google/android/gms/common/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/common/package-summary.html
@@ -656,8 +656,7 @@
   <table class="jd-sumtable-expando">
         <tr class="alt-color api apilevel-" >
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html">GooglePlayServicesClient</a></td>
-              <td class="jd-descrcol" width="100%">
-&nbsp;</td>
+              <td class="jd-descrcol" width="100%">Base class for clients that connect with Google Play services.&nbsp;</td>
           </tr>
         <tr class=" api apilevel-" >
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html">GooglePlayServicesClient.ConnectionCallbacks</a></td>
diff --git a/docs/html/reference/com/google/android/gms/games/Game.html b/docs/html/reference/com/google/android/gms/games/Game.html
index d45ede0..e9f4a6b 100644
--- a/docs/html/reference/com/google/android/gms/games/Game.html
+++ b/docs/html/reference/com/google/android/gms/games/Game.html
@@ -1119,24 +1119,6 @@
   </td></tr>
 
 
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            abstract
-            
-            
-            
-            
-            boolean</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/games/Game.html#isPlayEnabledGame()">isPlayEnabledGame</a></span>()</nobr>
-        
-        <div class="jd-descrdiv">Indicates whether the game is a Google Play-Enabled game.</div>
-  
-  </td></tr>
-
-
 
 </table>
 
@@ -1797,40 +1779,6 @@
 </div>
 
 
-<A NAME="isPlayEnabledGame()"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-         
-         
-        abstract 
-         
-        boolean
-      </span>
-      <span class="sympad">isPlayEnabledGame</span>
-      <span class="normal">()</span>
-    </h4>
-      <div class="api-level">
-        <div></div>
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p>Indicates whether the game is a Google Play-Enabled game.</p></div>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>Whether the game is a Google Play-Enabled game.
-</li></ul>
-  </div>
-
-    </div>
-</div>
-
-
 
 
 
diff --git a/docs/html/reference/com/google/android/gms/games/GameBuffer.html b/docs/html/reference/com/google/android/gms/games/GameBuffer.html
index 0791927..61678a6 100644
--- a/docs/html/reference/com/google/android/gms/games/GameBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/GameBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/GameEntity.html b/docs/html/reference/com/google/android/gms/games/GameEntity.html
index df5ef52..82e1ef0 100644
--- a/docs/html/reference/com/google/android/gms/games/GameEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/GameEntity.html
@@ -1271,8 +1271,6 @@
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/games/GameEntity.html#isPlayEnabledGame()">isPlayEnabledGame</a></span>()</nobr>
         
-        <div class="jd-descrdiv">Indicates whether the game is a Google Play-Enabled game.</div>
-  
   </td></tr>
 
 
@@ -1899,24 +1897,6 @@
   </td></tr>
 
 
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            abstract
-            
-            
-            
-            
-            boolean</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/games/Game.html#isPlayEnabledGame()">isPlayEnabledGame</a></span>()</nobr>
-        
-        <div class="jd-descrdiv">Indicates whether the game is a Google Play-Enabled game.</div>
-  
-  </td></tr>
-
-
 </table>
   </div>
 </div>
@@ -2746,12 +2726,7 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>Indicates whether the game is a Google Play-Enabled game.</p></div>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>Whether the game is a Google Play-Enabled game.
-</li></ul>
-  </div>
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
 </div>
diff --git a/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html b/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html
index d017bb0..d4d7253 100644
--- a/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html
+++ b/docs/html/reference/com/google/android/gms/games/GamesActivityResultCodes.html
@@ -1129,12 +1129,12 @@
  to "leave the room" from the real-time multiplayer "waiting room" screen.
 
  (Note that if the user simply exits the "waiting room" screen by pressing
- Back, that does *not* indicate that the user wants to leave the current room.
+ Back, that does <em>not</em> indicate that the user wants to leave the current room.
  The waiting room screen will return <code><a href="/reference/android/app/Activity.html#RESULT_CANCELED">RESULT_CANCELED</a></code> in that
  case.)</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">See Also</h5>
-      <ul class="nolist"><li><code><a href="/">ERROR(/GamesClient#getRealTimeWaitingRoomIntent())</a></code></li>
+      <ul class="nolist"><li><code><a href="/reference/com/google/android/gms/games/GamesClient.html#getRealTimeWaitingRoomIntent(com.google.android.gms.games.multiplayer.realtime.Room, int)">getRealTimeWaitingRoomIntent(Room, int)</a></code></li>
       </ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html b/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html
index 307da11..5cfd8ab 100644
--- a/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html
+++ b/docs/html/reference/com/google/android/gms/games/GamesClient.Builder.html
@@ -1183,16 +1183,16 @@
       <table class="jd-tagtable">
         <tr>
           <th>context</td>
-          <td>the context to use for the connection.</td>
+          <td>The context to use for the connection.</td>
         </tr>
         <tr>
           <th>connectedListener</td>
-          <td>the listener where the results of the asynchronous
+          <td>The listener where the results of the asynchronous
             <code><a href="/reference/com/google/android/gms/games/GamesClient.html#connect()">connect()</a></code> call are delivered.</td>
         </tr>
         <tr>
           <th>connectionFailedListener</td>
-          <td>the listener which will be notified if the connection
+          <td>The listener which will be notified if the connection
             attempt fails.
 </td>
         </tr>
diff --git a/docs/html/reference/com/google/android/gms/games/GamesClient.html b/docs/html/reference/com/google/android/gms/games/GamesClient.html
index 1a107bc..63c4d3a 100644
--- a/docs/html/reference/com/google/android/gms/games/GamesClient.html
+++ b/docs/html/reference/com/google/android/gms/games/GamesClient.html
@@ -852,7 +852,7 @@
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClient.html#MAX_RELIABLE_MESSAGE_LEN">MAX_RELIABLE_MESSAGE_LEN</a></td>
         <td class="jd-descrcol" width="100%">This gives the maximum message size supported via the <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendReliableRealTimeMessage(com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener, byte[], java.lang.String, java.lang.String)">sendReliableRealTimeMessage(RealTimeReliableMessageSentListener, byte[], String, String)</a></code>
- APIs (excluding protocol headers).</td>
+ methods (excluding protocol headers).</td>
     </tr>
     
     
@@ -860,7 +860,7 @@
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClient.html#MAX_UNRELIABLE_MESSAGE_LEN">MAX_UNRELIABLE_MESSAGE_LEN</a></td>
         <td class="jd-descrcol" width="100%">This gives the maximum (unfragmented) message size supported via the
- <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> APIs (excluding protocol headers).</td>
+ <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> methods (excluding protocol headers).</td>
     </tr>
     
     
@@ -934,8 +934,8 @@
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClient.html#STATUS_INVALID_REAL_TIME_ROOM_ID">STATUS_INVALID_REAL_TIME_ROOM_ID</a></td>
-        <td class="jd-descrcol" width="100%">Constant indicating that real-time room ID provided by the user is not a valid or it is
- not currently active real-time room.</td>
+        <td class="jd-descrcol" width="100%">Constant indicating that the real-time room ID provided to the operation was not valid, or
+ does not correspond to the currently active real-time room.</td>
     </tr>
     
     
@@ -1025,8 +1025,8 @@
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClient.html#STATUS_REAL_TIME_MESSAGE_FAILED">STATUS_REAL_TIME_MESSAGE_FAILED</a></td>
-        <td class="jd-descrcol" width="100%">Status code returned from <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> and the
- <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendReliableRealTimeMessage(com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener, byte[], java.lang.String, java.lang.String)">sendReliableRealTimeMessage(RealTimeReliableMessageSentListener, byte[], String, String)</a></code> APIs when the message send operation failed due to an
+        <td class="jd-descrcol" width="100%">Status code returned from the <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> and
+ <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendReliableRealTimeMessage(com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener, byte[], java.lang.String, java.lang.String)">sendReliableRealTimeMessage(RealTimeReliableMessageSentListener, byte[], String, String)</a></code> methods when the message send operation failed due to an
  immediate error.</td>
     </tr>
     
@@ -1275,6 +1275,22 @@
             
             
             
+            <a href="/reference/com/google/android/gms/games/Game.html">Game</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/games/GamesClient.html#getCurrentGame()">getCurrentGame</a></span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
             <a href="/reference/com/google/android/gms/games/Player.html">Player</a></nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -1284,7 +1300,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1300,7 +1316,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1318,7 +1334,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1336,7 +1352,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1354,7 +1370,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1373,7 +1389,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1391,7 +1407,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1410,7 +1426,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1428,7 +1444,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1446,7 +1462,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1465,7 +1481,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1483,7 +1499,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1502,7 +1518,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1521,7 +1537,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1539,7 +1555,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1557,7 +1573,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1575,7 +1591,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1593,7 +1609,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1612,7 +1628,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1630,7 +1646,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1648,7 +1664,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1666,7 +1682,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1684,7 +1700,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1702,7 +1718,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1720,7 +1736,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1738,7 +1754,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1756,7 +1772,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1774,7 +1790,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1792,7 +1808,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1810,7 +1826,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1828,7 +1844,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1847,7 +1863,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1865,7 +1881,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1883,7 +1899,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1901,7 +1917,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1919,7 +1935,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1937,7 +1953,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1955,7 +1971,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1973,7 +1989,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1992,7 +2008,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2011,7 +2027,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2029,7 +2045,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2047,7 +2063,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2065,7 +2081,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2083,7 +2099,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2101,7 +2117,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2119,7 +2135,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2137,7 +2153,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2155,7 +2171,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2173,7 +2189,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2910,7 +2926,7 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>This gives the maximum message size supported via the <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendReliableRealTimeMessage(com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener, byte[], java.lang.String, java.lang.String)">sendReliableRealTimeMessage(RealTimeReliableMessageSentListener, byte[], String, String)</a></code>
- APIs (excluding protocol headers).
+ methods (excluding protocol headers).
 </p></div>
 
     
@@ -2950,7 +2966,7 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>This gives the maximum (unfragmented) message size supported via the
- <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> APIs (excluding protocol headers).
+ <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> methods (excluding protocol headers).
 </p></div>
 
     
@@ -3342,8 +3358,8 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>Constant indicating that real-time room ID provided by the user is not a valid or it is
- not currently active real-time room.
+  <div class="jd-tagdata jd-tagdescr"><p>Constant indicating that the real-time room ID provided to the operation was not valid, or
+ does not correspond to the currently active real-time room.
 </p></div>
 
     
@@ -3820,8 +3836,8 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>Status code returned from <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> and the
- <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendReliableRealTimeMessage(com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener, byte[], java.lang.String, java.lang.String)">sendReliableRealTimeMessage(RealTimeReliableMessageSentListener, byte[], String, String)</a></code> APIs when the message send operation failed due to an
+  <div class="jd-tagdata jd-tagdescr"><p>Status code returned from the <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendUnreliableRealTimeMessage(byte[], java.lang.String, java.lang.String)">sendUnreliableRealTimeMessage(byte[], String, String)</a></code> and
+ <code><a href="/reference/com/google/android/gms/games/GamesClient.html#sendReliableRealTimeMessage(com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener, byte[], java.lang.String, java.lang.String)">sendReliableRealTimeMessage(RealTimeReliableMessageSentListener, byte[], String, String)</a></code> methods when the message send operation failed due to an
  immediate error.
 </p></div>
 
@@ -4095,7 +4111,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>config</td>
-          <td>the real-time room configuration.
+          <td>The real-time room configuration.
 </td>
         </tr>
       </table>
@@ -4134,7 +4150,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>invitationId</td>
-          <td>the ID of the invitation to decline.
+          <td>The ID of the invitation to decline.
 </td>
         </tr>
       </table>
@@ -4204,7 +4220,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>invitationId</td>
-          <td>the ID of the invitation to dismiss.
+          <td>The ID of the invitation to dismiss.
 </td>
         </tr>
       </table>
@@ -4246,7 +4262,7 @@
  state.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the currently signed in player's
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the currently signed in player's
          achievements.
 </li></ul>
   </div>
@@ -4287,7 +4303,7 @@
  state.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the list of leaderboards for a game.
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the list of leaderboards for a game.
 </li></ul>
   </div>
 
@@ -4378,6 +4394,41 @@
 </div>
 
 
+<A NAME="getCurrentGame()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/com/google/android/gms/games/Game.html">Game</a>
+      </span>
+      <span class="sympad">getCurrentGame</span>
+      <span class="normal">()</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Returns</h5>
+      <ul class="nolist"><li><code><a href="/reference/com/google/android/gms/games/Game.html">Game</a></code> metadata for the current game. May be null if the metadata is not
+         available locally.
+</li></ul>
+  </div>
+
+    </div>
+</div>
+
+
 <A NAME="getCurrentPlayer()"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -4438,7 +4489,7 @@
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the player ID for the currently signed in player.
+      <ul class="nolist"><li>The player ID for the currently signed in player.
 </li></ul>
   </div>
 
@@ -4473,13 +4524,13 @@
  that this must be invoked using <code><a href="/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int)">startActivityForResult(Intent, int)</a></code> so that
  the identity of the calling package can be established.
  <p>
- If the user canceled the result will be <code><a href="/reference/android/app/Activity.html#RESULT_CANCELED">RESULT_CANCELED</a></code>. If the user
+ If the user canceled, the result will be <code><a href="/reference/android/app/Activity.html#RESULT_CANCELED">RESULT_CANCELED</a></code>. If the user
  selected an invitation to accept, the result will be <code><a href="/reference/android/app/Activity.html#RESULT_OK">RESULT_OK</a></code> and the data
  intent will contain the selected invitation as a parcelable extra in
  <code><a href="/reference/com/google/android/gms/games/GamesClient.html#EXTRA_INVITATION">EXTRA_INVITATION</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the invitation inbox UI.
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the invitation inbox UI.
 </li></ul>
   </div>
 
@@ -4528,7 +4579,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the specified leaderboard.
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the specified leaderboard.
 </li></ul>
   </div>
 
@@ -4573,13 +4624,13 @@
         </tr>
         <tr>
           <th>participantId</td>
-          <td>the ID of the participant to whom this socket is bound</td>
+          <td>The ID of the participant to whom this socket is bound</td>
         </tr>
       </table>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>instance of a LocalSocket, or null on error.
+      <ul class="nolist"><li>An instance of a LocalSocket, or null on error.
 </li></ul>
   </div>
 
@@ -4626,8 +4677,18 @@
  data intent containing a <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/Room.html">Room</a></code> object in <code><a href="/reference/com/google/android/gms/games/GamesClient.html#EXTRA_ROOM">EXTRA_ROOM</a></code> that represents
  the current state of the Room that you originally passed as a parameter here.
  <p>
- Note that the waiting room itself will never explicitly take any action to change
- the state of the room or its participants.  So if the activity result is
+ If desired, the waiting room can allow the user to start playing the game even before
+ the room is fully connected.  This is controlled by the <code>minParticipantsToStart</code>
+ parameter: if at least that many participants (including the current player) are
+ connected to the room, a "Start playing" menu item will become enabled in the waiting
+ room UI.  Setting <code>minParticipantsToStart</code> to 0 means that "Start playing" will
+ always be available, and a value of <code><a href="/reference/java/lang/Integer.html#MAX_VALUE">MAX_VALUE</a></code> will disable the item
+ completely.  Note: if you do allow the user to start early, you'll need to handle that
+ situation by explicitly telling the other connected peers that the game is now starting;
+ see the developer documentation for more details.
+ <p>
+ Finally, note that the waiting room itself will never explicitly take any action to
+ change the state of the room or its participants.  So if the activity result is
  <code><a href="/reference/com/google/android/gms/games/GamesActivityResultCodes.html#RESULT_LEFT_ROOM">RESULT_LEFT_ROOM</a></code>, it's the caller's responsibility
  to actually leave the room.  Or if the result is <code><a href="/reference/android/app/Activity.html#RESULT_CANCELED">RESULT_CANCELED</a></code>,
  it's the responsibility of the caller to double-check the current state of the Room
@@ -4644,21 +4705,15 @@
         </tr>
         <tr>
           <th>minParticipantsToStart</td>
-          <td>the minimum number of participants that must
-            be connected to the room (including the current player) before the
-            "Start playing" option becomes enabled.
-            <p>
-            If this is 0, that means that "Start playing" will always be enabled.
-            If it's equal to the maximum possible number of participants (including
-            the current player <i>and</i> any auto-match participants) then the
-            'Start playing' option will never be enabled; instead the waiting room
-            will exit automatically as soon as all participants are fully connected.</td>
+          <td>the minimum number of participants that must be
+            connected to the room (including the current player) for the "Start
+            playing" menu item to become enabled.</td>
         </tr>
       </table>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to display the waiting room screen.</li></ul>
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to display the waiting room screen.</li></ul>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">See Also</h5>
@@ -4722,7 +4777,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to display the player selector.</li></ul>
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to display the player selector.</li></ul>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">See Also</h5>
@@ -4771,7 +4826,7 @@
  menu item.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>an <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the GamesClient Settings UI.
+      <ul class="nolist"><li>An <code><a href="/reference/android/content/Intent.html">Intent</a></code> that can be started to view the GamesClient Settings UI.
 </li></ul>
   </div>
 
@@ -4817,11 +4872,11 @@
       <table class="jd-tagtable">
         <tr>
           <th>id</td>
-          <td>the achievement ID to increment.</td>
+          <td>The achievement ID to increment.</td>
         </tr>
         <tr>
           <th>numSteps</td>
-          <td>the number of steps to increment by. Must be greater than 0.
+          <td>The number of steps to increment by. Must be greater than 0.
 </td>
         </tr>
       </table>
@@ -4869,16 +4924,16 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the increment achievement is complete. The
+          <td>The listener that is called when the increment achievement is complete. The
             listener is called on the main thread.</td>
         </tr>
         <tr>
           <th>id</td>
-          <td>the ID of the achievement to increment.</td>
+          <td>The ID of the achievement to increment.</td>
         </tr>
         <tr>
           <th>numSteps</td>
-          <td>the number of steps to increment by. Must be greater than 0.
+          <td>The number of steps to increment by. Must be greater than 0.
 </td>
         </tr>
       </table>
@@ -4916,7 +4971,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -4950,7 +5005,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -4994,7 +5049,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
 
@@ -5038,7 +5093,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
 
@@ -5080,7 +5135,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>config</td>
-          <td>the real-time room configuration.
+          <td>The real-time room configuration.
 </td>
         </tr>
       </table>
@@ -5121,7 +5176,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is notified after the room has been left. The listener is
+          <td>The listener that is notified after the room has been left. The listener is
             called on the main thread.</td>
         </tr>
         <tr>
@@ -5168,7 +5223,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.
 </td>
         </tr>
@@ -5208,7 +5263,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.
 </td>
         </tr>
@@ -5252,12 +5307,12 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
           <th>pageSize</td>
-          <td>the number of entries to request for this initial page. Note that if cached
+          <td>The number of entries to request for this initial page. Note that if cached
             data already exists, the returned buffer may contain more than this size, but it
             is guaranteed to contain at least this many if the collection contains enough
             records. This must be a value between 1 and 25.</td>
@@ -5309,7 +5364,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.
 </td>
         </tr>
@@ -5352,7 +5407,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
@@ -5399,7 +5454,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.
 </td>
         </tr>
@@ -5443,12 +5498,12 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
           <th>pageSize</td>
-          <td>the number of additional entries to request. This must be a value between 1
+          <td>The number of additional entries to request. This must be a value between 1
             and 25.
 </td>
         </tr>
@@ -5492,12 +5547,12 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
           <th>buffer</td>
-          <td>the existing buffer that will be expanded.</td>
+          <td>The existing buffer that will be expanded.</td>
         </tr>
         <tr>
           <th>maxResults</td>
@@ -5505,8 +5560,8 @@
         </tr>
         <tr>
           <th>pageDirection</td>
-          <td>the direction to expand the buffer. Values are defined in
-            <code><a href="/reference/com/google/android/gms/games/PageDirection.html">PageDirection</a></code>
+          <td>The direction to expand the buffer. Values are defined in
+            <code><a href="/reference/com/google/android/gms/games/PageDirection.html">PageDirection</a></code>.
 </td>
         </tr>
       </table>
@@ -5548,12 +5603,12 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
           <th>playerId</td>
-          <td>the player ID to get full profile data for.
+          <td>The player ID to get full profile data for.
 </td>
         </tr>
       </table>
@@ -5596,7 +5651,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
@@ -5668,7 +5723,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
@@ -5732,7 +5787,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the load is complete. The listener is called
+          <td>The listener that is called when the load is complete. The listener is called
             on the main thread.</td>
         </tr>
         <tr>
@@ -5901,9 +5956,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -5952,11 +6008,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
@@ -6013,7 +6070,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when a new invitation is received. The listener
+          <td>The listener that is called when a new invitation is received. The listener
             is called on the main thread.
 </td>
         </tr>
@@ -6061,7 +6118,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>id</td>
-          <td>the achievement ID to reveal</td>
+          <td>The achievement ID to reveal</td>
         </tr>
       </table>
   </div>
@@ -6112,12 +6169,12 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the reveal achievement is complete.
+          <td>The listener that is called when the reveal achievement is complete.
            The listener is called on the main thread.</td>
         </tr>
         <tr>
           <th>id</td>
-          <td>the ID of the achievement to reveal</td>
+          <td>The ID of the achievement to reveal</td>
         </tr>
       </table>
   </div>
@@ -6164,11 +6221,11 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is notified when the message has been sent.</td>
+          <td>The listener that is notified when the message has been sent.</td>
         </tr>
         <tr>
           <th>messageData</td>
-          <td>the message to be sent. Should be at most
+          <td>The message to be sent. Should be at most
             <code><a href="/reference/com/google/android/gms/games/GamesClient.html#MAX_RELIABLE_MESSAGE_LEN">MAX_RELIABLE_MESSAGE_LEN</a></code> bytes.</td>
         </tr>
         <tr>
@@ -6177,16 +6234,15 @@
         </tr>
         <tr>
           <th>recipientParticipantId</td>
-          <td>the participant ID to send the message to.</td>
+          <td>The participant ID to send the message to.</td>
         </tr>
       </table>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>token for the message sent, which is returned in callback
+      <ul class="nolist"><li>The token for the message sent, which is returned in callback
          <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html#onRealTimeMessageSent(int, int, java.lang.String)">onRealTimeMessageSent(int, int, String)</a></code> or
          <code><a href="/reference/com/google/android/gms/games/GamesClient.html#STATUS_REAL_TIME_MESSAGE_FAILED">STATUS_REAL_TIME_MESSAGE_FAILED</a></code> if the message failed to send.
-
 </li></ul>
   </div>
 
@@ -6227,7 +6283,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>messageData</td>
-          <td>the message to be sent. Should be at most
+          <td>The message to be sent. Should be at most
             <code><a href="/reference/com/google/android/gms/games/GamesClient.html#MAX_UNRELIABLE_MESSAGE_LEN">MAX_UNRELIABLE_MESSAGE_LEN</a></code> bytes.</td>
         </tr>
         <tr>
@@ -6284,7 +6340,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>messageData</td>
-          <td>the message to be sent. Should be at most
+          <td>The message to be sent. Should be at most
             <code><a href="/reference/com/google/android/gms/games/GamesClient.html#MAX_UNRELIABLE_MESSAGE_LEN">MAX_UNRELIABLE_MESSAGE_LEN</a></code> bytes.</td>
         </tr>
         <tr>
@@ -6293,7 +6349,7 @@
         </tr>
         <tr>
           <th>recipientParticipantId</td>
-          <td>the participant ID to send the message to.</td>
+          <td>The participant ID to send the message to.</td>
         </tr>
       </table>
   </div>
@@ -6339,7 +6395,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>messageData</td>
-          <td>the message to be sent. Should be at most
+          <td>The message to be sent. Should be at most
             <code><a href="/reference/com/google/android/gms/games/GamesClient.html#MAX_UNRELIABLE_MESSAGE_LEN">MAX_UNRELIABLE_MESSAGE_LEN</a></code> bytes.</td>
         </tr>
         <tr>
@@ -6512,7 +6568,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when sign-out is complete. The listener is called
+          <td>The listener that is called when sign-out is complete. The listener is called
             on the main thread.
 </td>
         </tr>
@@ -6597,8 +6653,8 @@
  </ul>
  <p>
  For more details, please see <a
- href="https://developers.google.com/games/services/common/concepts/leaderboards">this
- page</a>.</p></div>
+ href="https://developers.google.com/games/services/common/concepts/leaderboards">Leaderboard
+ Concepts</a>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Parameters</h5>
       <table class="jd-tagtable">
@@ -6731,7 +6787,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>id</td>
-          <td>the achievement ID to unlock</td>
+          <td>The achievement ID to unlock</td>
         </tr>
       </table>
   </div>
@@ -6782,12 +6838,12 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called when the unlock achievement is complete. The
+          <td>The listener that is called when the unlock achievement is complete. The
             listener is called on the main thread.</td>
         </tr>
         <tr>
           <th>id</td>
-          <td>the ID of the achievement to unlock.</td>
+          <td>The ID of the achievement to unlock.</td>
         </tr>
       </table>
   </div>
diff --git a/docs/html/reference/com/google/android/gms/games/GamesClientSettings.html b/docs/html/reference/com/google/android/gms/games/GamesClientSettings.html
deleted file mode 100644
index 29cad90..0000000
--- a/docs/html/reference/com/google/android/gms/games/GamesClientSettings.html
+++ /dev/null
@@ -1,1189 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>GamesClientSettings | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
-  var toRoot = "/";
-  var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
-  var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-5831155-1']);
-  _gaq.push(['_trackPageview']);
-
-  (function() {
-    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-  })();
-</script>
-</head>
-<body class="gc-documentation google
-  develop" itemscope itemtype="http://schema.org/Article">
-  <div id="doc-api-level" class="" style="display:none"></div>
-  <a name="top"></a>
-
-<a name="top"></a>
-
-    <!-- Header -->
-    <div id="header">
-        <div class="wrap" id="header-wrap">
-          <div class="col-3 logo">
-          <a href="/index.html">
-            <img src="/assets/images/dac_logo.png" width="123" height="25" alt="Android Developers" />
-          </a>
-          <div class="btn-quicknav" id="btn-quicknav">
-          	<a href="#" class="arrow-inactive">Quicknav</a>
-			      <a href="#" class="arrow-active">Quicknav</a>
-          </div>
-          </div>
-            <ul class="nav-x col-9">
-                <li class="design">
-                  <a href="/design/index.html"
-                  zh-tw-lang="設計"
-                  zh-cn-lang="设计"
-                  ru-lang="Проектирование"
-                  ko-lang="디자인"
-                  ja-lang="設計"
-                  es-lang="Diseñar"               
-                  >Design</a></li>
-                <li class="develop"><a href="/develop/index.html"
-                  zh-tw-lang="開發"
-                  zh-cn-lang="开发"
-                  ru-lang="Разработка"
-                  ko-lang="개발"
-                  ja-lang="開発"
-                  es-lang="Desarrollar"               
-                  >Develop</a></li>
-                <li class="distribute last"><a href="/distribute/index.html"
-                  zh-tw-lang="發佈"
-                  zh-cn-lang="分发"
-                  ru-lang="Распространение"
-                  ko-lang="배포"
-                  ja-lang="配布"
-                  es-lang="Distribuir"               
-                  >Distribute</a></li>
-            </ul>
-            
-            <!-- New Search -->
-            <div class="menu-container">
-            <div class="moremenu">
-    <div id="more-btn"></div>
-  </div>
-  <div class="morehover" id="moremenu">
-    <div class="top"></div>
-    <div class="mid">
-      <div class="header">Links</div>
-      <ul>
-        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
-        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
-        <li><a href="/about/index.html">About Android</a></li>
-      </ul>
-      <div class="header">Android Sites</div>
-      <ul>
-        <li><a href="http://www.android.com">Android.com</a></li>
-        <li class="active"><a>Android Developers</a></li>
-        <li><a href="http://source.android.com">Android Open Source Project</a></li>
-      </ul>
-      
-      
-      
-        <div class="header">Language</div>
-          <div id="language" class="locales">
-            <select name="language" onChange="changeLangPref(this.value, true)">
-                <option value="en">English</option>
-                <option value="es">Español</option>
-                <option value="ja">日本語</option>
-                <option value="ko">한국어</option>
-                <option value="ru">Русский</option>
-                <option value="zh-cn">中文 (中国)</option>
-                <option value="zh-tw">中文 (台灣)</option>
-            </select>
-          </div>
-        <script type="text/javascript">
-          <!--
-          loadLangPref();
-            //-->
-        </script>
-      
-      
-
-
-      <br class="clearfix" />
-    </div>
-    <div class="bottom"></div>
-  </div>
-  <div class="search" id="search-container">
-    <div class="search-inner">
-      <div id="search-btn"></div>
-      <div class="left"></div>
-      <form onsubmit="return submit_search()">
-        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')" 
-onkeyup="return search_changed(event, false, '/')" />
-      </form>
-      <div class="right"></div>
-        <a class="close hide">close</a>
-        <div class="left"></div>
-        <div class="right"></div>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper reference">
-    <div class="suggest-card reference no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper docs">
-    <div class="suggest-card dummy no-display">&nbsp;</div>
-    <div class="suggest-card develop no-display">
-      <ul class="search_filtered">
-      </ul>
-      <div class="child-card guides no-display">
-      </div>
-      <div class="child-card training no-display">
-      </div>
-    </div>
-    <div class="suggest-card design no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-    <div class="suggest-card distribute no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  </div>
-  <!-- /New Search>
-          
-          
-          <!-- Expanded quicknav -->
-           <div id="quicknav" class="col-9">
-                <ul>
-                    <li class="design">
-                      <ul>
-                        <li><a href="/design/index.html">Get Started</a></li>
-                        <li><a href="/design/style/index.html">Style</a></li>
-                        <li><a href="/design/patterns/index.html">Patterns</a></li>
-                        <li><a href="/design/building-blocks/index.html">Building Blocks</a></li>
-                        <li><a href="/design/downloads/index.html">Downloads</a></li>
-                        <li><a href="/design/videos/index.html">Videos</a></li>
-                      </ul>
-                    </li>
-                    <li class="develop">
-                      <ul>
-                        <li><a href="/training/index.html"
-                          zh-tw-lang="訓練課程"
-                          zh-cn-lang="培训"
-                          ru-lang="Курсы"
-                          ko-lang="교육"
-                          ja-lang="トレーニング"
-                          es-lang="Capacitación"               
-                          >Training</a></li>
-                        <li><a href="/guide/components/index.html"
-                          zh-tw-lang="API 指南"
-                          zh-cn-lang="API 指南"
-                          ru-lang="Руководства по API"
-                          ko-lang="API 가이드"
-                          ja-lang="API ガイド"
-                          es-lang="Guías de la API"               
-                          >API Guides</a></li>
-                        <li><a href="/reference/packages.html"
-                          zh-tw-lang="參考資源"
-                          zh-cn-lang="参考"
-                          ru-lang="Справочник"
-                          ko-lang="참조문서"
-                          ja-lang="リファレンス"
-                          es-lang="Referencia"               
-                          >Reference</a></li>
-                        <li><a href="/tools/index.html"
-                          zh-tw-lang="相關工具"
-                          zh-cn-lang="工具"
-                          ru-lang="Инструменты"
-                          ko-lang="도구"
-                          ja-lang="ツール"
-                          es-lang="Herramientas"               
-                          >Tools</a>
-                          <ul><li><a href="/sdk/index.html">Get the SDK</a></li></ul>
-                        </li>
-                        <li><a href="/google/index.html">Google Services</a>
-                        </li>
-                      </ul>
-                    </li>
-                    <li class="distribute last">
-                      <ul>
-                        <li><a href="/distribute/index.html">Google Play</a></li>
-                        <li><a href="/distribute/googleplay/publish/index.html">Publishing</a></li>
-                        <li><a href="/distribute/googleplay/promote/index.html">Promoting</a></li>
-                        <li><a href="/distribute/googleplay/quality/index.html">App Quality</a></li>
-                        <li><a href="/distribute/googleplay/spotlight/index.html">Spotlight</a></li>
-                        <li><a href="/distribute/open.html">Open Distribution</a></li>
-                      </ul>
-                    </li>
-                </ul>
-          </div>
-          <!-- /Expanded quicknav -->
-        </div>
-    </div>
-    <!-- /Header -->
-    
-    
-  <div id="searchResults" class="wrap" style="display:none;">
-          <h2 id="searchTitle">Results</h2>
-          <div id="leftSearchControl" class="search-control">Loading...</div>
-  </div>
-    
-    
-  
-    <!-- Secondary x-nav -->
-    <div id="nav-x">
-        <div class="wrap">
-            <ul class="nav-x col-9 develop" style="width:100%">
-                <li class="training"><a href="/training/index.html"
-                  zh-tw-lang="訓練課程"
-                  zh-cn-lang="培训"
-                  ru-lang="Курсы"
-                  ko-lang="교육"
-                  ja-lang="トレーニング"
-                  es-lang="Capacitación"               
-                  >Training</a></li>
-                <li class="guide"><a href="/guide/components/index.html"
-                  zh-tw-lang="API 指南"
-                  zh-cn-lang="API 指南"
-                  ru-lang="Руководства по API"
-                  ko-lang="API 가이드"
-                  ja-lang="API ガイド"
-                  es-lang="Guías de la API"               
-                  >API Guides</a></li>
-                <li class="reference"><a href="/reference/packages.html"
-                  zh-tw-lang="參考資源"
-                  zh-cn-lang="参考"
-                  ru-lang="Справочник"
-                  ko-lang="참조문서"
-                  ja-lang="リファレンス"
-                  es-lang="Referencia"               
-                  >Reference</a></li>
-                <li class="tools"><a href="/tools/index.html"
-                  zh-tw-lang="相關工具"
-                  zh-cn-lang="工具"
-                  ru-lang="Инструменты"
-                  ko-lang="도구"
-                  ja-lang="ツール"
-                  es-lang="Herramientas"
-                  >Tools</a></li>
-                <li class="google"><a href="/google/index.html"
-                  >Google Services</a>
-                </li>
-            </ul>
-        </div>
-        
-    </div>
-    <!-- /Sendondary x-nav -->
-  
-
-
-
-
-  
-
-
-  
-  <div class="wrap clearfix" id="body-content">
-    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
-      <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-
-
-<ul id="nav">
-
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/index.html">
-          <span class="en">Overview</span>
-      </a></div>
-  </li>
-
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/games.html">
-          <span class="en">Games</span>
-      </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/location.html">
-          <span class="en">Location</span>
-      </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/plus.html">
-          <span class="en">Google+</span>
-                </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/maps.html">
-          <span class="en">Google Maps</span>
-      </a></div>
-  </li>
-  <li class="nav-section">
-    <div class="nav-section-header empty"><a href="/google/play-services/auth.html">
-          <span class="en">Authorization</span>
-      </a></div>
-  </li>
-
-
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/play-services/index.html">
-      <span class="en">Google Play Services</span></a>
-    </div>
-    <ul>
-      <li><a href="/google/play-services/setup.html">
-          <span class="en">Setup</span></a>
-      </li>
-      <li id="gms-tree-list" class="nav-section">
-        <div class="nav-section-header">
-          <a href="/reference/gms-packages.html">
-            <span class="en">Reference</span>
-          </a>
-        <div>
-      </li>
-    </ul>
-  </li>
-
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/play/billing/index.html">
-      <span class="en">Google Play In-app Billing</span></a>
-    </div>
-    <ul>
-      <li><a href="/google/play/billing/billing_overview.html">
-              <span class="en">Overview</span></a>
-      </li>
-      <li class="nav-section"><div class="nav-section-header"><a href="/google/play/billing/api.html">
-              <span class="en">Version 3 API</span></a></div>
-              <ul>
-              <li><a href="/google/play/billing/billing_integrate.html">
-              <span class="en">Implementing the API</span></a></li>
-              <li><a href="/google/play/billing/billing_reference.html">
-              <span class="en">Reference</span></a></li>
-              </ul>
-      </li>
-      <li class="nav-section"><div class="nav-section-header"><a href="/google/play/billing/v2/api.html">
-              <span class="en">Version 2 API</span></a></div>
-              <ul>
-              <li><a href="/google/play/billing/v2/billing_integrate.html">
-              <span class="en">Implementing the API</span></a></li>
-              <li><a href="/google/play/billing/v2/billing_subscriptions.html">
-              <span class="en">Subscriptions</span></a></li>
-              <li><a href="/google/play/billing/v2/billing_reference.html">
-              <span class="en">Reference</span></a></li>
-              </ul>
-      </li>
-      <li><a href="/google/play/billing/billing_subscriptions.html">
-              <span class="en">Subscriptions</span></a>
-      </li>
-      <li><a href="/google/play/billing/billing_best_practices.html">
-              <span class="en">Security and Design</span></a>
-      </li>
-      <li><a href="/google/play/billing/billing_testing.html">
-              <span class="en">Testing In-app Billing</span></a>
-      </li>
-      <li><a href="/google/play/billing/billing_admin.html">
-              <span class="en">Administering In-app Billing</span></a>
-      </li>
-      <li><a href="/google/play/billing/gp-purchase-status-api.html">
-              <span class="en">Purchase Status API</span></a>
-      </li>
-      <li><a href="/google/play/billing/versions.html">
-              <span class="en">Version Notes</span></a>
-      </li>
-    </ul>
-  </li>
-
-
-
-  <li class="nav-section">
-      <div class="nav-section-header"><a href="/google/gcm/index.html">
-        <span class="en">Google Cloud Messaging</span></a>
-      </div>
-      <ul>
-        <li><a href="/google/gcm/gs.html">
-            <span class="en">Getting Started</span></a>
-        </li>
-        <li><a href="/google/gcm/gcm.html">
-            <span class="en">Architectural Overview</span></a>
-        </li>
-         <li><a href="/google/gcm/ccs.html">
-              <span class="en">Cloud Connection Server</span></a>
-        </li>
-        <li><a href="/google/gcm/notifications.html">
-              <span class="en">User Notifications</span></a>
-        </li>
-        <li><a href="/google/gcm/client.html">
-            <span class="en">GCM Client</span></a>
-        </li>
-        <li><a href="/google/gcm/server.html">
-            <span class="en">GCM Server</span></a>
-        </li>
-        <li><a href="/google/gcm/adv.html">
-            <span class="en">Advanced Topics</span></a>
-        </li>
-        <li><a href="/google/gcm/c2dm.html">
-            <span class="en">Migration</span></a>
-        </li>
-        <li id="gcm-tree-list" class="nav-section">
-          <div class="nav-section-header">
-            <a href="/reference/gcm-packages.html">
-              <span class="en">Reference</span>
-            </a>
-          <div>
-        </li>
-      </ul>
-  </li>
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/play/dist.html">
-      <span class="en">Google Play Distribution</span></a>
-    </div>
-    <ul>
-      <li><a href="/google/play/filters.html">
-          <span class="en">Filters on Google Play</span></a>
-      </li>
-
-      <li><a href="/google/play/publishing/multiple-apks.html">
-          <span class="en">Multiple APK Support</span></a>
-      </li>
-      <li><a href="/google/play/expansion-files.html">
-          <span class="en">APK Expansion Files</span></a>
-      </li>
-      <li class="nav-section">
-        <div class="nav-section-header"><a href="/google/play/licensing/index.html">
-          <span class="en">Application Licensing</span></a>
-        </div>
-        <ul>
-          <li><a href="/google/play/licensing/overview.html">
-              <span class="en">Licensing Overview</span></a>
-          </li>
-          <li><a href="/google/play/licensing/setting-up.html">
-              <span class="en">Setting Up for Licensing</span></a>
-          </li>
-          <li><a href="/google/play/licensing/adding-licensing.html">
-              <span class="en">Adding Licensing to Your App</span></a>
-          </li>
-          <li><a href="/google/play/licensing/licensing-reference.html">
-              <span class="en">Licensing Reference</span></a>
-          </li>
-        </ul>
-      </li>
-
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="/google/backup/index.html">
-      Android Backup Service</a>
-    </div>
-    <ul>
-      <li><a href="/google/backup/signup.html">
-          Register</a>
-      </li>
-    </ul>
-  </li>
-
-  </ul>
-
-</li>
-
-
-
-</ul>
-
-<script type="text/javascript">
-<!--
-    buildToggleLists();
-    changeNavLang(getLangPref());
-//-->
-</script>
-
-
-        
-
-      </div>
-      <script type="text/javascript">
-       showGoogleRefTree();
-    
-      </script>
-    </div> <!-- end side-nav -->
-    <script>
-      $(document).ready(function() {
-        scrollIntoView("devdoc-nav");
-        });
-    </script>
-
-
-     
-
-
-
-<div class="col-12"  id="doc-col">
-
-<div id="api-info-block">
-
-
-
-  
-   
-  
-  
-  
-  
-
-
-<div class="sum-details-links">
-
-Summary:
-
-
-
-
-
-  <a href="#constants">Constants</a>
-  
-
-
-
-
-
-
-
-
-
-  &#124; <a href="#inhmethods">Inherited Methods</a>
-
-&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
-
-</div><!-- end sum-details-links -->
-<div class="api-level">
-  
-  
-  
-
-</div>
-</div><!-- end api-info-block -->
-
-
-<!-- ======== START OF CLASS DATA ======== -->
-
-<div id="jd-header">
-    public
-     
-    final 
-    
-    class
-<h1 itemprop="name">GamesClientSettings</h1>
-
-
-
-  
-    extends Object<br/>
-  
-  
-  
-
-  
-  
-  
-
-
-</div><!-- end header -->
-
-<div id="naMessage"></div>
-
-<div id="jd-content" class="api apilevel-">
-<table class="jd-inheritance-table">
-
-
-    <tr>
-         	
-        <td colspan="2" class="jd-inheritance-class-cell">java.lang.Object</td>
-    </tr>
-    
-
-    <tr>
-        
-            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
-         	
-        <td colspan="1" class="jd-inheritance-class-cell">com.google.android.gms.games.GamesClientSettings</td>
-    </tr>
-    
-
-</table>
-
-
-
-
-
-
-
-<div class="jd-descr">
-
-
-<h2>Class Overview</h2>
-<p itemprop="articleBody">Settings for <code><a href="/reference/com/google/android/gms/games/GamesClient.html">GamesClient</a></code>.
-</p>
-
-
-
-
-
-</div><!-- jd-descr -->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div class="jd-descr">
-
-
-<h2>Summary</h2>
-
-
-
-
-
-
-
-
-
-
-
-
-
-<!-- =========== ENUM CONSTANT SUMMARY =========== -->
-<table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
-
-
-    
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol">int</td>
-        <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClientSettings.html#POPUP_POSITION_BOTTOM">POPUP_POSITION_BOTTOM</a></td>
-        <td class="jd-descrcol" width="100%">Display games service popups (achievements, welcome, ...) at the bottom of the screen
-</td>
-    </tr>
-    
-    
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol">int</td>
-        <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClientSettings.html#POPUP_POSITION_TOP">POPUP_POSITION_TOP</a></td>
-        <td class="jd-descrcol" width="100%">Display games service popups (achievements, welcome, ...) at the top of the screen
-</td>
-    </tr>
-    
-    
-
-</table>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<!-- ========== METHOD SUMMARY =========== -->
-<table id="inhmethods" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Methods</div></th></tr>
-
-
-<tr class="api apilevel-" >
-<td colspan="12">
-  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
-          ><img id="inherited-methods-java.lang.Object-trigger"
-          src="/assets/images/triangle-closed.png"
-          class="jd-expando-trigger-img" /></a>
-From class
-
-  java.lang.Object
-
-<div id="inherited-methods-java.lang.Object">
-  <div id="inherited-methods-java.lang.Object-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            Object</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">clone</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            boolean</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">equals</span>(Object arg0)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">finalize</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            Class&lt;?&gt;</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">getClass</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            int</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">hashCode</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">notify</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">notifyAll</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
-            String</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">toString</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">wait</span>()</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class=" api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
-        
-  </td></tr>
-
-
-	 
-    <tr class="alt-color api apilevel-" >
-        <td class="jd-typecol"><nobr>
-            
-            
-            final
-            
-            
-            void</nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad">wait</span>(long arg0)</nobr>
-        
-  </td></tr>
-
-
-</table>
-  </div>
-</div>
-</td></tr>
-
-
-</table>
-
-
-</div><!-- jd-descr (summary) -->
-
-<!-- Details -->
-
-
-
-
-
-
-
-
-<!-- XML Attributes -->
-
-
-<!-- Enum Values -->
-
-
-<!-- Constants -->
-
-
-<!-- ========= ENUM CONSTANTS DETAIL ======== -->
-<h2>Constants</h2>
-
-
-
-
-<A NAME="POPUP_POSITION_BOTTOM"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-        final 
-        int
-      </span>
-        POPUP_POSITION_BOTTOM
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p>Display games service popups (achievements, welcome, ...) at the bottom of the screen
-</p></div>
-
-    
-        <div class="jd-tagdata">
-        <span class="jd-tagtitle">Constant Value: </span>
-        <span>
-            
-                2
-                (0x00000002)
-            
-        </span>
-        </div>
-    
-    </div>
-</div>
-
-
-
-<A NAME="POPUP_POSITION_TOP"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-        final 
-        int
-      </span>
-        POPUP_POSITION_TOP
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-  <div class="jd-tagdata jd-tagdescr"><p>Display games service popups (achievements, welcome, ...) at the top of the screen
-</p></div>
-
-    
-        <div class="jd-tagdata">
-        <span class="jd-tagtitle">Constant Value: </span>
-        <span>
-            
-                1
-                (0x00000001)
-            
-        </span>
-        </div>
-    
-    </div>
-</div>
-
-
-
-
-<!-- Fields -->
-
-
-<!-- Public ctors -->
-
-
-
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<!-- Protected ctors -->
-
-
-
-<!-- ========= METHOD DETAIL ======== -->
-<!-- Public methdos -->
-
-
-
-<!-- ========= METHOD DETAIL ======== -->
-
-
-
-<!-- ========= END OF CLASS DATA ========= -->
-<A NAME="navbar_top"></A>
-
-<div id="footer" class="wrap" >
-        
-
-  <div id="copyright">
-    
-  Except as noted, this content is licensed under <a
-  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
-  For details and restrictions, see the <a href="/license.html">
-  Content License</a>.
-  </div>
-  <div id="build_info">
-    
-<script src="/timestamp.js" type="text/javascript"></script>
-<script>document.write(BUILD_TIMESTAMP)</script>
-
-  </div>
-
-
-  <div id="footerlinks">
-    
-  <p>
-    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
-    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
-    <a href="/support.html">Support</a>
-  </p>
-  </div>
-
-</div> <!-- end footer -->
-</div> <!-- jd-content -->
-
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content --> 
-
-
-
-
-
-
-</body>
-</html>
diff --git a/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html b/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html
index e0ad326..23425bc 100644
--- a/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/PlayerBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/RealTimeSocket.html b/docs/html/reference/com/google/android/gms/games/RealTimeSocket.html
index 7298e87..1e42cdd 100644
--- a/docs/html/reference/com/google/android/gms/games/RealTimeSocket.html
+++ b/docs/html/reference/com/google/android/gms/games/RealTimeSocket.html
@@ -685,7 +685,7 @@
  <p>
  Use <code><a href="/reference/com/google/android/gms/games/RealTimeSocket.html#getParcelFileDescriptor()">getParcelFileDescriptor()</a></code> to get a file descriptor for read/write, or
  use <code><a href="/reference/com/google/android/gms/games/RealTimeSocket.html#getInputStream()">getInputStream()</a></code> / <code><a href="/reference/com/google/android/gms/games/RealTimeSocket.html#getOutputStream()">getOutputStream()</a></code> to get
- access to an instance of <code><a href="/reference/java/io/InputStream.html">InputStream</a></code> and <code><a href="/reference/java/io/OutputStream.html">OutputStream</a></code>
+ access to an instance of <code><a href="/reference/java/io/InputStream.html">InputStream</a></code> or <code><a href="/reference/java/io/OutputStream.html">OutputStream</a></code>
  respectively.
  <p>
  Calling close() on any of (i) the returned <code><a href="/reference/android/os/ParcelFileDescriptor.html">ParcelFileDescriptor</a></code> or, (ii) the
@@ -957,7 +957,7 @@
  Calling close() on the InputStream will close the socket.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>instance of <code><a href="/reference/java/io/InputStream.html">InputStream</a></code>.</li></ul>
+      <ul class="nolist"><li>An instance of <code><a href="/reference/java/io/InputStream.html">InputStream</a></code>.</li></ul>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Throws</h5>
@@ -1006,7 +1006,7 @@
  packet will be dropped and an error message will be sent to the log.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>instance of <code><a href="/reference/java/io/OutputStream.html">OutputStream</a></code>.</li></ul>
+      <ul class="nolist"><li>An instance of <code><a href="/reference/java/io/OutputStream.html">OutputStream</a></code>.</li></ul>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Throws</h5>
@@ -1050,8 +1050,8 @@
  Calling close() on the returned ParcelFileDescriptor will close the socket.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>instance of <code><a href="/reference/android/os/ParcelFileDescriptor.html">ParcelFileDescriptor</a></code> or null if the underlying socket
-         is closed.</li></ul>
+      <ul class="nolist"><li>An instance of <code><a href="/reference/android/os/ParcelFileDescriptor.html">ParcelFileDescriptor</a></code> or null if the underlying
+         socket is closed.</li></ul>
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Throws</h5>
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html b/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html
index cf6e4f9..c40d4df 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/Achievement.html
@@ -1782,7 +1782,7 @@
  this directly. Instead, cache the result of <code><a href="/reference/com/google/android/gms/common/data/Freezable.html#freeze()">freeze()</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>player associated with this achievement.
+      <ul class="nolist"><li>The player associated with this achievement.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html b/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html
index 646f741..06bd27a 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/AchievementBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html b/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html
index 6c859440..d104974 100644
--- a/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html
@@ -868,7 +868,7 @@
         </tr>
         <tr>
           <th>achievementId</td>
-          <td>id of the achievement that was updated.
+          <td>The ID of the achievement that was updated.
 </td>
         </tr>
       </table>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html
index 0f3911b..2186179 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html
@@ -1343,13 +1343,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html
index b0369b3..93d96d3 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html
@@ -1338,7 +1338,7 @@
  this directly. Instead, cache the result of <code><a href="/reference/com/google/android/gms/common/data/Freezable.html#freeze()">freeze()</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>player associated with this leaderboard score.
+      <ul class="nolist"><li>The player associated with this leaderboard score.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html
index 07e266e..2ee0f33 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html
index 957bcf7..f67626d 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html
@@ -1427,9 +1427,8 @@
  is only accurate if <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#hasPlayerInfo()">hasPlayerInfo()</a></code> returns true.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the String representation of the viewing player's rank, or {@code null)
+      <ul class="nolist"><li>The String representation of the viewing player's rank, or {@code null)
          if the player has no rank for this variant.
-
 </li></ul>
   </div>
 
@@ -1464,7 +1463,7 @@
  accurate if <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#hasPlayerInfo()">hasPlayerInfo()</a></code> returns true.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the String representation of the viewing player's score, or <code>null</code> if the
+      <ul class="nolist"><li>The String representation of the viewing player's score, or <code>null</code> if the
          player has no score for this variant.
 </li></ul>
   </div>
@@ -1501,7 +1500,7 @@
  this method will return <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#NUM_SCORES_UNKNOWN">NUM_SCORES_UNKNOWN</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the number of scores for this variant, or <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#NUM_SCORES_UNKNOWN">NUM_SCORES_UNKNOWN</a></code>.
+      <ul class="nolist"><li>The number of scores for this variant, or <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#NUM_SCORES_UNKNOWN">NUM_SCORES_UNKNOWN</a></code>.
 </li></ul>
   </div>
 
@@ -1536,7 +1535,7 @@
  accurate if <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#hasPlayerInfo()">hasPlayerInfo()</a></code> returns true.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the long representation of the viewing player's rank, or <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#PLAYER_RANK_UNKNOWN">PLAYER_RANK_UNKNOWN</a></code>
+      <ul class="nolist"><li>The long representation of the viewing player's rank, or <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#PLAYER_RANK_UNKNOWN">PLAYER_RANK_UNKNOWN</a></code>
          if the player has no rank for this variant.
 </li></ul>
   </div>
@@ -1572,7 +1571,7 @@
  accurate if <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#hasPlayerInfo()">hasPlayerInfo()</a></code> returns true.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the long representation of the viewing player's score, or
+      <ul class="nolist"><li>The long representation of the viewing player's score, or
          <code><a href="/reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html#PLAYER_SCORE_UNKNOWN">PLAYER_SCORE_UNKNOWN</a></code> if the player has no score for this variant.
 </li></ul>
   </div>
@@ -1649,7 +1648,7 @@
  a rank.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>whether or not this variant contains score information for the viewing player.
+      <ul class="nolist"><li>Whether or not this variant contains score information for the viewing player.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html b/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html
index 07ee745..42b4e40 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html
@@ -857,7 +857,8 @@
         <tr>
           <th>result</td>
           <td>Detailed results of the operation, which includes data regarding whether this
-            was the new high score for any of the supported time spans.
+            was the new high score for any of the supported time spans. Note that the results
+            will only be populated if <code>statusCodes</code> is <code><a href="/reference/com/google/android/gms/games/GamesClient.html#STATUS_OK">STATUS_OK</a></code>.
 </td>
         </tr>
       </table>
diff --git a/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html b/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html
index 167b6a6..e33b848 100644
--- a/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html
+++ b/docs/html/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html
@@ -1310,7 +1310,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieves the ID of the leaderboard the score was submitted to.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the ID of the leaderboard.
+      <ul class="nolist"><li>The ID of the leaderboard.
 </li></ul>
   </div>
 
@@ -1344,7 +1344,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieves the ID of the player the score was submitted for.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the ID of submitting player.
+      <ul class="nolist"><li>The ID of submitting player.
 </li></ul>
   </div>
 
@@ -1390,7 +1390,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the appropriate <code><a href="/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html">SubmitScoreResult.Result</a></code> or <code>null</code> if no result was returned for the
+      <ul class="nolist"><li>The appropriate <code><a href="/reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html">SubmitScoreResult.Result</a></code> or <code>null</code> if no result was returned for the
          given time span.
 </li></ul>
   </div>
@@ -1433,7 +1433,7 @@
  </ul></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the status code of the submit score operation.
+      <ul class="nolist"><li>The status code of the submit score operation.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html b/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html
index c9b914f..95eac22 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/Invitation.html
@@ -1177,7 +1177,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieve the server timestamp at which this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code> was created.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the server timestamp at which this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code> was created.
+      <ul class="nolist"><li>The server timestamp at which this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code> was created.
 </li></ul>
   </div>
 
@@ -1245,7 +1245,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieve the ID of this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the ID of this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
+      <ul class="nolist"><li>The ID of this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
 </li></ul>
   </div>
 
@@ -1279,7 +1279,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieve the <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code> who created this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code> who created this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
+      <ul class="nolist"><li>The <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code> who created this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html
index 4edeb83..6f906a6 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html
@@ -1343,13 +1343,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html
index a38ddc4..9615ad3f 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/InvitationEntity.html
@@ -1772,7 +1772,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieve the server timestamp at which this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code> was created.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the server timestamp at which this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code> was created.
+      <ul class="nolist"><li>The server timestamp at which this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code> was created.
 </li></ul>
   </div>
 
@@ -1840,7 +1840,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieve the ID of this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the ID of this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
+      <ul class="nolist"><li>The ID of this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
 </li></ul>
   </div>
 
@@ -1903,7 +1903,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieve the <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code> who created this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code> who created this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
+      <ul class="nolist"><li>The <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code> who created this <code><a href="/reference/com/google/android/gms/games/multiplayer/Invitation.html">Invitation</a></code>.
 </li></ul>
   </div>
 
@@ -1938,7 +1938,7 @@
  applicable to the given object.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>a list of <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code>s for this object.
+      <ul class="nolist"><li>A list of <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code>s for this object.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html
index 5a3a803..59e0f54 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html b/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html
index 3b0250d..d543bef 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/Participatable.html
@@ -901,7 +901,7 @@
  applicable to the given object.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>a list of <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code>s for this object.
+      <ul class="nolist"><li>A list of <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code>s for this object.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html
index 64c6398..1b12a08 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/Room.html
@@ -1547,7 +1547,7 @@
  room has no automatch properties.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>bundle containing the automatch criteria for this room.
+      <ul class="nolist"><li>A bundle containing the automatch criteria for this room.
 </li></ul>
   </div>
 
@@ -1928,8 +1928,8 @@
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>Variant specified for this room, if any. A variant is an optional
-         developer-controlled parameter describing the type of game to play, ranging from
-         1-1023 (inclusive). If this room had no variant specified, returns
+         developer-controlled parameter describing the type of game to play. If specified,
+         this value will be a positive integer. If this room had no variant specified, returns
          <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/Room.html#ROOM_VARIANT_ANY">ROOM_VARIANT_ANY</a></code>.
 </li></ul>
   </div>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html
index 373578b..df6fb49 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html
@@ -1398,7 +1398,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>invitationId</td>
-          <td>the ID of the invitation to accept.
+          <td>The ID of the invitation to accept.
 </td>
         </tr>
       </table>
@@ -1440,7 +1440,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the message received listener that is called to notify the client when it
+          <td>The message received listener that is called to notify the client when it
             receives a message in a room. The listener is called on the main thread.
 </td>
         </tr>
@@ -1480,7 +1480,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>listener</td>
-          <td>the listener that is called to notify the client when the status of the
+          <td>The listener that is called to notify the client when the status of the
             room has changed. The listener is called on the main thread.
 </td>
         </tr>
@@ -1566,8 +1566,8 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Sets the variant for the room when calling <code><a href="/reference/com/google/android/gms/games/GamesClient.html#createRoom(com.google.android.gms.games.multiplayer.realtime.RoomConfig)">createRoom(RoomConfig)</a></code>. This is an
- optional, developer-controlled parameter describing the type of game to play, and is
- used for auto-matching criteria. Must be either a value from 1 to 1023 (inclusive), or
+ optional, developer-controlled parameter describing the type of game to play, and is used
+ for auto-matching criteria. Must be either a positive integer or
  <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/Room.html#ROOM_VARIANT_ANY">ROOM_VARIANT_ANY</a></code> (the default) if not desired.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Parameters</h5>
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html
index 93da6bbf..926eeda 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html
@@ -1317,15 +1317,15 @@
       <table class="jd-tagtable">
         <tr>
           <th>minAutoMatchPlayers</td>
-          <td>min number of auto-matched players.</td>
+          <td>Minimum number of auto-matched players.</td>
         </tr>
         <tr>
           <th>maxAutoMatchPlayers</td>
-          <td>max number of auto-matched players.</td>
+          <td>Maximum number of auto-matched players.</td>
         </tr>
         <tr>
           <th>exclusiveBitMask</td>
-          <td>exclusive bitmasks for the automatching request. The logical AND of
+          <td>Exclusive bitmasks for the automatching request. The logical AND of
             each pairing of automatching requests must equal zero for auto-match. If there
             are no exclusivity requirements for the game, this value should just be set to 0.</td>
         </tr>
@@ -1333,7 +1333,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>bundle of auto-match criteria data.
+      <ul class="nolist"><li>A bundle of auto-match criteria data.
 </li></ul>
   </div>
 
@@ -1470,7 +1470,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Retrieves the listener for message received from a peer.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>the <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html">RealTimeMessageReceivedListener</a></code> that is called when the client has
+      <ul class="nolist"><li>The <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html">RealTimeMessageReceivedListener</a></code> that is called when the client has
             received a message from a peer.
 </li></ul>
   </div>
@@ -1571,8 +1571,7 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Retrieves the (optional) developer-controlled parameter describing the type of game to play.
- Must be either a value from 1 to 1023 (inclusive), or <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/Room.html#ROOM_VARIANT_ANY">ROOM_VARIANT_ANY</a></code> if not
- desired.</p></div>
+ Must be either a positive integer or <code><a href="/reference/com/google/android/gms/games/multiplayer/realtime/Room.html#ROOM_VARIANT_ANY">ROOM_VARIANT_ANY</a></code> if not desired.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>The developer-specified game variant.
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html
index e3772e2..7e6861b 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html
@@ -2044,7 +2044,7 @@
  room has no automatch properties.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>bundle containing the automatch criteria for this room.
+      <ul class="nolist"><li>A bundle containing the automatch criteria for this room.
 </li></ul>
   </div>
 
@@ -2324,7 +2324,7 @@
  applicable to the given object.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>a list of <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code>s for this object.
+      <ul class="nolist"><li>A list of <code><a href="/reference/com/google/android/gms/games/multiplayer/Participant.html">Participant</a></code>s for this object.
 </li></ul>
   </div>
 
diff --git a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html
index 45fd518..988cc0c 100644
--- a/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html
+++ b/docs/html/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html
@@ -1059,7 +1059,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>participantIds</td>
-          <td>ID of the peers invited to a room.
+          <td>IDs of the peers invited to a room.
 </td>
         </tr>
       </table>
@@ -1098,7 +1098,7 @@
       <table class="jd-tagtable">
         <tr>
           <th>participantIds</td>
-          <td>ID of the peers invited to a room.
+          <td>IDs of the peers invited to a room.
 </td>
         </tr>
       </table>
diff --git a/docs/html/reference/com/google/android/gms/games/package-summary.html b/docs/html/reference/com/google/android/gms/games/package-summary.html
index 098524a..e5b82b2 100644
--- a/docs/html/reference/com/google/android/gms/games/package-summary.html
+++ b/docs/html/reference/com/google/android/gms/games/package-summary.html
@@ -711,18 +711,14 @@
               <td class="jd-descrcol" width="100%">Builder class for GamesClient.&nbsp;</td>
           </tr>
         <tr class=" api apilevel-" >
-              <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/GamesClientSettings.html">GamesClientSettings</a></td>
-              <td class="jd-descrcol" width="100%">Settings for <code><a href="/reference/com/google/android/gms/games/GamesClient.html">GamesClient</a></code>.&nbsp;</td>
-          </tr>
-        <tr class="alt-color api apilevel-" >
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/PageDirection.html">PageDirection</a></td>
               <td class="jd-descrcol" width="100%">Direction constants for pagination over data sets.&nbsp;</td>
           </tr>
-        <tr class=" api apilevel-" >
+        <tr class="alt-color api apilevel-" >
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/PlayerBuffer.html">PlayerBuffer</a></td>
               <td class="jd-descrcol" width="100%">Data structure providing access to a list of players.&nbsp;</td>
           </tr>
-        <tr class="alt-color api apilevel-" >
+        <tr class=" api apilevel-" >
               <td class="jd-linkcol"><a href="/reference/com/google/android/gms/games/PlayerEntity.html">PlayerEntity</a></td>
               <td class="jd-descrcol" width="100%">Data object representing a set of Player data.&nbsp;</td>
           </tr>
diff --git a/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html b/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html
index 492532e..5b50466 100644
--- a/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html
+++ b/docs/html/reference/com/google/android/gms/location/ActivityRecognitionClient.html
@@ -756,7 +756,7 @@
  ActivityRecognitionClient mActivityRecognitionClient =
          new ActivityRecognitionClient(this, this, this);
  mActivityRecognitionClient.connect();
- 
+
   // Called when a connection to the ActivityRecognitionService has been established.
  public void onConnected(Bundle connectionHint) {
      Intent intent = new Intent(this, MyIntentService.class);
@@ -1697,7 +1697,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -1731,7 +1731,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -1775,7 +1775,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
 
@@ -1819,7 +1819,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
 
@@ -1851,9 +1851,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -1902,11 +1903,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
diff --git a/docs/html/reference/com/google/android/gms/location/LocationClient.html b/docs/html/reference/com/google/android/gms/location/LocationClient.html
index 6652c0a..d7bd08a 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationClient.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationClient.html
@@ -2291,7 +2291,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -2325,7 +2325,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -2369,7 +2369,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
 
@@ -2413,7 +2413,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
 
@@ -2445,9 +2445,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -2496,11 +2497,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
diff --git a/docs/html/reference/com/google/android/gms/location/LocationRequest.html b/docs/html/reference/com/google/android/gms/location/LocationRequest.html
index 6eaf102..3ce6ef9 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationRequest.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationRequest.html
@@ -789,8 +789,8 @@
  slower interval, and the location object will be obfuscated to only show a coarse level of
  accuracy.
 
- <p>All location requests are considered hints, and you may receive locations that are more
- accurate, less accurate, and slower than requested.
+ <p>All location requests are considered hints, and you may receive locations that are
+ more/less accurate, and faster/slower than requested.
 </p>
 
 
@@ -998,6 +998,22 @@
             
             
             
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/location/LocationRequest.html#equals(java.lang.Object)">equals</a></span>(Object object)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
             long</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -1009,7 +1025,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1027,7 +1043,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1045,7 +1061,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1063,7 +1079,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1081,7 +1097,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1101,6 +1117,22 @@
 
 
 	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/location/LocationRequest.html#hashCode()">hashCode</a></span>()</nobr>
+        
+  </td></tr>
+
+
+	 
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
@@ -1847,6 +1879,35 @@
 </div>
 
 
+<A NAME="equals(java.lang.Object)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        boolean
+      </span>
+      <span class="sympad">equals</span>
+      <span class="normal">(Object object)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="getExpirationTime()"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2062,6 +2123,35 @@
 </div>
 
 
+<A NAME="hashCode()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        int
+      </span>
+      <span class="sympad">hashCode</span>
+      <span class="normal">()</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="setExpirationDuration(long)"></A>
 
 <div class="jd-details api apilevel-"> 
diff --git a/docs/html/reference/com/google/android/gms/maps/MapFragment.html b/docs/html/reference/com/google/android/gms/maps/MapFragment.html
index 0664856..72f86e5 100644
--- a/docs/html/reference/com/google/android/gms/maps/MapFragment.html
+++ b/docs/html/reference/com/google/android/gms/maps/MapFragment.html
@@ -1045,7 +1045,7 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/maps/MapFragment.html#onAttach(android.app.Activity)">onAttach</a></span>(Activity activity)</nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/maps/MapFragment.html#onActivityCreated(android.os.Bundle)">onActivityCreated</a></span>(Bundle savedInstanceState)</nobr>
         
   </td></tr>
 
@@ -1061,13 +1061,29 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/maps/MapFragment.html#onAttach(android.app.Activity)">onAttach</a></span>(Activity activity)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/maps/MapFragment.html#onCreate(android.os.Bundle)">onCreate</a></span>(Bundle savedInstanceState)</nobr>
         
   </td></tr>
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1083,7 +1099,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1099,7 +1115,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1115,7 +1131,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1133,7 +1149,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1149,7 +1165,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1165,7 +1181,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1181,7 +1197,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1197,7 +1213,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2879,6 +2895,35 @@
 </div>
 
 
+<A NAME="onActivityCreated(android.os.Bundle)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">onActivityCreated</span>
+      <span class="normal">(Bundle savedInstanceState)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="onAttach(android.app.Activity)"></A>
 
 <div class="jd-details api apilevel-"> 
diff --git a/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html b/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html
index 9ae0a84..3bccdee 100644
--- a/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html
+++ b/docs/html/reference/com/google/android/gms/maps/SupportMapFragment.html
@@ -944,7 +944,7 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="/reference/com/google/android/gms/maps/SupportMapFragment.html#onAttach(android.app.Activity)">onAttach</a></span>(Activity activity)</nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/maps/SupportMapFragment.html#onActivityCreated(android.os.Bundle)">onActivityCreated</a></span>(Bundle savedInstanceState)</nobr>
         
   </td></tr>
 
@@ -960,13 +960,29 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/com/google/android/gms/maps/SupportMapFragment.html#onAttach(android.app.Activity)">onAttach</a></span>(Activity activity)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/maps/SupportMapFragment.html#onCreate(android.os.Bundle)">onCreate</a></span>(Bundle savedInstanceState)</nobr>
         
   </td></tr>
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -982,7 +998,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -998,7 +1014,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1014,7 +1030,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1032,7 +1048,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1048,7 +1064,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1064,7 +1080,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1080,7 +1096,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1096,7 +1112,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2768,6 +2784,35 @@
 </div>
 
 
+<A NAME="onActivityCreated(android.os.Bundle)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">onActivityCreated</span>
+      <span class="normal">(Bundle savedInstanceState)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="onAttach(android.app.Activity)"></A>
 
 <div class="jd-details api apilevel-"> 
diff --git a/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html b/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html
index 832ae26..39a7525 100644
--- a/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html
+++ b/docs/html/reference/com/google/android/gms/panorama/PanoramaClient.html
@@ -1695,7 +1695,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -1729,7 +1729,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -1773,7 +1773,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
 
@@ -1817,7 +1817,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
 
@@ -1940,9 +1940,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -1991,11 +1992,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html
index 5d0383e..bcd39f6 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.Builder.html
@@ -825,7 +825,7 @@
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/plus/PlusClient.Builder.html#build()">build</a></span>()</nobr>
         
-        <div class="jd-descrdiv">Creates a new <code><a href="/reference/com/google/android/gms/plus/PlusClient.html">PlusClient</a></code>.</div>
+        <div class="jd-descrdiv">Builds a new <code><a href="/reference/com/google/android/gms/plus/PlusClient.html">PlusClient</a></code> object for communicating with the Google+ APIs.</div>
   
   </td></tr>
 
@@ -1239,8 +1239,12 @@
       </div>
     <div class="jd-details-descr">
       
-  <div class="jd-tagdata jd-tagdescr"><p>Creates a new <code><a href="/reference/com/google/android/gms/plus/PlusClient.html">PlusClient</a></code>.
-</p></div>
+  <div class="jd-tagdata jd-tagdescr"><p>Builds a new <code><a href="/reference/com/google/android/gms/plus/PlusClient.html">PlusClient</a></code> object for communicating with the Google+ APIs.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Returns</h5>
+      <ul class="nolist"><li>The <code><a href="/reference/com/google/android/gms/plus/PlusClient.html">PlusClient</a></code> object.
+</li></ul>
+  </div>
 
     </div>
 </div>
@@ -1390,7 +1394,7 @@
 
  <p>
  See <a href="https://developers.google.com/+/api/moment-types">Types of app
- activity</a>for the full list of valid app activity types. Example usage:
+ activity</a> for the full list of valid app activity types. Example usage:
  <pre>
       plusClientBuilder.setVisibleActivities(
           "http://schemas.google.com/AddActivity",
diff --git a/docs/html/reference/com/google/android/gms/plus/PlusClient.html b/docs/html/reference/com/google/android/gms/plus/PlusClient.html
index 529e2ad..e73301a 100644
--- a/docs/html/reference/com/google/android/gms/plus/PlusClient.html
+++ b/docs/html/reference/com/google/android/gms/plus/PlusClient.html
@@ -2024,7 +2024,7 @@
  client actions caused by the user with a call to this method.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is connected to the service.
+      <ul class="nolist"><li>true if the client is connected to the service.
 </li></ul>
   </div>
 
@@ -2058,7 +2058,7 @@
   <div class="jd-tagdata jd-tagdescr"><p>Checks if the client is attempting to connect to the service.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the client is attempting to connect to the service.
+      <ul class="nolist"><li>true if the client is attempting to connect to the service.
 </li></ul>
   </div>
 
@@ -2102,7 +2102,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              events.</li></ul>
   </div>
 
@@ -2146,7 +2146,7 @@
   </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li>true If the specified listener is currently registered to receive connection
+      <ul class="nolist"><li>true if the specified listener is currently registered to receive connection
              failed events.</li></ul>
   </div>
 
@@ -2320,7 +2320,7 @@
         <tr>
           <th>orderBy</td>
           <td>The order to return people in.  Valid values are:<p>
-             <code><a href="/reference/com/google/android/gms/plus/model/people/Person.OrderBy.html#ALPHABETICAL">ALPHABETICAL</a></code> - Order the people by their display name.
+             <code><a href="/reference/com/google/android/gms/plus/model/people/Person.OrderBy.html#ALPHABETICAL">ALPHABETICAL</a></code> - Order the people by their display name.<p>
              <code><a href="/reference/com/google/android/gms/plus/model/people/Person.OrderBy.html#BEST">BEST</a></code> - Order people based on the relevance to the viewer.</td>
         </tr>
         <tr>
@@ -2473,9 +2473,10 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection events from this <code>GooglePlayServicesClient</code>.
- If we are already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code> method
- will be called immediately.  Applications should balance calls to this method with calls to
- <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking resources.
+ If the service is already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected(Bundle)</a></code>
+ method will be called immediately.  Applications should balance calls to this method with
+ calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">unregisterConnectionCallbacks(ConnectionCallbacks)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection events, this
  method will not add a duplicate entry for the same listener, but <strong>will</strong>
@@ -2524,11 +2525,12 @@
     <div class="jd-details-descr">
       
   <div class="jd-tagdata jd-tagdescr"><p>Registers a listener to receive connection failed events from this
- <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if we are not
- already connected, the listener's <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code>
- method will not be called immediately.  Applications should balance calls to this method with
- calls to <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid
- leaking resources.
+ <code>GooglePlayServicesClient</code>. Unlike <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#registerConnectionCallbacks(com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks)">registerConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks)</a></code>, if the service
+ is not already connected, the listener's
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed(ConnectionResult)</a></code> method will not be called immediately.
+ Applications should balance calls to this method with calls to
+ <code><a href="/reference/com/google/android/gms/common/GooglePlayServicesClient.html#unregisterConnectionFailedListener(com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener)">unregisterConnectionFailedListener(OnConnectionFailedListener)</a></code> to avoid leaking
+ resources.
  <p>
  If the specified listener is already registered to receive connection failed events, this
  method will not add a duplicate entry for the same listener.
diff --git a/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html b/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html
index fac199f..893a3ee 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/moments/MomentBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html b/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html
index b722bcf..b58496b3 100644
--- a/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html
+++ b/docs/html/reference/com/google/android/gms/plus/model/people/PersonBuffer.html
@@ -1278,13 +1278,19 @@
   <div class="jd-tagdata jd-tagdescr"><p>Get the item at the specified position. Note that the objects returned from subsequent
  invocations of this method for the same position may not be identical objects, but will be
  equal in value. In other words:
-
- <pre>
- <code>
- buffer.get(i) == buffer.get(i) may return false.
- buffer.get(i).equals(buffer.get(i)) will return true.
- </code>
- </pre></p></div>
+ <p>
+ <code>buffer.get(i) == buffer.get(i)</code> may return false.
+ <p>
+ <code>buffer.get(i).equals(buffer.get(i))</code> will return true.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>position</td>
+          <td>The position of the item to retrieve.</td>
+        </tr>
+      </table>
+  </div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Returns</h5>
       <ul class="nolist"><li>the item at <code>position</code> in this buffer.
diff --git a/docs/html/reference/gms-packages.html b/docs/html/reference/gms-packages.html
index 5a7ae07..ff13938 100644
--- a/docs/html/reference/gms-packages.html
+++ b/docs/html/reference/gms-packages.html
@@ -670,7 +670,7 @@
     <tr class=" api apilevel-" >
         <td class="jd-linkcol">
   <a href="/reference/com/google/android/gms/common/images/package-summary.html">com.google.android.gms.common.images</a></td>
-        <td class="jd-descrcol" width="100%"></td>
+        <td class="jd-descrcol" width="100%">Contains classes for loading images from Google Play services.</td>
     </tr>
 
 
diff --git a/docs/html/reference/gms_lists.js b/docs/html/reference/gms_lists.js
index fe58709..a0e58fb 100644
--- a/docs/html/reference/gms_lists.js
+++ b/docs/html/reference/gms_lists.js
@@ -1,201 +1,199 @@
 var GMS_DATA = [
-      { id:0, label:"com.google.android.gms", link:"reference/com/google/android/gms/package-summary.html", type:"package" },
-      { id:1, label:"com.google.android.gms.R", link:"reference/com/google/android/gms/R.html", type:"class" },
-      { id:2, label:"com.google.android.gms.R.attr", link:"reference/com/google/android/gms/R.attr.html", type:"class" },
-      { id:3, label:"com.google.android.gms.R.color", link:"reference/com/google/android/gms/R.color.html", type:"class" },
-      { id:4, label:"com.google.android.gms.R.drawable", link:"reference/com/google/android/gms/R.drawable.html", type:"class" },
-      { id:5, label:"com.google.android.gms.R.id", link:"reference/com/google/android/gms/R.id.html", type:"class" },
-      { id:6, label:"com.google.android.gms.R.string", link:"reference/com/google/android/gms/R.string.html", type:"class" },
-      { id:7, label:"com.google.android.gms.R.styleable", link:"reference/com/google/android/gms/R.styleable.html", type:"class" },
-      { id:8, label:"com.google.android.gms.appstate", link:"reference/com/google/android/gms/appstate/package-summary.html", type:"package" },
-      { id:9, label:"com.google.android.gms.appstate.AppState", link:"reference/com/google/android/gms/appstate/AppState.html", type:"class" },
-      { id:10, label:"com.google.android.gms.appstate.AppStateBuffer", link:"reference/com/google/android/gms/appstate/AppStateBuffer.html", type:"class" },
-      { id:11, label:"com.google.android.gms.appstate.AppStateClient", link:"reference/com/google/android/gms/appstate/AppStateClient.html", type:"class" },
-      { id:12, label:"com.google.android.gms.appstate.AppStateClient.Builder", link:"reference/com/google/android/gms/appstate/AppStateClient.Builder.html", type:"class" },
-      { id:13, label:"com.google.android.gms.appstate.OnSignOutCompleteListener", link:"reference/com/google/android/gms/appstate/OnSignOutCompleteListener.html", type:"class" },
-      { id:14, label:"com.google.android.gms.appstate.OnStateDeletedListener", link:"reference/com/google/android/gms/appstate/OnStateDeletedListener.html", type:"class" },
-      { id:15, label:"com.google.android.gms.appstate.OnStateListLoadedListener", link:"reference/com/google/android/gms/appstate/OnStateListLoadedListener.html", type:"class" },
-      { id:16, label:"com.google.android.gms.appstate.OnStateLoadedListener", link:"reference/com/google/android/gms/appstate/OnStateLoadedListener.html", type:"class" },
-      { id:17, label:"com.google.android.gms.auth", link:"reference/com/google/android/gms/auth/package-summary.html", type:"package" },
-      { id:18, label:"com.google.android.gms.auth.GoogleAuthException", link:"reference/com/google/android/gms/auth/GoogleAuthException.html", type:"class" },
-      { id:19, label:"com.google.android.gms.auth.GoogleAuthUtil", link:"reference/com/google/android/gms/auth/GoogleAuthUtil.html", type:"class" },
-      { id:20, label:"com.google.android.gms.auth.GooglePlayServicesAvailabilityException", link:"reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html", type:"class" },
-      { id:21, label:"com.google.android.gms.auth.UserRecoverableAuthException", link:"reference/com/google/android/gms/auth/UserRecoverableAuthException.html", type:"class" },
-      { id:22, label:"com.google.android.gms.auth.UserRecoverableNotifiedException", link:"reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html", type:"class" },
-      { id:23, label:"com.google.android.gms.common", link:"reference/com/google/android/gms/common/package-summary.html", type:"package" },
-      { id:24, label:"com.google.android.gms.common.AccountPicker", link:"reference/com/google/android/gms/common/AccountPicker.html", type:"class" },
-      { id:25, label:"com.google.android.gms.common.ConnectionResult", link:"reference/com/google/android/gms/common/ConnectionResult.html", type:"class" },
-      { id:26, label:"com.google.android.gms.common.GooglePlayServicesClient", link:"reference/com/google/android/gms/common/GooglePlayServicesClient.html", type:"class" },
-      { id:27, label:"com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks", link:"reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html", type:"class" },
-      { id:28, label:"com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener", link:"reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html", type:"class" },
-      { id:29, label:"com.google.android.gms.common.GooglePlayServicesNotAvailableException", link:"reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html", type:"class" },
-      { id:30, label:"com.google.android.gms.common.GooglePlayServicesUtil", link:"reference/com/google/android/gms/common/GooglePlayServicesUtil.html", type:"class" },
-      { id:31, label:"com.google.android.gms.common.Scopes", link:"reference/com/google/android/gms/common/Scopes.html", type:"class" },
-      { id:32, label:"com.google.android.gms.common.SignInButton", link:"reference/com/google/android/gms/common/SignInButton.html", type:"class" },
-      { id:33, label:"com.google.android.gms.common.data", link:"reference/com/google/android/gms/common/data/package-summary.html", type:"package" },
-      { id:34, label:"com.google.android.gms.common.data.DataBuffer", link:"reference/com/google/android/gms/common/data/DataBuffer.html", type:"class" },
-      { id:35, label:"com.google.android.gms.common.data.DataBufferUtils", link:"reference/com/google/android/gms/common/data/DataBufferUtils.html", type:"class" },
-      { id:36, label:"com.google.android.gms.common.data.Freezable", link:"reference/com/google/android/gms/common/data/Freezable.html", type:"class" },
-      { id:37, label:"com.google.android.gms.common.images", link:"reference/com/google/android/gms/common/images/package-summary.html", type:"package" },
-      { id:38, label:"com.google.android.gms.common.images.ImageManager", link:"reference/com/google/android/gms/common/images/ImageManager.html", type:"class" },
-      { id:39, label:"com.google.android.gms.common.images.ImageManager.ImageReceiver", link:"reference/com/google/android/gms/common/images/ImageManager.ImageReceiver.html", type:"class" },
-      { id:40, label:"com.google.android.gms.common.images.ImageManager.OnImageLoadedListener", link:"reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html", type:"class" },
-      { id:41, label:"com.google.android.gms.games", link:"reference/com/google/android/gms/games/package-summary.html", type:"package" },
-      { id:42, label:"com.google.android.gms.games.Game", link:"reference/com/google/android/gms/games/Game.html", type:"class" },
-      { id:43, label:"com.google.android.gms.games.GameBuffer", link:"reference/com/google/android/gms/games/GameBuffer.html", type:"class" },
-      { id:44, label:"com.google.android.gms.games.GameEntity", link:"reference/com/google/android/gms/games/GameEntity.html", type:"class" },
-      { id:45, label:"com.google.android.gms.games.GamesActivityResultCodes", link:"reference/com/google/android/gms/games/GamesActivityResultCodes.html", type:"class" },
-      { id:46, label:"com.google.android.gms.games.GamesClient", link:"reference/com/google/android/gms/games/GamesClient.html", type:"class" },
-      { id:47, label:"com.google.android.gms.games.GamesClient.Builder", link:"reference/com/google/android/gms/games/GamesClient.Builder.html", type:"class" },
-      { id:48, label:"com.google.android.gms.games.GamesClientSettings", link:"reference/com/google/android/gms/games/GamesClientSettings.html", type:"class" },
-      { id:49, label:"com.google.android.gms.games.OnGamesLoadedListener", link:"reference/com/google/android/gms/games/OnGamesLoadedListener.html", type:"class" },
-      { id:50, label:"com.google.android.gms.games.OnPlayersLoadedListener", link:"reference/com/google/android/gms/games/OnPlayersLoadedListener.html", type:"class" },
-      { id:51, label:"com.google.android.gms.games.OnSignOutCompleteListener", link:"reference/com/google/android/gms/games/OnSignOutCompleteListener.html", type:"class" },
-      { id:52, label:"com.google.android.gms.games.PageDirection", link:"reference/com/google/android/gms/games/PageDirection.html", type:"class" },
-      { id:53, label:"com.google.android.gms.games.Player", link:"reference/com/google/android/gms/games/Player.html", type:"class" },
-      { id:54, label:"com.google.android.gms.games.PlayerBuffer", link:"reference/com/google/android/gms/games/PlayerBuffer.html", type:"class" },
-      { id:55, label:"com.google.android.gms.games.PlayerEntity", link:"reference/com/google/android/gms/games/PlayerEntity.html", type:"class" },
-      { id:56, label:"com.google.android.gms.games.RealTimeSocket", link:"reference/com/google/android/gms/games/RealTimeSocket.html", type:"class" },
-      { id:57, label:"com.google.android.gms.games.achievement", link:"reference/com/google/android/gms/games/achievement/package-summary.html", type:"package" },
-      { id:58, label:"com.google.android.gms.games.achievement.Achievement", link:"reference/com/google/android/gms/games/achievement/Achievement.html", type:"class" },
-      { id:59, label:"com.google.android.gms.games.achievement.AchievementBuffer", link:"reference/com/google/android/gms/games/achievement/AchievementBuffer.html", type:"class" },
-      { id:60, label:"com.google.android.gms.games.achievement.OnAchievementUpdatedListener", link:"reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html", type:"class" },
-      { id:61, label:"com.google.android.gms.games.achievement.OnAchievementsLoadedListener", link:"reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html", type:"class" },
-      { id:62, label:"com.google.android.gms.games.leaderboard", link:"reference/com/google/android/gms/games/leaderboard/package-summary.html", type:"package" },
-      { id:63, label:"com.google.android.gms.games.leaderboard.Leaderboard", link:"reference/com/google/android/gms/games/leaderboard/Leaderboard.html", type:"class" },
-      { id:64, label:"com.google.android.gms.games.leaderboard.LeaderboardBuffer", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html", type:"class" },
-      { id:65, label:"com.google.android.gms.games.leaderboard.LeaderboardScore", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html", type:"class" },
-      { id:66, label:"com.google.android.gms.games.leaderboard.LeaderboardScoreBuffer", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html", type:"class" },
-      { id:67, label:"com.google.android.gms.games.leaderboard.LeaderboardVariant", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html", type:"class" },
-      { id:68, label:"com.google.android.gms.games.leaderboard.OnLeaderboardMetadataLoadedListener", link:"reference/com/google/android/gms/games/leaderboard/OnLeaderboardMetadataLoadedListener.html", type:"class" },
-      { id:69, label:"com.google.android.gms.games.leaderboard.OnLeaderboardScoresLoadedListener", link:"reference/com/google/android/gms/games/leaderboard/OnLeaderboardScoresLoadedListener.html", type:"class" },
-      { id:70, label:"com.google.android.gms.games.leaderboard.OnScoreSubmittedListener", link:"reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html", type:"class" },
-      { id:71, label:"com.google.android.gms.games.leaderboard.SubmitScoreResult", link:"reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html", type:"class" },
-      { id:72, label:"com.google.android.gms.games.leaderboard.SubmitScoreResult.Result", link:"reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html", type:"class" },
-      { id:73, label:"com.google.android.gms.games.multiplayer", link:"reference/com/google/android/gms/games/multiplayer/package-summary.html", type:"package" },
-      { id:74, label:"com.google.android.gms.games.multiplayer.Invitation", link:"reference/com/google/android/gms/games/multiplayer/Invitation.html", type:"class" },
-      { id:75, label:"com.google.android.gms.games.multiplayer.InvitationBuffer", link:"reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html", type:"class" },
-      { id:76, label:"com.google.android.gms.games.multiplayer.InvitationEntity", link:"reference/com/google/android/gms/games/multiplayer/InvitationEntity.html", type:"class" },
-      { id:77, label:"com.google.android.gms.games.multiplayer.OnInvitationReceivedListener", link:"reference/com/google/android/gms/games/multiplayer/OnInvitationReceivedListener.html", type:"class" },
-      { id:78, label:"com.google.android.gms.games.multiplayer.OnInvitationsLoadedListener", link:"reference/com/google/android/gms/games/multiplayer/OnInvitationsLoadedListener.html", type:"class" },
-      { id:79, label:"com.google.android.gms.games.multiplayer.Participant", link:"reference/com/google/android/gms/games/multiplayer/Participant.html", type:"class" },
-      { id:80, label:"com.google.android.gms.games.multiplayer.ParticipantBuffer", link:"reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html", type:"class" },
-      { id:81, label:"com.google.android.gms.games.multiplayer.ParticipantEntity", link:"reference/com/google/android/gms/games/multiplayer/ParticipantEntity.html", type:"class" },
-      { id:82, label:"com.google.android.gms.games.multiplayer.ParticipantUtils", link:"reference/com/google/android/gms/games/multiplayer/ParticipantUtils.html", type:"class" },
-      { id:83, label:"com.google.android.gms.games.multiplayer.Participatable", link:"reference/com/google/android/gms/games/multiplayer/Participatable.html", type:"class" },
-      { id:84, label:"com.google.android.gms.games.multiplayer.realtime", link:"reference/com/google/android/gms/games/multiplayer/realtime/package-summary.html", type:"package" },
-      { id:85, label:"com.google.android.gms.games.multiplayer.realtime.RealTimeMessage", link:"reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessage.html", type:"class" },
-      { id:86, label:"com.google.android.gms.games.multiplayer.realtime.RealTimeMessageReceivedListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html", type:"class" },
-      { id:87, label:"com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html", type:"class" },
-      { id:88, label:"com.google.android.gms.games.multiplayer.realtime.Room", link:"reference/com/google/android/gms/games/multiplayer/realtime/Room.html", type:"class" },
-      { id:89, label:"com.google.android.gms.games.multiplayer.realtime.RoomConfig", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html", type:"class" },
-      { id:90, label:"com.google.android.gms.games.multiplayer.realtime.RoomConfig.Builder", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html", type:"class" },
-      { id:91, label:"com.google.android.gms.games.multiplayer.realtime.RoomEntity", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html", type:"class" },
-      { id:92, label:"com.google.android.gms.games.multiplayer.realtime.RoomStatusUpdateListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html", type:"class" },
-      { id:93, label:"com.google.android.gms.games.multiplayer.realtime.RoomUpdateListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html", type:"class" },
-      { id:94, label:"com.google.android.gms.gcm", link:"reference/com/google/android/gms/gcm/package-summary.html", type:"package" },
-      { id:95, label:"com.google.android.gms.gcm.GoogleCloudMessaging", link:"reference/com/google/android/gms/gcm/GoogleCloudMessaging.html", type:"class" },
-      { id:96, label:"com.google.android.gms.location", link:"reference/com/google/android/gms/location/package-summary.html", type:"package" },
-      { id:97, label:"com.google.android.gms.location.ActivityRecognitionClient", link:"reference/com/google/android/gms/location/ActivityRecognitionClient.html", type:"class" },
-      { id:98, label:"com.google.android.gms.location.ActivityRecognitionResult", link:"reference/com/google/android/gms/location/ActivityRecognitionResult.html", type:"class" },
-      { id:99, label:"com.google.android.gms.location.DetectedActivity", link:"reference/com/google/android/gms/location/DetectedActivity.html", type:"class" },
-      { id:100, label:"com.google.android.gms.location.Geofence", link:"reference/com/google/android/gms/location/Geofence.html", type:"class" },
-      { id:101, label:"com.google.android.gms.location.Geofence.Builder", link:"reference/com/google/android/gms/location/Geofence.Builder.html", type:"class" },
-      { id:102, label:"com.google.android.gms.location.LocationClient", link:"reference/com/google/android/gms/location/LocationClient.html", type:"class" },
-      { id:103, label:"com.google.android.gms.location.LocationClient.OnAddGeofencesResultListener", link:"reference/com/google/android/gms/location/LocationClient.OnAddGeofencesResultListener.html", type:"class" },
-      { id:104, label:"com.google.android.gms.location.LocationClient.OnRemoveGeofencesResultListener", link:"reference/com/google/android/gms/location/LocationClient.OnRemoveGeofencesResultListener.html", type:"class" },
-      { id:105, label:"com.google.android.gms.location.LocationListener", link:"reference/com/google/android/gms/location/LocationListener.html", type:"class" },
-      { id:106, label:"com.google.android.gms.location.LocationRequest", link:"reference/com/google/android/gms/location/LocationRequest.html", type:"class" },
-      { id:107, label:"com.google.android.gms.location.LocationStatusCodes", link:"reference/com/google/android/gms/location/LocationStatusCodes.html", type:"class" },
-      { id:108, label:"com.google.android.gms.maps", link:"reference/com/google/android/gms/maps/package-summary.html", type:"package" },
-      { id:109, label:"com.google.android.gms.maps.CameraUpdate", link:"reference/com/google/android/gms/maps/CameraUpdate.html", type:"class" },
-      { id:110, label:"com.google.android.gms.maps.CameraUpdateFactory", link:"reference/com/google/android/gms/maps/CameraUpdateFactory.html", type:"class" },
-      { id:111, label:"com.google.android.gms.maps.GoogleMap", link:"reference/com/google/android/gms/maps/GoogleMap.html", type:"class" },
-      { id:112, label:"com.google.android.gms.maps.GoogleMap.CancelableCallback", link:"reference/com/google/android/gms/maps/GoogleMap.CancelableCallback.html", type:"class" },
-      { id:113, label:"com.google.android.gms.maps.GoogleMap.InfoWindowAdapter", link:"reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter.html", type:"class" },
-      { id:114, label:"com.google.android.gms.maps.GoogleMap.OnCameraChangeListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener.html", type:"class" },
-      { id:115, label:"com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnInfoWindowClickListener.html", type:"class" },
-      { id:116, label:"com.google.android.gms.maps.GoogleMap.OnMapClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener.html", type:"class" },
-      { id:117, label:"com.google.android.gms.maps.GoogleMap.OnMapLongClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html", type:"class" },
-      { id:118, label:"com.google.android.gms.maps.GoogleMap.OnMarkerClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener.html", type:"class" },
-      { id:119, label:"com.google.android.gms.maps.GoogleMap.OnMarkerDragListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMarkerDragListener.html", type:"class" },
-      { id:120, label:"com.google.android.gms.maps.GoogleMap.OnMyLocationChangeListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener.html", type:"class" },
-      { id:121, label:"com.google.android.gms.maps.GoogleMapOptions", link:"reference/com/google/android/gms/maps/GoogleMapOptions.html", type:"class" },
-      { id:122, label:"com.google.android.gms.maps.LocationSource", link:"reference/com/google/android/gms/maps/LocationSource.html", type:"class" },
-      { id:123, label:"com.google.android.gms.maps.LocationSource.OnLocationChangedListener", link:"reference/com/google/android/gms/maps/LocationSource.OnLocationChangedListener.html", type:"class" },
-      { id:124, label:"com.google.android.gms.maps.MapFragment", link:"reference/com/google/android/gms/maps/MapFragment.html", type:"class" },
-      { id:125, label:"com.google.android.gms.maps.MapView", link:"reference/com/google/android/gms/maps/MapView.html", type:"class" },
-      { id:126, label:"com.google.android.gms.maps.MapsInitializer", link:"reference/com/google/android/gms/maps/MapsInitializer.html", type:"class" },
-      { id:127, label:"com.google.android.gms.maps.Projection", link:"reference/com/google/android/gms/maps/Projection.html", type:"class" },
-      { id:128, label:"com.google.android.gms.maps.SupportMapFragment", link:"reference/com/google/android/gms/maps/SupportMapFragment.html", type:"class" },
-      { id:129, label:"com.google.android.gms.maps.UiSettings", link:"reference/com/google/android/gms/maps/UiSettings.html", type:"class" },
-      { id:130, label:"com.google.android.gms.maps.model", link:"reference/com/google/android/gms/maps/model/package-summary.html", type:"package" },
-      { id:131, label:"com.google.android.gms.maps.model.BitmapDescriptor", link:"reference/com/google/android/gms/maps/model/BitmapDescriptor.html", type:"class" },
-      { id:132, label:"com.google.android.gms.maps.model.BitmapDescriptorFactory", link:"reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html", type:"class" },
-      { id:133, label:"com.google.android.gms.maps.model.CameraPosition", link:"reference/com/google/android/gms/maps/model/CameraPosition.html", type:"class" },
-      { id:134, label:"com.google.android.gms.maps.model.CameraPosition.Builder", link:"reference/com/google/android/gms/maps/model/CameraPosition.Builder.html", type:"class" },
-      { id:135, label:"com.google.android.gms.maps.model.Circle", link:"reference/com/google/android/gms/maps/model/Circle.html", type:"class" },
-      { id:136, label:"com.google.android.gms.maps.model.CircleOptions", link:"reference/com/google/android/gms/maps/model/CircleOptions.html", type:"class" },
-      { id:137, label:"com.google.android.gms.maps.model.GroundOverlay", link:"reference/com/google/android/gms/maps/model/GroundOverlay.html", type:"class" },
-      { id:138, label:"com.google.android.gms.maps.model.GroundOverlayOptions", link:"reference/com/google/android/gms/maps/model/GroundOverlayOptions.html", type:"class" },
-      { id:139, label:"com.google.android.gms.maps.model.LatLng", link:"reference/com/google/android/gms/maps/model/LatLng.html", type:"class" },
-      { id:140, label:"com.google.android.gms.maps.model.LatLngBounds", link:"reference/com/google/android/gms/maps/model/LatLngBounds.html", type:"class" },
-      { id:141, label:"com.google.android.gms.maps.model.LatLngBounds.Builder", link:"reference/com/google/android/gms/maps/model/LatLngBounds.Builder.html", type:"class" },
-      { id:142, label:"com.google.android.gms.maps.model.Marker", link:"reference/com/google/android/gms/maps/model/Marker.html", type:"class" },
-      { id:143, label:"com.google.android.gms.maps.model.MarkerOptions", link:"reference/com/google/android/gms/maps/model/MarkerOptions.html", type:"class" },
-      { id:144, label:"com.google.android.gms.maps.model.Polygon", link:"reference/com/google/android/gms/maps/model/Polygon.html", type:"class" },
-      { id:145, label:"com.google.android.gms.maps.model.PolygonOptions", link:"reference/com/google/android/gms/maps/model/PolygonOptions.html", type:"class" },
-      { id:146, label:"com.google.android.gms.maps.model.Polyline", link:"reference/com/google/android/gms/maps/model/Polyline.html", type:"class" },
-      { id:147, label:"com.google.android.gms.maps.model.PolylineOptions", link:"reference/com/google/android/gms/maps/model/PolylineOptions.html", type:"class" },
-      { id:148, label:"com.google.android.gms.maps.model.RuntimeRemoteException", link:"reference/com/google/android/gms/maps/model/RuntimeRemoteException.html", type:"class" },
-      { id:149, label:"com.google.android.gms.maps.model.Tile", link:"reference/com/google/android/gms/maps/model/Tile.html", type:"class" },
-      { id:150, label:"com.google.android.gms.maps.model.TileOverlay", link:"reference/com/google/android/gms/maps/model/TileOverlay.html", type:"class" },
-      { id:151, label:"com.google.android.gms.maps.model.TileOverlayOptions", link:"reference/com/google/android/gms/maps/model/TileOverlayOptions.html", type:"class" },
-      { id:152, label:"com.google.android.gms.maps.model.TileProvider", link:"reference/com/google/android/gms/maps/model/TileProvider.html", type:"class" },
-      { id:153, label:"com.google.android.gms.maps.model.UrlTileProvider", link:"reference/com/google/android/gms/maps/model/UrlTileProvider.html", type:"class" },
-      { id:154, label:"com.google.android.gms.maps.model.VisibleRegion", link:"reference/com/google/android/gms/maps/model/VisibleRegion.html", type:"class" },
-      { id:155, label:"com.google.android.gms.panorama", link:"reference/com/google/android/gms/panorama/package-summary.html", type:"package" },
-      { id:156, label:"com.google.android.gms.panorama.PanoramaClient", link:"reference/com/google/android/gms/panorama/PanoramaClient.html", type:"class" },
-      { id:157, label:"com.google.android.gms.panorama.PanoramaClient.OnPanoramaInfoLoadedListener", link:"reference/com/google/android/gms/panorama/PanoramaClient.OnPanoramaInfoLoadedListener.html", type:"class" },
-      { id:158, label:"com.google.android.gms.plus", link:"reference/com/google/android/gms/plus/package-summary.html", type:"package" },
-      { id:159, label:"com.google.android.gms.plus.GooglePlusUtil", link:"reference/com/google/android/gms/plus/GooglePlusUtil.html", type:"class" },
-      { id:160, label:"com.google.android.gms.plus.PlusClient", link:"reference/com/google/android/gms/plus/PlusClient.html", type:"class" },
-      { id:161, label:"com.google.android.gms.plus.PlusClient.Builder", link:"reference/com/google/android/gms/plus/PlusClient.Builder.html", type:"class" },
-      { id:162, label:"com.google.android.gms.plus.PlusClient.OnAccessRevokedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnAccessRevokedListener.html", type:"class" },
-      { id:163, label:"com.google.android.gms.plus.PlusClient.OnMomentsLoadedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnMomentsLoadedListener.html", type:"class" },
-      { id:164, label:"com.google.android.gms.plus.PlusClient.OnPeopleLoadedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnPeopleLoadedListener.html", type:"class" },
-      { id:165, label:"com.google.android.gms.plus.PlusClient.OnPersonLoadedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnPersonLoadedListener.html", type:"class" },
-      { id:166, label:"com.google.android.gms.plus.PlusOneButton", link:"reference/com/google/android/gms/plus/PlusOneButton.html", type:"class" },
-      { id:167, label:"com.google.android.gms.plus.PlusOneButton.OnPlusOneClickListener", link:"reference/com/google/android/gms/plus/PlusOneButton.OnPlusOneClickListener.html", type:"class" },
-      { id:168, label:"com.google.android.gms.plus.PlusShare", link:"reference/com/google/android/gms/plus/PlusShare.html", type:"class" },
-      { id:169, label:"com.google.android.gms.plus.PlusShare.Builder", link:"reference/com/google/android/gms/plus/PlusShare.Builder.html", type:"class" },
-      { id:170, label:"com.google.android.gms.plus.model.moments", link:"reference/com/google/android/gms/plus/model/moments/package-summary.html", type:"package" },
-      { id:171, label:"com.google.android.gms.plus.model.moments.ItemScope", link:"reference/com/google/android/gms/plus/model/moments/ItemScope.html", type:"class" },
-      { id:172, label:"com.google.android.gms.plus.model.moments.ItemScope.Builder", link:"reference/com/google/android/gms/plus/model/moments/ItemScope.Builder.html", type:"class" },
-      { id:173, label:"com.google.android.gms.plus.model.moments.Moment", link:"reference/com/google/android/gms/plus/model/moments/Moment.html", type:"class" },
-      { id:174, label:"com.google.android.gms.plus.model.moments.Moment.Builder", link:"reference/com/google/android/gms/plus/model/moments/Moment.Builder.html", type:"class" },
-      { id:175, label:"com.google.android.gms.plus.model.moments.MomentBuffer", link:"reference/com/google/android/gms/plus/model/moments/MomentBuffer.html", type:"class" },
-      { id:176, label:"com.google.android.gms.plus.model.people", link:"reference/com/google/android/gms/plus/model/people/package-summary.html", type:"package" },
-      { id:177, label:"com.google.android.gms.plus.model.people.Person", link:"reference/com/google/android/gms/plus/model/people/Person.html", type:"class" },
-      { id:178, label:"com.google.android.gms.plus.model.people.Person.AgeRange", link:"reference/com/google/android/gms/plus/model/people/Person.AgeRange.html", type:"class" },
-      { id:179, label:"com.google.android.gms.plus.model.people.Person.Collection", link:"reference/com/google/android/gms/plus/model/people/Person.Collection.html", type:"class" },
-      { id:180, label:"com.google.android.gms.plus.model.people.Person.Cover", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.html", type:"class" },
-      { id:181, label:"com.google.android.gms.plus.model.people.Person.Cover.CoverInfo", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.CoverInfo.html", type:"class" },
-      { id:182, label:"com.google.android.gms.plus.model.people.Person.Cover.CoverPhoto", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.CoverPhoto.html", type:"class" },
-      { id:183, label:"com.google.android.gms.plus.model.people.Person.Cover.Layout", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.Layout.html", type:"class" },
-      { id:184, label:"com.google.android.gms.plus.model.people.Person.Emails", link:"reference/com/google/android/gms/plus/model/people/Person.Emails.html", type:"class" },
-      { id:185, label:"com.google.android.gms.plus.model.people.Person.Emails.Type", link:"reference/com/google/android/gms/plus/model/people/Person.Emails.Type.html", type:"class" },
-      { id:186, label:"com.google.android.gms.plus.model.people.Person.Gender", link:"reference/com/google/android/gms/plus/model/people/Person.Gender.html", type:"class" },
-      { id:187, label:"com.google.android.gms.plus.model.people.Person.Image", link:"reference/com/google/android/gms/plus/model/people/Person.Image.html", type:"class" },
-      { id:188, label:"com.google.android.gms.plus.model.people.Person.Name", link:"reference/com/google/android/gms/plus/model/people/Person.Name.html", type:"class" },
-      { id:189, label:"com.google.android.gms.plus.model.people.Person.ObjectType", link:"reference/com/google/android/gms/plus/model/people/Person.ObjectType.html", type:"class" },
-      { id:190, label:"com.google.android.gms.plus.model.people.Person.OrderBy", link:"reference/com/google/android/gms/plus/model/people/Person.OrderBy.html", type:"class" },
-      { id:191, label:"com.google.android.gms.plus.model.people.Person.Organizations", link:"reference/com/google/android/gms/plus/model/people/Person.Organizations.html", type:"class" },
-      { id:192, label:"com.google.android.gms.plus.model.people.Person.Organizations.Type", link:"reference/com/google/android/gms/plus/model/people/Person.Organizations.Type.html", type:"class" },
-      { id:193, label:"com.google.android.gms.plus.model.people.Person.PlacesLived", link:"reference/com/google/android/gms/plus/model/people/Person.PlacesLived.html", type:"class" },
-      { id:194, label:"com.google.android.gms.plus.model.people.Person.RelationshipStatus", link:"reference/com/google/android/gms/plus/model/people/Person.RelationshipStatus.html", type:"class" },
-      { id:195, label:"com.google.android.gms.plus.model.people.Person.Urls", link:"reference/com/google/android/gms/plus/model/people/Person.Urls.html", type:"class" },
-      { id:196, label:"com.google.android.gms.plus.model.people.Person.Urls.Type", link:"reference/com/google/android/gms/plus/model/people/Person.Urls.Type.html", type:"class" },
-      { id:197, label:"com.google.android.gms.plus.model.people.PersonBuffer", link:"reference/com/google/android/gms/plus/model/people/PersonBuffer.html", type:"class" }
+      { id:0, label:"com.google.android.gms", link:"reference/com/google/android/gms/package-summary.html", type:"package", deprecated:"false" },
+      { id:1, label:"com.google.android.gms.R", link:"reference/com/google/android/gms/R.html", type:"class", deprecated:"false" },
+      { id:2, label:"com.google.android.gms.R.attr", link:"reference/com/google/android/gms/R.attr.html", type:"class", deprecated:"false" },
+      { id:3, label:"com.google.android.gms.R.color", link:"reference/com/google/android/gms/R.color.html", type:"class", deprecated:"false" },
+      { id:4, label:"com.google.android.gms.R.drawable", link:"reference/com/google/android/gms/R.drawable.html", type:"class", deprecated:"false" },
+      { id:5, label:"com.google.android.gms.R.id", link:"reference/com/google/android/gms/R.id.html", type:"class", deprecated:"false" },
+      { id:6, label:"com.google.android.gms.R.string", link:"reference/com/google/android/gms/R.string.html", type:"class", deprecated:"false" },
+      { id:7, label:"com.google.android.gms.R.styleable", link:"reference/com/google/android/gms/R.styleable.html", type:"class", deprecated:"false" },
+      { id:8, label:"com.google.android.gms.appstate", link:"reference/com/google/android/gms/appstate/package-summary.html", type:"package", deprecated:"false" },
+      { id:9, label:"com.google.android.gms.appstate.AppState", link:"reference/com/google/android/gms/appstate/AppState.html", type:"class", deprecated:"false" },
+      { id:10, label:"com.google.android.gms.appstate.AppStateBuffer", link:"reference/com/google/android/gms/appstate/AppStateBuffer.html", type:"class", deprecated:"false" },
+      { id:11, label:"com.google.android.gms.appstate.AppStateClient", link:"reference/com/google/android/gms/appstate/AppStateClient.html", type:"class", deprecated:"false" },
+      { id:12, label:"com.google.android.gms.appstate.AppStateClient.Builder", link:"reference/com/google/android/gms/appstate/AppStateClient.Builder.html", type:"class", deprecated:"false" },
+      { id:13, label:"com.google.android.gms.appstate.OnSignOutCompleteListener", link:"reference/com/google/android/gms/appstate/OnSignOutCompleteListener.html", type:"class", deprecated:"false" },
+      { id:14, label:"com.google.android.gms.appstate.OnStateDeletedListener", link:"reference/com/google/android/gms/appstate/OnStateDeletedListener.html", type:"class", deprecated:"false" },
+      { id:15, label:"com.google.android.gms.appstate.OnStateListLoadedListener", link:"reference/com/google/android/gms/appstate/OnStateListLoadedListener.html", type:"class", deprecated:"false" },
+      { id:16, label:"com.google.android.gms.appstate.OnStateLoadedListener", link:"reference/com/google/android/gms/appstate/OnStateLoadedListener.html", type:"class", deprecated:"false" },
+      { id:17, label:"com.google.android.gms.auth", link:"reference/com/google/android/gms/auth/package-summary.html", type:"package", deprecated:"false" },
+      { id:18, label:"com.google.android.gms.auth.GoogleAuthException", link:"reference/com/google/android/gms/auth/GoogleAuthException.html", type:"class", deprecated:"false" },
+      { id:19, label:"com.google.android.gms.auth.GoogleAuthUtil", link:"reference/com/google/android/gms/auth/GoogleAuthUtil.html", type:"class", deprecated:"false" },
+      { id:20, label:"com.google.android.gms.auth.GooglePlayServicesAvailabilityException", link:"reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html", type:"class", deprecated:"false" },
+      { id:21, label:"com.google.android.gms.auth.UserRecoverableAuthException", link:"reference/com/google/android/gms/auth/UserRecoverableAuthException.html", type:"class", deprecated:"false" },
+      { id:22, label:"com.google.android.gms.auth.UserRecoverableNotifiedException", link:"reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html", type:"class", deprecated:"false" },
+      { id:23, label:"com.google.android.gms.common", link:"reference/com/google/android/gms/common/package-summary.html", type:"package", deprecated:"false" },
+      { id:24, label:"com.google.android.gms.common.AccountPicker", link:"reference/com/google/android/gms/common/AccountPicker.html", type:"class", deprecated:"false" },
+      { id:25, label:"com.google.android.gms.common.ConnectionResult", link:"reference/com/google/android/gms/common/ConnectionResult.html", type:"class", deprecated:"false" },
+      { id:26, label:"com.google.android.gms.common.GooglePlayServicesClient", link:"reference/com/google/android/gms/common/GooglePlayServicesClient.html", type:"class", deprecated:"false" },
+      { id:27, label:"com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks", link:"reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html", type:"class", deprecated:"false" },
+      { id:28, label:"com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener", link:"reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html", type:"class", deprecated:"false" },
+      { id:29, label:"com.google.android.gms.common.GooglePlayServicesNotAvailableException", link:"reference/com/google/android/gms/common/GooglePlayServicesNotAvailableException.html", type:"class", deprecated:"false" },
+      { id:30, label:"com.google.android.gms.common.GooglePlayServicesUtil", link:"reference/com/google/android/gms/common/GooglePlayServicesUtil.html", type:"class", deprecated:"false" },
+      { id:31, label:"com.google.android.gms.common.Scopes", link:"reference/com/google/android/gms/common/Scopes.html", type:"class", deprecated:"false" },
+      { id:32, label:"com.google.android.gms.common.SignInButton", link:"reference/com/google/android/gms/common/SignInButton.html", type:"class", deprecated:"false" },
+      { id:33, label:"com.google.android.gms.common.data", link:"reference/com/google/android/gms/common/data/package-summary.html", type:"package", deprecated:"false" },
+      { id:34, label:"com.google.android.gms.common.data.DataBuffer", link:"reference/com/google/android/gms/common/data/DataBuffer.html", type:"class", deprecated:"false" },
+      { id:35, label:"com.google.android.gms.common.data.DataBufferUtils", link:"reference/com/google/android/gms/common/data/DataBufferUtils.html", type:"class", deprecated:"false" },
+      { id:36, label:"com.google.android.gms.common.data.Freezable", link:"reference/com/google/android/gms/common/data/Freezable.html", type:"class", deprecated:"false" },
+      { id:37, label:"com.google.android.gms.common.images", link:"reference/com/google/android/gms/common/images/package-summary.html", type:"package", deprecated:"false" },
+      { id:38, label:"com.google.android.gms.common.images.ImageManager", link:"reference/com/google/android/gms/common/images/ImageManager.html", type:"class", deprecated:"false" },
+      { id:39, label:"com.google.android.gms.common.images.ImageManager.OnImageLoadedListener", link:"reference/com/google/android/gms/common/images/ImageManager.OnImageLoadedListener.html", type:"class", deprecated:"false" },
+      { id:40, label:"com.google.android.gms.games", link:"reference/com/google/android/gms/games/package-summary.html", type:"package", deprecated:"false" },
+      { id:41, label:"com.google.android.gms.games.Game", link:"reference/com/google/android/gms/games/Game.html", type:"class", deprecated:"false" },
+      { id:42, label:"com.google.android.gms.games.GameBuffer", link:"reference/com/google/android/gms/games/GameBuffer.html", type:"class", deprecated:"false" },
+      { id:43, label:"com.google.android.gms.games.GameEntity", link:"reference/com/google/android/gms/games/GameEntity.html", type:"class", deprecated:"false" },
+      { id:44, label:"com.google.android.gms.games.GamesActivityResultCodes", link:"reference/com/google/android/gms/games/GamesActivityResultCodes.html", type:"class", deprecated:"false" },
+      { id:45, label:"com.google.android.gms.games.GamesClient", link:"reference/com/google/android/gms/games/GamesClient.html", type:"class", deprecated:"false" },
+      { id:46, label:"com.google.android.gms.games.GamesClient.Builder", link:"reference/com/google/android/gms/games/GamesClient.Builder.html", type:"class", deprecated:"false" },
+      { id:47, label:"com.google.android.gms.games.OnGamesLoadedListener", link:"reference/com/google/android/gms/games/OnGamesLoadedListener.html", type:"class", deprecated:"false" },
+      { id:48, label:"com.google.android.gms.games.OnPlayersLoadedListener", link:"reference/com/google/android/gms/games/OnPlayersLoadedListener.html", type:"class", deprecated:"false" },
+      { id:49, label:"com.google.android.gms.games.OnSignOutCompleteListener", link:"reference/com/google/android/gms/games/OnSignOutCompleteListener.html", type:"class", deprecated:"false" },
+      { id:50, label:"com.google.android.gms.games.PageDirection", link:"reference/com/google/android/gms/games/PageDirection.html", type:"class", deprecated:"false" },
+      { id:51, label:"com.google.android.gms.games.Player", link:"reference/com/google/android/gms/games/Player.html", type:"class", deprecated:"false" },
+      { id:52, label:"com.google.android.gms.games.PlayerBuffer", link:"reference/com/google/android/gms/games/PlayerBuffer.html", type:"class", deprecated:"false" },
+      { id:53, label:"com.google.android.gms.games.PlayerEntity", link:"reference/com/google/android/gms/games/PlayerEntity.html", type:"class", deprecated:"false" },
+      { id:54, label:"com.google.android.gms.games.RealTimeSocket", link:"reference/com/google/android/gms/games/RealTimeSocket.html", type:"class", deprecated:"false" },
+      { id:55, label:"com.google.android.gms.games.achievement", link:"reference/com/google/android/gms/games/achievement/package-summary.html", type:"package", deprecated:"false" },
+      { id:56, label:"com.google.android.gms.games.achievement.Achievement", link:"reference/com/google/android/gms/games/achievement/Achievement.html", type:"class", deprecated:"false" },
+      { id:57, label:"com.google.android.gms.games.achievement.AchievementBuffer", link:"reference/com/google/android/gms/games/achievement/AchievementBuffer.html", type:"class", deprecated:"false" },
+      { id:58, label:"com.google.android.gms.games.achievement.OnAchievementUpdatedListener", link:"reference/com/google/android/gms/games/achievement/OnAchievementUpdatedListener.html", type:"class", deprecated:"false" },
+      { id:59, label:"com.google.android.gms.games.achievement.OnAchievementsLoadedListener", link:"reference/com/google/android/gms/games/achievement/OnAchievementsLoadedListener.html", type:"class", deprecated:"false" },
+      { id:60, label:"com.google.android.gms.games.leaderboard", link:"reference/com/google/android/gms/games/leaderboard/package-summary.html", type:"package", deprecated:"false" },
+      { id:61, label:"com.google.android.gms.games.leaderboard.Leaderboard", link:"reference/com/google/android/gms/games/leaderboard/Leaderboard.html", type:"class", deprecated:"false" },
+      { id:62, label:"com.google.android.gms.games.leaderboard.LeaderboardBuffer", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardBuffer.html", type:"class", deprecated:"false" },
+      { id:63, label:"com.google.android.gms.games.leaderboard.LeaderboardScore", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardScore.html", type:"class", deprecated:"false" },
+      { id:64, label:"com.google.android.gms.games.leaderboard.LeaderboardScoreBuffer", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardScoreBuffer.html", type:"class", deprecated:"false" },
+      { id:65, label:"com.google.android.gms.games.leaderboard.LeaderboardVariant", link:"reference/com/google/android/gms/games/leaderboard/LeaderboardVariant.html", type:"class", deprecated:"false" },
+      { id:66, label:"com.google.android.gms.games.leaderboard.OnLeaderboardMetadataLoadedListener", link:"reference/com/google/android/gms/games/leaderboard/OnLeaderboardMetadataLoadedListener.html", type:"class", deprecated:"false" },
+      { id:67, label:"com.google.android.gms.games.leaderboard.OnLeaderboardScoresLoadedListener", link:"reference/com/google/android/gms/games/leaderboard/OnLeaderboardScoresLoadedListener.html", type:"class", deprecated:"false" },
+      { id:68, label:"com.google.android.gms.games.leaderboard.OnScoreSubmittedListener", link:"reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html", type:"class", deprecated:"false" },
+      { id:69, label:"com.google.android.gms.games.leaderboard.SubmitScoreResult", link:"reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.html", type:"class", deprecated:"false" },
+      { id:70, label:"com.google.android.gms.games.leaderboard.SubmitScoreResult.Result", link:"reference/com/google/android/gms/games/leaderboard/SubmitScoreResult.Result.html", type:"class", deprecated:"false" },
+      { id:71, label:"com.google.android.gms.games.multiplayer", link:"reference/com/google/android/gms/games/multiplayer/package-summary.html", type:"package", deprecated:"false" },
+      { id:72, label:"com.google.android.gms.games.multiplayer.Invitation", link:"reference/com/google/android/gms/games/multiplayer/Invitation.html", type:"class", deprecated:"false" },
+      { id:73, label:"com.google.android.gms.games.multiplayer.InvitationBuffer", link:"reference/com/google/android/gms/games/multiplayer/InvitationBuffer.html", type:"class", deprecated:"false" },
+      { id:74, label:"com.google.android.gms.games.multiplayer.InvitationEntity", link:"reference/com/google/android/gms/games/multiplayer/InvitationEntity.html", type:"class", deprecated:"false" },
+      { id:75, label:"com.google.android.gms.games.multiplayer.OnInvitationReceivedListener", link:"reference/com/google/android/gms/games/multiplayer/OnInvitationReceivedListener.html", type:"class", deprecated:"false" },
+      { id:76, label:"com.google.android.gms.games.multiplayer.OnInvitationsLoadedListener", link:"reference/com/google/android/gms/games/multiplayer/OnInvitationsLoadedListener.html", type:"class", deprecated:"false" },
+      { id:77, label:"com.google.android.gms.games.multiplayer.Participant", link:"reference/com/google/android/gms/games/multiplayer/Participant.html", type:"class", deprecated:"false" },
+      { id:78, label:"com.google.android.gms.games.multiplayer.ParticipantBuffer", link:"reference/com/google/android/gms/games/multiplayer/ParticipantBuffer.html", type:"class", deprecated:"false" },
+      { id:79, label:"com.google.android.gms.games.multiplayer.ParticipantEntity", link:"reference/com/google/android/gms/games/multiplayer/ParticipantEntity.html", type:"class", deprecated:"false" },
+      { id:80, label:"com.google.android.gms.games.multiplayer.ParticipantUtils", link:"reference/com/google/android/gms/games/multiplayer/ParticipantUtils.html", type:"class", deprecated:"false" },
+      { id:81, label:"com.google.android.gms.games.multiplayer.Participatable", link:"reference/com/google/android/gms/games/multiplayer/Participatable.html", type:"class", deprecated:"false" },
+      { id:82, label:"com.google.android.gms.games.multiplayer.realtime", link:"reference/com/google/android/gms/games/multiplayer/realtime/package-summary.html", type:"package", deprecated:"false" },
+      { id:83, label:"com.google.android.gms.games.multiplayer.realtime.RealTimeMessage", link:"reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessage.html", type:"class", deprecated:"false" },
+      { id:84, label:"com.google.android.gms.games.multiplayer.realtime.RealTimeMessageReceivedListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMessageReceivedListener.html", type:"class", deprecated:"false" },
+      { id:85, label:"com.google.android.gms.games.multiplayer.realtime.RealTimeReliableMessageSentListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RealTimeReliableMessageSentListener.html", type:"class", deprecated:"false" },
+      { id:86, label:"com.google.android.gms.games.multiplayer.realtime.Room", link:"reference/com/google/android/gms/games/multiplayer/realtime/Room.html", type:"class", deprecated:"false" },
+      { id:87, label:"com.google.android.gms.games.multiplayer.realtime.RoomConfig", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.html", type:"class", deprecated:"false" },
+      { id:88, label:"com.google.android.gms.games.multiplayer.realtime.RoomConfig.Builder", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomConfig.Builder.html", type:"class", deprecated:"false" },
+      { id:89, label:"com.google.android.gms.games.multiplayer.realtime.RoomEntity", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomEntity.html", type:"class", deprecated:"false" },
+      { id:90, label:"com.google.android.gms.games.multiplayer.realtime.RoomStatusUpdateListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html", type:"class", deprecated:"false" },
+      { id:91, label:"com.google.android.gms.games.multiplayer.realtime.RoomUpdateListener", link:"reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html", type:"class", deprecated:"false" },
+      { id:92, label:"com.google.android.gms.gcm", link:"reference/com/google/android/gms/gcm/package-summary.html", type:"package", deprecated:"false" },
+      { id:93, label:"com.google.android.gms.gcm.GoogleCloudMessaging", link:"reference/com/google/android/gms/gcm/GoogleCloudMessaging.html", type:"class", deprecated:"false" },
+      { id:94, label:"com.google.android.gms.location", link:"reference/com/google/android/gms/location/package-summary.html", type:"package", deprecated:"false" },
+      { id:95, label:"com.google.android.gms.location.ActivityRecognitionClient", link:"reference/com/google/android/gms/location/ActivityRecognitionClient.html", type:"class", deprecated:"false" },
+      { id:96, label:"com.google.android.gms.location.ActivityRecognitionResult", link:"reference/com/google/android/gms/location/ActivityRecognitionResult.html", type:"class", deprecated:"false" },
+      { id:97, label:"com.google.android.gms.location.DetectedActivity", link:"reference/com/google/android/gms/location/DetectedActivity.html", type:"class", deprecated:"false" },
+      { id:98, label:"com.google.android.gms.location.Geofence", link:"reference/com/google/android/gms/location/Geofence.html", type:"class", deprecated:"false" },
+      { id:99, label:"com.google.android.gms.location.Geofence.Builder", link:"reference/com/google/android/gms/location/Geofence.Builder.html", type:"class", deprecated:"false" },
+      { id:100, label:"com.google.android.gms.location.LocationClient", link:"reference/com/google/android/gms/location/LocationClient.html", type:"class", deprecated:"false" },
+      { id:101, label:"com.google.android.gms.location.LocationClient.OnAddGeofencesResultListener", link:"reference/com/google/android/gms/location/LocationClient.OnAddGeofencesResultListener.html", type:"class", deprecated:"false" },
+      { id:102, label:"com.google.android.gms.location.LocationClient.OnRemoveGeofencesResultListener", link:"reference/com/google/android/gms/location/LocationClient.OnRemoveGeofencesResultListener.html", type:"class", deprecated:"false" },
+      { id:103, label:"com.google.android.gms.location.LocationListener", link:"reference/com/google/android/gms/location/LocationListener.html", type:"class", deprecated:"false" },
+      { id:104, label:"com.google.android.gms.location.LocationRequest", link:"reference/com/google/android/gms/location/LocationRequest.html", type:"class", deprecated:"false" },
+      { id:105, label:"com.google.android.gms.location.LocationStatusCodes", link:"reference/com/google/android/gms/location/LocationStatusCodes.html", type:"class", deprecated:"false" },
+      { id:106, label:"com.google.android.gms.maps", link:"reference/com/google/android/gms/maps/package-summary.html", type:"package", deprecated:"false" },
+      { id:107, label:"com.google.android.gms.maps.CameraUpdate", link:"reference/com/google/android/gms/maps/CameraUpdate.html", type:"class", deprecated:"false" },
+      { id:108, label:"com.google.android.gms.maps.CameraUpdateFactory", link:"reference/com/google/android/gms/maps/CameraUpdateFactory.html", type:"class", deprecated:"false" },
+      { id:109, label:"com.google.android.gms.maps.GoogleMap", link:"reference/com/google/android/gms/maps/GoogleMap.html", type:"class", deprecated:"false" },
+      { id:110, label:"com.google.android.gms.maps.GoogleMap.CancelableCallback", link:"reference/com/google/android/gms/maps/GoogleMap.CancelableCallback.html", type:"class", deprecated:"false" },
+      { id:111, label:"com.google.android.gms.maps.GoogleMap.InfoWindowAdapter", link:"reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter.html", type:"class", deprecated:"false" },
+      { id:112, label:"com.google.android.gms.maps.GoogleMap.OnCameraChangeListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener.html", type:"class", deprecated:"false" },
+      { id:113, label:"com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnInfoWindowClickListener.html", type:"class", deprecated:"false" },
+      { id:114, label:"com.google.android.gms.maps.GoogleMap.OnMapClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener.html", type:"class", deprecated:"false" },
+      { id:115, label:"com.google.android.gms.maps.GoogleMap.OnMapLongClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html", type:"class", deprecated:"false" },
+      { id:116, label:"com.google.android.gms.maps.GoogleMap.OnMarkerClickListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener.html", type:"class", deprecated:"false" },
+      { id:117, label:"com.google.android.gms.maps.GoogleMap.OnMarkerDragListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMarkerDragListener.html", type:"class", deprecated:"false" },
+      { id:118, label:"com.google.android.gms.maps.GoogleMap.OnMyLocationChangeListener", link:"reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener.html", type:"class", deprecated:"true" },
+      { id:119, label:"com.google.android.gms.maps.GoogleMapOptions", link:"reference/com/google/android/gms/maps/GoogleMapOptions.html", type:"class", deprecated:"false" },
+      { id:120, label:"com.google.android.gms.maps.LocationSource", link:"reference/com/google/android/gms/maps/LocationSource.html", type:"class", deprecated:"false" },
+      { id:121, label:"com.google.android.gms.maps.LocationSource.OnLocationChangedListener", link:"reference/com/google/android/gms/maps/LocationSource.OnLocationChangedListener.html", type:"class", deprecated:"false" },
+      { id:122, label:"com.google.android.gms.maps.MapFragment", link:"reference/com/google/android/gms/maps/MapFragment.html", type:"class", deprecated:"false" },
+      { id:123, label:"com.google.android.gms.maps.MapView", link:"reference/com/google/android/gms/maps/MapView.html", type:"class", deprecated:"false" },
+      { id:124, label:"com.google.android.gms.maps.MapsInitializer", link:"reference/com/google/android/gms/maps/MapsInitializer.html", type:"class", deprecated:"false" },
+      { id:125, label:"com.google.android.gms.maps.Projection", link:"reference/com/google/android/gms/maps/Projection.html", type:"class", deprecated:"false" },
+      { id:126, label:"com.google.android.gms.maps.SupportMapFragment", link:"reference/com/google/android/gms/maps/SupportMapFragment.html", type:"class", deprecated:"false" },
+      { id:127, label:"com.google.android.gms.maps.UiSettings", link:"reference/com/google/android/gms/maps/UiSettings.html", type:"class", deprecated:"false" },
+      { id:128, label:"com.google.android.gms.maps.model", link:"reference/com/google/android/gms/maps/model/package-summary.html", type:"package", deprecated:"false" },
+      { id:129, label:"com.google.android.gms.maps.model.BitmapDescriptor", link:"reference/com/google/android/gms/maps/model/BitmapDescriptor.html", type:"class", deprecated:"false" },
+      { id:130, label:"com.google.android.gms.maps.model.BitmapDescriptorFactory", link:"reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html", type:"class", deprecated:"false" },
+      { id:131, label:"com.google.android.gms.maps.model.CameraPosition", link:"reference/com/google/android/gms/maps/model/CameraPosition.html", type:"class", deprecated:"false" },
+      { id:132, label:"com.google.android.gms.maps.model.CameraPosition.Builder", link:"reference/com/google/android/gms/maps/model/CameraPosition.Builder.html", type:"class", deprecated:"false" },
+      { id:133, label:"com.google.android.gms.maps.model.Circle", link:"reference/com/google/android/gms/maps/model/Circle.html", type:"class", deprecated:"false" },
+      { id:134, label:"com.google.android.gms.maps.model.CircleOptions", link:"reference/com/google/android/gms/maps/model/CircleOptions.html", type:"class", deprecated:"false" },
+      { id:135, label:"com.google.android.gms.maps.model.GroundOverlay", link:"reference/com/google/android/gms/maps/model/GroundOverlay.html", type:"class", deprecated:"false" },
+      { id:136, label:"com.google.android.gms.maps.model.GroundOverlayOptions", link:"reference/com/google/android/gms/maps/model/GroundOverlayOptions.html", type:"class", deprecated:"false" },
+      { id:137, label:"com.google.android.gms.maps.model.LatLng", link:"reference/com/google/android/gms/maps/model/LatLng.html", type:"class", deprecated:"false" },
+      { id:138, label:"com.google.android.gms.maps.model.LatLngBounds", link:"reference/com/google/android/gms/maps/model/LatLngBounds.html", type:"class", deprecated:"false" },
+      { id:139, label:"com.google.android.gms.maps.model.LatLngBounds.Builder", link:"reference/com/google/android/gms/maps/model/LatLngBounds.Builder.html", type:"class", deprecated:"false" },
+      { id:140, label:"com.google.android.gms.maps.model.Marker", link:"reference/com/google/android/gms/maps/model/Marker.html", type:"class", deprecated:"false" },
+      { id:141, label:"com.google.android.gms.maps.model.MarkerOptions", link:"reference/com/google/android/gms/maps/model/MarkerOptions.html", type:"class", deprecated:"false" },
+      { id:142, label:"com.google.android.gms.maps.model.Polygon", link:"reference/com/google/android/gms/maps/model/Polygon.html", type:"class", deprecated:"false" },
+      { id:143, label:"com.google.android.gms.maps.model.PolygonOptions", link:"reference/com/google/android/gms/maps/model/PolygonOptions.html", type:"class", deprecated:"false" },
+      { id:144, label:"com.google.android.gms.maps.model.Polyline", link:"reference/com/google/android/gms/maps/model/Polyline.html", type:"class", deprecated:"false" },
+      { id:145, label:"com.google.android.gms.maps.model.PolylineOptions", link:"reference/com/google/android/gms/maps/model/PolylineOptions.html", type:"class", deprecated:"false" },
+      { id:146, label:"com.google.android.gms.maps.model.RuntimeRemoteException", link:"reference/com/google/android/gms/maps/model/RuntimeRemoteException.html", type:"class", deprecated:"false" },
+      { id:147, label:"com.google.android.gms.maps.model.Tile", link:"reference/com/google/android/gms/maps/model/Tile.html", type:"class", deprecated:"false" },
+      { id:148, label:"com.google.android.gms.maps.model.TileOverlay", link:"reference/com/google/android/gms/maps/model/TileOverlay.html", type:"class", deprecated:"false" },
+      { id:149, label:"com.google.android.gms.maps.model.TileOverlayOptions", link:"reference/com/google/android/gms/maps/model/TileOverlayOptions.html", type:"class", deprecated:"false" },
+      { id:150, label:"com.google.android.gms.maps.model.TileProvider", link:"reference/com/google/android/gms/maps/model/TileProvider.html", type:"class", deprecated:"false" },
+      { id:151, label:"com.google.android.gms.maps.model.UrlTileProvider", link:"reference/com/google/android/gms/maps/model/UrlTileProvider.html", type:"class", deprecated:"false" },
+      { id:152, label:"com.google.android.gms.maps.model.VisibleRegion", link:"reference/com/google/android/gms/maps/model/VisibleRegion.html", type:"class", deprecated:"false" },
+      { id:153, label:"com.google.android.gms.panorama", link:"reference/com/google/android/gms/panorama/package-summary.html", type:"package", deprecated:"false" },
+      { id:154, label:"com.google.android.gms.panorama.PanoramaClient", link:"reference/com/google/android/gms/panorama/PanoramaClient.html", type:"class", deprecated:"false" },
+      { id:155, label:"com.google.android.gms.panorama.PanoramaClient.OnPanoramaInfoLoadedListener", link:"reference/com/google/android/gms/panorama/PanoramaClient.OnPanoramaInfoLoadedListener.html", type:"class", deprecated:"false" },
+      { id:156, label:"com.google.android.gms.plus", link:"reference/com/google/android/gms/plus/package-summary.html", type:"package", deprecated:"false" },
+      { id:157, label:"com.google.android.gms.plus.GooglePlusUtil", link:"reference/com/google/android/gms/plus/GooglePlusUtil.html", type:"class", deprecated:"false" },
+      { id:158, label:"com.google.android.gms.plus.PlusClient", link:"reference/com/google/android/gms/plus/PlusClient.html", type:"class", deprecated:"false" },
+      { id:159, label:"com.google.android.gms.plus.PlusClient.Builder", link:"reference/com/google/android/gms/plus/PlusClient.Builder.html", type:"class", deprecated:"false" },
+      { id:160, label:"com.google.android.gms.plus.PlusClient.OnAccessRevokedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnAccessRevokedListener.html", type:"class", deprecated:"false" },
+      { id:161, label:"com.google.android.gms.plus.PlusClient.OnMomentsLoadedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnMomentsLoadedListener.html", type:"class", deprecated:"false" },
+      { id:162, label:"com.google.android.gms.plus.PlusClient.OnPeopleLoadedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnPeopleLoadedListener.html", type:"class", deprecated:"false" },
+      { id:163, label:"com.google.android.gms.plus.PlusClient.OnPersonLoadedListener", link:"reference/com/google/android/gms/plus/PlusClient.OnPersonLoadedListener.html", type:"class", deprecated:"false" },
+      { id:164, label:"com.google.android.gms.plus.PlusOneButton", link:"reference/com/google/android/gms/plus/PlusOneButton.html", type:"class", deprecated:"false" },
+      { id:165, label:"com.google.android.gms.plus.PlusOneButton.OnPlusOneClickListener", link:"reference/com/google/android/gms/plus/PlusOneButton.OnPlusOneClickListener.html", type:"class", deprecated:"false" },
+      { id:166, label:"com.google.android.gms.plus.PlusShare", link:"reference/com/google/android/gms/plus/PlusShare.html", type:"class", deprecated:"false" },
+      { id:167, label:"com.google.android.gms.plus.PlusShare.Builder", link:"reference/com/google/android/gms/plus/PlusShare.Builder.html", type:"class", deprecated:"false" },
+      { id:168, label:"com.google.android.gms.plus.model.moments", link:"reference/com/google/android/gms/plus/model/moments/package-summary.html", type:"package", deprecated:"false" },
+      { id:169, label:"com.google.android.gms.plus.model.moments.ItemScope", link:"reference/com/google/android/gms/plus/model/moments/ItemScope.html", type:"class", deprecated:"false" },
+      { id:170, label:"com.google.android.gms.plus.model.moments.ItemScope.Builder", link:"reference/com/google/android/gms/plus/model/moments/ItemScope.Builder.html", type:"class", deprecated:"false" },
+      { id:171, label:"com.google.android.gms.plus.model.moments.Moment", link:"reference/com/google/android/gms/plus/model/moments/Moment.html", type:"class", deprecated:"false" },
+      { id:172, label:"com.google.android.gms.plus.model.moments.Moment.Builder", link:"reference/com/google/android/gms/plus/model/moments/Moment.Builder.html", type:"class", deprecated:"false" },
+      { id:173, label:"com.google.android.gms.plus.model.moments.MomentBuffer", link:"reference/com/google/android/gms/plus/model/moments/MomentBuffer.html", type:"class", deprecated:"false" },
+      { id:174, label:"com.google.android.gms.plus.model.people", link:"reference/com/google/android/gms/plus/model/people/package-summary.html", type:"package", deprecated:"false" },
+      { id:175, label:"com.google.android.gms.plus.model.people.Person", link:"reference/com/google/android/gms/plus/model/people/Person.html", type:"class", deprecated:"false" },
+      { id:176, label:"com.google.android.gms.plus.model.people.Person.AgeRange", link:"reference/com/google/android/gms/plus/model/people/Person.AgeRange.html", type:"class", deprecated:"false" },
+      { id:177, label:"com.google.android.gms.plus.model.people.Person.Collection", link:"reference/com/google/android/gms/plus/model/people/Person.Collection.html", type:"class", deprecated:"false" },
+      { id:178, label:"com.google.android.gms.plus.model.people.Person.Cover", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.html", type:"class", deprecated:"false" },
+      { id:179, label:"com.google.android.gms.plus.model.people.Person.Cover.CoverInfo", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.CoverInfo.html", type:"class", deprecated:"false" },
+      { id:180, label:"com.google.android.gms.plus.model.people.Person.Cover.CoverPhoto", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.CoverPhoto.html", type:"class", deprecated:"false" },
+      { id:181, label:"com.google.android.gms.plus.model.people.Person.Cover.Layout", link:"reference/com/google/android/gms/plus/model/people/Person.Cover.Layout.html", type:"class", deprecated:"false" },
+      { id:182, label:"com.google.android.gms.plus.model.people.Person.Emails", link:"reference/com/google/android/gms/plus/model/people/Person.Emails.html", type:"class", deprecated:"false" },
+      { id:183, label:"com.google.android.gms.plus.model.people.Person.Emails.Type", link:"reference/com/google/android/gms/plus/model/people/Person.Emails.Type.html", type:"class", deprecated:"false" },
+      { id:184, label:"com.google.android.gms.plus.model.people.Person.Gender", link:"reference/com/google/android/gms/plus/model/people/Person.Gender.html", type:"class", deprecated:"false" },
+      { id:185, label:"com.google.android.gms.plus.model.people.Person.Image", link:"reference/com/google/android/gms/plus/model/people/Person.Image.html", type:"class", deprecated:"false" },
+      { id:186, label:"com.google.android.gms.plus.model.people.Person.Name", link:"reference/com/google/android/gms/plus/model/people/Person.Name.html", type:"class", deprecated:"false" },
+      { id:187, label:"com.google.android.gms.plus.model.people.Person.ObjectType", link:"reference/com/google/android/gms/plus/model/people/Person.ObjectType.html", type:"class", deprecated:"false" },
+      { id:188, label:"com.google.android.gms.plus.model.people.Person.OrderBy", link:"reference/com/google/android/gms/plus/model/people/Person.OrderBy.html", type:"class", deprecated:"false" },
+      { id:189, label:"com.google.android.gms.plus.model.people.Person.Organizations", link:"reference/com/google/android/gms/plus/model/people/Person.Organizations.html", type:"class", deprecated:"false" },
+      { id:190, label:"com.google.android.gms.plus.model.people.Person.Organizations.Type", link:"reference/com/google/android/gms/plus/model/people/Person.Organizations.Type.html", type:"class", deprecated:"false" },
+      { id:191, label:"com.google.android.gms.plus.model.people.Person.PlacesLived", link:"reference/com/google/android/gms/plus/model/people/Person.PlacesLived.html", type:"class", deprecated:"false" },
+      { id:192, label:"com.google.android.gms.plus.model.people.Person.RelationshipStatus", link:"reference/com/google/android/gms/plus/model/people/Person.RelationshipStatus.html", type:"class", deprecated:"false" },
+      { id:193, label:"com.google.android.gms.plus.model.people.Person.Urls", link:"reference/com/google/android/gms/plus/model/people/Person.Urls.html", type:"class", deprecated:"false" },
+      { id:194, label:"com.google.android.gms.plus.model.people.Person.Urls.Type", link:"reference/com/google/android/gms/plus/model/people/Person.Urls.Type.html", type:"class", deprecated:"false" },
+      { id:195, label:"com.google.android.gms.plus.model.people.PersonBuffer", link:"reference/com/google/android/gms/plus/model/people/PersonBuffer.html", type:"class", deprecated:"false" }
 
     ];
diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd
index a686efd..12d2527 100644
--- a/docs/html/sdk/installing/studio-tips.jd
+++ b/docs/html/sdk/installing/studio-tips.jd
@@ -10,6 +10,8 @@
  >Eclipse Compatibility Mode</a></li>
  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
  >FAQ on Migrating</a></li>
+ <li><a href="http://android-developers.blogspot.com/2013/06/adding-backend-to-your-app-in-android.html"
+ class="external-link">Adding a Backend to Your App In Android Studio</a></li>
 </ul>
 </div>
 </div>
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index 8825bcc..2e9c4b4 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -249,36 +249,36 @@
     <td>Windows</td>
     <td>
   <a onclick="return onDownload(this)" id="win-studio"
-      href="http://dl.google.com/android/studio/android-studio-bundle-130.687321-windows.exe">
-      android-studio-bundle-130.677228-windows.exe
+      href="http://dl.google.com/android/studio/android-studio-bundle-130.737825-windows.exe">
+      android-studio-bundle-130.737825-windows.exe
       </a>
     </td>
-    <td>393023485 bytes</td>
-    <td>3da987a9778b66edb68fb43d8b53bfcb</td>
+    <td>396091268 bytes</td>
+    <td>6da1bc8effa048c8ff669e4c484eb11f</td>
   </tr>
 
   <tr>
     <td><nobr>Mac OS X</nobr></td>
     <td>
   <a onclick="return onDownload(this)" id="mac-studio"
-    href="http://dl.google.com/android/studio/android-studio-bundle-130.687321-mac.dmg">
-    android-studio-bundle-130.687321-mac.dmg
+    href="http://dl.google.com/android/studio/android-studio-bundle-130.737825-mac.dmg">
+    android-studio-bundle-130.737825-mac.dmg
     </a>
     </td>
-    <td>379877697 bytes</td>
-    <td>eb5ca6c77f4a119595d941daeda58810</td>
+    <td>383326582 bytes</td>
+    <td>2959bc5039238d286670cc6225342b89</td>
   </tr>
 
   <tr>
     <td>Linux</td>
     <td>
   <a onclick="return onDownload(this)" id="linux-studio"
-    href="http://dl.google.com/android/studio/android-studio-bundle-130.687321-linux.tgz">
-    android-studio-bundle-130.687321-linux.tgz
+    href="http://dl.google.com/android/studio/android-studio-bundle-130.737825-linux.tgz">
+    android-studio-bundle-130.737825-linux.tgz
     </a>
     </td>
-    <td>406516375 bytes</td>
-    <td>6796d66de07c85b2822ca8d501a043c0</td>
+    <td>409935592 bytes</td>
+    <td>dcd13922f7cf577e3c852b224205d843</td>
   </tr>
   </table>
 
@@ -286,6 +286,25 @@
 
 
 
+<h2 id="Updating">Updating to 0.2.x</h2>
+
+<p>To update from Android Studio 0.1.x to 0.2.x,
+follow the <a href="#Installing">installation instructions</a> below and replace your existing
+installation.</p>
+
+<p class="caution"><strong>Caution:</strong> Replacing your existing installation of
+Android Studio will remove any additional SDK packages you've installed, such as target
+platforms, system images, and sample apps. To preserve these, copy them from your current
+SDK directory under Android Studio to a temporary location
+before installing the update. Then move them back once the update is complete.
+If you fail to copy these packages, then you can instead download them again through
+the Android SDK Manager.</p>
+
+<p>Also note that due to the update to Gradle 0.5, you will encounter errors when opening
+existing projects. See the <a href="#Troubleshooting">Troubleshooting</a> notes below for
+information about how to resolve them.</p>
+
+
 <h2 id="Installing">Installing Android Studio</h2>
 <ol>
 <li>Download the <strong>Android Studio</strong> package from above.</li>
@@ -390,14 +409,78 @@
 
 <h2 id="Revisions">Revisions</h2>
 
-<p class="note"><strong>Note:</strong> Periodic updates are pushed to Android Studio
-without requiring you to update from here. To manually check for updates, select
-<strong>Help > Check for updates</strong> (on Mac, select <strong>Android Studio >
-Check for updates</strong>).</p>
+<p class="note"><strong>Note:</strong> <strong>There is not a patch update available from
+0.1.9 to 0.2</strong>. To update from Android Studio 0.1.x to 0.2.x, you must
+install a new Android Studio bundle from this page.  The reason for that is that we have made
+changes to the bundled SDK such that it includes a pre-configured local Maven repository
+which can serve up the v4 support library and which is required for creating new projects.</p>
+
 
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>Android Studio v0.2.x</a> <em>(July 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+  <ul>
+    <li>Merged in the latest IntelliJ codebase changes. Includes fixes for issues reported by Studio users such as tweaks to Linux font sizes and font rendering.</li>
+    <li>Android Gradle plug-in updated to 0.5.0.
+      <p class="caution"><strong>Caution:</strong> This new version is not backwards compatible.
+      When opening a project that uses an older version of the plug-in, Studio will show an error
+      stating <strong>Gradle &lt;project_name&gt; project refresh failed.</strong> See <a
+      href="#Troubleshooting">Troubleshooting</a> below for details.</p>
+      <p>The updated Gradle plug-in includes the following changes:</p>
+      <ul>
+        <li>Fixed IDE model to contain the output file even if it's customized through the DSL. Also
+        fixed the DSL to get/set the output file on the variant object so that it's not necessary to
+        use <code>variant.packageApplication or variant.zipAlign</code></li>
+        <li>Fixed dependency resolution so that we resolved the combination of (default config,
+        build types, flavor(s)) together instead of separately.</li>
+        <li>Fixed dependency for tests of library project to properly include all the dependencies
+        of the library itself.</li>
+        <li>Fixed case where two dependencies have the same leaf name.</li>
+        <li>Fixed issue where Proguard rules file cannot be applied on flavors.</li>
+      </ul>
+      <p>All Gradle plugin release notes are available are here: <a href=
+      "http://tools.android.com/tech-docs/new-build-system"
+      >http://tools.android.com/tech-docs/new-build-system</a>.</p>
+    </li>
+    <li>Gradle errors from aapt no longer point to merged output files in the build/ folder, they
+    point back to the real source locations.</li>
+    <li>Parallel Builds. It's now possible to use Gradle's parallel builds. Please be aware that
+    parallel builds are in "incubation" (see <a
+    href="http://www.gradle.org/docs/current/userguide/gradle_command_line.html">Gradle's
+    documentation</a>.) This feature is off by default. To enable it, go to
+    <strong>Preferences</strong> &gt; <strong>Compiler</strong> and check the box <em>Compile
+    independent modules in parallel</em>.</li>
+    <li>Further work on the new resource repository used for layout rendering, resource
+    folding in the editor, and more:
+      <ul>
+      <li>Basic support for .aar library dependencies (e.g. using a library without a local copy of
+      the sources). Still not working for resource XML validation and navigation in source editors.
+      </li>
+      <li>Cycle detection in resource references.</li>
+      <li>Quick Documentation (F1), which can show all translations of the string under the caret,
+      will now also show all resource overlays from the various Gradle flavors and build types, as
+      well as libraries. They are listed in reverse resource overlay order, with strikethrough on
+      the versions of the string that are masked.</li>
+      <li>Fixes to handle updating the merged resources when the set of module dependencies
+      change.</li>
+      <li>XML rendering fixes to properly handle character entity declarations and XML and unicode
+      escapes.</li>
+      </ul>
+    <li>Save screenshot support for the layout preview and layout editor windows.</li>
+    <li>Template bug fixes.</li>
+    <li>Lint bug fixes.</li>
+    <li>Various fixes for crash reports. Thank you, and keep filing crash reports!</li>
+  </ul>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>Android Studio v0.1.x</a> <em>(May 2013)</em>
   </p>
 
@@ -408,12 +491,75 @@
   </div>
 </div>
 
+<p>&nbsp;</p>
+
+<p class="note"><strong>Note:</strong> Periodic updates are pushed to Android Studio
+without requiring you to update from here. To manually check for updates, select
+<strong>Help > Check for updates</strong> (on Mac, select <strong>Android Studio >
+Check for updates</strong>).</p>
 
 
 
 
+<h2 id="Troubleshooting">Troubleshooting</h2>
 
 
+<div class="figure" style="width:330px">
+<img src="{@docRoot}images/tools/studio_error_gradle5.png" width="330"/>
+<p class="img-caption"><strong>Figure 1.</strong> Error dialog when opening an existing project.</p>
+</div>
+
+<h3>Error: Gradle project refresh failed</h3>
+
+<p>Android Studio 0.2.0 has updated the Gradle plug-in to 0.5.0, which is not backwards compatible.
+When opening a project that uses an older version of the plug-in, Studio will display the error
+shown in figure 1 in the upper right corner of the IDE.
+To resolve the error, you must change the version of the Android Gradle plug-in to 0.5.0.</p>
+
+<ol>
+  <li>Click the link in the error dialog <strong>Search in build.gradle files</strong>. If the dialog
+is no longer visible, click <strong>Event Log</strong>
+<img src="{@docRoot}images/tools/studio_error_eventlog.png"
+style="vertical-align:bottom;margin:0;height:19px"/> in the bottom-right corner of the IDE,
+then click <strong>Search in build.gradle files</strong>.</li>
+  <li>Double-click the line under the <em>build.gradle</em> usage. For example:
+  <strong>classpath 'com.android.tools.build:gradle:0.4</strong>. This opens the project
+  <code>build.gradle</code> file.</li>
+  <li>Edit the <code>classpath</code> to change the gradle version to <code>0.5.+</code>.
+  For example:
+  <pre class="no-pretty-print">
+dependencies {
+  classpath 'com.android.tools.build:gradle:<strong>0.5.+</strong>'
+}
+</pre>
+  </li>
+  <li>Save the file and rebuild your project.</li>
+</ol>
+
+
+
+<div class="figure" style="width:330px">
+<img src="{@docRoot}images/tools/studio_error_supportlib.png" width="330"/>
+<p class="img-caption"><strong>Figure 2.</strong> Error dialog when creating a new project
+or opening a project using the support library.</p>
+</div>
+
+<h3>Error: Failed to import Gradle project</h3>
+
+<p>If, after updating to Android Studio 0.2.x and creating or opening a project, you receive an
+error stating <em>"Could not find any version that matches
+com.android.support:support-v4:13.0.+"</em>, then you must install the <strong>Android Studio
+Repository</strong>. This was likely caused because you're pointing Android Studio to an external
+Android SDK location that does not have the new Maven repository included with Android Studio
+0.2.x. This new Maven repository is used by the new build system for the Support Library, instead
+of using the Support Library JAR files, so must be present in the SDK.</p>
+
+
+<ol>
+  <li>Open the <strong>Android SDK Manager</strong>.</li>
+  <li>Expand the <strong>Extras</strong> directory
+and install <strong>Android Studio Repository</strong>.</li>
+</ol>
 
 
 
@@ -430,7 +576,7 @@
 
 
 
-  
+
 <script>
   var os;
   var bundlename;
@@ -450,15 +596,15 @@
   if (os) {
     /* set up primary ACE download button */
     $('#download-ide-button').show();
-    $('#download-ide-button').append("Download Android Studio <span class='small'>v0.1.x</span>"
-        + "<br/><span class='small'>for " + os + "</span>");
+    $('#download-ide-button').append("Download Android Studio <span class='small'>v0.2.x</span>"
+        + "<br/> <span class='small'>for " + os + "</span>");
     $('#download-ide-button').click(function() {return onDownload(this,true);}).attr('href', bundlename);
 
   } else {
     $('.pax').show();
   }
-  
-  
+
+
   function onDownload(link, button) {
     var $studioLink;
 
@@ -470,7 +616,7 @@
       $studioLink = $(link);
       $("#downloadForRealz").html("Download " + $(link).text());
     }
-    
+
     $("#downloadForRealz").attr('href', $studioLink.attr('href'));
 
     $("#tos").fadeIn('fast');
@@ -493,10 +639,9 @@
 
   function onDownloadForRealz(link) {
     if ($("input#agree").is(':checked')) {
-      $("div.sdk-terms,#sdk-terms-form,.sdk-terms-intro").hide();
-      $("#main").show(function() {
-          location.hash = "Installing";
-          });
+      $("#tos").hide();
+      $("#main").show();
+      location.hash = "Updating";
       return true;
     } else {
       $("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#258AAF"}, 200,
diff --git a/docs/html/tools/extras/oem-usb.jd b/docs/html/tools/extras/oem-usb.jd
index 87734a1..5e0e893 100644
--- a/docs/html/tools/extras/oem-usb.jd
+++ b/docs/html/tools/extras/oem-usb.jd
@@ -250,14 +250,6 @@
 href="http://www.fmworld.net/product/phone/sp/android/develop/">http://www.fmworld.net/product/phone/sp/android/develop/</a>
     </td>
   </tr>
-  <tr>
-    <td>
-      Fujitsu Toshiba
-    </td>
-    <td><a
-href="http://www.fmworld.net/product/phone/sp/android/develop/">http://www.fmworld.net/product/phone/sp/android/develop/</a>
-    </td>
-  </tr>
   <tr><td>
        Garmin-Asus
     </td>	<td><a
@@ -327,6 +319,10 @@
 href="http://www.teleepoch.com/android.html">http://www.teleepoch.com/android.html</a></td>
 </tr>
 
+<tr><td>Toshiba</td>  <td><a
+href="http://support.toshiba.com/sscontent?docId=4001814">http://support.toshiba.com/sscontent?docId=4001814</a></td>
+</tr>
+
 <tr><td>Yulong Coolpad</td>	<td><a
 href="http://www.yulong.com/product/product/product/downloadList.html#downListUL">http://www.yulong.com/product/product/product/downloadList.html#downListUL</a></td>
 </tr>
diff --git a/docs/html/tools/index.jd b/docs/html/tools/index.jd
index f9d452c..e9094a7 100644
--- a/docs/html/tools/index.jd
+++ b/docs/html/tools/index.jd
@@ -1,6 +1,13 @@
 page.title=Developer Tools
 @jd:body
-
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
     
 <img src="{@docRoot}images/tools-home.png" style="float:right;" height="415" width="763" />
 
diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd
index 72ad018..82fbd16 100644
--- a/docs/html/training/index.jd
+++ b/docs/html/training/index.jd
@@ -3,7 +3,14 @@
 page.metaDescription=Android Training provides a collection of classes that aim to help you build great apps for Android. Each class explains the steps required to solve a problem or implement a feature using code snippets and sample code for you to use in your apps.
 
 @jd:body
-
+<div id="butterbar-wrapper" >
+  <div id="butterbar" >
+    <div id="butterbar-message">
+<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
+      Take the Android Developer Survey</a>
+    </div>
+  </div>
+</div>
 
 <p>Welcome to Training for Android developers. Here you'll find sets of lessons within classes
 that describe how to accomplish a specific task with code samples you can re-use in your app.
diff --git a/docs/html/training/sync-adapters/creating-authenticator.jd b/docs/html/training/sync-adapters/creating-authenticator.jd
index 1b272e7..dfa9027 100644
--- a/docs/html/training/sync-adapters/creating-authenticator.jd
+++ b/docs/html/training/sync-adapters/creating-authenticator.jd
@@ -235,7 +235,7 @@
 <p>
     The following snippet shows the XML file for the authenticator you created previously:
 </p>
-<pre>the
+<pre>
 &lt;?xml version="1.0" encoding="utf-8"?&gt;
 &lt;account-authenticator
         xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/docs/html/training/sync-adapters/index.jd b/docs/html/training/sync-adapters/index.jd
index 1f7977b..b107cbe 100644
--- a/docs/html/training/sync-adapters/index.jd
+++ b/docs/html/training/sync-adapters/index.jd
@@ -11,7 +11,7 @@
 
 <h2>Dependencies and prerequisites</h2>
 <ul>
-    <li>Android 3.0 (API Level 11) or higher</li>
+    <li>Android 2.1 (API Level 7) or higher</li>
 </ul>
 
 <h2>You should also read</h2>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 106f4bd..50231da 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -45,9 +45,13 @@
 
     /**
      * Backing buffer for the Bitmap.
+     * Made public for quick access from drawing methods -- do NOT modify
+     * from outside this class
+     *
+     * @hide
      */
     @SuppressWarnings("UnusedDeclaration") // native code only
-    private byte[] mBuffer;
+    public byte[] mBuffer;
 
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
     private final BitmapFinalizer mFinalizer;
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index deccac1..aff4cd8 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -18,6 +18,7 @@
 
 import android.content.res.AssetManager;
 import android.content.res.Resources;
+import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
@@ -436,12 +437,21 @@
         if ((offset | length) < 0 || data.length < offset + length) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        Bitmap bm = nativeDecodeByteArray(data, offset, length, opts);
 
-        if (bm == null && opts != null && opts.inBitmap != null) {
-            throw new IllegalArgumentException("Problem decoding into existing bitmap");
+        Bitmap bm;
+
+        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
+        try {
+            bm = nativeDecodeByteArray(data, offset, length, opts);
+
+            if (bm == null && opts != null && opts.inBitmap != null) {
+                throw new IllegalArgumentException("Problem decoding into existing bitmap");
+            }
+            setDensityFromOptions(bm, opts);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
         }
-        setDensityFromOptions(bm, opts);
+
         return bm;
     }
 
@@ -508,39 +518,43 @@
             return null;
         }
 
-        // we need mark/reset to work properly
-
-        if (!is.markSupported()) {
-            is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
-        }
-
-        // so we can call reset() if a given codec gives up after reading up to
-        // this many bytes. FIXME: need to find out from the codecs what this
-        // value should be.
-        is.mark(1024);
-
         Bitmap bm;
-        boolean finish = true;
 
-        if (is instanceof AssetManager.AssetInputStream) {
-            final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
-            bm = nativeDecodeAsset(asset, outPadding, opts);
-        } else {
-            // pass some temp storage down to the native code. 1024 is made up,
-            // but should be large enough to avoid too many small calls back
-            // into is.read(...) This number is not related to the value passed
-            // to mark(...) above.
-            byte [] tempStorage = null;
-            if (opts != null) tempStorage = opts.inTempStorage;
-            if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
-            bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
+        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
+        try {
+            // we need mark/reset to work properly
+            if (!is.markSupported()) {
+                is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
+            }
+
+            // so we can call reset() if a given codec gives up after reading up to
+            // this many bytes. FIXME: need to find out from the codecs what this
+            // value should be.
+            is.mark(1024);
+
+            if (is instanceof AssetManager.AssetInputStream) {
+                final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
+                bm = nativeDecodeAsset(asset, outPadding, opts);
+            } else {
+                // pass some temp storage down to the native code. 1024 is made up,
+                // but should be large enough to avoid too many small calls back
+                // into is.read(...) This number is not related to the value passed
+                // to mark(...) above.
+                byte [] tempStorage = null;
+                if (opts != null) tempStorage = opts.inTempStorage;
+                if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
+                bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
+            }
+
+            if (bm == null && opts != null && opts.inBitmap != null) {
+                throw new IllegalArgumentException("Problem decoding into existing bitmap");
+            }
+
+            setDensityFromOptions(bm, opts);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
         }
 
-        if (bm == null && opts != null && opts.inBitmap != null) {
-            throw new IllegalArgumentException("Problem decoding into existing bitmap");
-        }
-
-        setDensityFromOptions(bm, opts);
         return bm;
     }
 
@@ -608,10 +622,7 @@
     private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
             Rect padding, Options opts);
     private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts);
-    private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
-            boolean applyScale, float scale);
     private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
             int length, Options opts);
-    private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
     private static native boolean nativeIsSeekable(FileDescriptor fd);
 }
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index a837294..4e06448 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -267,13 +267,23 @@
             native_set(native_instance, src.native_instance);
         }
     }
-    
+
     /** Returns true iff obj is a Matrix and its values equal our values.
     */
+    @Override
     public boolean equals(Object obj) {
-        return obj != null &&
-               obj instanceof Matrix &&
-               native_equals(native_instance, ((Matrix)obj).native_instance);
+        //if (obj == this) return true;     -- NaN value would mean matrix != itself
+        if (!(obj instanceof Matrix)) return false;
+        return native_equals(native_instance, ((Matrix)obj).native_instance);
+    }
+
+    @Override
+    public int hashCode() {
+        // This should generate the hash code by performing some arithmetic operation on all
+        // the matrix elements -- our equals() does an element-by-element comparison, and we
+        // need to ensure that the hash code for two equal objects is the same.  We're not
+        // really using this at the moment, so we take the easy way out.
+        return 44;
     }
 
     /** Set the matrix to identity */
@@ -512,7 +522,7 @@
          */
         END     (3);
 
-        // the native values must match those in SkMatrix.h 
+        // the native values must match those in SkMatrix.h
         ScaleToFit(int nativeInt) {
             this.nativeInt = nativeInt;
         }
@@ -535,7 +545,7 @@
         }
         return native_setRectToRect(native_instance, src, dst, stf.nativeInt);
     }
-    
+
     // private helper to perform range checks on arrays of "points"
     private static void checkPointArrays(float[] src, int srcIndex,
                                          float[] dst, int dstIndex,
@@ -598,7 +608,7 @@
         native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
                          pointCount, true);
     }
-    
+
     /**
     * Apply this matrix to the array of 2D vectors specified by src, and write
      * the transformed vectors into the array of vectors specified by dst. The
@@ -620,7 +630,7 @@
         native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
                          vectorCount, false);
     }
-    
+
     /**
      * Apply this matrix to the array of 2D points specified by src, and write
      * the transformed points into the array of points specified by dst. The
@@ -713,7 +723,7 @@
     public float mapRadius(float radius) {
         return native_mapRadius(native_instance, radius);
     }
-    
+
     /** Copy 9 values from the matrix into the array.
     */
     public void getValues(float[] values) {
@@ -736,13 +746,14 @@
         native_setValues(native_instance, values);
     }
 
+    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(64);
         sb.append("Matrix{");
         toShortString(sb);
         sb.append('}');
         return sb.toString();
-                
+
     }
 
     public String toShortString() {
@@ -780,13 +791,18 @@
                 pw.print(values[5]); pw.print("][");
         pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", ");
                 pw.print(values[8]); pw.print(']');
-                
+
     }
 
+    @Override
     protected void finalize() throws Throwable {
-        finalizer(native_instance);
+        try {
+            finalizer(native_instance);
+        } finally {
+            super.finalize();
+        }
     }
-    
+
     /*package*/ final int ni() {
         return native_instance;
     }
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 58fa21c..3f77021 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -62,7 +62,7 @@
 }
 
 void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
-    SkSafeRef(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
@@ -100,7 +100,7 @@
 }
 
 void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
-    SkSafeRef(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
@@ -133,7 +133,7 @@
 }
 
 void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
-    SkSafeUnref(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
@@ -174,7 +174,7 @@
 }
 
 void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
-    SkSafeUnref(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
index 3400434..8a2d347 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -18,7 +18,17 @@
 
 import android.os.Parcel;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.graphics.ImageFormat;
 import android.hardware.photography.CameraMetadata;
+import android.hardware.photography.Rational;
+
+import static android.hardware.photography.CameraMetadata.*;
+
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import static org.junit.Assert.assertArrayEquals;
 
 /**
  * <pre>
@@ -32,6 +42,21 @@
     CameraMetadata mMetadata;
     Parcel mParcel;
 
+    // Sections
+    static final int ANDROID_COLOR_CORRECTION = 0;
+    static final int ANDROID_CONTROL = 1;
+
+    // Section starts
+    static final int ANDROID_COLOR_CORRECTION_START = ANDROID_COLOR_CORRECTION << 16;
+    static final int ANDROID_CONTROL_START = ANDROID_CONTROL << 16;
+
+    // Tags
+    static final int ANDROID_COLOR_CORRECTION_MODE = ANDROID_COLOR_CORRECTION_START;
+    static final int ANDROID_COLOR_CORRECTION_TRANSFORM = ANDROID_COLOR_CORRECTION_START + 1;
+
+    static final int ANDROID_CONTROL_AE_ANTIBANDING_MODE = ANDROID_CONTROL_START;
+    static final int ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION = ANDROID_CONTROL_START + 1;
+
     @Override
     public void setUp() {
         mMetadata = new CameraMetadata();
@@ -105,5 +130,310 @@
         } catch (IllegalStateException e) {
          // good: we expect calling this method after close to fail
         }
+
+        try {
+            mMetadata.readValues(/*tag*/0);
+            fail("Unreachable -- readValues after close should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+         // good: we expect calling this method after close to fail
+        }
+
+        try {
+            mMetadata.writeValues(/*tag*/0, /*source*/new byte[] { 1,2,3 });
+            fail("Unreachable -- readValues after close should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+         // good: we expect calling this method after close to fail
+        }
+    }
+
+    @SmallTest
+    public void testGetTagFromKey() {
+
+        // Test success
+
+        assertEquals(ANDROID_COLOR_CORRECTION_MODE,
+                CameraMetadata.getTag("android.colorCorrection.mode"));
+        assertEquals(ANDROID_COLOR_CORRECTION_TRANSFORM,
+                CameraMetadata.getTag("android.colorCorrection.transform"));
+        assertEquals(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+                CameraMetadata.getTag("android.control.aeAntibandingMode"));
+        assertEquals(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+                CameraMetadata.getTag("android.control.aeExposureCompensation"));
+
+        // Test failures
+
+        try {
+            CameraMetadata.getTag(null);
+            fail("A null key should throw NPE");
+        } catch(NullPointerException e) {
+        }
+
+        try {
+            CameraMetadata.getTag("android.control");
+            fail("A section name only should not be a valid key");
+        } catch(IllegalArgumentException e) {
+        }
+
+        try {
+            CameraMetadata.getTag("android.control.thisTagNameIsFakeAndDoesNotExist");
+            fail("A valid section with an invalid tag name should not be a valid key");
+        } catch(IllegalArgumentException e) {
+        }
+
+        try {
+            CameraMetadata.getTag("android");
+            fail("A namespace name only should not be a valid key");
+        } catch(IllegalArgumentException e) {
+        }
+
+        try {
+            CameraMetadata.getTag("this.key.is.definitely.invalid");
+            fail("A completely fake key name should not be valid");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    @SmallTest
+    public void testGetTypeFromTag() {
+        assertEquals(TYPE_BYTE, CameraMetadata.getNativeType(ANDROID_COLOR_CORRECTION_MODE));
+        assertEquals(TYPE_FLOAT, CameraMetadata.getNativeType(ANDROID_COLOR_CORRECTION_TRANSFORM));
+        assertEquals(TYPE_BYTE, CameraMetadata.getNativeType(ANDROID_CONTROL_AE_ANTIBANDING_MODE));
+        assertEquals(TYPE_INT32,
+                CameraMetadata.getNativeType(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION));
+
+        try {
+            CameraMetadata.getNativeType(0xDEADF00D);
+            fail("No type should exist for invalid tag 0xDEADF00D");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    @SmallTest
+    public void testReadWriteValues() {
+        final byte ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY = 2;
+        byte[] valueResult;
+
+        assertEquals(0, mMetadata.getEntryCount());
+        assertEquals(true, mMetadata.isEmpty());
+
+        //
+        // android.colorCorrection.mode (single enum byte)
+        //
+
+        assertEquals(null, mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE));
+
+        // Write 0 values
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, new byte[] {});
+
+        // Read 0 values
+        valueResult = mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE);
+        assertNotNull(valueResult);
+        assertEquals(0, valueResult.length);
+
+        assertEquals(1, mMetadata.getEntryCount());
+        assertEquals(false, mMetadata.isEmpty());
+
+        // Write 1 value
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, new byte[] {
+            ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY
+        });
+
+        // Read 1 value
+        valueResult = mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE);
+        assertNotNull(valueResult);
+        assertEquals(1, valueResult.length);
+        assertEquals(ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY, valueResult[0]);
+
+        assertEquals(1, mMetadata.getEntryCount());
+        assertEquals(false, mMetadata.isEmpty());
+
+        //
+        // android.colorCorrection.transform (3x3 matrix)
+        //
+
+        final float[] transformMatrix = new float[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+        byte[] transformMatrixAsByteArray = new byte[transformMatrix.length * 4];
+        ByteBuffer transformMatrixByteBuffer =
+                ByteBuffer.wrap(transformMatrixAsByteArray).order(ByteOrder.nativeOrder());
+        for (float f : transformMatrix)
+            transformMatrixByteBuffer.putFloat(f);
+
+        // Read
+        assertNull(mMetadata.readValues(ANDROID_COLOR_CORRECTION_TRANSFORM));
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_TRANSFORM, transformMatrixAsByteArray);
+
+        // Write
+        assertArrayEquals(transformMatrixAsByteArray,
+                mMetadata.readValues(ANDROID_COLOR_CORRECTION_TRANSFORM));
+
+        assertEquals(2, mMetadata.getEntryCount());
+        assertEquals(false, mMetadata.isEmpty());
+
+        // Erase
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_TRANSFORM, null);
+        assertNull(mMetadata.readValues(ANDROID_COLOR_CORRECTION_TRANSFORM));
+        assertEquals(1, mMetadata.getEntryCount());
+    }
+
+    private static <T> void assertArrayEquals(T expected, T actual) {
+        assertEquals(Array.getLength(expected), Array.getLength(actual));
+
+        int len = Array.getLength(expected);
+        for (int i = 0; i < len; ++i) {
+            assertEquals(Array.get(expected, i), Array.get(actual, i));
+        }
+    }
+
+    private <T> void checkKeyGetAndSet(String keyStr, Class<T> type, T value) {
+        Key<T> key = new Key<T>(keyStr, type);
+        assertNull(mMetadata.get(key));
+        mMetadata.set(key, value);
+        assertEquals(value, mMetadata.get(key));
+    }
+
+    private <T> void checkKeyGetAndSetArray(String keyStr, Class<T> type, T value) {
+        Key<T> key = new Key<T>(keyStr, type);
+        assertNull(mMetadata.get(key));
+        mMetadata.set(key, value);
+        assertArrayEquals(value, mMetadata.get(key));
+    }
+
+    @SmallTest
+    public void testReadWritePrimitive() {
+        // int32 (single)
+        checkKeyGetAndSet("android.control.aeExposureCompensation", Integer.TYPE, 0xC0FFEE);
+
+        // byte (single)
+        checkKeyGetAndSet("android.flash.maxEnergy", Byte.TYPE, (byte)6);
+
+        // int64 (single)
+        checkKeyGetAndSet("android.flash.firingTime", Long.TYPE, 0xABCD12345678FFFFL);
+
+        // float (single)
+        checkKeyGetAndSet("android.lens.aperture", Float.TYPE, Float.MAX_VALUE);
+
+        // double (single) -- technically double x 3, but we fake it
+        checkKeyGetAndSet("android.jpeg.gpsCoordinates", Double.TYPE, Double.MAX_VALUE);
+
+        // rational (single)
+        checkKeyGetAndSet("android.sensor.baseGainFactor", Rational.class, new Rational(1, 2));
+
+        /**
+         * Weirder cases, that don't map 1:1 with the native types
+         */
+
+        // bool (single) -- with TYPE_BYTE
+        checkKeyGetAndSet("android.control.aeLock", Boolean.TYPE, true);
+
+        // integer (single) -- with TYPE_BYTE
+        checkKeyGetAndSet("android.control.aePrecaptureTrigger", Integer.TYPE, 6);
+    }
+
+    @SmallTest
+    public void testReadWritePrimitiveArray() {
+        // int32 (n)
+        checkKeyGetAndSetArray("android.sensor.info.availableSensitivities", int[].class,
+                new int[] {
+                        0xC0FFEE, 0xDEADF00D
+                });
+
+        // byte (n)
+        checkKeyGetAndSetArray("android.statistics.faceScores", byte[].class, new byte[] {
+                1, 2, 3, 4
+        });
+
+        // int64 (n)
+        checkKeyGetAndSetArray("android.scaler.availableProcessedMinDurations", long[].class,
+                new long[] {
+                        0xABCD12345678FFFFL, 0x1234ABCD5678FFFFL, 0xFFFF12345678ABCDL
+                });
+
+        // float (n)
+        checkKeyGetAndSetArray("android.lens.info.availableApertures", float[].class,
+                new float[] {
+                        Float.MAX_VALUE, Float.MIN_NORMAL, Float.MIN_VALUE
+                });
+
+        // double (n) -- in particular double x 3
+        checkKeyGetAndSetArray("android.jpeg.gpsCoordinates", double[].class,
+                new double[] {
+                        Double.MAX_VALUE, Double.MIN_NORMAL, Double.MIN_VALUE
+                });
+
+        // rational (n) -- in particular rational x 9
+        checkKeyGetAndSetArray("android.sensor.calibrationTransform1", Rational[].class,
+                new Rational[] {
+                        new Rational(1, 2), new Rational(3, 4), new Rational(5, 6),
+                        new Rational(7, 8), new Rational(9, 10), new Rational(10, 11),
+                        new Rational(12, 13), new Rational(14, 15), new Rational(15, 16)
+                });
+
+        /**
+         * Weirder cases, that don't map 1:1 with the native types
+         */
+
+        // bool (n) -- with TYPE_BYTE
+        checkKeyGetAndSetArray("android.control.aeLock", boolean[].class, new boolean[] {
+                true, false, true
+        });
+
+
+        // integer (n) -- with TYPE_BYTE
+        checkKeyGetAndSetArray("android.control.aeAvailableModes", int[].class, new int[] {
+            1, 2, 3, 4
+        });
+    }
+
+    private enum ColorCorrectionMode {
+        TRANSFORM_MATRIX,
+        FAST,
+        HIGH_QUALITY
+    }
+
+    private enum AeAntibandingMode {
+        OFF,
+        _50HZ,
+        _60HZ,
+        AUTO
+    }
+
+    // TODO: special values for the enum.
+    private enum AvailableFormat {
+        RAW_SENSOR,
+        YV12,
+        YCrCb_420_SP,
+        IMPLEMENTATION_DEFINED,
+        YCbCr_420_888,
+        BLOB
+    }
+
+    @SmallTest
+    public void testReadWriteEnum() {
+        // byte (single)
+        checkKeyGetAndSet("android.colorCorrection.mode", ColorCorrectionMode.class,
+                ColorCorrectionMode.HIGH_QUALITY);
+
+        // byte (single)
+        checkKeyGetAndSet("android.control.aeAntibandingMode", AeAntibandingMode.class,
+                AeAntibandingMode.AUTO);
+
+        // byte (n)
+        checkKeyGetAndSetArray("android.control.aeAvailableAntibandingModes",
+                AeAntibandingMode[].class, new AeAntibandingMode[] {
+                        AeAntibandingMode.OFF, AeAntibandingMode._50HZ, AeAntibandingMode._60HZ,
+                        AeAntibandingMode.AUTO
+                });
+
+        /**
+         * Stranger cases that don't use byte enums
+         */
+        // int (n)
+        checkKeyGetAndSetArray("android.scaler.availableFormats", AvailableFormat[].class,
+                new AvailableFormat[] {
+                        AvailableFormat.RAW_SENSOR,
+                        AvailableFormat.YV12,
+                        AvailableFormat.IMPLEMENTATION_DEFINED
+                });
+
     }
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
new file mode 100644
index 0000000..c15d030
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest.unit;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.hardware.photography.Rational;
+
+/**
+ * <pre>
+ * adb shell am instrument \
+ *      -e class 'com.android.mediaframeworktest.unit.RationalTest' \
+ *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
+ * </pre>
+ */
+public class RationalTest extends junit.framework.TestCase {
+    @SmallTest
+    public void testConstructor() {
+
+        // Simple case
+        Rational r = new Rational(1, 2);
+        assertEquals(1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Denominator negative
+        r = new Rational(-1, 2);
+        assertEquals(-1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Numerator negative
+        r = new Rational(1, -2);
+        assertEquals(-1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Both negative
+        r = new Rational(-1, -2);
+        assertEquals(1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Dividing by zero is not allowed
+        try {
+            r = new Rational(1, 0);
+            fail("Expected Rational constructor to throw an IllegalArgumentException");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    @SmallTest
+    public void testGcd() {
+        Rational r = new Rational(1, 2);
+        assertEquals(1, r.gcd());
+
+        Rational twoThirds = new Rational(2, 3);
+        assertEquals(1, twoThirds.gcd());
+
+        Rational moreComplicated2 = new Rational(5*78, 7*78);
+        assertEquals(78, moreComplicated2.gcd());
+
+        Rational oneHalf = new Rational(-1, 2);
+        assertEquals(1, oneHalf.gcd());
+
+        twoThirds = new Rational(-2, 3);
+        assertEquals(1, twoThirds.gcd());
+    }
+
+    @SmallTest
+    public void testEquals() {
+        Rational r = new Rational(1, 2);
+        assertEquals(1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        assertEquals(r, r);
+        assertFalse(r.equals(null));
+        assertFalse(r.equals(new Object()));
+
+        Rational twoThirds = new Rational(2, 3);
+        assertFalse(r.equals(twoThirds));
+        assertFalse(twoThirds.equals(r));
+
+        Rational fourSixths = new Rational(4, 6);
+        assertEquals(twoThirds, fourSixths);
+        assertEquals(fourSixths, twoThirds);
+
+        Rational moreComplicated = new Rational(5*6*7*8*9, 1*2*3*4*5);
+        Rational moreComplicated2 = new Rational(5*6*7*8*9*78, 1*2*3*4*5*78);
+        assertEquals(moreComplicated, moreComplicated2);
+        assertEquals(moreComplicated2, moreComplicated);
+
+        // Ensure negatives are fine
+        twoThirds = new Rational(-2, 3);
+        fourSixths = new Rational(-4, 6);
+        assertEquals(twoThirds, fourSixths);
+        assertEquals(fourSixths, twoThirds);
+
+        moreComplicated = new Rational(-5*6*7*8*9, 1*2*3*4*5);
+        moreComplicated2 = new Rational(-5*6*7*8*9*78, 1*2*3*4*5*78);
+        assertEquals(moreComplicated, moreComplicated2);
+        assertEquals(moreComplicated2, moreComplicated);
+
+    }
+}
\ No newline at end of file
diff --git a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
index d525429..7bb0e9b 100644
--- a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
@@ -26,9 +26,9 @@
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Niet herstellen"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Geef hieronder uw huidige back-upwachtwoord op:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geef hieronder uw wachtwoord voor apparaatcodering op."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder uw wachtwoord voor apparaatcodering op. Dit wordt ook gebruikt om het back-uparchief te coderen."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder uw wachtwoord voor apparaatversleuteling op. Dit wordt ook gebruikt om het back-uparchief te versleutelen."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Geef een wachtwoord op dat u wilt gebruiken voor het coderen van de gegevens van de volledige back-up. Als u dit leeg laat, wordt uw huidige back-upwachtwoord gebruikt:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt coderen, geeft u daarvoor hieronder een wachtwoord op:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt versleutelen, geeft u daarvoor hieronder een wachtwoord op:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Als deze herstelgegevens zijn gecodeerd, geeft u hieronder het wachtwoord op:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Back-up starten..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Back-up voltooid"</string>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 58fc8e8..6343d0a 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -71,7 +71,7 @@
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
 import libcore.io.Streams;
-import libcore.io.StructStatFs;
+import libcore.io.StructStatVfs;
 
 /*
  * This service copies a downloaded apk to a file passed in as
@@ -246,7 +246,7 @@
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
             try {
-                final StructStatFs stat = Libcore.os.statfs(path);
+                final StructStatVfs stat = Libcore.os.statvfs(path);
                 final long totalSize = stat.f_blocks * stat.f_bsize;
                 final long availSize = stat.f_bavail * stat.f_bsize;
                 return new long[] { totalSize, availSize };
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm
new file mode 100644
index 0000000..72e6d04
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm
@@ -0,0 +1,330 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# English (US), Colemak keyboard layout.
+# Unlike the default (generic) keyboard layout, English (US) does not contain any
+# special ALT characters.
+#
+
+type OVERLAY
+
+map key 18 F
+map key 19 P
+map key 20 G
+map key 21 J
+map key 22 L
+map key 23 U
+map key 24 Y
+map key 25 SEMICOLON
+map key 31 R
+map key 32 S
+map key 33 T
+map key 34 D
+map key 36 N
+map key 37 E
+map key 38 I
+map key 39 O
+map key 49 K
+map key 58 DEL
+
+### ROW 1
+
+key GRAVE {
+    label:                              '`'
+    base:                               '`'
+    shift:                              '~'
+}
+
+key 1 {
+    label:                              '1'
+    base:                               '1'
+    shift:                              '!'
+}
+
+key 2 {
+    label:                              '2'
+    base:                               '2'
+    shift:                              '@'
+}
+
+key 3 {
+    label:                              '3'
+    base:                               '3'
+    shift:                              '#'
+}
+
+key 4 {
+    label:                              '4'
+    base:                               '4'
+    shift:                              '$'
+}
+
+key 5 {
+    label:                              '5'
+    base:                               '5'
+    shift:                              '%'
+}
+
+key 6 {
+    label:                              '6'
+    base:                               '6'
+    shift:                              '^'
+}
+
+key 7 {
+    label:                              '7'
+    base:                               '7'
+    shift:                              '&'
+}
+
+key 8 {
+    label:                              '8'
+    base:                               '8'
+    shift:                              '*'
+}
+
+key 9 {
+    label:                              '9'
+    base:                               '9'
+    shift:                              '('
+}
+
+key 0 {
+    label:                              '0'
+    base:                               '0'
+    shift:                              ')'
+}
+
+key MINUS {
+    label:                              '-'
+    base:                               '-'
+    shift:                              '_'
+}
+
+key EQUALS {
+    label:                              '='
+    base:                               '='
+    shift:                              '+'
+}
+
+### ROW 2
+
+key Q {
+    label:                              'Q'
+    base:                               'q'
+    shift, capslock:                    'Q'
+}
+
+key W {
+    label:                              'W'
+    base:                               'w'
+    shift, capslock:                    'W'
+}
+
+key F {
+    label:                              'F'
+    base:                               'f'
+    shift, capslock:                    'F'
+}
+
+key P {
+    label:                              'P'
+    base:                               'p'
+    shift, capslock:                    'P'
+}
+
+key G {
+    label:                              'G'
+    base:                               'g'
+    shift, capslock:                    'G'
+}
+
+key J {
+    label:                              'J'
+    base:                               'j'
+    shift, capslock:                    'J'
+}
+
+key L {
+    label:                              'L'
+    base:                               'l'
+    shift, capslock:                    'L'
+}
+
+key U {
+    label:                              'U'
+    base:                               'u'
+    shift, capslock:                    'U'
+}
+
+key Y {
+    label:                              'Y'
+    base:                               'y'
+    shift, capslock:                    'Y'
+}
+
+key SEMICOLON {
+    label:                              ';'
+    base:                               ';'
+    shift, capslock:                    ':'
+}
+
+key LEFT_BRACKET {
+    label:                              '['
+    base:                               '['
+    shift:                              '{'
+}
+
+key RIGHT_BRACKET {
+    label:                              ']'
+    base:                               ']'
+    shift:                              '}'
+}
+
+key BACKSLASH {
+    label:                              '\\'
+    base:                               '\\'
+    shift:                              '|'
+}
+
+### ROW 3
+
+key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+}
+
+key R {
+    label:                              'R'
+    base:                               'r'
+    shift, capslock:                    'R'
+}
+
+key S {
+    label:                              'S'
+    base:                               's'
+    shift, capslock:                    'S'
+}
+
+key T {
+    label:                              'T'
+    base:                               't'
+    shift, capslock:                    'T'
+}
+
+key D {
+    label:                              'D'
+    base:                               'd'
+    shift, capslock:                    'D'
+}
+
+key H {
+    label:                              'H'
+    base:                               'h'
+    shift, capslock:                    'H'
+}
+
+key N {
+    label:                              'N'
+    base:                               'n'
+    shift, capslock:                    'N'
+}
+
+key E {
+    label:                              'E'
+    base:                               'e'
+    shift, capslock:                    'E'
+}
+
+key I {
+    label:                              'I'
+    base:                               'i'
+    shift, capslock:                    'I'
+}
+
+key O {
+    label:                              'O'
+    base:                               'o'
+    shift:                              'O'
+}
+
+key APOSTROPHE {
+    label:                              '\''
+    base:                               '\''
+    shift:                              '"'
+}
+
+### ROW 4
+
+key Z {
+    label:                              'Z'
+    base:                               'z'
+    shift, capslock:                    'Z'
+}
+
+key X {
+    label:                              'X'
+    base:                               'x'
+    shift, capslock:                    'X'
+}
+
+key C {
+    label:                              'C'
+    base:                               'c'
+    shift, capslock:                    'C'
+}
+
+key V {
+    label:                              'V'
+    base:                               'v'
+    shift, capslock:                    'V'
+}
+
+key B {
+    label:                              'B'
+    base:                               'b'
+    shift, capslock:                    'B'
+}
+
+key K {
+    label:                              'K'
+    base:                               'k'
+    shift, capslock:                    'K'
+}
+
+key M {
+    label:                              'M'
+    base:                               'm'
+    shift, capslock:                    'M'
+}
+
+key COMMA {
+    label:                              ','
+    base:                               ','
+    shift:                              '<'
+}
+
+key PERIOD {
+    label:                              '.'
+    base:                               '.'
+    shift:                              '>'
+}
+
+key SLASH {
+    label:                              '/'
+    base:                               '/'
+    shift:                              '?'
+}
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 32c665a..54c18f1 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -15,6 +15,9 @@
     <!-- US English (International style) keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_english_us_intl">English (US), International style</string>
 
+    <!-- US English (Colemak style) keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_english_us_colemak_label">English (US), Colemak style</string>
+
     <!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak style</string>
 
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index ffd1a23..1f48a36 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -12,6 +12,10 @@
             android:label="@string/keyboard_layout_english_us_intl"
             android:keyboardLayout="@raw/keyboard_layout_english_us_intl" />
 
+    <keyboard-layout android:name="keyboard_layout_english_us_colemak"
+            android:label="@string/keyboard_layout_english_us_colemak_label"
+            android:keyboardLayout="@raw/keyboard_layout_english_us_colemak" />
+
     <keyboard-layout android:name="keyboard_layout_english_us_dvorak"
             android:label="@string/keyboard_layout_english_us_dvorak_label"
             android:keyboardLayout="@raw/keyboard_layout_english_us_dvorak" />
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index 325163d..fc9d946 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -85,7 +85,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ፈልግ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
     <string name="description_direction_down" msgid="5087739728639014595">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ታች አንሸራትት።"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index a1d11cd..35bea26 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -171,8 +171,6 @@
 
     private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
             Bundle options) {
-        final boolean isActivity = (mContext instanceof Activity); // for test activity
-
         if (mKeyguardHost != null) {
             mKeyguardHost.saveHierarchyState(mStateContainer);
         }
@@ -190,9 +188,6 @@
             if (!mNeedsInput) {
                 flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
             }
-            if (ActivityManager.isHighEndGfx()) {
-                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-            }
 
             final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
             final int type = WindowManager.LayoutParams.TYPE_KEYGUARD;
@@ -209,11 +204,8 @@
                         WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
             }
             lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
-            if (isActivity) {
-                lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            }
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
-            lp.setTitle(isActivity ? "KeyguardMock" : "Keyguard");
+            lp.setTitle("Keyguard");
             mWindowLayoutParams = lp;
             mViewManager.addView(mKeyguardHost, lp);
         }
@@ -233,9 +225,6 @@
         if (v != null) {
             mKeyguardHost.removeView(v);
         }
-        // TODO: Remove once b/7094175 is fixed
-        if (false) Slog.d(TAG, "inflateKeyguardView: b/7094175 mContext.config="
-                + mContext.getResources().getConfiguration());
         final LayoutInflater inflater = LayoutInflater.from(mContext);
         View view = inflater.inflate(R.layout.keyguard_host_view, mKeyguardHost, true);
         mKeyguardView = (KeyguardHostView) view.findViewById(R.id.keyguard_host_view);
diff --git a/packages/SystemUI/res/anim/priority_alert_enter.xml b/packages/SystemUI/res/anim/heads_up_enter.xml
similarity index 100%
rename from packages/SystemUI/res/anim/priority_alert_enter.xml
rename to packages/SystemUI/res/anim/heads_up_enter.xml
diff --git a/packages/SystemUI/res/anim/priority_alert_exit.xml b/packages/SystemUI/res/anim/heads_up_exit.xml
similarity index 100%
rename from packages/SystemUI/res/anim/priority_alert_exit.xml
rename to packages/SystemUI/res/anim/heads_up_exit.xml
diff --git a/packages/SystemUI/res/drawable/intruder_row_bg.xml b/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
similarity index 79%
rename from packages/SystemUI/res/drawable/intruder_row_bg.xml
rename to packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
index 1c7c9c4..59d9fcf 100644
--- a/packages/SystemUI/res/drawable/intruder_row_bg.xml
+++ b/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
@@ -15,6 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"  android:drawable="@drawable/intruder_bg_pressed" />
+          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+    <item android:state_pressed="true"
+          android:drawable="@drawable/heads_up_notification_bg_pressed" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/intruder_window_bg.9.png b/packages/SystemUI/res/drawable/heads_up_window_bg.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable/intruder_window_bg.9.png
rename to packages/SystemUI/res/drawable/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/intruder_alert.xml b/packages/SystemUI/res/layout/heads_up.xml
similarity index 75%
rename from packages/SystemUI/res/layout/intruder_alert.xml
rename to packages/SystemUI/res/layout/heads_up.xml
index c4141ae..b7c1666 100644
--- a/packages/SystemUI/res/layout/intruder_alert.xml
+++ b/packages/SystemUI/res/layout/heads_up.xml
@@ -19,7 +19,7 @@
 -->
 
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
-<com.android.systemui.statusbar.policy.IntruderAlertView
+<com.android.systemui.statusbar.policy.HeadsUpNotificationView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
@@ -29,12 +29,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:id="@+id/contentHolder"
-        android:background="@drawable/intruder_window_bg"
+        android:background="@drawable/heads_up_window_bg"
         />
-<!--    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/title_bar_shadow"
-        android:scaleType="fitXY"
-        /> -->
-</com.android.systemui.statusbar.policy.IntruderAlertView>
+</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index ca6e06d..4a7d090 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -27,7 +27,7 @@
     <color name="notification_list_shadow_top">#80000000</color>
     <drawable name="recents_callout_line">#99ffffff</drawable>
     <drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
-    <drawable name="intruder_bg_pressed">#ff33B5E5</drawable>
+    <drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable>
     <drawable name="notification_header_bg">#FF000000</drawable>
     <color name="notification_panel_scrim_color">#B0000000</color>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7ddf261..11940a3 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -34,7 +34,7 @@
         <item name="android:wallpaperIntraOpenExitAnimation">@anim/wallpaper_recents_launch_from_launcher_exit</item>
     </style>
 
-    <style name="TextAppearance.StatusBar.IntruderAlert"
+    <style name="TextAppearance.StatusBar.HeadsUp"
         parent="@*android:style/TextAppearance.StatusBar">
     </style>
 
@@ -154,9 +154,9 @@
     <style name="Animation.StatusBar">
     </style>
 
-    <style name="Animation.StatusBar.IntruderAlert">
-        <item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
-        <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
+    <style name="Animation.StatusBar.HeadsUp">
+        <item name="android:windowEnterAnimation">@anim/heads_up_enter</item>
+        <item name="android:windowExitAnimation">@anim/heads_up_exit</item>
     </style>
 
     <style name="TextAppearance.StatusBar.PhoneTicker"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 3583081..69fc3cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -35,10 +35,13 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.Log;
@@ -83,16 +86,19 @@
     protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
     protected static final int MSG_OPEN_SEARCH_PANEL = 1024;
     protected static final int MSG_CLOSE_SEARCH_PANEL = 1025;
-    protected static final int MSG_SHOW_INTRUDER = 1026;
-    protected static final int MSG_HIDE_INTRUDER = 1027;
+    protected static final int MSG_SHOW_HEADS_UP = 1026;
+    protected static final int MSG_HIDE_HEADS_UP = 1027;
 
-    protected static final boolean ENABLE_INTRUDERS = false;
+    protected static final boolean ENABLE_HEADS_UP = true;
+    // scores above this threshold should be displayed in heads up mode.
+    private static final int INTERRUPTION_THRESHOLD = 10;
 
     // Should match the value in PhoneWindowManager
     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
 
     public static final int EXPANDED_LEAVE_ALONE = -10000;
     public static final int EXPANDED_FULL_OPEN = -10001;
+    private static final String SETTING_HEADS_UP = "heads_up_enabled";
 
     protected CommandQueue mCommandQueue;
     protected IStatusBarService mBarService;
@@ -102,7 +108,7 @@
     protected NotificationData mNotificationData = new NotificationData();
     protected NotificationRowLayout mPile;
 
-    protected StatusBarNotification mCurrentlyIntrudingNotification;
+    protected StatusBarNotification mCurrentlyInterruptingNotification;
 
     // used to notify status bar for suppressing notification LED
     protected boolean mPanelSlightlyVisible;
@@ -116,6 +122,11 @@
 
     protected int mLayoutDirection;
     private Locale mLocale;
+    protected boolean mUseHeadsUp = true;
+
+    protected IDreamManager mDreamManager;
+    KeyguardManager mKeyguardManager;
+    PowerManager mPowerManager;
 
     // UI-specific methods
 
@@ -155,6 +166,19 @@
         }
     };
 
+    final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange) {
+            mUseHeadsUp = ENABLE_HEADS_UP && 0 != Settings.Global.getInt(
+                    mContext.getContentResolver(), SETTING_HEADS_UP, 0);
+            Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
+            if (!mUseHeadsUp) {
+                Log.d(TAG, "dismissing any existing heads up notification on disable event");
+                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+            }
+        }
+    };
+
     private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
         @Override
         public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
@@ -204,11 +228,21 @@
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
         mDisplay = mWindowManager.getDefaultDisplay();
 
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
+        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+
         mProvisioningObserver.onChange(false); // set up
         mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
                 mProvisioningObserver);
 
+        mHeadsUpObserver.onChange(false); // set up
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(SETTING_HEADS_UP), true,
+                mHeadsUpObserver);
+
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
 
@@ -398,7 +432,7 @@
         }
     }
 
-    public void dismissIntruder() {
+    public void dismissHeadsUp() {
         // pass
     }
 
@@ -677,13 +711,13 @@
         return new NotificationClicker(intent, pkg, tag, id);
     }
 
-    private class NotificationClicker implements View.OnClickListener {
+    protected class NotificationClicker implements View.OnClickListener {
         private PendingIntent mIntent;
         private String mPkg;
         private String mTag;
         private int mId;
 
-        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
+        public NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
             mIntent = intent;
             mPkg = pkg;
             mTag = tag;
@@ -730,9 +764,6 @@
             // close the shade if it was open
             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
             visibilityChanged(false);
-
-            // If this click was on the intruder alert, hide that instead
-//            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
         }
     }
     /**
@@ -997,18 +1028,30 @@
         setAreThereNotifications();
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
 
-        // See if we need to update the intruder.
-        if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
-            if (DEBUG) Log.d(TAG, "updating the current intruder:" + notification);
+        // See if we need to update the heads up.
+        if (ENABLE_HEADS_UP && oldNotification == mCurrentlyInterruptingNotification) {
+            if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
             // XXX: this is a hack for Alarms. The real implementation will need to *update*
-            // the intruder.
-            if (notification.getNotification().fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
-                if (DEBUG) Log.d(TAG, "no longer intrudes!");
-                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+            // the heads up.
+            if (!shouldInterrupt(notification)) {
+                if (DEBUG) Log.d(TAG, "no longer interrupts!");
+                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
             }
         }
     }
 
+    protected boolean shouldInterrupt(StatusBarNotification notification) {
+        boolean interrupt = notification.getNotification().fullScreenIntent == null
+                && notification.getScore() >= INTERRUPTION_THRESHOLD
+                && mPowerManager.isScreenOn() && !mKeyguardManager.isKeyguardLocked();
+        try {
+            interrupt = interrupt && !mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.d(TAG, "failed to query dream manager", e);
+        }
+        return interrupt;
+    }
+
     // Q: What kinds of notifications should show during setup?
     // A: Almost none! Only things coming from the system (package is "android") that also
     // have special "kind" tags marking them as relevant for setup (see below).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ee94cc8..fd99f5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -45,12 +45,9 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -76,7 +73,6 @@
 import android.widget.ScrollView;
 import android.widget.TextView;
 import android.widget.Toast;
-
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
@@ -90,7 +86,7 @@
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.DateView;
-import com.android.systemui.statusbar.policy.IntruderAlertView;
+import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
 import com.android.systemui.statusbar.policy.LocationController;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NotificationRowLayout;
@@ -127,7 +123,7 @@
     // 1020-1030 reserved for BaseStatusBar
 
     // will likely move to a resource or other tunable param at some point
-    private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
+    private static final int HEADS_UP_DECAY_MS = 0; // disabled, was 10000;
 
     private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
 
@@ -169,8 +165,6 @@
     Display mDisplay;
     Point mCurrentDisplaySize = new Point();
 
-    IDreamManager mDreamManager;
-
     StatusBarWindowView mStatusBarWindow;
     PhoneStatusBarView mStatusBarView;
 
@@ -230,8 +224,8 @@
     // the date view
     DateView mDateView;
 
-    // for immersive activities
-    private IntruderAlertView mIntruderAlertView;
+    // for heads up notifications
+    private HeadsUpNotificationView mHeadsUpNotificationView;
 
     // on-screen navigation buttons
     private NavigationBarView mNavigationBarView = null;
@@ -358,14 +352,11 @@
                 .getDefaultDisplay();
         mDisplay.getSize(mCurrentDisplaySize);
 
-        mDreamManager = IDreamManager.Stub.asInterface(
-                ServiceManager.checkService(DreamService.DREAM_SERVICE));
-
         super.start(); // calls createAndAddWindows()
 
         addNavigationBar();
 
-        if (ENABLE_INTRUDERS) addIntruderView();
+        if (ENABLE_HEADS_UP) addHeadsUpView();
 
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext);
@@ -424,10 +415,11 @@
             mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
                     R.color.notification_panel_solid_background)));
         }
-        if (ENABLE_INTRUDERS) {
-            mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
-            mIntruderAlertView.setVisibility(View.GONE);
-            mIntruderAlertView.setBar(this);
+        if (ENABLE_HEADS_UP) {
+            mHeadsUpNotificationView =
+                    (HeadsUpNotificationView) View.inflate(context, R.layout.heads_up, null);
+            mHeadsUpNotificationView.setVisibility(View.GONE);
+            mHeadsUpNotificationView.setBar(this);
         }
         if (MULTIUSER_DEBUG) {
             mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
@@ -833,7 +825,7 @@
         return lp;
     }
 
-    private void addIntruderView() {
+    private void addHeadsUpView() {
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -847,11 +839,11 @@
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         //lp.y += height * 1.5; // FIXME
-        lp.setTitle("IntruderAlert");
+        lp.setTitle("Heads Up");
         lp.packageName = mContext.getPackageName();
-        lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
+        lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
 
-        mWindowManager.addView(mIntruderAlertView, lp);
+        mWindowManager.addView(mHeadsUpNotificationView, lp);
     }
 
     public void refreshAllStatusBarIcons() {
@@ -895,52 +887,31 @@
         StatusBarIconView iconView = addNotificationViews(key, notification);
         if (iconView == null) return;
 
-        boolean immersive = false;
-        try {
-            immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
-            if (DEBUG) {
-                Log.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
-            }
-        } catch (RemoteException ex) {
-        }
-
-        /*
-         * DISABLED due to missing API
-        if (ENABLE_INTRUDERS && (
-                   // TODO(dsandler): Only if the screen is on
-                notification.notification.intruderView != null)) {
-            Log.d(TAG, "Presenting high-priority notification");
-            // special new transient ticker mode
-            // 1. Populate mIntruderAlertView
-
-            if (notification.notification.intruderView == null) {
-                Log.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
-                return;
-            }
+        if (mUseHeadsUp && shouldInterrupt(notification)) {
+            if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
+            // 1. Populate mHeadsUpNotificationView
 
             // bind the click event to the content area
-            PendingIntent contentIntent = notification.notification.contentIntent;
+            PendingIntent contentIntent = notification.getNotification().contentIntent;
             final View.OnClickListener listener = (contentIntent != null)
                     ? new NotificationClicker(contentIntent,
-                            notification.pkg, notification.tag, notification.id)
+                    notification.getPackageName(), notification.getTag(), notification.getId())
                     : null;
 
-            mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
+            if (mHeadsUpNotificationView.applyContent(notification.getNotification(), listener)) {
 
-            mCurrentlyIntrudingNotification = notification;
+                mCurrentlyInterruptingNotification = notification;
 
-            // 2. Animate mIntruderAlertView in
-            mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
+                // 2. Animate mHeadsUpNotificationView in
+                mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
 
-            // 3. Set alarm to age the notification off (TODO)
-            mHandler.removeMessages(MSG_HIDE_INTRUDER);
-            if (INTRUDER_ALERT_DECAY_MS > 0) {
-                mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
+                // 3. Set alarm to age the notification off (TODO)
+                mHandler.removeMessages(MSG_HIDE_HEADS_UP);
+                if (HEADS_UP_DECAY_MS > 0) {
+                    mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, HEADS_UP_DECAY_MS);
+                }
             }
-        } else
-         */
-
-        if (notification.getNotification().fullScreenIntent != null) {
+        } else if (notification.getNotification().fullScreenIntent != null) {
             // Stop screensaver if the notification has a full-screen intent.
             // (like an incoming phone call)
             awakenDreams();
@@ -954,8 +925,8 @@
         } else {
             // usual case: status bar visible & not immersive
 
-            // show the ticker if there isn't an intruder too
-            if (mCurrentlyIntrudingNotification == null) {
+            // show the ticker if there isn't already a heads up
+            if (mCurrentlyInterruptingNotification == null) {
                 tick(null, notification, true);
             }
         }
@@ -976,8 +947,8 @@
             // Recalculate the position of the sliding windows and the titles.
             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
 
-            if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
-                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+            if (ENABLE_HEADS_UP && old == mCurrentlyInterruptingNotification) {
+                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
             }
 
             if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0) {
@@ -1359,12 +1330,12 @@
                 case MSG_CLOSE_PANELS:
                     animateCollapsePanels();
                     break;
-                case MSG_SHOW_INTRUDER:
-                    setIntruderAlertVisibility(true);
+                case MSG_SHOW_HEADS_UP:
+                    setHeadsUpVisibility(true);
                     break;
-                case MSG_HIDE_INTRUDER:
-                    setIntruderAlertVisibility(false);
-                    mCurrentlyIntrudingNotification = null;
+                case MSG_HIDE_HEADS_UP:
+                    setHeadsUpVisibility(false);
+                    mCurrentlyInterruptingNotification = null;
                     break;
             }
         }
@@ -2487,22 +2458,20 @@
                 mCurrentUserId);
     }
 
-    private void setIntruderAlertVisibility(boolean vis) {
-        if (!ENABLE_INTRUDERS) return;
-        if (DEBUG) {
-            Log.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
-        }
-        mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
+    private void setHeadsUpVisibility(boolean vis) {
+        if (!ENABLE_HEADS_UP) return;
+        if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
+        mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
     }
 
-    public void dismissIntruder() {
-        if (mCurrentlyIntrudingNotification == null) return;
+    public void dismissHeadsUp() {
+        if (mCurrentlyInterruptingNotification == null) return;
 
         try {
             mBarService.onNotificationClear(
-                    mCurrentlyIntrudingNotification.getPackageName(),
-                    mCurrentlyIntrudingNotification.getTag(),
-                    mCurrentlyIntrudingNotification.getId());
+                    mCurrentlyInterruptingNotification.getPackageName(),
+                    mCurrentlyInterruptingNotification.getTag(),
+                    mCurrentlyInterruptingNotification.getId());
         } catch (android.os.RemoteException ex) {
             // oh well
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
similarity index 79%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index dbd36af..dbf9957 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.app.Notification;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -27,14 +28,13 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
-import android.widget.RemoteViews;
 
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.statusbar.BaseStatusBar;
 
-public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callback {
-    private static final String TAG = "IntruderAlertView";
+public class HeadsUpNotificationView extends LinearLayout implements SwipeHelper.Callback {
+    private static final String TAG = "HeadsUpNotificationView";
     private static final boolean DEBUG = false;
 
     Rect mTmpRect = new Rect();
@@ -44,14 +44,14 @@
     BaseStatusBar mBar;
     private ViewGroup mContentHolder;
     
-    private RemoteViews mIntruderRemoteViews;
+    private Notification mHeadsUp;
     private OnClickListener mOnClickListener;
 
-    public IntruderAlertView(Context context, AttributeSet attrs) {
+    public HeadsUpNotificationView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public IntruderAlertView(Context context, AttributeSet attrs, int defStyle) {
+    public HeadsUpNotificationView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
         setOrientation(LinearLayout.VERTICAL);
@@ -64,9 +64,9 @@
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
         
         mContentHolder = (ViewGroup) findViewById(R.id.contentHolder);
-        if (mIntruderRemoteViews != null) {
+        if (mHeadsUp != null) {
             // whoops, we're on already!
-            applyIntruderContent(mIntruderRemoteViews, mOnClickListener);
+            applyContent(mHeadsUp, mOnClickListener);
         }
     }
     
@@ -92,8 +92,8 @@
     }
 
     public void onChildDismissed(View v) {
-        Log.v(TAG, "User swiped intruder to dismiss");
-        mBar.dismissIntruder();
+        Log.v(TAG, "User swiped heads up to dismiss");
+        mBar.dismissHeadsUp();
     }
 
     public void onBeginDrag(View v) {
@@ -134,33 +134,34 @@
         }
     }
 
-    public void applyIntruderContent(RemoteViews intruderView, OnClickListener listener) {
-        if (DEBUG) {
-            Log.v(TAG, "applyIntruderContent: view=" + intruderView + " listener=" + listener);
-        }
-        mIntruderRemoteViews = intruderView;
+    public boolean applyContent(Notification headsUp, OnClickListener listener) {
+        mHeadsUp = headsUp;
         mOnClickListener = listener;
-        if (mContentHolder == null) { 
+        if (mContentHolder == null) {
             // too soon!
-            return;
+            return false;
+        }
+        if (headsUp.contentView == null) {
+            // bad data
+            return false;
         }
         mContentHolder.setX(0);
         mContentHolder.setVisibility(View.VISIBLE);
         mContentHolder.setAlpha(1f);
         mContentHolder.removeAllViews();
-        final View content = intruderView.apply(getContext(), mContentHolder);
+        final View content = headsUp.contentView.apply(getContext(), mContentHolder);
         if (listener != null) {
             content.setOnClickListener(listener);
-            
-            //content.setBackgroundResource(R.drawable.intruder_row_bg);
-            Drawable bg = getResources().getDrawable(R.drawable.intruder_row_bg);
+
+            Drawable bg = getResources().getDrawable(R.drawable.heads_up_notification_row_bg);
             if (bg == null) {
-                Log.e(TAG, String.format("Can't find background drawable id=0x%08x", R.drawable.intruder_row_bg));
+                Log.e(TAG, String.format("Can't find background drawable id=0x%08x",
+                        R.drawable.heads_up_notification_row_bg));
             } else {
                 content.setBackgroundDrawable(bg);
             }
         }
         mContentHolder.addView(content);
-        
+        return true;
     }
 }
\ No newline at end of file
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0b8b028..262b7ee 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -33,6 +33,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -4789,8 +4790,8 @@
         ActivityInfo ai = null;
         ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(
                 intent,
-                PackageManager.MATCH_DEFAULT_ONLY,
-                UserHandle.USER_CURRENT);
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
+                getCurrentUserId());
         if (info != null) {
             ai = info.activityInfo;
         }
@@ -4805,6 +4806,16 @@
         return null;
     }
 
+    private int getCurrentUserId() {
+        try {
+            UserInfo user = ActivityManagerNative.getDefault().getCurrentUser();
+            return user != null ? user.id : UserHandle.USER_NULL;
+        } catch (RemoteException e) {
+            // noop
+        }
+        return UserHandle.USER_NULL;
+    }
+
     void startDockOrHome() {
         awakenDreams();
 
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 65749b3..fab091f 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -1188,6 +1188,11 @@
             mBuiltInKeyboardId = device->id;
         }
 
+        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
+        if (hasKeycodeLocked(device, AKEYCODE_Q)) {
+            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
+        }
+
         // See if this device has a DPAD.
         if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
                 hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
@@ -1205,14 +1210,6 @@
             }
         }
 
-        // 'Q' key support = cheap test of whether this is an alpha-capable kbd. Many gamepads will
-        // report a broader set of HID usages than they need, however, so we only want to mark this
-        // device as a keyboard if it is not a gamepad.
-        if (hasKeycodeLocked(device, AKEYCODE_Q) &&
-                !(device->classes & INPUT_DEVICE_CLASS_GAMEPAD)) {
-            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
-        }
-
         // Disable kernel key repeat since we handle it ourselves
         unsigned int repeatRate[] = {0,0};
         if (ioctl(fd, EVIOCSREP, repeatRate)) {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 6e24d68..1c1b002 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1511,23 +1511,16 @@
                 final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
                 if (imi != null && iconVisibility && needsToShowImeSwitchOngoingNotification()) {
                     // Used to load label
-                    final PackageManager pm = mContext.getPackageManager();
                     final CharSequence title = mRes.getText(
                             com.android.internal.R.string.select_input_method);
-                    final CharSequence imiLabel = imi.loadLabel(pm);
-                    final CharSequence summary = mCurrentSubtype != null
-                            ? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext,
-                                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
-                                                (TextUtils.isEmpty(imiLabel) ?
-                                                        "" : " - " + imiLabel))
-                            : imiLabel;
+                    final CharSequence summary = InputMethodUtils.getImeAndSubtypeDisplayName(
+                            mContext, imi, mCurrentSubtype);
 
                     mImeSwitcherNotification.setLatestEventInfo(
                             mContext, title, summary, mImeSwitchPendingIntent);
                     if (mNotificationManager != null) {
                         if (DEBUG) {
-                            Slog.d(TAG, "--- show notification: label =  " + imiLabel
-                                    + ", summary = " + summary);
+                            Slog.d(TAG, "--- show notification: label =  " + summary);
                         }
                         mNotificationManager.notifyAsUser(null,
                                 com.android.internal.R.string.select_input_method,
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 231cfe1..c6c9845 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -47,7 +47,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -222,6 +221,9 @@
             AppOpsManager.Callback callback = new AppOpsManager.Callback() {
                 public void opChanged(int op, String packageName) {
                     synchronized (mLock) {
+                        for (Receiver receiver : mReceivers.values()) {
+                            receiver.updateMonitoring(true);
+                        }
                         applyAllProviderRequirementsLocked();
                     }
                 }
@@ -460,6 +462,7 @@
 
         final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
 
+        boolean mOpMonitoring;
         int mPendingBroadcasts;
         PowerManager.WakeLock mWakeLock;
 
@@ -477,6 +480,8 @@
             mPid = pid;
             mPackageName = packageName;
 
+            updateMonitoring(true);
+
             // construct/configure wakelock
             mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
             mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName));
@@ -512,6 +517,21 @@
             return s.toString();
         }
 
+        public void updateMonitoring(boolean allow) {
+            if (!mOpMonitoring) {
+                if (allow) {
+                    mOpMonitoring = mAppOps.startOpNoThrow(AppOpsManager.OP_MONITOR_LOCATION,
+                            mUid, mPackageName) == AppOpsManager.MODE_ALLOWED;
+                }
+            } else {
+                if (!allow || mAppOps.checkOpNoThrow(AppOpsManager.OP_MONITOR_LOCATION,
+                        mUid, mPackageName) != AppOpsManager.MODE_ALLOWED) {
+                    mAppOps.finishOp(AppOpsManager.OP_MONITOR_LOCATION, mUid, mPackageName);
+                    mOpMonitoring = false;
+                }
+            }
+        }
+
         public boolean isListener() {
             return mListener != null;
         }
@@ -1366,6 +1386,8 @@
             }
         }
 
+        receiver.updateMonitoring(false);
+
         // Record which providers were associated with this listener
         HashSet<String> providers = new HashSet<String>();
         HashMap<String, UpdateRecord> oldRecords = receiver.mUpdateRecords;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0bd0d8e..65006e5 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1000,7 +1000,6 @@
     static final int USER_SWITCH_TIMEOUT_MSG = 36;
     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
     static final int PERSIST_URI_GRANTS = 38;
-    static final int SET_FOCUSED_STACK = 39;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1493,18 +1492,6 @@
                 writeGrantedUriPermissions();
                 break;
             }
-            case SET_FOCUSED_STACK: {
-                synchronized (ActivityManagerService.this) {
-                    ActivityStack stack = mStackSupervisor.getStack(msg.arg1);
-                    if (stack != null) {
-                        ActivityRecord r = stack.topRunningActivityLocked(null);
-                        if (r != null) {
-                            setFocusedActivityLocked(r);
-                        }
-                    }
-                }
-                break;
-            }
             }
         }
     };
@@ -1795,7 +1782,7 @@
                 return;
             }
 
-            mActivityManagerService.dumpProcessTracker(fd, pw, args);
+            mActivityManagerService.mProcessTracker.dump(fd, pw, args);
         }
     }
 
@@ -1821,7 +1808,7 @@
                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
         mBatteryStatsService.getActiveStatistics().setCallback(this);
 
-        mProcessTracker = new ProcessTracker(new File(systemDir, "procstats"));
+        mProcessTracker = new ProcessTracker(this, new File(systemDir, "procstats"));
 
         mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
@@ -2081,7 +2068,26 @@
     @Override
     public void setFocusedStack(int stackId) {
         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
-        mHandler.obtainMessage(SET_FOCUSED_STACK, stackId, 0).sendToTarget();
+        synchronized (ActivityManagerService.this) {
+            ActivityStack stack = mStackSupervisor.getStack(stackId);
+            if (stack != null) {
+                ActivityRecord r = stack.topRunningActivityLocked(null);
+                if (r != null) {
+                    setFocusedActivityLocked(r);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void notifyActivityDrawn(IBinder token) {
+        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
+        synchronized (this) {
+            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
+            if (r != null) {
+                r.task.stack.notifyActivityDrawnLocked(r);
+            }
+        }
     }
 
     final void applyUpdateLockStateLocked(ActivityRecord r) {
@@ -8048,7 +8054,7 @@
     }
 
     @Override
-    public void convertToOpaque(IBinder token) {
+    public void convertFromTranslucent(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
@@ -8056,8 +8062,28 @@
                 if (r == null) {
                     return;
                 }
-                if (r.convertToOpaque()) {
-                    mWindowManager.setAppFullscreen(token);
+                if (r.changeWindowTranslucency(true)) {
+                    mWindowManager.setAppFullscreen(token, true);
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void convertToTranslucent(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return;
+                }
+                if (r.changeWindowTranslucency(false)) {
+                    r.task.stack.convertToTranslucent(r);
+                    mWindowManager.setAppFullscreen(token, false);
                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
                 }
             }
@@ -10186,7 +10212,7 @@
                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
                         pw.println("");
                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
-                pw.println("  mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
+                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
                         + " (" + mLruProcesses.size() + " total)"
@@ -10963,23 +10989,37 @@
     }
 
     final static class MemItem {
+        final boolean isProc;
         final String label;
         final String shortLabel;
         final long pss;
         final int id;
+        final boolean hasActivities;
         ArrayList<MemItem> subitems;
 
-        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
+        public MemItem(String _label, String _shortLabel, long _pss, int _id,
+                boolean _hasActivities) {
+            isProc = true;
             label = _label;
             shortLabel = _shortLabel;
             pss = _pss;
             id = _id;
+            hasActivities = _hasActivities;
+        }
+
+        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
+            isProc = false;
+            label = _label;
+            shortLabel = _shortLabel;
+            pss = _pss;
+            id = _id;
+            hasActivities = false;
         }
     }
 
-    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
-            boolean sort) {
-        if (sort) {
+    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
+            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
+        if (sort && !isCompact) {
             Collections.sort(items, new Comparator<MemItem>() {
                 @Override
                 public int compare(MemItem lhs, MemItem rhs) {
@@ -10995,9 +11035,19 @@
 
         for (int i=0; i<items.size(); i++) {
             MemItem mi = items.get(i);
-            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
+            if (!isCompact) {
+                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
+            } else if (mi.isProc) {
+                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
+                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
+                pw.println(mi.hasActivities ? ",a" : ",e");
+            } else {
+                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
+                pw.println(mi.pss);
+            }
             if (mi.subitems != null) {
-                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
+                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
+                        true, isCompact);
             }
         }
     }
@@ -11042,6 +11092,12 @@
             "Backup", "A Services", "Home", "Previous",
             "B Services", "Cached"
     };
+    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
+            "sys", "pers", "fore",
+            "vis", "percept", "heavy",
+            "backup", "servicea", "home", "prev",
+            "serviceb", "cached"
+    };
 
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
             PrintWriter pw, String prefix, String[] args, boolean brief,
@@ -11049,6 +11105,7 @@
         boolean dumpDetails = false;
         boolean dumpDalvik = false;
         boolean oomOnly = false;
+        boolean isCompact = false;
         
         int opti = 0;
         while (opti < args.length) {
@@ -11062,12 +11119,15 @@
                 dumpDalvik = true;
             } else if ("-d".equals(opt)) {
                 dumpDalvik = true;
+            } else if ("-c".equals(opt)) {
+                isCompact = true;
             } else if ("--oom".equals(opt)) {
                 oomOnly = true;
             } else if ("-h".equals(opt)) {
-                pw.println("meminfo dump options: [-a] [--oom] [process]");
+                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
                 pw.println("  -a: include all available information for each process.");
                 pw.println("  -d: include dalvik details when dumping process details.");
+                pw.println("  -c: dump in a compact machine-parseable representation.");
                 pw.println("  --oom: only show processes organized by oom adj.");
                 pw.println("If [process] is specified it can be the name or ");
                 pw.println("pid of a specific process to dump.");
@@ -11090,10 +11150,9 @@
             dumpDetails = true;
         }
 
-        if (isCheckinRequest) {
+        if (isCheckinRequest || isCompact) {
             // short checkin version
-            pw.println(uptime + "," + realtime);
-            pw.flush();
+            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
         } else {
             pw.println("Applications Memory Usage (kB):");
             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
@@ -11115,20 +11174,24 @@
 
         Debug.MemoryInfo mi = null;
         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
-            ProcessRecord r = procs.get(i);
-            IApplicationThread thread;
-            int oomAdj;
+            final ProcessRecord r = procs.get(i);
+            final IApplicationThread thread;
+            final int pid;
+            final int oomAdj;
+            final boolean hasActivities;
             synchronized (this) {
                 thread = r.thread;
+                pid = r.pid;
                 oomAdj = r.getSetAdjWithServices();
+                hasActivities = r.hasActivities;
             }
             if (thread != null) {
                 if (!isCheckinRequest && dumpDetails) {
-                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
-                    pw.flush();
+                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
                 }
                 if (dumpDetails) {
                     try {
+                        pw.flush();
                         mi = null;
                         mi = thread.dumpMemInfo(fd, isCheckinRequest, true, dumpDalvik, innerArgs);
                     } catch (RemoteException e) {
@@ -11142,9 +11205,9 @@
                         mi = new Debug.MemoryInfo();
                     }
                     if (!brief && !oomOnly) {
-                        Debug.getMemoryInfo(r.pid, mi);
+                        Debug.getMemoryInfo(pid, mi);
                     } else {
-                        mi.dalvikPss = (int)Debug.getPss(r.pid);
+                        mi.dalvikPss = (int)Debug.getPss(pid);
                     }
                 }
 
@@ -11159,8 +11222,9 @@
 
                 if (!isCheckinRequest && mi != null) {
                     totalPss += myTotalPss;
-                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
-                            r.processName, myTotalPss, 0);
+                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
+                            (hasActivities ? " / activities)" : ")"),
+                            r.processName, myTotalPss, pid, hasActivities);
                     procMems.add(pssItem);
 
                     nativePss += mi.nativePss;
@@ -11177,7 +11241,7 @@
                     }
 
                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
-                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
+                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
                                 || oomIndex == (oomPss.length-1)) {
                             oomPss[oomIndex] += myTotalPss;
                             if (oomProcs[oomIndex] == null) {
@@ -11205,7 +11269,8 @@
             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
             for (int j=0; j<oomPss.length; j++) {
                 if (oomPss[j] != 0) {
-                    String label = DUMP_MEM_OOM_LABEL[j];
+                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
+                            : DUMP_MEM_OOM_LABEL[j];
                     MemItem item = new MemItem(label, label, oomPss[j],
                             DUMP_MEM_OOM_ADJ[j]);
                     item.subitems = oomProcs[j];
@@ -11275,29 +11340,45 @@
                 }
             }
 
-            if (!brief && !oomOnly) {
+            if (!brief && !oomOnly && !isCompact) {
                 pw.println();
                 pw.println("Total PSS by process:");
-                dumpMemItems(pw, "  ", procMems, true);
+                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
                 pw.println();
             }
-            pw.println("Total PSS by OOM adjustment:");
-            dumpMemItems(pw, "  ", oomMems, false);
+            if (!isCompact) {
+                pw.println("Total PSS by OOM adjustment:");
+            }
+            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
             if (!brief && !oomOnly) {
                 PrintWriter out = categoryPw != null ? categoryPw : pw;
-                out.println();
-                out.println("Total PSS by category:");
-                dumpMemItems(out, "  ", catMems, true);
+                if (!isCompact) {
+                    out.println();
+                    out.println("Total PSS by category:");
+                }
+                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
             }
-            pw.println();
+            if (!isCompact) {
+                pw.println();
+            }
             if (!brief) {
                 MemInfoReader memInfo = new MemInfoReader();
                 memInfo.readMemInfo();
-                pw.print("Total RAM: "); pw.print(memInfo.getTotalSize()/1024); pw.println(" kB");
-                pw.print(" Free RAM: "); pw.print(cachedPss + (memInfo.getCachedSize()/1024)
-                        + (memInfo.getFreeSize()/1024)); pw.println(" kB");
+                if (!isCompact) {
+                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSize()/1024);
+                    pw.println(" kB");
+                    pw.print(" Free RAM: "); pw.print(cachedPss + (memInfo.getCachedSize()/1024)
+                            + (memInfo.getFreeSize()/1024)); pw.println(" kB");
+                } else {
+                    pw.print("ram,"); pw.print(memInfo.getTotalSize()/1024); pw.print(",");
+                    pw.print(cachedPss + (memInfo.getCachedSize()/1024)
+                            + (memInfo.getFreeSize()/1024)); pw.print(",");
+                    pw.println(totalPss - cachedPss);
+                }
             }
-            pw.print(" Used PSS: "); pw.print(totalPss - cachedPss); pw.println(" kB");
+            if (!isCompact) {
+                pw.print(" Used PSS: "); pw.print(totalPss - cachedPss); pw.println(" kB");
+            }
             if (!brief) {
                 final int[] SINGLE_LONG_FORMAT = new int[] {
                     Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
@@ -11318,11 +11399,18 @@
                 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
                         SINGLE_LONG_FORMAT, null, longOut, null);
                 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
-                if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
-                    pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
-                            pw.print(shared); pw.println(" kB");
-                    pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
-                            pw.print(voltile); pw.println(" kB volatile");
+                if (!isCompact) {
+                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
+                        pw.print("      KSM: "); pw.print(sharing);
+                                pw.print(" kB saved from shared ");
+                                pw.print(shared); pw.println(" kB");
+                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
+                                pw.print(voltile); pw.println(" kB volatile");
+                    }
+                } else {
+                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
+                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
+                    pw.println(voltile);
                 }
             }
         }
@@ -11345,12 +11433,6 @@
         return false;
     }
 
-    final void dumpProcessTracker(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (this) {
-            mProcessTracker.dumpLocked(fd, pw, args);
-        }
-    }
-
     private final boolean removeDyingProviderLocked(ProcessRecord proc,
             ContentProviderRecord cpr, boolean always) {
         final boolean inLaunching = mLaunchingProviders.contains(cpr);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 4f09407..2ae9ed6 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import android.os.Trace;
+import com.android.internal.R.styleable;
 import com.android.internal.app.ResolverActivity;
 import com.android.server.AttributeCache;
 import com.android.server.am.ActivityStack.ActivityState;
@@ -505,19 +506,23 @@
         }
     }
 
-    boolean convertToOpaque() {
-        if (fullscreen) {
+    boolean changeWindowTranslucency(boolean toOpaque) {
+        if (fullscreen == toOpaque) {
+            return false;
+        }
+        AttributeCache.Entry ent =
+                AttributeCache.instance().get(packageName, realTheme, styleable.Window);
+        if (ent == null
+                || !ent.array.getBoolean(styleable.Window_windowIsTranslucent, false)
+                || ent.array.getBoolean(styleable.Window_windowIsFloating, false)) {
             return false;
         }
 
-        AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
-                realTheme, com.android.internal.R.styleable.Window);
-        if (ent != null && !ent.array.getBoolean(
-                com.android.internal.R.styleable.Window_windowIsFloating, false)) {
-            fullscreen = true;
-            ++task.numFullscreen;
-        }
-        return fullscreen;
+        // Keep track of the number of fullscreen activities in this task.
+        task.numFullscreen += toOpaque ? +1 : -1;
+
+        fullscreen = toOpaque;
+        return true;
     }
 
     void putInHistory() {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index de220e5..be03ee3 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -70,7 +70,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -103,9 +102,6 @@
     // from the application in order to get its saved state.
     static final int STOP_TIMEOUT = 10*1000;
 
-    // How long we can hold the launch wake lock before giving up.
-    static final int LAUNCH_TIMEOUT = 10*1000;
-
     // How long we wait until giving up on an activity telling us it has
     // finished destroying itself.
     static final int DESTROY_TIMEOUT = 10*1000;
@@ -122,9 +118,9 @@
     // is being started.
     static final boolean SHOW_APP_STARTING_PREVIEW = true;
 
-    // For debugging to make sure the caller when acquiring/releasing our
-    // wake lock is the system process.
-    static final boolean VALIDATE_WAKE_LOCK_CALLER = true;
+    // How long to wait for all background Activities to redraw following a call to
+    // convertToTranslucent().
+    static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
 
     enum ActivityState {
         INITIALIZING,
@@ -168,14 +164,6 @@
     final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();
 
     /**
-     * We don't want to allow the device to go to sleep while in the process
-     * of launching an activity.  This is primarily to allow alarm intent
-     * receivers to launch an activity and get that to run before the device
-     * goes back to sleep.
-     */
-    final PowerManager.WakeLock mLaunchingActivity;
-
-    /**
      * When we are in the process of pausing an activity, before starting the
      * next one, this variable holds the activity that is currently being paused.
      */
@@ -200,6 +188,16 @@
      */
     ActivityRecord mLastStartedActivity = null;
 
+    // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
+    // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
+    // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
+    // Activity in mTranslucentActivityWaiting is notified via
+    // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
+    // background activity being drawn then the same call will be made with a true value.
+    ActivityRecord mTranslucentActivityWaiting = null;
+    ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
+            new ArrayList<ActivityRecord>();
+
     /**
      * Set when we know we are going to be calling updateConfiguration()
      * soon, so want to skip intermediate config checks.
@@ -226,12 +224,12 @@
     /** Run all ActivityStacks through this */
     final ActivityStackSupervisor mStackSupervisor;
 
-    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG;
-    static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
+    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
     static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
     static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
     static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
     static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
+    static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
 
     static class ScheduleDestroyArgs {
         final ProcessRecord mOwner;
@@ -286,23 +284,6 @@
                         activityDestroyedLocked(r != null ? r.appToken : null);
                     }
                 } break;
-                case LAUNCH_TIMEOUT_MSG: {
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
-                        return;
-                    }
-                    synchronized (mService) {
-                        if (mLaunchingActivity.isHeld()) {
-                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
-                            if (VALIDATE_WAKE_LOCK_CALLER
-                                    && Binder.getCallingUid() != Process.myUid()) {
-                                throw new IllegalStateException("Calling must be system uid");
-                            }
-                            mLaunchingActivity.release();
-                        }
-                    }
-                } break;
                 case STOP_TIMEOUT_MSG: {
                     ActivityRecord r = (ActivityRecord)msg.obj;
                     // We don't at this point know if the activity is fullscreen,
@@ -319,7 +300,12 @@
                     synchronized (mService) {
                         destroyActivitiesLocked(args.mOwner, args.mOomAdj, args.mReason);
                     }
-                }
+                } break;
+                case TRANSLUCENT_TIMEOUT_MSG: {
+                    synchronized (mService) {
+                        notifyActivityDrawnLocked(null);
+                    }
+                } break;
             }
         }
     }
@@ -339,12 +325,6 @@
         mStackSupervisor = service.mStackSupervisor;
         mContext = context;
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-            throw new IllegalStateException("Calling must be system uid");
-        }
-        mLaunchingActivity =
-                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
-        mLaunchingActivity.setReferenceCounted(false);
         mStackId = stackId;
         mCurrentUser = service.mCurrentUserId;
     }
@@ -628,16 +608,6 @@
         r.displayStartTime = r.fullyDrawnStartTime = 0;
     }
 
-    void stopIfSleepingLocked() {
-        if (mLaunchingActivity.isHeld()) {
-            if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-                throw new IllegalStateException("Calling must be system uid");
-            }
-            mLaunchingActivity.release();
-            mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-        }
-    }
-
     void awakeFromSleepingLocked() {
         // Ensure activities are no longer sleeping.
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -762,14 +732,7 @@
         // If we are not going to sleep, we want to ensure the device is
         // awake until the next activity is started.
         if (!mService.isSleepingOrShuttingDown()) {
-            if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-                throw new IllegalStateException("Calling must be system uid");
-            }
-            mLaunchingActivity.acquire();
-            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
-                // To be safe, don't allow the wake lock to be held for too long.
-                mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
-            }
+            mStackSupervisor.acquireLaunchWakelock();
         }
 
         if (mPausingActivity != null) {
@@ -1009,6 +972,16 @@
                 TAG, "ensureActivitiesVisible behind " + top
                 + " configChanges=0x" + Integer.toHexString(configChanges));
 
+        if (mTranslucentActivityWaiting != top) {
+            mUndrawnActivitiesBelowTopTranslucent.clear();
+            if (mTranslucentActivityWaiting != null) {
+                // Call the callback with a timeout indication.
+                notifyActivityDrawnLocked(null);
+                mTranslucentActivityWaiting = null;
+            }
+            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
+        }
+
         // If the top activity is not fullscreen, then we need to
         // make sure any activities under it are now visible.
         boolean aboveTop = true;
@@ -1075,6 +1048,9 @@
                             if (DEBUG_VISBILITY) Slog.v(
                                     TAG, "Making visible and scheduling visibility: " + r);
                             try {
+                                if (mTranslucentActivityWaiting != null) {
+                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
+                                }
                                 mWindowManager.setAppVisibility(r.appToken, true);
                                 r.sleeping = false;
                                 r.app.pendingUiClean = true;
@@ -1148,6 +1124,42 @@
         return showHomeBehindStack;
     }
 
+    void convertToTranslucent(ActivityRecord r) {
+        mTranslucentActivityWaiting = r;
+        mUndrawnActivitiesBelowTopTranslucent.clear();
+        mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
+    }
+
+    /**
+     * Called as activities below the top translucent activity are redrawn. When the last one is
+     * redrawn notify the top activity by calling
+     * {@link Activity#onTranslucentConversionComplete}.
+     *
+     * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
+     * occurred and the activity will be notified immediately.
+     */
+    void notifyActivityDrawnLocked(ActivityRecord r) {
+        if ((r == null)
+                || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
+                        mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
+            // The last undrawn activity below the top has just been drawn. If there is an
+            // opaque activity at the top, notify it that it can become translucent safely now.
+            final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
+            mTranslucentActivityWaiting = null;
+            mUndrawnActivitiesBelowTopTranslucent.clear();
+            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
+
+            if (waitingActivity != null && waitingActivity.app != null &&
+                    waitingActivity.app.thread != null) {
+                try {
+                    waitingActivity.app.thread.scheduleTranslucentConversionComplete(
+                            waitingActivity.appToken, r != null);
+                } catch (RemoteException e) {
+                }
+            }
+        }
+    }
+
     /**
      * Ensure that the top activity in the stack is resumed.
      *
@@ -2140,29 +2152,6 @@
         }
     }
 
-    final ActivityRecord activityIdleInternalLocked(final IBinder token) {
-        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
-
-        // Get the activity record.
-        ActivityRecord res = isInStackLocked(token);
-        if (res != null) {
-            // No longer need to keep the device awake.
-            if (mResumedActivity == res && mLaunchingActivity.isHeld()) {
-                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
-                    throw new IllegalStateException("Calling must be system uid");
-                }
-                mLaunchingActivity.release();
-            }
-
-            // If this activity is fullscreen, set up to hide those under it.
-            if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + res);
-            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-        }
-
-        return res;
-    }
-
     /**
      * @return Returns true if the activity is being finished, false if for
      * some reason it is being left as-is.
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 9afac2c..d39798d 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -62,6 +62,7 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -98,10 +99,18 @@
     /** How long we can hold the sleep wake lock before giving up. */
     static final int SLEEP_TIMEOUT = 5*1000;
 
+    // How long we can hold the launch wake lock before giving up.
+    static final int LAUNCH_TIMEOUT = 10*1000;
+
     static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
     static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
     static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
     static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
+    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
+
+    // For debugging to make sure the caller when acquiring/releasing our
+    // wake lock is the system process.
+    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
 
     final ActivityManagerService mService;
     final Context mContext;
@@ -183,6 +192,14 @@
     boolean mSleepTimeout = false;
 
     /**
+     * We don't want to allow the device to go to sleep while in the process
+     * of launching an activity.  This is primarily to allow alarm intent
+     * receivers to launch an activity and get that to run before the device
+     * goes back to sleep.
+     */
+    final PowerManager.WakeLock mLaunchingActivity;
+
+    /**
      * Set when the system is going to sleep, until we have
      * successfully paused the current activity and released our wake lock.
      * At that point the system is allowed to actually sleep.
@@ -197,6 +214,12 @@
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
         mHandler = new ActivityStackSupervisorHandler(looper);
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+            throw new IllegalStateException("Calling must be system uid");
+        }
+        mLaunchingActivity =
+                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
+        mLaunchingActivity.setReferenceCounted(false);
     }
 
     void setWindowManager(WindowManagerService wm) {
@@ -388,7 +411,11 @@
 
     boolean allResumedActivitiesIdle() {
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity;
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!isFrontStack(stack)) {
+                continue;
+            }
+            final ActivityRecord resumedActivity = stack.mResumedActivity;
             if (resumedActivity == null || !resumedActivity.idle) {
                 return false;
             }
@@ -1666,13 +1693,22 @@
         return ActivityManager.START_SUCCESS;
     }
 
+    void acquireLaunchWakelock() {
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+            throw new IllegalStateException("Calling must be system uid");
+        }
+        mLaunchingActivity.acquire();
+        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
+            // To be safe, don't allow the wake lock to be held for too long.
+            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
+        }
+    }
+
     // Checked.
     final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
             Configuration config) {
         if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
 
-        ActivityRecord res = null;
-
         ArrayList<ActivityRecord> stops = null;
         ArrayList<ActivityRecord> finishes = null;
         ArrayList<UserStartedState> startingUsers = null;
@@ -1689,41 +1725,50 @@
                     Debug.getCallers(4));
             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
             r.finishLaunchTickingLocked();
-            res = r.task.stack.activityIdleInternalLocked(token);
-            if (res != null) {
-                if (fromTimeout) {
-                    reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
-                }
-
-                // This is a hack to semi-deal with a race condition
-                // in the client where it can be constructed with a
-                // newer configuration from when we asked it to launch.
-                // We'll update with whatever configuration it now says
-                // it used to launch.
-                if (config != null) {
-                    r.configuration = config;
-                }
-
-                // We are now idle.  If someone is waiting for a thumbnail from
-                // us, we can now deliver.
-                r.idle = true;
-                if (allResumedActivitiesIdle()) {
-                    mService.scheduleAppGcsLocked();
-                    mService.requestPssLocked(r.app, SystemClock.uptimeMillis(), false);
-                }
-                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
-                    sendThumbnail = r.app.thread;
-                    r.thumbnailNeeded = false;
-                }
-    
-                //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
-                if (!mService.mBooted && isFrontStack(r.task.stack)) {
-                    mService.mBooted = true;
-                    enableScreen = true;
-                }
-            } else if (fromTimeout) {
-                reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
+            if (fromTimeout) {
+                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
             }
+
+            // This is a hack to semi-deal with a race condition
+            // in the client where it can be constructed with a
+            // newer configuration from when we asked it to launch.
+            // We'll update with whatever configuration it now says
+            // it used to launch.
+            if (config != null) {
+                r.configuration = config;
+            }
+
+            // We are now idle.  If someone is waiting for a thumbnail from
+            // us, we can now deliver.
+            r.idle = true;
+
+            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
+                sendThumbnail = r.app.thread;
+                r.thumbnailNeeded = false;
+            }
+
+            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
+            if (!mService.mBooted && isFrontStack(r.task.stack)) {
+                mService.mBooted = true;
+                enableScreen = true;
+            }
+        }
+
+        if (allResumedActivitiesIdle()) {
+            if (r != null) {
+                mService.scheduleAppGcsLocked();
+                mService.requestPssLocked(r.app, SystemClock.uptimeMillis(), false);
+            }
+
+            if (mLaunchingActivity.isHeld()) {
+                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+                if (VALIDATE_WAKE_LOCK_CALLER &&
+                        Binder.getCallingUid() != Process.myUid()) {
+                    throw new IllegalStateException("Calling must be system uid");
+                }
+                mLaunchingActivity.release();
+            }
+            ensureActivitiesVisibleLocked(null, 0);
         }
 
         // Atomically retrieve all of the other things to do.
@@ -1814,7 +1859,7 @@
             resumeTopActivitiesLocked();
         }
 
-        return res;
+        return r;
     }
 
     void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
@@ -1882,7 +1927,7 @@
     void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
-                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + 
+                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
                         mStacks.get(stackNdx));
                 return;
             }
@@ -1956,11 +2001,12 @@
         scheduleSleepTimeout();
         if (!mGoingToSleep.isHeld()) {
             mGoingToSleep.acquire();
-            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = mStacks.get(stackNdx);
-                if (stack.mResumedActivity != null) {
-                    stack.stopIfSleepingLocked();
+            if (mLaunchingActivity.isHeld()) {
+                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+                    throw new IllegalStateException("Calling must be system uid");
                 }
+                mLaunchingActivity.release();
+                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
             }
         }
     }
@@ -2423,14 +2469,13 @@
             synchronized (mService) {
                 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
             }
-        }    
-            
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case IDLE_TIMEOUT_MSG: {
-                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
-                            Debug.getCallers(4));
+                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
                     if (mService.mDidDexOpt) {
                         mService.mDidDexOpt = false;
                         Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
@@ -2443,6 +2488,7 @@
                     activityIdleInternal((ActivityRecord)msg.obj);
                 } break;
                 case IDLE_NOW_MSG: {
+                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
                     activityIdleInternal((ActivityRecord)msg.obj);
                 } break;
                 case RESUME_TOP_ACTIVITY_MSG: {
@@ -2459,6 +2505,23 @@
                         }
                     }
                 } break;
+                case LAUNCH_TIMEOUT_MSG: {
+                    if (mService.mDidDexOpt) {
+                        mService.mDidDexOpt = false;
+                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
+                        return;
+                    }
+                    synchronized (mService) {
+                        if (mLaunchingActivity.isHeld()) {
+                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
+                            if (VALIDATE_WAKE_LOCK_CALLER
+                                    && Binder.getCallingUid() != Process.myUid()) {
+                                throw new IllegalStateException("Calling must be system uid");
+                            }
+                            mLaunchingActivity.release();
+                        }
+                    }
+                } break;
             }
         }
     }
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index 0e7513c..5238bd1 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -410,7 +410,7 @@
             }
         }
         if (r.appOp != AppOpsManager.OP_NONE) {
-            int mode = mService.mAppOpsService.checkOperation(r.appOp,
+            int mode = mService.mAppOpsService.noteOperation(r.appOp,
                     filter.receiverList.uid, filter.packageName);
             if (mode != AppOpsManager.MODE_ALLOWED) {
                 if (DEBUG_BROADCAST)  Slog.v(TAG,
@@ -717,7 +717,7 @@
                 }
             }
             if (r.appOp != AppOpsManager.OP_NONE) {
-                int mode = mService.mAppOpsService.checkOperation(r.appOp,
+                int mode = mService.mAppOpsService.noteOperation(r.appOp,
                         info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
                 if (mode != AppOpsManager.MODE_ALLOWED) {
                     if (DEBUG_BROADCAST)  Slog.v(TAG,
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index 5585ac8..6a72e44f 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -39,7 +39,7 @@
     // This is a process only hosting activities that are not visible,
     // so it can be killed without any disruption.
     static final int CACHED_APP_MAX_ADJ = 15;
-    static int CACHED_APP_MIN_ADJ = 9;
+    static final int CACHED_APP_MIN_ADJ = 9;
 
     // The B list of SERVICE_ADJ -- these are the old and decrepit
     // services that aren't as shiny and interesting as the ones in the A list.
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 1671d24..21a6ff0 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -425,8 +425,14 @@
         } else {
             sb.append('u');
             sb.append(userId);
-            sb.append('a');
-            sb.append(UserHandle.getAppId(info.uid));
+            int appId = UserHandle.getAppId(info.uid);
+            if (appId >= Process.FIRST_APPLICATION_UID) {
+                sb.append('a');
+                sb.append(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                sb.append('s');
+                sb.append(appId);
+            }
             if (uid != info.uid) {
                 sb.append('i');
                 sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
@@ -459,8 +465,10 @@
     }
 
     public int getSetAdjWithServices() {
-        if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ && hasStartedServices) {
-            return ProcessList.SERVICE_B_ADJ;
+        if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+            if (hasStartedServices) {
+                return ProcessList.SERVICE_B_ADJ;
+            }
         }
         return setAdj;
     }
diff --git a/services/java/com/android/server/am/ProcessTracker.java b/services/java/com/android/server/am/ProcessTracker.java
index 488582d..0ea93e8 100644
--- a/services/java/com/android/server/am/ProcessTracker.java
+++ b/services/java/com/android/server/am/ProcessTracker.java
@@ -140,9 +140,12 @@
 
     static final int MAX_HISTORIC_STATES = 4;   // Maximum number of historic states we will keep.
     static final String STATE_FILE_PREFIX = "state-"; // Prefix to use for state filenames.
+    static final String STATE_FILE_SUFFIX = ".bin"; // Suffix to use for state filenames.
+    static final String STATE_FILE_CHECKIN_SUFFIX = ".ci"; // State files that have checked in.
     static long WRITE_PERIOD = 30*60*1000;      // Write file every 30 minutes or so.
     static long COMMIT_PERIOD = 24*60*60*1000;  // Commit current stats every day.
 
+    final Object mLock;
     final File mBaseDir;
     State mState;
     boolean mCommitPending;
@@ -694,7 +697,7 @@
                     mTimePeriodStartClock).toString();
             if (mBaseDir != null) {
                 mFile = new AtomicFile(new File(mBaseDir,
-                        STATE_FILE_PREFIX + mTimePeriodStartClockStr));
+                        STATE_FILE_PREFIX + mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
             }
         }
 
@@ -1255,8 +1258,7 @@
             return ps;
         }
 
-        void dumpLocked(PrintWriter pw, String reqPackage, boolean dumpAll) {
-            final long now = SystemClock.uptimeMillis();
+        void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpAll) {
             ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
             boolean printedHeader = false;
             for (int ip=0; ip<pkgMap.size(); ip++) {
@@ -1318,29 +1320,53 @@
                 }
             }
 
-            dumpFilteredProcesses(pw, "Processes running while critical mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_CRITICAL},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
-                    now, reqPackage);
-            dumpFilteredProcesses(pw, "Processes running while low mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_LOW},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
-                    now, reqPackage);
-            dumpFilteredProcesses(pw, "Processes running while moderate mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_MODERATE},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
-                    now, reqPackage);
-            dumpFilteredProcesses(pw, "Processes running while normal mem:", "  ",
-                    new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    new int[] {ADJ_MEM_FACTOR_NORMAL},
-                    new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS},
+            if (reqPackage == null) {
+                ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+                printedHeader = false;
+                for (int ip=0; ip<procMap.size(); ip++) {
+                    String procName = procMap.keyAt(ip);
+                    SparseArray<ProcessState> uids = procMap.valueAt(ip);
+                    for (int iu=0; iu<uids.size(); iu++) {
+                        int uid = uids.keyAt(iu);
+                        ProcessState proc = uids.valueAt(iu);
+                        if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
+                                && proc.mPssTableSize == 0) {
+                            continue;
+                        }
+                        if (!printedHeader) {
+                            pw.println("Process Stats:");
+                            printedHeader = true;
+                        }
+                        pw.print("  * "); pw.print(procName); pw.print(" / ");
+                                UserHandle.formatUid(pw, uid);
+                                pw.print(" ("); pw.print(proc.mDurationsTableSize);
+                                pw.print(" entries)"); pw.println(":");
+                        dumpProcessState(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                ALL_PROC_STATES, now);
+                        dumpProcessPss(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                ALL_PROC_STATES);
+                    }
+                }
+
+                pw.println();
+                pw.println("Summary:");
+                dumpSummaryLocked(pw, reqPackage, now);
+            }
+
+            if (dumpAll) {
+                pw.println();
+                pw.println("Internal state:");
+                pw.print("  mFile="); pw.println(mFile.getBaseFile());
+                pw.print("  Num long arrays: "); pw.println(mLongs.size());
+                pw.print("  Next long entry: "); pw.println(mNextLong);
+                pw.print("  mRunning="); pw.println(mRunning);
+            }
+        }
+
+        void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now) {
+            dumpFilteredSummaryLocked(pw, null, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                    new int[] { STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME, STATE_PREVIOUS },
                     now, reqPackage);
             pw.println();
             pw.println("Run time Stats:");
@@ -1352,26 +1378,20 @@
             pw.print("  Total elapsed time: ");
             TimeUtils.formatDuration(
                     (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
-                    - mTimePeriodStartRealtime, pw);
+                            - mTimePeriodStartRealtime, pw);
             pw.println();
-            if (dumpAll) {
-                pw.println();
-                pw.println("Internal state:");
-                pw.print("  mFile="); pw.println(mFile.getBaseFile());
-                pw.print("  Num long arrays: "); pw.println(mLongs.size());
-                pw.print("  Next long entry: "); pw.println(mNextLong);
-                pw.print("  mRunning="); pw.println(mRunning);
-            }
         }
 
-        void dumpFilteredProcesses(PrintWriter pw, String header, String prefix,
+        void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
                 int[] screenStates, int[] memStates, int[] procStates, long now, String reqPackage) {
             ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
                     procStates, now, reqPackage);
             if (procs.size() > 0) {
-                pw.println();
-                pw.println(header);
-                dumpProcessList(pw, prefix, procs, screenStates, memStates, procStates, now);
+                if (header != null) {
+                    pw.println();
+                    pw.println(header);
+                }
+                dumpProcessSummary(pw, prefix, procs, screenStates, memStates, procStates, now);
             }
         }
 
@@ -1542,7 +1562,8 @@
         }
     }
 
-    public ProcessTracker(File file) {
+    public ProcessTracker(Object lock, File file) {
+        mLock = lock;
         mBaseDir = file;
         mBaseDir.mkdirs();
         mState = new State(mBaseDir, this);
@@ -1637,27 +1658,34 @@
         mState.writeStateLocked(sync, commitPending);
     }
 
-    private ArrayList<String> getCommittedFiles(int minNum) {
+    private ArrayList<String> getCommittedFiles(int minNum, boolean inclAll) {
         File[] files = mBaseDir.listFiles();
         if (files == null || files.length <= minNum) {
             return null;
         }
         ArrayList<String> filesArray = new ArrayList<String>(files.length);
-        String currentFile = mState.mFile.getBaseFile().toString();
+        String currentFile = mState.mFile.getBaseFile().getPath();
         if (DEBUG) Slog.d(TAG, "Collecting " + files.length + " files except: " + currentFile);
         for (int i=0; i<files.length; i++) {
             File file = files[i];
-            if (DEBUG) Slog.d(TAG, "Collecting: " + file);
-            if (!file.toString().equals(currentFile)) {
-                filesArray.add(files[i].toString());
+            String fileStr = file.getPath();
+            if (DEBUG) Slog.d(TAG, "Collecting: " + fileStr);
+            if (!inclAll && fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX)) {
+                if (DEBUG) Slog.d(TAG, "Skipping: already checked in");
+                continue;
             }
+            if (fileStr.equals(currentFile)) {
+                if (DEBUG) Slog.d(TAG, "Skipping: current stats");
+                continue;
+            }
+            filesArray.add(fileStr);
         }
         Collections.sort(filesArray);
         return filesArray;
     }
 
     public void trimHistoricStatesWriteLocked() {
-        ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES);
+        ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES, true);
         if (filesArray == null) {
             return;
         }
@@ -1803,6 +1831,76 @@
         pw.println();
     }
 
+    static final class ProcessDataCollection {
+        final int[] screenStates;
+        final int[] memStates;
+        final int[] procStates;
+
+        long totalTime;
+        long numPss;
+        long minPss;
+        long avgPss;
+        long maxPss;
+
+        ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
+            screenStates = _screenStates;
+            memStates = _memStates;
+            procStates = _procStates;
+        }
+
+        void print(PrintWriter pw, boolean full) {
+            TimeUtils.formatDuration(totalTime, pw);
+            if (numPss > 0) {
+                pw.print(" (");
+                printSizeValue(pw, minPss * 1024);
+                pw.print("-");
+                printSizeValue(pw, avgPss * 1024);
+                pw.print("-");
+                printSizeValue(pw, maxPss * 1024);
+                if (full) {
+                    pw.print(" over ");
+                    pw.print(numPss);
+                }
+                pw.print(")");
+            }
+        }
+    }
+
+    static void computeProcessData(ProcessState proc, ProcessDataCollection data, long now) {
+        data.totalTime = 0;
+        data.numPss = data.minPss = data.avgPss = data.maxPss = 0;
+        for (int is=0; is<data.screenStates.length; is++) {
+            for (int im=0; im<data.memStates.length; im++) {
+                for (int ip=0; ip<data.procStates.length; ip++) {
+                    int bucket = ((data.screenStates[is] + data.memStates[im]) * STATE_COUNT)
+                            + data.procStates[ip];
+                    data.totalTime += proc.getDuration(bucket, now);
+                    long samples = proc.getPssSampleCount(bucket);
+                    if (samples > 0) {
+                        long minPss = proc.getPssMinimum(bucket);
+                        long avgPss = proc.getPssAverage(bucket);
+                        long maxPss = proc.getPssMaximum(bucket);
+                        if (data.numPss == 0) {
+                            data.minPss = minPss;
+                            data.avgPss = avgPss;
+                            data.maxPss = maxPss;
+                        } else {
+                            if (minPss < data.minPss) {
+                                data.minPss = minPss;
+                            }
+                            data.avgPss = (long)( ((data.avgPss*(double)data.numPss)
+                                    + (avgPss*(double)samples)) / (data.numPss+samples) );
+                            if (maxPss > data.maxPss) {
+                                data.maxPss = maxPss;
+                            }
+                        }
+                        data.numPss += samples;
+                    }
+                }
+            }
+        }
+    }
+
     static long computeProcessTimeLocked(ProcessState proc, int[] screenStates, int[] memStates,
                 int[] procStates, long now) {
         long totalTime = 0;
@@ -1818,7 +1916,7 @@
         for (int is=0; is<screenStates.length; is++) {
             for (int im=0; im<memStates.length; im++) {
                 for (int ip=0; ip<procStates.length; ip++) {
-                    int bucket = ((screenStates[is]+ memStates[im]) * STATE_COUNT)
+                    int bucket = ((screenStates[is] + memStates[im]) * STATE_COUNT)
                             + procStates[ip];
                     totalTime += proc.getDuration(bucket, now);
                 }
@@ -1910,12 +2008,12 @@
                         pw.print(STATE_NAMES[procStates[ip]]); pw.print(": ");
                         pw.print(count);
                         pw.print(" samples ");
-                        pw.print(proc.getPssMinimum(bucket));
-                        pw.print("kB ");
-                        pw.print(proc.getPssAverage(bucket));
-                        pw.print("kB ");
-                        pw.print(proc.getPssMaximum(bucket));
-                        pw.println("kB");
+                        printSizeValue(pw, proc.getPssMinimum(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssAverage(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssMaximum(bucket) * 1024);
+                        pw.println();
                     }
                 }
             }
@@ -2017,6 +2115,94 @@
         }
     }
 
+    static void dumpProcessSummaryDetails(PrintWriter pw, ProcessState proc, String prefix,
+            String label, int[] screenStates, int[] memStates, int[] procStates,
+            long now, boolean full) {
+        ProcessDataCollection totals = new ProcessDataCollection(screenStates,
+                memStates, procStates);
+        computeProcessData(proc, totals, now);
+        if (totals.totalTime != 0 || totals.numPss != 0) {
+            if (prefix != null) {
+                pw.print(prefix);
+            }
+            if (label != null) {
+                pw.print(label);
+            }
+            totals.print(pw, full);
+            if (prefix != null) {
+                pw.println();
+            }
+        }
+    }
+
+    static void dumpProcessSummary(PrintWriter pw, String prefix, ArrayList<ProcessState> procs,
+            int[] screenStates, int[] memStates, int[] procStates, long now) {
+        for (int i=procs.size()-1; i>=0; i--) {
+            ProcessState proc = procs.get(i);
+            pw.print(prefix);
+            pw.print("* ");
+            pw.print(proc.mName);
+            pw.print(" / ");
+            UserHandle.formatUid(pw, proc.mUid);
+            pw.println(":");
+            dumpProcessSummaryDetails(pw, proc, prefix, "         TOTAL: ", screenStates, memStates,
+                    procStates, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    Persistent: ", screenStates, memStates,
+                    new int[] {STATE_PERSISTENT}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "           Top: ", screenStates, memStates,
+                    new int[] {STATE_TOP}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    Foreground: ", screenStates, memStates,
+                    new int[] {STATE_FOREGROUND, STATE_VISIBLE, STATE_PERCEPTIBLE}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "        Backup: ", screenStates, memStates,
+                    new int[] {STATE_BACKUP}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "       Service: ", screenStates, memStates,
+                    new int[] {STATE_SERVICE}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "          Home: ", screenStates, memStates,
+                    new int[] {STATE_HOME}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "      Previous: ", screenStates, memStates,
+                    new int[] {STATE_PREVIOUS}, now, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "      (Cached): ", screenStates, memStates,
+                    new int[] {STATE_CACHED}, now, true);
+        }
+    }
+
+    private static void printSizeValue(PrintWriter pw, long number) {
+        float result = number;
+        String suffix = "";
+        if (result > 900) {
+            suffix = "KB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "MB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "GB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "TB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "PB";
+            result = result / 1024;
+        }
+        String value;
+        if (result < 1) {
+            value = String.format("%.2f", result);
+        } else if (result < 10) {
+            value = String.format("%.2f", result);
+        } else if (result < 100) {
+            value = String.format("%.2f", result);
+        } else {
+            value = String.format("%.0f", result);
+        }
+        pw.print(value);
+        pw.print(suffix);
+    }
+
     static void dumpProcessListCsv(PrintWriter pw, ArrayList<ProcessState> procs,
             boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
             boolean sepProcStates, int[] procStates, long now) {
@@ -2171,7 +2357,7 @@
     static private void dumpHelp(PrintWriter pw) {
         pw.println("Process stats (procstats) dump options:");
         pw.println("    [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
-        pw.println("    [--include-committed] [--commit] [--write] [-h] [<package.name>]");
+        pw.println("    [--details] [--current] [--commit] [--write] [-h] [<package.name>]");
         pw.println("  --checkin: perform a checkin: print and delete old committed states.");
         pw.println("  --c: print only state in checkin format.");
         pw.println("  --csv: output data suitable for putting in a spreadsheet.");
@@ -2179,7 +2365,8 @@
         pw.println("  --csv-mem: norm, mod, low, crit.");
         pw.println("  --csv-proc: pers, top, fore, vis, precept, backup,");
         pw.println("    service, home, prev, cached");
-        pw.println("  --include-committed: also dump any old committed states.");
+        pw.println("  --details: dump all execution details, not just summary.");
+        pw.println("  --current: only dump current state.");
         pw.println("  --commit: commit current stats to disk and reset to start new stats.");
         pw.println("  --write: write current in-memory stats to disk.");
         pw.println("  --read: replace current stats with last-written stats.");
@@ -2188,13 +2375,14 @@
         pw.println("  <package.name>: optional name of package to filter output by.");
     }
 
-    public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         final long now = SystemClock.uptimeMillis();
 
         boolean isCheckin = false;
         boolean isCompact = false;
         boolean isCsv = false;
-        boolean includeCommitted = false;
+        boolean currentOnly = false;
+        boolean dumpDetails = false;
         boolean dumpAll = false;
         String reqPackage = null;
         boolean csvSepScreenStats = false;
@@ -2264,8 +2452,10 @@
                         return;
                     }
                     csvSepProcStats = sep[0];
-                } else if ("--include-committed".equals(arg)) {
-                    includeCommitted = true;
+                } else if ("--details".equals(arg)) {
+                    dumpDetails = true;
+                } else if ("--current".equals(arg)) {
+                    currentOnly = true;
                 } else if ("--commit".equals(arg)) {
                     mState.writeStateLocked(true, true);
                     pw.println("Process stats committed.");
@@ -2282,8 +2472,8 @@
                     dumpHelp(pw);
                     return;
                 } else if ("-a".equals(arg)) {
+                    dumpDetails = true;
                     dumpAll = true;
-                    includeCommitted = true;
                 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
                     pw.println("Unknown option: " + arg);
                     dumpHelp(pw);
@@ -2294,9 +2484,11 @@
                         IPackageManager pm = AppGlobals.getPackageManager();
                         if (pm.getPackageUid(arg, UserHandle.getCallingUserId()) >= 0) {
                             reqPackage = arg;
-                            // We will automatically include all committed state,
-                            // since we are going to end up with much less printed.
-                            includeCommitted = true;
+                            // Include all details, since we know we are only going to
+                            // be dumping a smaller set of data.  In fact only the details
+                            // container per-package data, so that are needed to be able
+                            // to dump anything at all when filtering by package.
+                            dumpDetails = true;
                         }
                     } catch (RemoteException e) {
                     }
@@ -2330,70 +2522,94 @@
                 }
             }
             pw.println();
-            dumpFilteredProcessesCsvLocked(pw, null,
-                    csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
-                    csvSepProcStats, csvProcStats, now, reqPackage);
-            /*
-            dumpFilteredProcessesCsvLocked(pw, "Processes running while critical mem:",
-                    false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    true, new int[] {ADJ_MEM_FACTOR_CRITICAL},
-                    true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
-                            STATE_PREVIOUS, STATE_CACHED},
-                    now, reqPackage);
-            dumpFilteredProcessesCsvLocked(pw, "Processes running over all mem:",
-                    false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
-                    false, new int[] {ADJ_MEM_FACTOR_CRITICAL, ADJ_MEM_FACTOR_LOW,
-                            ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_MODERATE},
-                    true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
-                            STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
-                            STATE_PREVIOUS, STATE_CACHED},
-                    now, reqPackage);
-            */
+            synchronized (mLock) {
+                dumpFilteredProcessesCsvLocked(pw, null,
+                        csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
+                        csvSepProcStats, csvProcStats, now, reqPackage);
+                /*
+                dumpFilteredProcessesCsvLocked(pw, "Processes running while critical mem:",
+                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
+                        true, new int[] {ADJ_MEM_FACTOR_CRITICAL},
+                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
+                                STATE_PREVIOUS, STATE_CACHED},
+                        now, reqPackage);
+                dumpFilteredProcessesCsvLocked(pw, "Processes running over all mem:",
+                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
+                        false, new int[] {ADJ_MEM_FACTOR_CRITICAL, ADJ_MEM_FACTOR_LOW,
+                                ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_MODERATE},
+                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
+                                STATE_PREVIOUS, STATE_CACHED},
+                        now, reqPackage);
+                */
+            }
             return;
         }
 
         boolean sepNeeded = false;
-        if (includeCommitted || isCheckin) {
-            ArrayList<String> files = getCommittedFiles(0);
-            if (files != null) {
-                for (int i=0; i<files.size(); i++) {
-                    if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
-                    try {
-                        State state = new State(files.get(i));
-                        if (isCheckin || isCompact) {
-                            state.dumpCheckinLocked(pw, reqPackage);
-                        } else {
-                            if (sepNeeded) {
-                                pw.println();
+        if (!currentOnly || isCheckin) {
+            mWriteLock.lock();
+            try {
+                ArrayList<String> files = getCommittedFiles(0, !isCheckin);
+                if (files != null) {
+                    for (int i=0; i<files.size(); i++) {
+                        if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
+                        try {
+                            State state = new State(files.get(i));
+                            String fileStr = state.mFile.getBaseFile().getPath();
+                            boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
+                            if (isCheckin || isCompact) {
+                                // Don't really need to lock because we uniquely own this object.
+                                state.dumpCheckinLocked(pw, reqPackage);
                             } else {
-                                sepNeeded = true;
+                                if (sepNeeded) {
+                                    pw.println();
+                                } else {
+                                    sepNeeded = true;
+                                }
+                                pw.print("COMMITTED STATS FROM ");
+                                pw.print(state.mTimePeriodStartClockStr);
+                                if (checkedIn) pw.print(" (checked in)");
+                                pw.println(":");
+                                // Don't really need to lock because we uniquely own this object.
+                                if (dumpDetails) {
+                                    state.dumpLocked(pw, reqPackage, now, dumpAll);
+                                } else {
+                                    state.dumpSummaryLocked(pw, reqPackage, now);
+                                }
                             }
-                            pw.print("COMMITTED STATS FROM ");
-                            pw.print(state.mTimePeriodStartClockStr);
-                            pw.println(":");
-                            state.dumpLocked(pw, reqPackage, dumpAll);
+                            if (isCheckin) {
+                                // Rename file suffix to mark that it has checked in.
+                                state.mFile.getBaseFile().renameTo(new File(
+                                        fileStr + STATE_FILE_CHECKIN_SUFFIX));
+                            }
+                        } catch (Throwable e) {
+                            pw.print("**** FAILURE DUMPING STATE: "); pw.println(files.get(i));
+                            e.printStackTrace(pw);
                         }
-                        if (isCheckin) {
-                            state.mFile.delete();
-                        }
-                    } catch (Throwable e) {
-                        pw.print("**** FAILURE DUMPING STATE: "); pw.println(files.get(i));
-                        e.printStackTrace(pw);
+                        if (DEBUG) Slog.d(TAG, "Deleting state: " + files.get(i));
                     }
-                    if (DEBUG) Slog.d(TAG, "Deleting state: " + files.get(i));
                 }
+            } finally {
+                mWriteLock.unlock();
             }
         }
         if (!isCheckin) {
-            if (isCompact) {
-                mState.dumpCheckinLocked(pw, reqPackage);
-            } else {
-                if (sepNeeded) {
-                    pw.println();
-                    pw.println("CURRENT STATS:");
+            synchronized (mLock) {
+                if (isCompact) {
+                    mState.dumpCheckinLocked(pw, reqPackage);
+                } else {
+                    if (sepNeeded) {
+                        pw.println();
+                        pw.println("CURRENT STATS:");
+                    }
+                    if (dumpDetails) {
+                        mState.dumpLocked(pw, reqPackage, now, dumpAll);
+                    } else {
+                        mState.dumpSummaryLocked(pw, reqPackage, now);
+                    }
                 }
-                mState.dumpLocked(pw, reqPackage, dumpAll);
             }
         }
     }
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 2fc972f..63d3958 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -467,15 +467,15 @@
     private native int jniCheck(String interfaze);
     private native void jniProtect(int socket, String interfaze);
 
-    private static String findLegacyVpnGateway(LinkProperties prop) {
-        for (RouteInfo route : prop.getRoutes()) {
+    private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) {
+        for (RouteInfo route : prop.getAllRoutes()) {
             // Currently legacy VPN only works on IPv4.
             if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) {
-                return route.getGateway().getHostAddress();
+                return route;
             }
         }
 
-        throw new IllegalStateException("Unable to find suitable gateway");
+        throw new IllegalStateException("Unable to find IPv4 default gateway");
     }
 
     /**
@@ -488,8 +488,9 @@
             throw new IllegalStateException("KeyStore isn't unlocked");
         }
 
-        final String iface = egress.getInterfaceName();
-        final String gateway = findLegacyVpnGateway(egress);
+        final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress);
+        final String gateway = ipv4DefaultRoute.getGateway().getHostAddress();
+        final String iface = ipv4DefaultRoute.getInterface();
 
         // Load certificates.
         String privateKey = "";
diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/java/com/android/server/pm/KeySetManager.java
index 9c14a91..93992c2 100644
--- a/services/java/com/android/server/pm/KeySetManager.java
+++ b/services/java/com/android/server/pm/KeySetManager.java
@@ -42,7 +42,10 @@
 
     static final String TAG = "KeySetManager";
 
-    private static final long KEYSET_NOT_FOUND = -1;
+    /** Sentinel value returned when a {@code KeySet} is not found. */
+    public static final long KEYSET_NOT_FOUND = -1;
+
+    /** Sentinel value returned when public key is not found. */
     private static final long PUBLIC_KEY_NOT_FOUND = -1;
 
     private final Object mLockObject = new Object();
@@ -66,7 +69,7 @@
         mPackages = packages;
     }
 
-    /*
+    /**
      * Determine if a package is signed by the given KeySet.
      *
      * Returns false if the package was not signed by all the
@@ -91,7 +94,7 @@
         }
     }
 
-    /*
+    /**
      * This informs the system that the given package has defined a KeySet
      * in its manifest that a) contains the given keys and b) is named
      * alias by that package.
@@ -113,7 +116,7 @@
         }
     }
 
-    /*
+    /**
      * Similar to the above, this informs the system that the given package
      * was signed by the provided KeySet.
      */
@@ -150,10 +153,9 @@
         }
     }
 
-    /*
-     * Fetches the stable identifier associated with the given KeySet.
-     *
-     * Returns KEYSET_NOT_FOUND if the KeySet... wasn't found.
+    /**
+     * Fetches the stable identifier associated with the given KeySet. Returns
+     * {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found.
      */
     public long getIdByKeySet(KeySet ks) {
         synchronized (mLockObject) {
@@ -171,10 +173,11 @@
         return KEYSET_NOT_FOUND;
     }
 
-    /*
+    /**
      * Fetches the KeySet corresponding to the given stable identifier.
      *
-     * Returns KEYSET_NOT_FOUND if the identifier doesn't identify a KeySet.
+     * Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't
+     * identify a {@link KeySet}.
      */
     public KeySet getKeySetById(long id) {
         synchronized (mLockObject) {
@@ -182,7 +185,7 @@
         }
     }
 
-    /*
+    /**
      * Fetches the KeySet that a given package refers to by the provided alias.
      *
      * If the package isn't known to us, throws an IllegalArgumentException.
@@ -202,10 +205,9 @@
         }
     }
 
-    /*
-     * Fetches all the known KeySets that signed the given package.
-     *
-     * If the package is unknown to us, throws an IllegalArgumentException.
+    /**
+     * Fetches all the known {@link KeySet KeySets} that signed the given
+     * package. Returns {@code null} if package is unknown.
      */
     public Set<KeySet> getSigningKeySetsByPackageName(String packageName) {
         synchronized (mLockObject) {
@@ -224,16 +226,16 @@
         }
     }
 
-    /*
+    /**
      * Creates a new KeySet corresponding to the given keys.
      *
-     * If the PublicKeys aren't known to the system, this adds them. Otherwise,
-     * they're deduped.
+     * If the {@link PublicKey PublicKeys} aren't known to the system, this
+     * adds them. Otherwise, they're deduped.
      *
      * If the KeySet isn't known to the system, this adds that and creates the
      * mapping to the PublicKeys. If it is known, then it's deduped.
      *
-     * Throws if the provided set is null.
+     * Throws if the provided set is {@code null}.
      */
     private KeySet addKeySetLocked(Set<PublicKey> keys) {
         if (keys == null) {
@@ -264,7 +266,7 @@
         return ks;
     }
 
-    /*
+    /**
      * Adds the given PublicKey to the system, deduping as it goes.
      */
     private long addPublicKeyLocked(PublicKey key) {
@@ -281,7 +283,7 @@
         return id;
     }
 
-    /*
+    /**
      * Finds the stable identifier for a KeySet based on a set of PublicKey stable IDs.
      *
      * Returns KEYSET_NOT_FOUND if there isn't one.
@@ -296,7 +298,7 @@
         return KEYSET_NOT_FOUND;
     }
 
-    /*
+    /**
      * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND.
      */
     private long getIdForPublicKeyLocked(PublicKey k) {
@@ -311,7 +313,7 @@
         return PUBLIC_KEY_NOT_FOUND;
     }
 
-    /*
+    /**
      * Gets an unused stable identifier for a KeySet.
      */
     private long getFreeKeySetIDLocked() {
@@ -319,7 +321,7 @@
         return lastIssuedKeySetId;
     }
 
-    /*
+    /**
      * Same as above, but for public keys.
      */
     private long getFreePublicKeyIdLocked() {
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index d86f2c7..2901212 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -822,6 +822,11 @@
                 pinState.failedAttempts = failedAttempts;
                 pinState.lastAttemptTime = lastAttemptTime;
             }
+            // If this is not a restricted profile and there is no restrictions pin, clean up
+            // any restrictions files that might have been left behind.
+            if (!userInfo.isRestricted() && salt == 0) {
+                cleanAppRestrictions(id);
+            }
             return userInfo;
 
         } catch (IOException ioe) {
@@ -873,6 +878,26 @@
         }
     }
 
+    /**
+     * Removes all the restrictions files (res_<packagename>) for a given user.
+     * Does not do any permissions checking.
+     */
+    private void cleanAppRestrictions(int userId) {
+        synchronized (mPackagesLock) {
+            File dir = Environment.getUserSystemDirectory(userId);
+            String[] files = dir.list();
+            if (files == null) return;
+            for (String fileName : files) {
+                if (fileName.startsWith(RESTRICTIONS_FILE_PREFIX)) {
+                    File resFile = new File(dir, fileName);
+                    if (resFile.exists()) {
+                        resFile.delete();
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public UserInfo createUser(String name, int flags) {
         checkManageUsersPermission("Only the system can create users");
diff --git a/services/java/com/android/server/power/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
index ba321bc..88a27f5 100644
--- a/services/java/com/android/server/power/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -297,7 +297,9 @@
         
         // First send the high-level shut down broadcast.
         mActionDone = false;
-        mContext.sendOrderedBroadcastAsUser(new Intent(Intent.ACTION_SHUTDOWN),
+        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendOrderedBroadcastAsUser(intent,
                 UserHandle.ALL, null, br, mHandler, 0, null, null);
         
         final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index a70978e..6118503 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -48,16 +48,23 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.os.AsyncTask;
 import android.provider.Settings;
 import android.util.Log;
 import android.util.Slog;
 
+import java.io.FileNotFoundException;
+import java.io.BufferedReader;
 import java.io.FileDescriptor;
+import java.io.FileReader;
+import java.io.IOException;
 import java.io.PrintWriter;
+
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.util.ArrayList;
 import java.util.List;
+
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import com.android.internal.R;
@@ -749,6 +756,92 @@
     }
 
     /**
+     * enable TDLS for the local NIC to remote NIC
+     * The APPs don't know the remote MAC address to identify NIC though,
+     * so we need to do additional work to find it from remote IP address
+     */
+
+    class TdlsTaskParams {
+        public String remoteIpAddress;
+        public boolean enable;
+    }
+
+    class TdlsTask extends AsyncTask<TdlsTaskParams, Integer, Integer> {
+        @Override
+        protected Integer doInBackground(TdlsTaskParams... params) {
+
+            // Retrieve parameters for the call
+            TdlsTaskParams param = params[0];
+            String remoteIpAddress = param.remoteIpAddress.trim();
+            boolean enable = param.enable;
+
+            // Get MAC address of Remote IP
+            String macAddress = null;
+
+            BufferedReader reader = null;
+
+            try {
+                reader = new BufferedReader(new FileReader("/proc/net/arp"));
+
+                // Skip over the line bearing colum titles
+                String line = reader.readLine();
+
+                while ((line = reader.readLine()) != null) {
+                    String[] tokens = line.split("[ ]+");
+                    if (tokens.length < 6) {
+                        continue;
+                    }
+
+                    // ARP column format is
+                    // Address HWType HWAddress Flags Mask IFace
+                    String ip = tokens[0];
+                    String mac = tokens[3];
+
+                    if (remoteIpAddress.equals(ip)) {
+                        macAddress = mac;
+                        break;
+                    }
+                }
+
+                if (macAddress == null) {
+                    Slog.w(TAG, "Did not find remoteAddress {" + remoteIpAddress + "} in " +
+                            "/proc/net/arp");
+                } else {
+                    enableTdlsWithMacAddress(macAddress, enable);
+                }
+
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "Could not open /proc/net/arp to lookup mac address");
+            } catch (IOException e) {
+                Slog.e(TAG, "Could not read /proc/net/arp to lookup mac address");
+            } finally {
+                try {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                }
+                catch (IOException e) {
+                    // Do nothing
+                }
+            }
+
+            return 0;
+        }
+    }
+
+    public void enableTdls(String remoteAddress, boolean enable) {
+        TdlsTaskParams params = new TdlsTaskParams();
+        params.remoteIpAddress = remoteAddress;
+        params.enable = enable;
+        new TdlsTask().execute(params);
+    }
+
+
+    public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
+        mWifiStateMachine.enableTdls(remoteMacAddress, enable);
+    }
+
+    /**
      * Get a reference to handler. This is used by a client to establish
      * an AsyncChannel communication with WifiService
      */
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index ee2ef37..50d267f 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -25,6 +25,7 @@
 import android.app.AppOpsManager;
 import android.util.TimeUtils;
 import android.view.IWindowId;
+
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.policy.impl.PhoneWindowManager;
@@ -4117,10 +4118,11 @@
         }
     }
 
-    public void setAppFullscreen(IBinder token) {
+    public void setAppFullscreen(IBinder token, boolean toOpaque) {
         AppWindowToken atoken = findAppWindowToken(token);
         if (atoken != null) {
-            atoken.appFullscreen = true;
+            atoken.appFullscreen = toOpaque;
+            requestTraversal();
         }
     }
 
@@ -7020,6 +7022,7 @@
 
         public static final int CLIENT_FREEZE_TIMEOUT = 30;
         public static final int TAP_OUTSIDE_STACK = 31;
+        public static final int NOTIFY_ACTIVITY_DRAWN = 32;
 
         @Override
         public void handleMessage(Message msg) {
@@ -7452,6 +7455,13 @@
                         }
                     }
                 }
+                break;
+                case NOTIFY_ACTIVITY_DRAWN:
+                    try {
+                        mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
+                    } catch (RemoteException e) {
+                    }
+                    break;
             }
             if (DEBUG_WINDOW_TRACE) {
                 Slog.v(TAG, "handleMessage: exit");
@@ -8759,6 +8769,7 @@
                                 + " interesting=" + numInteresting
                                 + " drawn=" + wtoken.numDrawnWindows);
                         wtoken.allDrawn = true;
+                        mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
                     }
                 }
             }
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 7c6da92..dd19f89 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -363,7 +363,32 @@
             mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
             mAttachedWindow = attachedWindow;
             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
-            mAttachedWindow.mChildWindows.add(this);
+
+            int children_size = mAttachedWindow.mChildWindows.size();
+            if (children_size == 0) {
+                mAttachedWindow.mChildWindows.add(this);
+            } else {
+                for (int i = 0; i < children_size; i++) {
+                    WindowState child = (WindowState)mAttachedWindow.mChildWindows.get(i);
+                    if (this.mSubLayer < child.mSubLayer) {
+                        mAttachedWindow.mChildWindows.add(i, this);
+                        break;
+                    } else if (this.mSubLayer > child.mSubLayer) {
+                        continue;
+                    }
+
+                    if (this.mBaseLayer <= child.mBaseLayer) {
+                        mAttachedWindow.mChildWindows.add(i, this);
+                        break;
+                    } else {
+                        continue;
+                    }
+                }
+                if (children_size == mAttachedWindow.mChildWindows.size()) {
+                    mAttachedWindow.mChildWindows.add(this);
+                }
+            }
+
             mLayoutAttached = mAttrs.type !=
                     WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
             mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
diff --git a/tests/CanvasCompare/res/layout/manual_layout.xml b/tests/CanvasCompare/res/layout/manual_layout.xml
index d7838eb..1a9288c 100644
--- a/tests/CanvasCompare/res/layout/manual_layout.xml
+++ b/tests/CanvasCompare/res/layout/manual_layout.xml
@@ -64,7 +64,7 @@
         </LinearLayout>
     </LinearLayout>
 
-    <com.android.test.hwuicompare.NearestImageView
+    <ImageView
         android:id="@+id/compare_image_view"
         android:layout_width="@dimen/layer_width_double"
         android:layout_height="@dimen/layer_height_double"
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
index 400dff0..405ff65 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
@@ -82,6 +82,7 @@
                         mCompareImageView.setImageBitmap(mCompareBitmap);
                         break;
                 }
+                mCompareImageView.getDrawable().setFilterBitmap(false);
                 mCompareImageView.invalidate();
             }
 
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/NearestImageView.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/NearestImageView.java
deleted file mode 100644
index 542b55a..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/NearestImageView.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.hwuicompare;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-public class NearestImageView extends ImageView {
-    public NearestImageView(Context context) {
-        super(context);
-    }
-
-    public NearestImageView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public NearestImageView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    final PaintFlagsDrawFilter mFilter = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        canvas.setDrawFilter(mFilter);
-        super.onDraw(canvas);
-        canvas.setDrawFilter(null);
-    }
-}
\ No newline at end of file
diff --git a/tests/TransitionTests/AndroidManifest.xml b/tests/TransitionTests/AndroidManifest.xml
index 5483f64..9a399d0 100644
--- a/tests/TransitionTests/AndroidManifest.xml
+++ b/tests/TransitionTests/AndroidManifest.xml
@@ -233,6 +233,13 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:label="CrossfadeImage"
+                  android:name=".CrossfadeImage">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
 
     </application>
 
diff --git a/tests/TransitionTests/res/layout/crossfade_image.xml b/tests/TransitionTests/res/layout/crossfade_image.xml
new file mode 100644
index 0000000..c46327a
--- /dev/null
+++ b/tests/TransitionTests/res/layout/crossfade_image.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/self_portrait_square_100"
+            android:onClick="sendMessage"
+            android:id="@+id/contact_picture"/>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/self_portrait_square_100"
+            android:onClick="sendMessage"
+            android:id="@+id/contact_picture1"/>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/self_portrait_square_100"
+            android:onClick="sendMessage"
+            android:id="@+id/contact_picture2"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
new file mode 100644
index 0000000..28e055f
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.transition.Crossfade;
+import android.view.transition.Move;
+import android.view.transition.Scene;
+import android.view.transition.Transition;
+import android.view.transition.TransitionGroup;
+import android.view.transition.TransitionManager;
+import android.widget.ImageView;
+
+public class CrossfadeImage extends Activity {
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+    Scene mScene1, mScene2;
+    TransitionManager mTransitionManager;
+    boolean mExpanded = false;
+    Transition mTransition;
+    ImageView mImageView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.crossfade_image);
+
+        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        mSceneRoot = container;
+
+        mImageView = (ImageView) findViewById(R.id.contact_picture);
+        mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
+
+        Crossfade mCrossfade = new Crossfade();
+        mCrossfade.setTargetIds(R.id.contact_picture);
+
+        TransitionGroup group = new TransitionGroup();
+        group.setDuration(1500);
+        group.addTransitions(mCrossfade, new Move());
+        mTransition = group;
+    }
+
+    public void sendMessage(View view) {
+        TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+        if (mExpanded) {
+            mImageView.setImageResource(R.drawable.self_portrait_square_100);
+        } else {
+            mImageView.setImageResource(R.drawable.self_portrait_square_200);
+        }
+        mExpanded = !mExpanded;
+    }
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 547ae95..6a4bd45 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -110,5 +110,9 @@
     String getConfigFile();
 
     void captivePortalCheckComplete();
+
+    void enableTdls(String remoteIPAddress, boolean enable);
+
+    void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
 }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index a3c172a..86ca4a7 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import java.net.InetAddress;
 import java.util.concurrent.CountDownLatch;
 
 import com.android.internal.util.AsyncChannel;
@@ -1132,6 +1133,43 @@
         }
     }
 
+
+    /**
+     * Enable TDLS on a specific local route
+     *
+     * This API is used by WiFi display, but eventually it can be made public,
+     * just depends on how popular TDLS gets
+     *
+     * @param remoteIPAddress IP address of the endpoint to setup TDLS with
+     * @param enable true = setup and false = tear down TDLS
+     * @hide
+     */
+    public void enableTdls(InetAddress remoteIPAddress, boolean enable) {
+        try {
+            mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
+        } catch (RemoteException e) {
+            // Just ignore the exception
+        }
+    }
+
+    /**
+     * Enable TDLS on a specific local route
+     *
+     * This API is used by WiFi display, but eventually it can be made public,
+     * just depends on how popular TDLS gets
+     *
+     * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
+     * @param enable true = setup and false = tear down TDLS
+     * @hide
+     */
+    public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
+        try {
+            mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
+        } catch (RemoteException e) {
+            // Just ignore the exception
+        }
+    }
+
     /* TODO: deprecate synchronous API and open up the following API */
 
     private static final int BASE = Protocol.BASE_WIFI_MANAGER;
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 375a160..7ee7085 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -370,6 +370,13 @@
         doBooleanCommand("SCAN_INTERVAL " + scanInterval);
     }
 
+    public void startTdls(String macAddr, boolean enable) {
+        if (enable)
+            doBooleanCommand("TDLS_SETUP " + macAddr);
+        else
+            doBooleanCommand("TDLS_TEARDOWN " + macAddr);
+    }
+
     /** Example output:
      * RSSI=-65
      * LINKSPEED=48
@@ -388,6 +395,10 @@
         return doStringCommand("PKTCNT_POLL");
     }
 
+    public void bssFlush() {
+        doBooleanCommand("BSS_FLUSH");
+    }
+
     public boolean startWpsPbc(String bssid) {
         if (TextUtils.isEmpty(bssid)) {
             return doBooleanCommand("WPS_PBC");
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 1f51b2a..858fbcc 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -337,6 +337,8 @@
     static final int CMD_SET_FREQUENCY_BAND               = BASE + 90;
     /* Enable background scan for configured networks */
     static final int CMD_ENABLE_BACKGROUND_SCAN           = BASE + 91;
+    /* Enable TDLS on a specific MAC address */
+    static final int CMD_ENABLE_TDLS                      = BASE + 92;
 
     /* Commands from/to the SupplicantStateTracker */
     /* Reset the supplicant state tracker */
@@ -1074,6 +1076,14 @@
     }
 
     /**
+     * Enable TDLS for a specific MAC address
+     */
+    public void enableTdls(String remoteMacAddress, boolean enable) {
+        int enabler = enable ? 1 : 0;
+        sendMessage(CMD_ENABLE_TDLS, enabler, 0, remoteMacAddress);
+    }
+
+    /**
      * Returns the operational frequency band
      */
     public int getFrequencyBand() {
@@ -1773,6 +1783,14 @@
         // TODO: Remove this comment when the driver is fixed.
         setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
         mWifiNative.setPowerSave(false);
+
+        /* P2p discovery breaks dhcp, shut it down in order to get through this */
+        Message msg = new Message();
+        msg.what = WifiP2pService.BLOCK_DISCOVERY;
+        msg.arg1 = WifiP2pService.ENABLED;
+        msg.arg2 = DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE;
+        msg.obj = mDhcpStateMachine;
+        mWifiP2pChannel.sendMessage(msg);
     }
 
 
@@ -1799,6 +1817,8 @@
         setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
         mWifiNative.setPowerSave(true);
 
+        mWifiP2pChannel.sendMessage(WifiP2pService.BLOCK_DISCOVERY, WifiP2pService.DISABLED);
+
         // Set the coexistence mode back to its default value
         mWifiNative.setBluetoothCoexistenceMode(
                 mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
@@ -2497,6 +2517,8 @@
                     if (DBG) log("set frequency band " + band);
                     if (mWifiNative.setBand(band)) {
                         mFrequencyBand.set(band);
+                        // flush old data - like scan results
+                        mWifiNative.bssFlush();
                         //Fetch the latest scan results when frequency band is set
                         startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
                     } else {
@@ -2593,6 +2615,13 @@
                         setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
                     }
                     break;
+                case CMD_ENABLE_TDLS:
+                    if (message.obj != null) {
+                        String remoteAddress = (String) message.obj;
+                        boolean enable = (message.arg1 == 1);
+                        mWifiNative.startTdls(remoteAddress, enable);
+                    }
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -2993,7 +3022,6 @@
             switch (message.what) {
               case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
                   handlePreDhcpSetup();
-                  mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
                   break;
               case DhcpStateMachine.CMD_POST_DHCP_ACTION:
                   handlePostDhcpSetup();
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 4cfc4ac..68a082a 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -166,6 +166,16 @@
 
     public static final int SET_MIRACAST_MODE               =   BASE + 14;
 
+    // During dhcp (and perhaps other times) we can't afford to drop packets
+    // but Discovery will switch our channel enough we will.
+    //   msg.arg1 = ENABLED for blocking, DISABLED for resumed.
+    //   msg.arg2 = msg to send when blocked
+    //   msg.obj  = StateMachine to send to when blocked
+    public static final int BLOCK_DISCOVERY                 =   BASE + 15;
+
+    public static final int ENABLED                         = 1;
+    public static final int DISABLED                        = 0;
+
     private final boolean mP2pSupported;
 
     private WifiP2pDevice mThisDevice = new WifiP2pDevice();
@@ -182,6 +192,15 @@
      * broadcasts
      */
     private boolean mDiscoveryStarted;
+    /* Track whether servcice/peer discovery is blocked in favor of other wifi actions
+     * (notably dhcp)
+     */
+    private boolean mDiscoveryBlocked;
+
+    /*
+     * remember if we were in a scan when it had to be stopped
+     */
+    private boolean mDiscoveryPostponed = false;
 
     private NetworkInfo mNetworkInfo;
 
@@ -479,6 +498,20 @@
                     AsyncChannel ac = new AsyncChannel();
                     ac.connect(mContext, getHandler(), message.replyTo);
                     break;
+                case BLOCK_DISCOVERY:
+                    mDiscoveryBlocked = (message.arg1 == ENABLED ? true : false);
+                    // always reset this - we went to a state that doesn't support discovery so
+                    // it would have stopped regardless
+                    mDiscoveryPostponed = false;
+                    if (mDiscoveryBlocked) {
+                        try {
+                            StateMachine m = (StateMachine)message.obj;
+                            m.sendMessage(message.arg2);
+                        } catch (Exception e) {
+                            loge("unable to send BLOCK_DISCOVERY response: " + e);
+                        }
+                    }
+                    break;
                 case WifiP2pManager.DISCOVER_PEERS:
                     replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                             WifiP2pManager.BUSY);
@@ -851,7 +884,33 @@
                     }
                     break;
                 }
+                case BLOCK_DISCOVERY:
+                    boolean blocked = (message.arg1 == ENABLED ? true : false);
+                    if (mDiscoveryBlocked == blocked) break;
+                    mDiscoveryBlocked = blocked;
+                    if (blocked && mDiscoveryStarted) {
+                        mWifiNative.p2pStopFind();
+                        mDiscoveryPostponed = true;
+                    }
+                    if (!blocked && mDiscoveryPostponed) {
+                        mDiscoveryPostponed = false;
+                        mWifiNative.p2pFind(DISCOVER_TIMEOUT_S);
+                    }
+                    if (blocked) {
+                        try {
+                            StateMachine m = (StateMachine)message.obj;
+                            m.sendMessage(message.arg2);
+                        } catch (Exception e) {
+                            loge("unable to send BLOCK_DISCOVERY response: " + e);
+                        }
+                    }
+                    break;
                 case WifiP2pManager.DISCOVER_PEERS:
+                    if (mDiscoveryBlocked) {
+                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
+                                WifiP2pManager.BUSY);
+                        break;
+                    }
                     // do not send service discovery request while normal find operation.
                     clearSupplicantServiceRequest();
                     if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
@@ -874,6 +933,11 @@
                     }
                     break;
                 case WifiP2pManager.DISCOVER_SERVICES:
+                    if (mDiscoveryBlocked) {
+                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
+                                WifiP2pManager.BUSY);
+                        break;
+                    }
                     if (DBG) logd(getName() + " discover services");
                     if (!updateSupplicantServiceRequest()) {
                         replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,