Merge "Fix orthographic shadows projection, simplify shadow reordering"
diff --git a/api/current.txt b/api/current.txt
index 0a0f148..9df5c9e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6772,6 +6772,7 @@
     field public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME";
     field public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO";
     field public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
+    field public static final java.lang.String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
     field public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK";
     field public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY";
     field public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE";
@@ -38419,6 +38420,11 @@
     method public abstract java.net.SocketImpl createSocketImpl();
   }
 
+  public abstract interface SocketOption {
+    method public abstract java.lang.String name();
+    method public abstract java.lang.Class<T> type();
+  }
+
   public abstract interface SocketOptions {
     method public abstract java.lang.Object getOption(int) throws java.net.SocketException;
     method public abstract void setOption(int, java.lang.Object) throws java.net.SocketException;
@@ -38449,6 +38455,21 @@
     ctor public SocketTimeoutException(java.lang.String);
   }
 
+  public final class StandardSocketOptions {
+    ctor public StandardSocketOptions();
+    field public static final java.net.SocketOption IP_MULTICAST_IF;
+    field public static final java.net.SocketOption IP_MULTICAST_LOOP;
+    field public static final java.net.SocketOption IP_MULTICAST_TTL;
+    field public static final java.net.SocketOption IP_TOS;
+    field public static final java.net.SocketOption SO_BROADCAST;
+    field public static final java.net.SocketOption SO_KEEPALIVE;
+    field public static final java.net.SocketOption SO_LINGER;
+    field public static final java.net.SocketOption SO_RCVBUF;
+    field public static final java.net.SocketOption SO_REUSEADDR;
+    field public static final java.net.SocketOption SO_SNDBUF;
+    field public static final java.net.SocketOption TCP_NODELAY;
+  }
+
   public final class URI implements java.lang.Comparable java.io.Serializable {
     ctor public URI(java.lang.String) throws java.net.URISyntaxException;
     ctor public URI(java.lang.String, java.lang.String, java.lang.String) throws java.net.URISyntaxException;
@@ -38544,6 +38565,7 @@
     method public java.lang.Object getContent(java.lang.Class[]) throws java.io.IOException;
     method public java.lang.String getContentEncoding();
     method public int getContentLength();
+    method public long getContentLengthLong();
     method public java.lang.String getContentType();
     method public long getDate();
     method public static boolean getDefaultAllowUserInteraction();
@@ -38558,6 +38580,7 @@
     method public long getHeaderFieldDate(java.lang.String, long);
     method public int getHeaderFieldInt(java.lang.String, int);
     method public java.lang.String getHeaderFieldKey(int);
+    method public long getHeaderFieldLong(java.lang.String, long);
     method public java.util.Map<java.lang.String, java.util.List<java.lang.String>> getHeaderFields();
     method public long getIfModifiedSince();
     method public java.io.InputStream getInputStream() throws java.io.IOException;
@@ -38908,6 +38931,10 @@
 
 package java.nio.channels {
 
+  public class AlreadyBoundException extends java.lang.IllegalStateException {
+    ctor public AlreadyBoundException();
+  }
+
   public class AlreadyConnectedException extends java.lang.IllegalStateException {
     ctor public AlreadyConnectedException();
   }
@@ -38957,8 +38984,11 @@
 
   public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
+    method public java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel disconnect() throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
     method public abstract boolean isConnected();
     method public static java.nio.channels.DatagramChannel open() throws java.io.IOException;
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
@@ -38966,14 +38996,16 @@
     method public final synchronized long read(java.nio.ByteBuffer[]) throws java.io.IOException;
     method public abstract java.net.SocketAddress receive(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract int send(java.nio.ByteBuffer, java.net.SocketAddress) throws java.io.IOException;
+    method public java.nio.channels.DatagramChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
     method public abstract java.net.DatagramSocket socket();
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
     method public final int validOps();
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
     method public final synchronized long write(java.nio.ByteBuffer[]) throws java.io.IOException;
   }
 
-  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel java.nio.channels.SeekableByteChannel {
     ctor protected FileChannel();
     method public abstract void force(boolean) throws java.io.IOException;
     method public final java.nio.channels.FileLock lock() throws java.io.IOException;
@@ -39037,6 +39069,14 @@
     method public abstract void close() throws java.io.IOException;
   }
 
+  public abstract interface NetworkChannel implements java.lang.AutoCloseable java.nio.channels.Channel java.io.Closeable {
+    method public abstract java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public abstract T getOption(java.net.SocketOption<T>) throws java.io.IOException;
+    method public abstract java.nio.channels.NetworkChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public abstract java.util.Set<java.net.SocketOption<?>> supportedOptions();
+  }
+
   public class NoConnectionPendingException extends java.lang.IllegalStateException {
     ctor public NoConnectionPendingException();
   }
@@ -39087,6 +39127,15 @@
     method public abstract long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
   }
 
+  public abstract interface SeekableByteChannel implements java.nio.channels.ByteChannel {
+    method public abstract long position() throws java.io.IOException;
+    method public abstract java.nio.channels.SeekableByteChannel position(long) throws java.io.IOException;
+    method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
+    method public abstract long size() throws java.io.IOException;
+    method public abstract java.nio.channels.SeekableByteChannel truncate(long) throws java.io.IOException;
+    method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
+  }
+
   public abstract class SelectableChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.Channel {
     ctor protected SelectableChannel();
     method public abstract java.lang.Object blockingLock();
@@ -39135,18 +39184,27 @@
     method public abstract java.nio.channels.Selector wakeup();
   }
 
-  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel {
+  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.NetworkChannel {
     ctor protected ServerSocketChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.SocketChannel accept() throws java.io.IOException;
+    method public final java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
     method public static java.nio.channels.ServerSocketChannel open() throws java.io.IOException;
+    method public java.nio.channels.ServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
     method public abstract java.net.ServerSocket socket();
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
     method public final int validOps();
   }
 
-  public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
+    method public java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract boolean connect(java.net.SocketAddress) throws java.io.IOException;
     method public abstract boolean finishConnect() throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
     method public abstract boolean isConnected();
     method public abstract boolean isConnectionPending();
     method public static java.nio.channels.SocketChannel open() throws java.io.IOException;
@@ -39154,7 +39212,9 @@
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
     method public final synchronized long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+    method public java.nio.channels.SocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
     method public abstract java.net.Socket socket();
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
     method public final int validOps();
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
@@ -45204,6 +45264,7 @@
     method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
     method public final boolean hasQueuedThreads();
     method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method protected boolean isHeldExclusively();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9cfd85a..69ada6a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -161,7 +161,7 @@
     private static final int LOG_ON_PAUSE_CALLED = 30021;
     private static final int LOG_ON_RESUME_CALLED = 30022;
 
-    static ContextImpl mSystemContext = null;
+    private ContextImpl mSystemContext;
 
     static IPackageManager sPackageManager;
 
@@ -1709,7 +1709,7 @@
                                 ? mBoundApplication.processName : null)
                         + ")");
                 packageInfo =
-                    new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
+                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                             securityViolation, includeCode &&
                             (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
                 if (includeCode) {
@@ -1762,26 +1762,15 @@
     public ContextImpl getSystemContext() {
         synchronized (this) {
             if (mSystemContext == null) {
-                ContextImpl context =
-                    ContextImpl.createSystemContext(this);
-                LoadedApk info = new LoadedApk(this, "android", context, null,
-                        CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
-                context.init(info, null, this);
-                context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),
-                        mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
-                mSystemContext = context;
-                //Slog.i(TAG, "Created system resources " + context.getResources()
-                //        + ": " + context.getResources().getConfiguration());
+                mSystemContext = ContextImpl.createSystemContext(this);
             }
+            return mSystemContext;
         }
-        return mSystemContext;
     }
 
     public void installSystemApplicationInfo(ApplicationInfo info) {
         synchronized (this) {
-            ContextImpl context = getSystemContext();
-            context.init(new LoadedApk(this, "android", context, info,
-                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
+            getSystemContext().installSystemApplicationInfo(info);
 
             // give ourselves a default profiler
             mProfiler = new Profiler();
@@ -2268,8 +2257,7 @@
 
     private Context createBaseContextForActivity(ActivityClientRecord r,
             final Activity activity) {
-        ContextImpl appContext = new ContextImpl();
-        appContext.init(r.packageInfo, r.token, this);
+        ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
         appContext.setOuterContext(activity);
         Context baseContext = appContext;
 
@@ -2567,8 +2555,7 @@
                 agent = (BackupAgent) cl.loadClass(classname).newInstance();
 
                 // set up the agent's context
-                ContextImpl context = new ContextImpl();
-                context.init(packageInfo, null, this);
+                ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
                 context.setOuterContext(agent);
                 agent.attach(context);
 
@@ -2640,11 +2627,10 @@
         try {
             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
 
-            ContextImpl context = new ContextImpl();
-            context.init(packageInfo, null, this);
+            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
+            context.setOuterContext(service);
 
             Application app = packageInfo.makeApplication(false, mInstrumentation);
-            context.setOuterContext(service);
             service.attach(context, this, data.info.name, data.token, app,
                     ActivityManagerNative.getDefault());
             service.onCreate();
@@ -4249,8 +4235,7 @@
         }
         updateDefaultDensity();
 
-        final ContextImpl appContext = new ContextImpl();
-        appContext.init(data.info, null, this);
+        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
         if (!Process.isIsolated()) {
             final File cacheDir = appContext.getCacheDir();
 
@@ -4366,8 +4351,7 @@
             instrApp.nativeLibraryDir = ii.nativeLibraryDir;
             LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                     appContext.getClassLoader(), false, true);
-            ContextImpl instrContext = new ContextImpl();
-            instrContext.init(pi, null, this);
+            ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
 
             try {
                 java.lang.ClassLoader cl = instrContext.getClassLoader();
@@ -4982,8 +4966,8 @@
                                                     UserHandle.myUserId());
             try {
                 mInstrumentation = new Instrumentation();
-                ContextImpl context = new ContextImpl();
-                context.init(getSystemContext().mPackageInfo, null, this);
+                ContextImpl context = ContextImpl.createAppContext(
+                        this, getSystemContext().mPackageInfo);
                 Application app = Instrumentation.newApplication(Application.class, context);
                 mAllApplications.add(app);
                 mInitialApplication = app;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 9b3643c..0351292 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -185,22 +185,31 @@
      */
     private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
 
-    /*package*/ LoadedApk mPackageInfo;
-    private String mBasePackageName;
-    private String mOpPackageName;
-    private Resources mResources;
-    /*package*/ ActivityThread mMainThread;
+    final ActivityThread mMainThread;
+    final LoadedApk mPackageInfo;
+
+    private final IBinder mActivityToken;
+
+    private final UserHandle mUser;
+
+    private final ApplicationContentResolver mContentResolver;
+
+    private final String mBasePackageName;
+    private final String mOpPackageName;
+
+    private final ResourcesManager mResourcesManager;
+    private final Resources mResources;
+    private final Display mDisplay; // may be null if default display
+    private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
+    private final Configuration mOverrideConfiguration;
+
+    private final boolean mRestricted;
+
     private Context mOuterContext;
-    private IBinder mActivityToken = null;
-    private ApplicationContentResolver mContentResolver;
     private int mThemeResource = 0;
     private Resources.Theme mTheme = null;
     private PackageManager mPackageManager;
-    private Display mDisplay; // may be null if default display
     private Context mReceiverRestrictedContext = null;
-    private boolean mRestricted;
-    private UserHandle mUser;
-    private ResourcesManager mResourcesManager;
 
     private final Object mSync = new Object();
 
@@ -222,8 +231,6 @@
 
     private static final String[] EMPTY_FILE_LIST = {};
 
-    final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
-
     /**
      * Override this class when the system service constructor needs a
      * ContextImpl.  Else, use StaticServiceFetcher below.
@@ -1887,20 +1894,17 @@
     @Override
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws NameNotFoundException {
+        final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
         if (packageName.equals("system") || packageName.equals("android")) {
-            final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
-            context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
-            context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
-            return context;
+            return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                    user, restricted, mDisplay, mOverrideConfiguration);
         }
 
-        LoadedApk pi =
-            mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags,
-                    user.getIdentifier());
+        LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
+                flags, user.getIdentifier());
         if (pi != null) {
-            ContextImpl c = new ContextImpl();
-            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
-            c.init(pi, null, mMainThread, mResources, mBasePackageName, user);
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
+                    user, restricted, mDisplay, mOverrideConfiguration);
             if (c.mResources != null) {
                 return c;
             }
@@ -1908,7 +1912,7 @@
 
         // Should be a better exception.
         throw new PackageManager.NameNotFoundException(
-            "Application package " + packageName + " not found");
+                "Application package " + packageName + " not found");
     }
 
     @Override
@@ -1917,12 +1921,8 @@
             throw new IllegalArgumentException("overrideConfiguration must not be null");
         }
 
-        ContextImpl c = new ContextImpl();
-        c.init(mPackageInfo, null, mMainThread);
-        c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
-                mPackageInfo.getOverlayDirs(), getDisplayId(), overrideConfiguration,
-                mResources.getCompatibilityInfo(), mActivityToken);
-        return c;
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, mRestricted, mDisplay, overrideConfiguration);
     }
 
     @Override
@@ -1931,15 +1931,8 @@
             throw new IllegalArgumentException("display must not be null");
         }
 
-        int displayId = display.getDisplayId();
-
-        ContextImpl context = new ContextImpl();
-        context.init(mPackageInfo, null, mMainThread);
-        context.mDisplay = display;
-        DisplayAdjustments daj = getDisplayAdjustments(displayId);
-        context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
-                mPackageInfo.getOverlayDirs(), displayId, null, daj.getCompatibilityInfo(), null);
-        return context;
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, mRestricted, display, mOverrideConfiguration);
     }
 
     private int getDisplayId() {
@@ -1981,43 +1974,76 @@
     }
 
     static ContextImpl createSystemContext(ActivityThread mainThread) {
-        final ContextImpl context = new ContextImpl();
-        context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
+        LoadedApk packageInfo = new LoadedApk(mainThread);
+        ContextImpl context = new ContextImpl(null, mainThread,
+                packageInfo, null, null, false, null, null);
+        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
+                context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
         return context;
     }
 
-    ContextImpl() {
+    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
+        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
+        return new ContextImpl(null, mainThread,
+                packageInfo, null, null, false, null, null);
+    }
+
+    static ContextImpl createActivityContext(ActivityThread mainThread,
+            LoadedApk packageInfo, IBinder activityToken) {
+        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
+        if (activityToken == null) throw new IllegalArgumentException("activityInfo");
+        return new ContextImpl(null, mainThread,
+                packageInfo, activityToken, null, false, null, null);
+    }
+
+    private ContextImpl(ContextImpl container, ActivityThread mainThread,
+            LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
+            Display display, Configuration overrideConfiguration) {
         mOuterContext = this;
-    }
 
-    /**
-     * Create a new ApplicationContext from an existing one.  The new one
-     * works and operates the same as the one it is copying.
-     *
-     * @param context Existing application context.
-     */
-    public ContextImpl(ContextImpl context) {
-        mPackageInfo = context.mPackageInfo;
-        mBasePackageName = context.mBasePackageName;
-        mOpPackageName = context.mOpPackageName;
-        mResources = context.mResources;
-        mMainThread = context.mMainThread;
-        mContentResolver = context.mContentResolver;
-        mUser = context.mUser;
-        mDisplay = context.mDisplay;
-        mOuterContext = this;
-        mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
-    }
+        mMainThread = mainThread;
+        mActivityToken = activityToken;
+        mRestricted = restricted;
 
-    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
-        init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
-    }
+        if (user == null) {
+            user = Process.myUserHandle();
+        }
+        mUser = user;
 
-    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
-            Resources container, String basePackageName, UserHandle user) {
         mPackageInfo = packageInfo;
-        if (basePackageName != null) {
-            mBasePackageName = mOpPackageName = basePackageName;
+        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
+        mResourcesManager = ResourcesManager.getInstance();
+        mDisplay = display;
+        mOverrideConfiguration = overrideConfiguration;
+
+        final int displayId = getDisplayId();
+        CompatibilityInfo compatInfo = null;
+        if (container != null) {
+            compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
+        }
+        if (compatInfo == null && displayId == Display.DEFAULT_DISPLAY) {
+            compatInfo = packageInfo.getCompatibilityInfo();
+        }
+        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+        mDisplayAdjustments.setActivityToken(activityToken);
+
+        Resources resources = packageInfo.getResources(mainThread);
+        if (resources != null) {
+            if (activityToken != null
+                    || displayId != Display.DEFAULT_DISPLAY
+                    || overrideConfiguration != null
+                    || (compatInfo != null && compatInfo.applicationScale
+                            != resources.getCompatibilityInfo().applicationScale)) {
+                resources = mResourcesManager.getTopLevelResources(
+                        packageInfo.getResDir(), packageInfo.getOverlayDirs(), displayId,
+                        overrideConfiguration, compatInfo, activityToken);
+            }
+        }
+        mResources = resources;
+
+        if (container != null) {
+            mBasePackageName = container.mBasePackageName;
+            mOpPackageName = container.mOpPackageName;
         } else {
             mBasePackageName = packageInfo.mPackageName;
             ApplicationInfo ainfo = packageInfo.getApplicationInfo();
@@ -2031,45 +2057,10 @@
                 mOpPackageName = mBasePackageName;
             }
         }
-        mResources = mPackageInfo.getResources(mainThread);
-        mResourcesManager = ResourcesManager.getInstance();
-
-        CompatibilityInfo compatInfo =
-                container == null ? null : container.getCompatibilityInfo();
-        if (mResources != null &&
-                ((compatInfo != null && compatInfo.applicationScale !=
-                        mResources.getCompatibilityInfo().applicationScale)
-                || activityToken != null)) {
-            if (DEBUG) {
-                Log.d(TAG, "loaded context has different scaling. Using container's" +
-                        " compatiblity info:" + container.getDisplayMetrics());
-            }
-            if (compatInfo == null) {
-                compatInfo = packageInfo.getCompatibilityInfo();
-            }
-            mDisplayAdjustments.setCompatibilityInfo(compatInfo);
-            mDisplayAdjustments.setActivityToken(activityToken);
-            mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
-                    mPackageInfo.getOverlayDirs(), Display.DEFAULT_DISPLAY, null, compatInfo,
-                    activityToken);
-        } else {
-            mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
-            mDisplayAdjustments.setActivityToken(activityToken);
-        }
-        mMainThread = mainThread;
-        mActivityToken = activityToken;
-        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
-        mUser = user;
     }
 
-    final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
-        mPackageInfo = null;
-        mBasePackageName = null;
-        mOpPackageName = null;
-        mResources = resources;
-        mMainThread = mainThread;
-        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
-        mUser = user;
+    void installSystemApplicationInfo(ApplicationInfo info) {
+        mPackageInfo.installSystemApplicationInfo(info);
     }
 
     final void scheduleFinalCleanup(String who, String what) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 0115d1b..d409352 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -72,7 +72,7 @@
     private static final String TAG = "LoadedApk";
 
     private final ActivityThread mActivityThread;
-    private final ApplicationInfo mApplicationInfo;
+    private ApplicationInfo mApplicationInfo;
     final String mPackageName;
     private final String mAppDir;
     private final String mResDir;
@@ -111,8 +111,7 @@
      * so MUST NOT call back out to the activity manager.
      */
     public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
-            CompatibilityInfo compatInfo,
-            ActivityThread mainThread, ClassLoader baseLoader,
+            CompatibilityInfo compatInfo, ClassLoader baseLoader,
             boolean securityViolation, boolean includeCode) {
         mActivityThread = activityThread;
         mApplicationInfo = aInfo;
@@ -134,31 +133,17 @@
         mSecurityViolation = securityViolation;
         mIncludeCode = includeCode;
         mDisplayAdjustments.setCompatibilityInfo(compatInfo);
-
-        if (mAppDir == null) {
-            if (ActivityThread.mSystemContext == null) {
-                ActivityThread.mSystemContext =
-                    ContextImpl.createSystemContext(mainThread);
-                ResourcesManager resourcesManager = ResourcesManager.getInstance();
-                ActivityThread.mSystemContext.getResources().updateConfiguration(
-                        resourcesManager.getConfiguration(),
-                        resourcesManager.getDisplayMetricsLocked(
-                                 Display.DEFAULT_DISPLAY, mDisplayAdjustments), compatInfo);
-                //Slog.i(TAG, "Created system resources "
-                //        + mSystemContext.getResources() + ": "
-                //        + mSystemContext.getResources().getConfiguration());
-            }
-            mClassLoader = ActivityThread.mSystemContext.getClassLoader();
-            mResources = ActivityThread.mSystemContext.getResources();
-        }
     }
 
-    public LoadedApk(ActivityThread activityThread, String name,
-            Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
+    /**
+     * Create information about the system package.
+     * Must call {@link #installSystemApplicationInfo} later.
+     */
+    LoadedApk(ActivityThread activityThread) {
         mActivityThread = activityThread;
-        mApplicationInfo = info != null ? info : new ApplicationInfo();
-        mApplicationInfo.packageName = name;
-        mPackageName = name;
+        mApplicationInfo = new ApplicationInfo();
+        mApplicationInfo.packageName = "android";
+        mPackageName = "android";
         mAppDir = null;
         mResDir = null;
         mOverlayDirs = null;
@@ -169,9 +154,16 @@
         mBaseClassLoader = null;
         mSecurityViolation = false;
         mIncludeCode = true;
-        mClassLoader = systemContext.getClassLoader();
-        mResources = systemContext.getResources();
-        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+        mClassLoader = ClassLoader.getSystemClassLoader();
+        mResources = Resources.getSystem();
+    }
+
+    /**
+     * Sets application info about the system package.
+     */
+    void installSystemApplicationInfo(ApplicationInfo info) {
+        assert info.packageName.equals("android");
+        mApplicationInfo = info;
     }
 
     public String getPackageName() {
@@ -513,8 +505,7 @@
 
         try {
             java.lang.ClassLoader cl = getClassLoader();
-            ContextImpl appContext = new ContextImpl();
-            appContext.init(this, null, mActivityThread);
+            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
             app = mActivityThread.mInstrumentation.newApplication(
                     cl, appClass, appContext);
             appContext.setOuterContext(app);
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 6f4533c..f9d9059 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -169,7 +169,7 @@
      * the provisioning of a managed profile has completed successfully.
      *
      * <p>The broadcast is limited to the package which started the provisioning as specified in
-     * the extra {@link DevicePolicyManager#EXTRA_PROVISIONING_MDM_PACKAGE_NAME} of the
+     * the extra {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} of the
      * {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
      * provisioning. It is also limited to the managed profile.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f0b7ca8..96479e2 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2768,6 +2768,12 @@
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
     /**
+     * Indicates an activity optimized for Leanback mode, and that should
+     * be displayed in the Leanback launcher.
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+    /**
      * Provides information about the package it is in; typically used if
      * a package does not contain a {@link #CATEGORY_LAUNCHER} to provide
      * a front-door to the user without having to be shown in the all apps list.
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 0da77ea..7db4ac2 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -343,8 +343,9 @@
         }
 
         public class Pid {
-            public long mWakeSum;
-            public long mWakeStart;
+            public int mWakeNesting;
+            public long mWakeSumMs;
+            public long mWakeStartMs;
         }
 
         /**
@@ -515,7 +516,8 @@
         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
         public static final byte CMD_NULL = -1;
         public static final byte CMD_START = 4;
-        public static final byte CMD_OVERFLOW = 5;
+        public static final byte CMD_CURRENT_TIME = 5;
+        public static final byte CMD_OVERFLOW = 6;
 
         public byte cmd = CMD_NULL;
         
@@ -610,6 +612,9 @@
         public int eventCode;
         public HistoryTag eventTag;
 
+        // Only set for CMD_CURRENT_TIME.
+        public long currentTime;
+
         // Meta-data when reading.
         public int numReadInts;
 
@@ -637,29 +642,28 @@
                     | ((((int)batteryLevel)<<8)&0xff00)
                     | ((((int)batteryStatus)<<16)&0xf0000)
                     | ((((int)batteryHealth)<<20)&0xf00000)
-                    | ((((int)batteryPlugType)<<24)&0xf000000);
+                    | ((((int)batteryPlugType)<<24)&0xf000000)
+                    | (wakelockTag != null ? 0x10000000 : 0)
+                    | (wakeReasonTag != null ? 0x20000000 : 0)
+                    | (eventCode != EVENT_NONE ? 0x40000000 : 0);
             dest.writeInt(bat);
             bat = (((int)batteryTemperature)&0xffff)
                     | ((((int)batteryVoltage)<<16)&0xffff0000);
             dest.writeInt(bat);
             dest.writeInt(states);
             if (wakelockTag != null) {
-                dest.writeInt(1);
                 wakelockTag.writeToParcel(dest, flags);
-            } else {
-                dest.writeInt(0);
             }
             if (wakeReasonTag != null) {
-                dest.writeInt(1);
                 wakeReasonTag.writeToParcel(dest, flags);
-            } else {
-                dest.writeInt(0);
             }
-            dest.writeInt(eventCode);
             if (eventCode != EVENT_NONE) {
                 dest.writeInt(eventCode);
                 eventTag.writeToParcel(dest, flags);
             }
+            if (cmd == CMD_CURRENT_TIME) {
+                dest.writeLong(currentTime);
+            }
         }
 
         public void readFromParcel(Parcel src) {
@@ -670,26 +674,34 @@
             batteryStatus = (byte)((bat>>16)&0xf);
             batteryHealth = (byte)((bat>>20)&0xf);
             batteryPlugType = (byte)((bat>>24)&0xf);
-            bat = src.readInt();
-            batteryTemperature = (short)(bat&0xffff);
-            batteryVoltage = (char)((bat>>16)&0xffff);
+            int bat2 = src.readInt();
+            batteryTemperature = (short)(bat2&0xffff);
+            batteryVoltage = (char)((bat2>>16)&0xffff);
             states = src.readInt();
-            if (src.readInt() != 0) {
+            if ((bat&0x10000000) != 0) {
                 wakelockTag = localWakelockTag;
                 wakelockTag.readFromParcel(src);
             } else {
                 wakelockTag = null;
             }
-            if (src.readInt() != 0) {
+            if ((bat&0x20000000) != 0) {
                 wakeReasonTag = localWakeReasonTag;
                 wakeReasonTag.readFromParcel(src);
             } else {
                 wakeReasonTag = null;
             }
-            eventCode = src.readInt();
-            if (eventCode != EVENT_NONE) {
+            if ((bat&0x40000000) != 0) {
+                eventCode = src.readInt();
                 eventTag = localEventTag;
                 eventTag.readFromParcel(src);
+            } else {
+                eventCode = EVENT_NONE;
+                eventTag = null;
+            }
+            if (cmd == CMD_CURRENT_TIME) {
+                currentTime = src.readLong();
+            } else {
+                currentTime = 0;
             }
             numReadInts += (src.dataPosition()-start)/4;
         }
@@ -749,6 +761,7 @@
             } else {
                 eventTag = null;
             }
+            currentTime = o.currentTime;
         }
 
         public boolean sameNonEvent(HistoryItem o) {
@@ -758,7 +771,8 @@
                     && batteryPlugType == o.batteryPlugType
                     && batteryTemperature == o.batteryTemperature
                     && batteryVoltage == o.batteryVoltage
-                    && states == o.states;
+                    && states == o.states
+                    && currentTime == o.currentTime;
         }
 
         public boolean same(HistoryItem o) {
@@ -2788,6 +2802,18 @@
                     pw.print(":");
                 }
                 pw.println("START");
+            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
+                if (checkin) {
+                    pw.print(":");
+                }
+                pw.print("TIME:");
+                if (checkin) {
+                    pw.println(rec.currentTime);
+                } else {
+                    pw.print(" ");
+                    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
+                            rec.currentTime).toString());
+                }
             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
                 if (checkin) {
                     pw.print(":");
@@ -2941,8 +2967,8 @@
                     }
                 }
                 pw.println();
+                oldState = rec.states;
             }
-            oldState = rec.states;
         }
     }
 
@@ -3059,8 +3085,8 @@
                             pw.println("Per-PID Stats:");
                             didPid = true;
                         }
-                        long time = pid.mWakeSum + (pid.mWakeStart != 0
-                                ? (nowRealtime - pid.mWakeStart) : 0);
+                        long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
+                                ? (nowRealtime - pid.mWakeStartMs) : 0);
                         pw.print("  PID "); pw.print(pids.keyAt(j));
                                 pw.print(" wake time: ");
                                 TimeUtils.formatDuration(time, pw);
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 6650fca..5d55143 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -21,11 +21,11 @@
 /**
  * Class that operates the vibrator on the device.
  * <p>
- * If your process exits, any vibration you started with will stop.
+ * If your process exits, any vibration you started will stop.
  * </p>
  *
  * To obtain an instance of the system vibrator, call
- * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
+ * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as the argument.
  */
 public abstract class Vibrator {
     /**
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 3f90f76..5ba5c57 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -41,6 +41,9 @@
 
     void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, String historyName,
             int type, boolean unimportantForLogging);
+    void noteChangeWakelockFromSource(in WorkSource ws, int pid, String name, int type,
+            in WorkSource newWs, int newPid, String newName,
+            String newHistoryName, int newType, boolean newUnimportantForLogging);
     void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
 
     void noteVibratorOn(int uid, long durationMillis);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index db21906..10fd2f0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -87,7 +87,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 98 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 99 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -2274,9 +2274,8 @@
     }
 
     public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
-            boolean unimportantForLogging) {
+            boolean unimportantForLogging, long elapsedRealtime) {
         uid = mapUid(uid);
-        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (type == WAKE_TYPE_PARTIAL) {
             // Only care about partial wake locks, since full wake locks
             // will be canceled when the user puts the screen to sleep.
@@ -2308,9 +2307,8 @@
         }
     }
 
-    public void noteStopWakeLocked(int uid, int pid, String name, int type) {
+    public void noteStopWakeLocked(int uid, int pid, String name, int type, long elapsedRealtime) {
         uid = mapUid(uid);
-        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (type == WAKE_TYPE_PARTIAL) {
             mWakeLockNesting--;
             if (mWakeLockNesting == 0) {
@@ -2328,16 +2326,37 @@
 
     public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
             String historyName, int type, boolean unimportantForLogging) {
-        int N = ws.size();
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging);
+            noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
+                    elapsedRealtime);
+        }
+    }
+
+    public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, int type,
+            WorkSource newWs, int newPid, String newName,
+            String newHistoryName, int newType, boolean newUnimportantForLogging) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        // For correct semantics, we start the need worksources first, so that we won't
+        // make inappropriate history items as if all wake locks went away and new ones
+        // appeared.  This is okay because tracking of wake locks allows nesting.
+        final int NN = ws.size();
+        for (int i=0; i<NN; i++) {
+            noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
+                    newUnimportantForLogging, elapsedRealtime);
+        }
+        final int NO = ws.size();
+        for (int i=0; i<NO; i++) {
+            noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime);
         }
     }
 
     public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
-        int N = ws.size();
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStopWakeLocked(ws.get(i), pid, name, type);
+            noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime);
         }
     }
 
@@ -2466,7 +2485,7 @@
         if (u != null) {
             Uid.Pid p = u.mPids.get(pid);
             if (p != null) {
-                return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
+                return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
             }
         }
         return 0;
@@ -2562,8 +2581,8 @@
 
             // Fake a wake lock, so we consider the device waked as long
             // as the screen is on.
-            noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false);
-            
+            noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false, elapsedRealtime);
+
             // Update discharge amounts.
             if (mOnBatteryInternal) {
                 updateDischargeScreenLevelsLocked(false, true);
@@ -2584,7 +2603,7 @@
                 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
             }
 
-            noteStopWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL);
+            noteStopWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL, elapsedRealtime);
 
             updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
                     SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
@@ -3999,10 +4018,12 @@
                 mProcessStats.clear();
             }
             if (mPids.size() > 0) {
-                for (int i=0; !active && i<mPids.size(); i++) {
+                for (int i=mPids.size()-1; i>=0; i--) {
                     Pid pid = mPids.valueAt(i);
-                    if (pid.mWakeStart != 0) {
+                    if (pid.mWakeNesting > 0) {
                         active = true;
+                    } else {
+                        mPids.removeAt(i);
                     }
                 }
             }
@@ -4024,8 +4045,6 @@
                 mPackageStats.clear();
             }
 
-            mPids.clear();
-
             if (!active) {
                 if (mWifiRunningTimer != null) {
                     mWifiRunningTimer.detach();
@@ -4067,6 +4086,7 @@
                         mNetworkPacketActivityCounters[i].detach();
                     }
                 }
+                mPids.clear();
             }
 
             return !active;
@@ -5304,8 +5324,8 @@
             }
             if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
                 Pid p = getPidStatsLocked(pid);
-                if (p.mWakeStart == 0) {
-                    p.mWakeStart = elapsedRealtimeMs;
+                if (p.mWakeNesting++ == 0) {
+                    p.mWakeStartMs = elapsedRealtimeMs;
                 }
             }
         }
@@ -5317,9 +5337,11 @@
             }
             if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
                 Pid p = mPids.get(pid);
-                if (p != null && p.mWakeStart != 0) {
-                    p.mWakeSum += elapsedRealtimeMs - p.mWakeStart;
-                    p.mWakeStart = 0;
+                if (p != null && p.mWakeNesting > 0) {
+                    if (p.mWakeNesting-- == 1) {
+                        p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
+                        p.mWakeStartMs = 0;
+                    }
                 }
             }
         }
@@ -5765,6 +5787,9 @@
             mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
                     + Integer.toHexString(mHistoryCur.states));
+            mHistoryCur.currentTime = System.currentTimeMillis();
+            addHistoryBufferLocked(mSecRealtime, HistoryItem.CMD_CURRENT_TIME);
+            mHistoryCur.currentTime = 0;
             addHistoryRecordLocked(mSecRealtime);
             mDischargeCurrentLevel = mDischargeUnplugLevel = level;
             if (mScreenOn) {
@@ -6414,11 +6439,16 @@
             Slog.e("BatteryStats", "Error reading battery statistics", e);
         }
 
-        long now = SystemClock.elapsedRealtime();
-        if (USE_OLD_HISTORY) {
-            addHistoryRecordLocked(now, HistoryItem.CMD_START);
+        if (mHistoryBuffer.dataPosition() > 0) {
+            long now = SystemClock.elapsedRealtime();
+            if (USE_OLD_HISTORY) {
+                addHistoryRecordLocked(now, HistoryItem.CMD_START);
+            }
+            addHistoryBufferLocked(now, HistoryItem.CMD_START);
+            mHistoryCur.currentTime = System.currentTimeMillis();
+            addHistoryBufferLocked(now, HistoryItem.CMD_CURRENT_TIME);
+            mHistoryCur.currentTime = 0;
         }
-        addHistoryBufferLocked(now, HistoryItem.CMD_START);
     }
 
     public int describeContents() {
diff --git a/docs/html/google/auth/api-client.jd b/docs/html/google/auth/api-client.jd
index fda3310..402a95f 100644
--- a/docs/html/google/auth/api-client.jd
+++ b/docs/html/google/auth/api-client.jd
@@ -112,7 +112,7 @@
 href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html"
 >{@code ConnectionCallbacks}</a> and <a
 href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html"
->{@code onConnectionFailedListener}</a>. These interfaces receive callbacks in
+>{@code OnConnectionFailedListener}</a>. These interfaces receive callbacks in
 response to the asynchronous <a
 href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html#connect()"
 >{@code connect()}</a> method when the connection to Google Play services
@@ -512,7 +512,7 @@
     new GetFileTask().execute(filename);
 }
 
-private class GetFileTask extends AsyncTask<String, Void, Void> {
+private class GetFileTask extends AsyncTask&lt;String, Void, Void> {
     protected void doInBackground(String filename) {
         Query query = new Query.Builder()
                 .addFilter(Filters.eq(SearchableField.TITLE, filename))
diff --git a/docs/html/guide/topics/ui/controls/button.jd b/docs/html/guide/topics/ui/controls/button.jd
index 02597c8..b52c3e9 100644
--- a/docs/html/guide/topics/ui/controls/button.jd
+++ b/docs/html/guide/topics/ui/controls/button.jd
@@ -113,7 +113,7 @@
 
 <h3 id="ClickListener">Using an OnClickListener</h3>
 
-<p>You can also declare the click event handler pragmatically rather than in an XML layout. This
+<p>You can also declare the click event handler programmatically rather than in an XML layout. This
 might be necessary if you instantiate the {@link android.widget.Button} at runtime or you need to
 declare the click behavior in a {@link android.app.Fragment} subclass.</p>
 
diff --git a/docs/html/guide/topics/ui/controls/togglebutton.jd b/docs/html/guide/topics/ui/controls/togglebutton.jd
index c57b510..09af516 100644
--- a/docs/html/guide/topics/ui/controls/togglebutton.jd
+++ b/docs/html/guide/topics/ui/controls/togglebutton.jd
@@ -99,7 +99,7 @@
 
 <h3 id="ClickListener">Using an OnCheckedChangeListener</h3>
 
-<p>You can also declare a click event handler pragmatically rather than in an XML layout. This
+<p>You can also declare a click event handler programmatically rather than in an XML layout. This
 might be necessary if you instantiate the {@link android.widget.ToggleButton} or {@link
 android.widget.Switch} at runtime or you need to
 declare the click behavior in a {@link android.app.Fragment} subclass.</p>
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index bda0183..9de3efe 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -426,8 +426,10 @@
         final Pair<String, ComponentName> mTarget;
         final BroadcastStats mBroadcastStats;
         final FilterStats mFilterStats;
+        final int mAlarmType;
 
-        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) {
+        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource,
+                int alarmType) {
             mPendingIntent = pendingIntent;
             mWorkSource = workSource;
             Intent intent = pendingIntent.getIntent();
@@ -441,6 +443,7 @@
                 mBroadcastStats.filterStats.put(mTarget, fs);
             }
             mFilterStats = fs;
+            mAlarmType = alarmType;
         }
     }
 
@@ -1280,17 +1283,12 @@
                             
                             // we have an active broadcast so stay awake.
                             if (mBroadcastRefCount == 0) {
-                                setWakelockWorkSource(alarm.operation, alarm.workSource);
-                                mWakeLock.setUnimportantForLogging(
-                                        alarm.operation == mTimeTickSender);
-                                mWakeLock.setHistoryTag(alarm.operation.getTag(
-                                        alarm.type == ELAPSED_REALTIME_WAKEUP
-                                                || alarm.type == RTC_WAKEUP
-                                                ? "*walarm*:" : "*alarm*:"));
+                                setWakelockWorkSource(alarm.operation, alarm.workSource,
+                                        alarm.type, true);
                                 mWakeLock.acquire();
                             }
                             final InFlight inflight = new InFlight(AlarmManagerService.this,
-                                    alarm.operation, alarm.workSource);
+                                    alarm.operation, alarm.workSource, alarm.type);
                             mInFlight.add(inflight);
                             mBroadcastRefCount++;
 
@@ -1345,9 +1343,17 @@
      * @param pi PendingIntent to attribute blame to if ws is null.
      * @param ws WorkSource to attribute blame.
      */
-    void setWakelockWorkSource(PendingIntent pi, WorkSource ws) {
+    void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, boolean first) {
         try {
+            mWakeLock.setUnimportantForLogging(pi == mTimeTickSender);
             if (ws != null) {
+                if (first) {
+                    mWakeLock.setHistoryTag(pi.getTag(
+                            type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
+                                    ? "*walarm*:" : "*alarm*:"));
+                } else {
+                    mWakeLock.setHistoryTag(null);
+                }
                 mWakeLock.setWorkSource(ws);
                 return;
             }
@@ -1355,6 +1361,7 @@
             final int uid = ActivityManagerNative.getDefault()
                     .getUidForIntentSender(pi.getTarget());
             if (uid >= 0) {
+                mWakeLock.setHistoryTag(null);
                 mWakeLock.setWorkSource(new WorkSource(uid));
                 return;
             }
@@ -1579,7 +1586,8 @@
                     // the next of our alarms is now in flight.  reattribute the wakelock.
                     if (mInFlight.size() > 0) {
                         InFlight inFlight = mInFlight.get(0);
-                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
+                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource,
+                                inFlight.mAlarmType, false);
                     } else {
                         // should never happen
                         mLog.w("Alarm wakelock still held but sent queue empty");
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 39bfc23..3414daf 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -29,6 +29,7 @@
 import android.os.Parcel;
 import android.os.Process;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.telephony.SignalStrength;
@@ -133,14 +134,15 @@
             boolean unimportantForLogging) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging);
+            mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
+                    SystemClock.elapsedRealtime());
         }
     }
 
     public void noteStopWakelock(int uid, int pid, String name, int type) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStopWakeLocked(uid, pid, name, type);
+            mStats.noteStopWakeLocked(uid, pid, name, type, SystemClock.elapsedRealtime());
         }
     }
 
@@ -153,6 +155,16 @@
         }
     }
 
+    public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, int type,
+            WorkSource newWs, int newPid, String newName,
+            String newHistoryName, int newType, boolean newUnimportantForLogging) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, type,
+                    newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
+        }
+    }
+
     public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, int type) {
         enforceCallingPermission();
         synchronized (mStats) {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index e1ccf46..df06bae 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -158,6 +158,39 @@
     }
 
     /**
+     * Called when a wake lock is changing.
+     */
+    public void onWakeLockChanging(int flags, String tag, String packageName,
+            int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
+            int newFlags, String newTag, String newPackageName, int newOwnerUid,
+            int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
+
+        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+        final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+        boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
+                && ownerUid == Process.SYSTEM_UID;
+        if (workSource != null && newWorkSource != null) {
+            if (DEBUG) {
+                Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+                        + "\", packageName=" + newPackageName
+                        + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+                        + ", workSource=" + newWorkSource);
+            }
+            try {
+                mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, monitorType,
+                        newWorkSource, newOwnerPid, newTag, newHistoryTag,
+                        newMonitorType, unimportantForLogging);
+            } catch (RemoteException ex) {
+                // Ignore
+            }
+        } else {
+            onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource);
+            onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
+                    newWorkSource, newHistoryTag);
+        }
+    }
+
+    /**
      * Called when a wake lock is released.
      */
     public void onWakeLockReleased(int flags, String tag, String packageName,
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index e7bbf1c..40ebe8d 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -646,9 +646,9 @@
                 wakeLock = mWakeLocks.get(index);
                 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
                     // Update existing wake lock.  This shouldn't happen but is harmless.
-                    notifyWakeLockReleasedLocked(wakeLock);
+                    notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,
+                            uid, pid, ws, historyTag);
                     wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
-                    notifyWakeLockAcquiredLocked(wakeLock);
                 }
             } else {
                 wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
@@ -765,9 +765,10 @@
             }
 
             if (!wakeLock.hasSameWorkSource(ws)) {
-                notifyWakeLockReleasedLocked(wakeLock);
+                notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
+                        wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
+                        ws, wakeLock.mHistoryTag);
                 wakeLock.updateWorkSource(ws);
-                notifyWakeLockAcquiredLocked(wakeLock);
             }
         }
     }
@@ -791,6 +792,15 @@
         }
     }
 
+    private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag,
+            String packageName, int uid, int pid, WorkSource ws, String historyTag) {
+        if (mSystemReady && wakeLock.mNotifiedAcquired) {
+            mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
+                    wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag);
+        }
+    }
+
     private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
         if (mSystemReady && wakeLock.mNotifiedAcquired) {
             wakeLock.mNotifiedAcquired = false;