Merge "Don't use OpenGL ES 2.0 to render the wallpaper on the emulator. Bug #5352896"
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 254c98f..ea5c3db 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -781,7 +781,7 @@
      * Get the current connection state of a profile.
      * This function can be used to check whether the local Bluetooth adapter
      * is connected to any remote device for a specific profile.
-     * Profile can be one of {@link BluetoothProfile#HEADSET},
+     * Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET},
      * {@link BluetoothProfile#A2DP}.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
@@ -1132,15 +1132,15 @@
     /**
      * Get the profile proxy object associated with the profile.
      *
-     * <p>Profile can be one of {@link BluetoothProfile#HEADSET} or
+     * <p>Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET} or
      * {@link BluetoothProfile#A2DP}. Clients must implements
      * {@link BluetoothProfile.ServiceListener} to get notified of
      * the connection status and to get the proxy object.
      *
      * @param context Context of the application
      * @param listener The service Listener for connection callbacks.
-     * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEADSET}
-     *                or {@link BluetoothProfile#A2DP}.
+     * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH},
+     *                {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#A2DP}.
      * @return true on success, false on error
      */
     public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
@@ -1172,7 +1172,7 @@
      *
      * <p> Clients should call this when they are no longer using
      * the proxy obtained from {@link #getProfileProxy}.
-     * Profile can be one of {@link BluetoothProfile#HEADSET} or
+     * Profile can be one of  {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET} or
      * {@link BluetoothProfile#A2DP}
      *
      * @param profile
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index f7ccfbd..1920efa 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -161,9 +161,9 @@
         /**
          * Called to notify the client when the proxy object has been
          * connected to the service.
-         * @param profile - One of {@link #HEADSET} or
+         * @param profile - One of {@link #HEALTH}, {@link #HEADSET} or
          *                  {@link #A2DP}
-         * @param proxy - One of {@link BluetoothHeadset} or
+         * @param proxy - One of {@link BluetoothHealth}, {@link BluetoothHeadset} or
          *                {@link BluetoothA2dp}
          */
         public void onServiceConnected(int profile, BluetoothProfile proxy);
@@ -171,7 +171,7 @@
         /**
          * Called to notify the client that this proxy object has been
          * disconnected from the service.
-         * @param profile - One of {@link #HEADSET} or
+         * @param profile - One of {@link #HEALTH}, {@link #HEADSET} or
          *                  {@link #A2DP}
          */
         public void onServiceDisconnected(int profile);
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 684c4fe..127efa2 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -16,6 +16,26 @@
 
 package android.content;
 
+import com.android.internal.R;
+import com.android.internal.util.ArrayUtils;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.OnAccountsUpdateListener;
+import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.RegisteredServicesCache;
+import android.content.pm.RegisteredServicesCacheListener;
+import android.content.pm.ResolveInfo;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -27,27 +47,6 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-
-import com.android.internal.R;
-import com.android.internal.util.ArrayUtils;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.OnAccountsUpdateListener;
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.RegisteredServicesCache;
-import android.content.pm.ProviderInfo;
-import android.content.pm.RegisteredServicesCacheListener;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.text.format.DateUtils;
@@ -59,12 +58,15 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 
@@ -1006,9 +1008,8 @@
     }
 
     protected void dump(FileDescriptor fd, PrintWriter pw) {
-        StringBuilder sb = new StringBuilder();
-        dumpSyncState(pw, sb);
-        dumpSyncHistory(pw, sb);
+        dumpSyncState(pw);
+        dumpSyncHistory(pw);
 
         pw.println();
         pw.println("SyncAdapters:");
@@ -1023,7 +1024,7 @@
         return tobj.format("%Y-%m-%d %H:%M:%S");
     }
 
-    protected void dumpSyncState(PrintWriter pw, StringBuilder sb) {
+    protected void dumpSyncState(PrintWriter pw) {
         pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
         pw.print("memory low: "); pw.println(mStorageIsLow);
 
@@ -1055,7 +1056,7 @@
         }
 
         pw.print("notification info: ");
-        sb.setLength(0);
+        final StringBuilder sb = new StringBuilder();
         mSyncHandler.mSyncNotificationInfo.toString(sb);
         pw.println(sb.toString());
 
@@ -1204,7 +1205,197 @@
         pw.println(")");
     }
 
-    protected void dumpSyncHistory(PrintWriter pw, StringBuilder sb) {
+    protected void dumpSyncHistory(PrintWriter pw) {
+        dumpRecentHistory(pw);
+        dumpDayStatistics(pw);
+    }
+
+    private void dumpRecentHistory(PrintWriter pw) {
+        final ArrayList<SyncStorageEngine.SyncHistoryItem> items
+                = mSyncStorageEngine.getSyncHistory();
+        if (items != null && items.size() > 0) {
+            final Map<String, AuthoritySyncStats> authorityMap = Maps.newHashMap();
+            long totalElapsedTime = 0;
+            long totalTimes = 0;
+            final int N = items.size();
+
+            int maxAuthority = 0;
+            int maxAccount = 0;
+            for (SyncStorageEngine.SyncHistoryItem item : items) {
+                SyncStorageEngine.AuthorityInfo authority
+                        = mSyncStorageEngine.getAuthority(item.authorityId);
+                final String authorityName;
+                final String accountKey;
+                if (authority != null) {
+                    authorityName = authority.authority;
+                    accountKey = authority.account.name + "/" + authority.account.type;
+                } else {
+                    authorityName = "Unknown";
+                    accountKey = "Unknown";
+                }
+
+                int length = authorityName.length();
+                if (length > maxAuthority) {
+                    maxAuthority = length;
+                }
+                length = accountKey.length();
+                if (length > maxAccount) {
+                    maxAccount = length;
+                }
+
+                final long elapsedTime = item.elapsedTime;
+                totalElapsedTime += elapsedTime;
+                totalTimes++;
+                AuthoritySyncStats authoritySyncStats = authorityMap.get(authorityName);
+                if (authoritySyncStats == null) {
+                    authoritySyncStats = new AuthoritySyncStats(authorityName);
+                    authorityMap.put(authorityName, authoritySyncStats);
+                }
+                authoritySyncStats.elapsedTime += elapsedTime;
+                authoritySyncStats.times++;
+                final Map<String, AccountSyncStats> accountMap = authoritySyncStats.accountMap;
+                AccountSyncStats accountSyncStats = accountMap.get(accountKey);
+                if (accountSyncStats == null) {
+                    accountSyncStats = new AccountSyncStats(accountKey);
+                    accountMap.put(accountKey, accountSyncStats);
+                }
+                accountSyncStats.elapsedTime += elapsedTime;
+                accountSyncStats.times++;
+
+            }
+
+            pw.println();
+            pw.printf("Detailed Statistics (Recent history):  %d (# of times) %ds (sync time)\n",
+                    totalTimes, totalElapsedTime / 1000);
+
+            final List<AuthoritySyncStats> sortedAuthorities =
+                    new ArrayList<AuthoritySyncStats>(authorityMap.values());
+            Collections.sort(sortedAuthorities, new Comparator<AuthoritySyncStats>() {
+                @Override
+                public int compare(AuthoritySyncStats lhs, AuthoritySyncStats rhs) {
+                    // reverse order
+                    int compare = Integer.compare(rhs.times, lhs.times);
+                    if (compare == 0) {
+                        compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
+                    }
+                    return compare;
+                }
+            });
+
+            final int maxLength = Math.max(maxAuthority, maxAccount + 3);
+            final int padLength = 2 + 2 + maxLength + 2 + 10 + 11;
+            final char chars[] = new char[padLength];
+            Arrays.fill(chars, '-');
+            final String separator = new String(chars);
+
+            final String authorityFormat = String.format("  %%-%ds: %%-9s  %%-11s\n", maxLength + 2);
+            final String accountFormat = String.format("    %%-%ds:   %%-9s  %%-11s\n", maxLength);
+
+            pw.println(separator);
+            for (AuthoritySyncStats authoritySyncStats : sortedAuthorities) {
+                String name = authoritySyncStats.name;
+                long elapsedTime;
+                int times;
+                String timeStr;
+                String timesStr;
+
+                elapsedTime = authoritySyncStats.elapsedTime;
+                times = authoritySyncStats.times;
+                timeStr = String.format("%d/%d%%",
+                        elapsedTime / 1000,
+                        elapsedTime * 100 / totalElapsedTime);
+                timesStr = String.format("%d/%d%%",
+                        times,
+                        times * 100 / totalTimes);
+                pw.printf(authorityFormat, name, timesStr, timeStr);
+
+                if (authoritySyncStats.accountMap.size() > 1) {
+                    final List<AccountSyncStats> sortedAccounts =
+                            new ArrayList<AccountSyncStats>(
+                                    authoritySyncStats.accountMap.values());
+                    Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() {
+                        @Override
+                        public int compare(AccountSyncStats lhs, AccountSyncStats rhs) {
+                            // reverse order
+                            int compare = Integer.compare(rhs.times, lhs.times);
+                            if (compare == 0) {
+                                compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
+                            }
+                            return compare;
+                        }
+                    });
+                    for (AccountSyncStats stats: sortedAccounts) {
+                        elapsedTime = stats.elapsedTime;
+                        times = stats.times;
+                        timeStr = String.format("%d/%d%%",
+                                elapsedTime / 1000,
+                                elapsedTime * 100 / totalElapsedTime);
+                        timesStr = String.format("%d/%d%%",
+                                times,
+                                times * 100 / totalTimes);
+                        pw.printf(accountFormat, stats.name, timesStr, timeStr);
+                    }
+                }
+                pw.println(separator);
+            }
+
+            pw.println();
+            pw.println("Recent Sync History");
+            final String format = "  %-" + maxAccount + "s  %s\n";
+            String lastAuthorityName = null;
+            String lastAccountKey = null;
+            long lastEventTime = 0;
+            for (int i = 0; i < N; i++) {
+                SyncStorageEngine.SyncHistoryItem item = items.get(i);
+                SyncStorageEngine.AuthorityInfo authority
+                        = mSyncStorageEngine.getAuthority(item.authorityId);
+                final String authorityName;
+                final String accountKey;
+                if (authority != null) {
+                    authorityName = authority.authority;
+                    accountKey = authority.account.name + "/" + authority.account.type;
+                } else {
+                    authorityName = "Unknown";
+                    accountKey = "Unknown";
+                }
+                final long elapsedTime = item.elapsedTime;
+                final Time time = new Time();
+                final long eventTime = item.eventTime;
+                time.set(eventTime);
+
+                pw.printf("  #%-3d: %s %8s  %5.1fs",
+                        i + 1,
+                        formatTime(eventTime),
+                        SyncStorageEngine.SOURCES[item.source],
+                        ((float) elapsedTime) / 1000);
+                if (authorityName.equals(lastAuthorityName) && accountKey.equals(lastAccountKey)) {
+                    final long span = (lastEventTime - eventTime) / 1000;
+                    pw.printf("  %02d:%02d\n", span / 60, span % 60);
+                } else {
+                    pw.printf(format, accountKey, authorityName);
+                }
+
+                lastAuthorityName = authorityName;
+                lastAccountKey = accountKey;
+                lastEventTime = eventTime;
+
+                if (item.event != SyncStorageEngine.EVENT_STOP
+                        || item.upstreamActivity != 0
+                        || item.downstreamActivity != 0) {
+                    pw.printf("    event=%d upstreamActivity=%d downstreamActivity=%d\n",
+                            item.event,
+                            item.upstreamActivity,
+                            item.downstreamActivity);
+                }
+                if (item.mesg != null
+                        && !SyncStorageEngine.MESG_SUCCESS.equals(item.mesg)) {
+                    pw.printf("    mesg=%s\n", item.mesg);
+                }
+            }
+        }
+    }
+
+    private void dumpDayStatistics(PrintWriter pw) {
         SyncStorageEngine.DayStats dses[] = mSyncStorageEngine.getDayStatistics();
         if (dses != null && dses[0] != null) {
             pw.println();
@@ -1254,47 +1445,26 @@
                 }
             }
         }
+    }
 
-        ArrayList<SyncStorageEngine.SyncHistoryItem> items
-                = mSyncStorageEngine.getSyncHistory();
-        if (items != null && items.size() > 0) {
-            pw.println();
-            pw.println("Recent Sync History");
-            final int N = items.size();
-            for (int i=0; i<N; i++) {
-                SyncStorageEngine.SyncHistoryItem item = items.get(i);
-                SyncStorageEngine.AuthorityInfo authority
-                        = mSyncStorageEngine.getAuthority(item.authorityId);
-                pw.print("  #"); pw.print(i+1); pw.print(": ");
-                        if (authority != null) {
-                            pw.print(authority.account.name);
-                            pw.print(":");
-                            pw.print(authority.account.type);
-                            pw.print(" ");
-                            pw.print(authority.authority);
-                        } else {
-                            pw.print("<no account>");
-                        }
-                Time time = new Time();
-                time.set(item.eventTime);
-                pw.print(" "); pw.print(SyncStorageEngine.SOURCES[item.source]);
-                        pw.print(" @ ");
-                        pw.print(formatTime(item.eventTime));
-                        pw.print(" for ");
-                        dumpTimeSec(pw, item.elapsedTime);
-                        pw.println();
-                if (item.event != SyncStorageEngine.EVENT_STOP
-                        || item.upstreamActivity !=0
-                        || item.downstreamActivity != 0) {
-                    pw.print("    event="); pw.print(item.event);
-                            pw.print(" upstreamActivity="); pw.print(item.upstreamActivity);
-                            pw.print(" downstreamActivity="); pw.println(item.downstreamActivity);
-                }
-                if (item.mesg != null
-                        && !SyncStorageEngine.MESG_SUCCESS.equals(item.mesg)) {
-                    pw.print("    mesg="); pw.println(item.mesg);
-                }
-            }
+    private static class AuthoritySyncStats {
+        String name;
+        long elapsedTime;
+        int times;
+        Map<String, AccountSyncStats> accountMap = Maps.newHashMap();
+
+        private AuthoritySyncStats(String name) {
+            this.name = name;
+        }
+    }
+
+    private static class AccountSyncStats {
+        String name;
+        long elapsedTime;
+        int times;
+
+        private AccountSyncStats(String name) {
+            this.name = name;
         }
     }
 
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index e392bca..fe0106d 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -208,7 +208,9 @@
     final NfcActivityManager mNfcActivityManager;
 
     /**
-     * @see {@link #setNdefPushMessageCallback}
+     * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
+     * to another device.
+     * @see #setOnNdefPushCompleteCallback
      */
     public interface OnNdefPushCompleteCallback {
         /**
@@ -217,13 +219,21 @@
          * <p>This callback is usually made on a binder thread (not the UI thread).
          *
          * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
-         * @see {@link #setNdefPushMessageCallback}
+         * @see #setNdefPushMessageCallback
          */
         public void onNdefPushComplete(NfcEvent event);
     }
 
     /**
-     * @see {@link #setCeateNdefMessageCallback}
+     * A callback to be invoked when another NFC device capable of NDEF push (Android Beam)
+     * is within range.
+     * <p>Implement this interface and pass it to {@link
+     * NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} in order to create an
+     * {@link NdefMessage} at the moment that another device is within range for NFC. Using this
+     * callback allows you to create a message with data that might vary based on the
+     * content currently visible to the user. Alternatively, you can call {@link
+     * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
+     * same data.
      */
     public interface CreateNdefMessageCallback {
         /**
@@ -507,13 +517,15 @@
      * <p>Pass a null NDEF message to disable foreground NDEF push in the
      * specified activities.
      *
-     * <p>One or more activities must be specified.
+     * <p>At least one activity must be specified, and usually only one is necessary.
      *
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param message NDEF message to push over NFC, or null to disable
-     * @param activity an activity to enable for NDEF push (at least one is required)
-     * @param activities zero or more additional activities to enable for NDEF Push
+     * @param activity an activity in which NDEF push should be enabled to share the provided
+     *                 NDEF message
+     * @param activities optional additional activities that should also enable NDEF push with
+     *                   the provided NDEF message
      */
     public void setNdefPushMessage(NdefMessage message, Activity activity,
             Activity ... activities) {
@@ -544,13 +556,15 @@
      * <p>Pass a null callback to disable the callback in the
      * specified activities.
      *
-     * <p>One or more activities must be specified.
+     * <p>At least one activity must be specified, and usually only one is necessary.
      *
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param callback callback, or null to disable
-     * @param activity an activity to enable for NDEF push (at least one is required)
-     * @param activities zero or more additional activities to enable for NDEF Push
+     * @param activity an activity in which NDEF push should be enabled to share an NDEF message
+     *                 that's retrieved from the provided callback
+     * @param activities optional additional activities that should also enable NDEF push using
+     *                   the provided callback
      */
     public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
             Activity ... activities) {
diff --git a/core/java/android/nfc/NfcEvent.java b/core/java/android/nfc/NfcEvent.java
index b00d8b7..860700a 100644
--- a/core/java/android/nfc/NfcEvent.java
+++ b/core/java/android/nfc/NfcEvent.java
@@ -29,8 +29,8 @@
  * in the callback) because it allows new fields to be added without breaking
  * API compatibility.
  *
- * @see {@link NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete}
- * @see {@link NfcAdapter.CreateNdefMessageCallback#createNdefMessage}
+ * @see NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete
+ * @see NfcAdapter.CreateNdefMessageCallback#createNdefMessage
  */
 public final class NfcEvent {
     /**
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
index 1b7f499..5f8a7d1 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_focused.png
deleted file mode 100644
index da77340..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
index 754d7bc..1d547e1 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_focused.png
deleted file mode 100644
index 6f51447..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
index 544924e..b09071b 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_focused.png
deleted file mode 100644
index d067ab8..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_focused.png
+++ /dev/null
Binary files differ
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 493993d..926eb9a 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -25,8 +25,9 @@
 
 #include <ui/GraphicBuffer.h>
 
-#include <utils/threads.h>
+#include <utils/String8.h>
 #include <utils/Vector.h>
+#include <utils/threads.h>
 
 #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
 
@@ -202,6 +203,10 @@
     // by OpenGL ES as a texture) then those buffer will remain allocated.
     void abandon();
 
+    // set the name of the SurfaceTexture that will be used to identify it in
+    // log messages.
+    void setName(const String8& name);
+
     // dump our state in a String
     void dump(String8& result) const;
     void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
@@ -444,6 +449,10 @@
     // all ISurfaceTexture methods capable of returning an error.
     bool mAbandoned;
 
+    // mName is a string used to identify the SurfaceTexture in log messages.
+    // It is set by the setName method.
+    String8 mName;
+
     // mMutex is the mutex used to prevent concurrent access to the member
     // variables of SurfaceTexture objects. It must be locked whenever the
     // member variables are accessed.
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index f2bc81e..dac9418 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -39,6 +39,12 @@
 
 #define ALLOW_DEQUEUE_CURRENT_BUFFER    false
 
+// Macros for including the SurfaceTexture name in log messages
+#define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGI(x, ...) LOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGW(x, ...) LOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGE(x, ...) LOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
 
 namespace android {
 
@@ -82,6 +88,12 @@
 
 static void mtxMul(float out[16], const float a[16], const float b[16]);
 
+// Get an ID that's unique within this process.
+static int32_t createProcessUniqueId() {
+    static volatile int32_t globalCounter = 0;
+    return android_atomic_inc(&globalCounter);
+}
+
 SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode) :
     mDefaultWidth(1),
     mDefaultHeight(1),
@@ -99,15 +111,19 @@
     mAllowSynchronousMode(allowSynchronousMode),
     mConnectedApi(NO_CONNECTED_API),
     mAbandoned(false) {
-    LOGV("SurfaceTexture::SurfaceTexture");
+    // Choose a name using the PID and a process-unique ID.
+    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+
+    ST_LOGV("SurfaceTexture::SurfaceTexture");
     sp<ISurfaceComposer> composer(ComposerService::getComposerService());
     mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
     mNextCrop.makeInvalid();
-    memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix));
+    memcpy(mCurrentTransformMatrix, mtxIdentity,
+            sizeof(mCurrentTransformMatrix));
 }
 
 SurfaceTexture::~SurfaceTexture() {
-    LOGV("SurfaceTexture::~SurfaceTexture");
+    ST_LOGV("SurfaceTexture::~SurfaceTexture");
     freeAllBuffersLocked();
 }
 
@@ -151,22 +167,22 @@
 }
 
 status_t SurfaceTexture::setBufferCount(int bufferCount) {
-    LOGV("SurfaceTexture::setBufferCount");
+    ST_LOGV("SurfaceTexture::setBufferCount");
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("setBufferCount: SurfaceTexture has been abandoned!");
+        ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
     if (bufferCount > NUM_BUFFER_SLOTS) {
-        LOGE("setBufferCount: bufferCount larger than slots available");
+        ST_LOGE("setBufferCount: bufferCount larger than slots available");
         return BAD_VALUE;
     }
 
     // Error out if the user has dequeued buffers
     for (int i=0 ; i<mBufferCount ; i++) {
         if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
-            LOGE("setBufferCount: client owns some buffers");
+            ST_LOGE("setBufferCount: client owns some buffers");
             return -EINVAL;
         }
     }
@@ -181,7 +197,7 @@
     }
 
     if (bufferCount < minBufferSlots) {
-        LOGE("setBufferCount: requested buffer count (%d) is less than "
+        ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
                 "minimum (%d)", bufferCount, minBufferSlots);
         return BAD_VALUE;
     }
@@ -200,7 +216,8 @@
 status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
 {
     if (!w || !h) {
-        LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", w, h);
+        ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
+                w, h);
         return BAD_VALUE;
     }
 
@@ -211,14 +228,14 @@
 }
 
 status_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
-    LOGV("SurfaceTexture::requestBuffer");
+    ST_LOGV("SurfaceTexture::requestBuffer");
     Mutex::Autolock lock(mMutex);
     if (mAbandoned) {
-        LOGE("requestBuffer: SurfaceTexture has been abandoned!");
+        ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
     if (slot < 0 || mBufferCount <= slot) {
-        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
+        ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
                 mBufferCount, slot);
         return BAD_VALUE;
     }
@@ -229,10 +246,10 @@
 
 status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
         uint32_t format, uint32_t usage) {
-    LOGV("SurfaceTexture::dequeueBuffer");
+    ST_LOGV("SurfaceTexture::dequeueBuffer");
 
     if ((w && !h) || (!w && h)) {
-        LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
+        ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
         return BAD_VALUE;
     }
 
@@ -245,7 +262,7 @@
     bool tryAgain = true;
     while (tryAgain) {
         if (mAbandoned) {
-            LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
+            ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
             return NO_INIT;
         }
 
@@ -334,7 +351,8 @@
             // than allowed.
             const int avail = mBufferCount - (dequeuedCount+1);
             if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
-                LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
+                ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
+                        "(dequeued=%d)",
                         MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
                         dequeuedCount);
                 return -EBUSY;
@@ -391,7 +409,8 @@
                 mGraphicBufferAlloc->createGraphicBuffer(
                         w, h, format, usage, &error));
         if (graphicBuffer == 0) {
-            LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
+            ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
+                    "failed");
             return error;
         }
         if (updateFormat) {
@@ -413,7 +432,7 @@
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
+        ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
 
@@ -441,29 +460,29 @@
 
 status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
         uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
-    LOGV("SurfaceTexture::queueBuffer");
+    ST_LOGV("SurfaceTexture::queueBuffer");
 
     sp<FrameAvailableListener> listener;
 
     { // scope for the lock
         Mutex::Autolock lock(mMutex);
         if (mAbandoned) {
-            LOGE("queueBuffer: SurfaceTexture has been abandoned!");
+            ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
             return NO_INIT;
         }
         if (buf < 0 || buf >= mBufferCount) {
-            LOGE("queueBuffer: slot index out of range [0, %d]: %d",
+            ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
                     mBufferCount, buf);
             return -EINVAL;
         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
-            LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
-                    buf, mSlots[buf].mBufferState);
+            ST_LOGE("queueBuffer: slot %d is not owned by the client "
+                    "(state=%d)", buf, mSlots[buf].mBufferState);
             return -EINVAL;
         } else if (buf == mCurrentTexture) {
-            LOGE("queueBuffer: slot %d is current!", buf);
+            ST_LOGE("queueBuffer: slot %d is current!", buf);
             return -EINVAL;
         } else if (!mSlots[buf].mRequestBufferCalled) {
-            LOGE("queueBuffer: slot %d was enqueued without requesting a "
+            ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
                     "buffer", buf);
             return -EINVAL;
         }
@@ -513,20 +532,20 @@
 }
 
 void SurfaceTexture::cancelBuffer(int buf) {
-    LOGV("SurfaceTexture::cancelBuffer");
+    ST_LOGV("SurfaceTexture::cancelBuffer");
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
+        ST_LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
         return;
     }
 
     if (buf < 0 || buf >= mBufferCount) {
-        LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
+        ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
                 mBufferCount, buf);
         return;
     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
-        LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
+        ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
                 buf, mSlots[buf].mBufferState);
         return;
     }
@@ -535,10 +554,10 @@
 }
 
 status_t SurfaceTexture::setCrop(const Rect& crop) {
-    LOGV("SurfaceTexture::setCrop");
+    ST_LOGV("SurfaceTexture::setCrop");
     Mutex::Autolock lock(mMutex);
     if (mAbandoned) {
-        LOGE("setCrop: SurfaceTexture has been abandoned!");
+        ST_LOGE("setCrop: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
     mNextCrop = crop;
@@ -546,10 +565,10 @@
 }
 
 status_t SurfaceTexture::setTransform(uint32_t transform) {
-    LOGV("SurfaceTexture::setTransform");
+    ST_LOGV("SurfaceTexture::setTransform");
     Mutex::Autolock lock(mMutex);
     if (mAbandoned) {
-        LOGE("setTransform: SurfaceTexture has been abandoned!");
+        ST_LOGE("setTransform: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
     mNextTransform = transform;
@@ -558,11 +577,11 @@
 
 status_t SurfaceTexture::connect(int api,
         uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
-    LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
+    ST_LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("connect: SurfaceTexture has been abandoned!");
+        ST_LOGE("connect: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
 
@@ -573,7 +592,7 @@
         case NATIVE_WINDOW_API_MEDIA:
         case NATIVE_WINDOW_API_CAMERA:
             if (mConnectedApi != NO_CONNECTED_API) {
-                LOGE("connect: already connected (cur=%d, req=%d)",
+                ST_LOGE("connect: already connected (cur=%d, req=%d)",
                         mConnectedApi, api);
                 err = -EINVAL;
             } else {
@@ -591,11 +610,11 @@
 }
 
 status_t SurfaceTexture::disconnect(int api) {
-    LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api);
+    ST_LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api);
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("disconnect: SurfaceTexture has been abandoned!");
+        ST_LOGE("disconnect: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
 
@@ -613,7 +632,7 @@
                 mNextTransform = 0;
                 mDequeueCondition.signal();
             } else {
-                LOGE("disconnect: connected to another api (cur=%d, req=%d)",
+                ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
                         mConnectedApi, api);
                 err = -EINVAL;
             }
@@ -626,7 +645,7 @@
 }
 
 status_t SurfaceTexture::setScalingMode(int mode) {
-    LOGV("SurfaceTexture::setScalingMode(%d)", mode);
+    ST_LOGV("SurfaceTexture::setScalingMode(%d)", mode);
 
     switch (mode) {
         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
@@ -642,11 +661,11 @@
 }
 
 status_t SurfaceTexture::updateTexImage() {
-    LOGV("SurfaceTexture::updateTexImage");
+    ST_LOGV("SurfaceTexture::updateTexImage");
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("calling updateTexImage() on an abandoned SurfaceTexture");
+        ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture");
         return NO_INIT;
     }
 
@@ -661,7 +680,7 @@
         if (image == EGL_NO_IMAGE_KHR) {
             EGLDisplay dpy = eglGetCurrentDisplay();
             if (mSlots[buf].mGraphicBuffer == 0) {
-                LOGE("buffer at slot %d is null", buf);
+                ST_LOGE("buffer at slot %d is null", buf);
                 return BAD_VALUE;
             }
             image = createImage(dpy, mSlots[buf].mGraphicBuffer);
@@ -676,15 +695,16 @@
 
         GLint error;
         while ((error = glGetError()) != GL_NO_ERROR) {
-            LOGW("updateTexImage: clearing GL error: %#04x", error);
+            ST_LOGW("updateTexImage: clearing GL error: %#04x", error);
         }
 
         glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
-        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image);
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
+                (GLeglImageOES)image);
 
         bool failed = false;
         while ((error = glGetError()) != GL_NO_ERROR) {
-            LOGE("error binding external texture image %p (slot %d): %#04x",
+            ST_LOGE("error binding external texture image %p (slot %d): %#04x",
                     image, buf, error);
             failed = true;
         }
@@ -750,7 +770,7 @@
 }
 
 void SurfaceTexture::computeCurrentTransformMatrix() {
-    LOGV("SurfaceTexture::computeCurrentTransformMatrix");
+    ST_LOGV("SurfaceTexture::computeCurrentTransformMatrix");
 
     float xform[16];
     for (int i = 0; i < 16; i++) {
@@ -841,14 +861,14 @@
 }
 
 nsecs_t SurfaceTexture::getTimestamp() {
-    LOGV("SurfaceTexture::getTimestamp");
+    ST_LOGV("SurfaceTexture::getTimestamp");
     Mutex::Autolock lock(mMutex);
     return mCurrentTimestamp;
 }
 
 void SurfaceTexture::setFrameAvailableListener(
         const sp<FrameAvailableListener>& listener) {
-    LOGV("SurfaceTexture::setFrameAvailableListener");
+    ST_LOGV("SurfaceTexture::setFrameAvailableListener");
     Mutex::Autolock lock(mMutex);
     mFrameAvailableListener = listener;
 }
@@ -892,11 +912,11 @@
     while (mSynchronousMode && !mQueue.isEmpty()) {
         mDequeueCondition.wait(mMutex);
         if (mAbandoned) {
-            LOGE("drainQueueLocked: SurfaceTexture has been abandoned!");
+            ST_LOGE("drainQueueLocked: SurfaceTexture has been abandoned!");
             return NO_INIT;
         }
         if (mConnectedApi == NO_CONNECTED_API) {
-            LOGE("drainQueueLocked: SurfaceTexture is not connected!");
+            ST_LOGE("drainQueueLocked: SurfaceTexture is not connected!");
             return NO_INIT;
         }
     }
@@ -926,7 +946,7 @@
             EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
     if (image == EGL_NO_IMAGE_KHR) {
         EGLint error = eglGetError();
-        LOGE("error creating EGLImage: %#x", error);
+        ST_LOGE("error creating EGLImage: %#x", error);
     }
     return image;
 }
@@ -956,7 +976,7 @@
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("query: SurfaceTexture has been abandoned!");
+        ST_LOGE("query: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
 
@@ -991,6 +1011,10 @@
     mDequeueCondition.signal();
 }
 
+void SurfaceTexture::setName(const String8& name) {
+    mName = name;
+}
+
 void SurfaceTexture::dump(String8& result) const
 {
     char buffer[1024];
@@ -1004,8 +1028,8 @@
     snprintf(buffer, SIZE,
             "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
             "mPixelFormat=%d, mTexName=%d\n",
-            prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
-            mPixelFormat, mTexName);
+            prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
+            mDefaultHeight, mPixelFormat, mTexName);
     result.append(buffer);
 
     String8 fifo;
@@ -1024,8 +1048,8 @@
             prefix, mCurrentCrop.left,
             mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
             mCurrentTransform, mCurrentTexture,
-            prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right, mNextCrop.bottom,
-            mNextTransform, fifoSize, fifo.string()
+            prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
+            mNextCrop.bottom, mNextTransform, fifoSize, fifo.string()
     );
     result.append(buffer);
 
@@ -1048,8 +1072,8 @@
                 "transform=0x%02x, timestamp=%lld",
                 prefix, (i==mCurrentTexture)?">":" ", i,
                 stateName(slot.mBufferState),
-                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, slot.mCrop.bottom,
-                slot.mTransform, slot.mTimestamp
+                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
+                slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
         );
         result.append(buffer);
 
@@ -1057,7 +1081,8 @@
         if (buf != NULL) {
             snprintf(buffer, SIZE,
                     ", %p [%4ux%4u:%4u,%3X]",
-                    buf->handle, buf->width, buf->height, buf->stride, buf->format);
+                    buf->handle, buf->width, buf->height, buf->stride,
+                    buf->format);
             result.append(buffer);
         }
         result.append("\n");
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index fb14204..079f6fa 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -41,7 +41,7 @@
       mUIDValid(uidValid),
       mUID(uid),
       mFlags(0),
-      mEOS(false),
+      mFinalResult(OK),
       mOffset(0) {
     if (headers) {
         mExtraHeaders = *headers;
@@ -95,9 +95,9 @@
     return source->getFormat();
 }
 
-bool NuPlayer::HTTPLiveSource::feedMoreTSData() {
-    if (mEOS) {
-        return false;
+status_t NuPlayer::HTTPLiveSource::feedMoreTSData() {
+    if (mFinalResult != OK) {
+        return mFinalResult;
     }
 
     sp<LiveDataSource> source =
@@ -111,12 +111,12 @@
             break;
         } else if (n < 0) {
             if (n != ERROR_END_OF_STREAM) {
-                LOGI("input data EOS reached, error %d", n);
+                LOGI("input data EOS reached, error %ld", n);
             } else {
                 LOGI("input data EOS reached.");
             }
             mTSParser->signalEOS(n);
-            mEOS = true;
+            mFinalResult = n;
             break;
         } else {
             if (buffer[0] == 0x00) {
@@ -133,7 +133,7 @@
                 if (err != OK) {
                     LOGE("TS Parser returned error %d", err);
                     mTSParser->signalEOS(err);
-                    mEOS = true;
+                    mFinalResult = err;
                     break;
                 }
             }
@@ -142,7 +142,7 @@
         }
     }
 
-    return true;
+    return OK;
 }
 
 status_t NuPlayer::HTTPLiveSource::dequeueAccessUnit(
@@ -172,7 +172,7 @@
 status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
     // We need to make sure we're not seeking until we have seen the very first
     // PTS timestamp in the whole stream (from the beginning of the stream).
-    while (!mTSParser->PTSTimeDeltaEstablished() && feedMoreTSData()) {
+    while (!mTSParser->PTSTimeDeltaEstablished() && feedMoreTSData() == OK) {
         usleep(100000);
     }
 
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index 36c67c5..f22af5b 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -35,8 +35,7 @@
 
     virtual void start();
 
-    // Returns true iff more data was available, false on EOS.
-    virtual bool feedMoreTSData();
+    virtual status_t feedMoreTSData();
 
     virtual sp<MetaData> getFormat(bool audio);
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
@@ -59,7 +58,7 @@
     bool mUIDValid;
     uid_t mUID;
     uint32_t mFlags;
-    bool mEOS;
+    status_t mFinalResult;
     off64_t mOffset;
     sp<ALooper> mLiveLooper;
     sp<LiveSession> mLiveSession;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 7bfd358..6b40528 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -235,11 +235,17 @@
                 instantiateDecoder(true, &mAudioDecoder);
             }
 
-            if (!mSource->feedMoreTSData()) {
+            status_t err;
+            if ((err = mSource->feedMoreTSData()) != OK) {
                 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
                     // We're not currently decoding anything (no audio or
                     // video tracks found) and we just ran out of input data.
-                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
+
+                    if (err == ERROR_END_OF_STREAM) {
+                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
+                    } else {
+                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+                    }
                 }
                 break;
             }
@@ -267,7 +273,7 @@
                         audio, codecRequest);
 
                 if (err == -EWOULDBLOCK) {
-                    if (mSource->feedMoreTSData()) {
+                    if (mSource->feedMoreTSData() == OK) {
                         msg->post();
                     }
                 }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 5e55487..8a7eece 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -29,8 +29,9 @@
 
     virtual void start() = 0;
 
-    // Returns true iff more data was available, false on EOS.
-    virtual bool feedMoreTSData() = 0;
+    // Returns OK iff more data was available,
+    // an error or ERROR_END_OF_STREAM if not.
+    virtual status_t feedMoreTSData() = 0;
 
     virtual sp<MetaData> getFormat(bool audio) = 0;
 
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index 7319e4c..f795654 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -34,7 +34,7 @@
 
 NuPlayer::StreamingSource::StreamingSource(const sp<IStreamSource> &source)
     : mSource(source),
-      mEOS(false) {
+      mFinalResult(OK) {
 }
 
 NuPlayer::StreamingSource::~StreamingSource() {
@@ -47,9 +47,9 @@
     mStreamListener->start();
 }
 
-bool NuPlayer::StreamingSource::feedMoreTSData() {
-    if (mEOS) {
-        return false;
+status_t NuPlayer::StreamingSource::feedMoreTSData() {
+    if (mFinalResult != OK) {
+        return mFinalResult;
     }
 
     for (int32_t i = 0; i < 50; ++i) {
@@ -60,7 +60,7 @@
         if (n == 0) {
             LOGI("input data EOS reached.");
             mTSParser->signalEOS(ERROR_END_OF_STREAM);
-            mEOS = true;
+            mFinalResult = ERROR_END_OF_STREAM;
             break;
         } else if (n == INFO_DISCONTINUITY) {
             ATSParser::DiscontinuityType type = ATSParser::DISCONTINUITY_SEEK;
@@ -92,14 +92,14 @@
                     LOGE("TS Parser returned error %d", err);
 
                     mTSParser->signalEOS(err);
-                    mEOS = true;
+                    mFinalResult = err;
                     break;
                 }
             }
         }
     }
 
-    return true;
+    return OK;
 }
 
 sp<MetaData> NuPlayer::StreamingSource::getFormat(bool audio) {
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.h b/media/libmediaplayerservice/nuplayer/StreamingSource.h
index 7abce84..ca00ef9 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.h
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.h
@@ -31,8 +31,7 @@
 
     virtual void start();
 
-    // Returns true iff more data was available, false on EOS.
-    virtual bool feedMoreTSData();
+    virtual status_t feedMoreTSData();
 
     virtual sp<MetaData> getFormat(bool audio);
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
@@ -42,7 +41,7 @@
 
 private:
     sp<IStreamSource> mSource;
-    bool mEOS;
+    status_t mFinalResult;
     sp<NuPlayerStreamListener> mStreamListener;
     sp<ATSParser> mTSParser;
 
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 07a46bd..fa9417a 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -249,7 +249,7 @@
 }
 
 void AwesomePlayer::setUID(uid_t uid) {
-    LOGI("AwesomePlayer running on behalf of uid %d", uid);
+    LOGV("AwesomePlayer running on behalf of uid %d", uid);
 
     mUID = uid;
     mUIDValid = true;
@@ -362,7 +362,7 @@
         if (!meta->findInt32(kKeyBitRate, &bitrate)) {
             const char *mime;
             CHECK(meta->findCString(kKeyMIMEType, &mime));
-            LOGW("track of type '%s' does not publish bitrate", mime);
+            LOGV("track of type '%s' does not publish bitrate", mime);
 
             totalBitRate = -1;
             break;
@@ -1192,7 +1192,7 @@
         usleep(1000);
     }
     IPCThreadState::self()->flushCommands();
-    LOGI("video decoder shutdown completed");
+    LOGV("video decoder shutdown completed");
 }
 
 status_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
@@ -1202,7 +1202,7 @@
         return OK;
     }
 
-    LOGI("attempting to reconfigure to use new surface");
+    LOGV("attempting to reconfigure to use new surface");
 
     bool wasPlaying = (mFlags & PLAYING) != 0;
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 6280f51..9eb1469 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1635,7 +1635,7 @@
         return err;
     }
 
-    CODEC_LOGI("allocating %lu buffers of size %lu on %s port",
+    CODEC_LOGV("allocating %lu buffers of size %lu on %s port",
             def.nBufferCountActual, def.nBufferSize,
             portIndex == kPortIndexInput ? "input" : "output");
 
@@ -1876,7 +1876,7 @@
         return err;
     }
 
-    CODEC_LOGI("allocating %lu buffers from a native window of size %lu on "
+    CODEC_LOGV("allocating %lu buffers from a native window of size %lu on "
             "output port", def.nBufferCountActual, def.nBufferSize);
 
     // Dequeue buffers and send them to OMX
@@ -3654,7 +3654,7 @@
 
     mSource->stop();
 
-    CODEC_LOGI("stopped in state %d", mState);
+    CODEC_LOGV("stopped in state %d", mState);
 
     return OK;
 }
@@ -4219,14 +4219,14 @@
                 inputFormat->findInt32(kKeySampleRate, &sampleRate);
 
                 if ((OMX_U32)numChannels != params.nChannels) {
-                    LOGW("Codec outputs a different number of channels than "
+                    LOGV("Codec outputs a different number of channels than "
                          "the input stream contains (contains %d channels, "
                          "codec outputs %ld channels).",
                          numChannels, params.nChannels);
                 }
 
                 if (sampleRate != (int32_t)params.nSamplingRate) {
-                    LOGW("Codec outputs at different sampling rate than "
+                    LOGV("Codec outputs at different sampling rate than "
                          "what the input stream contains (contains data at "
                          "%d Hz, codec outputs %lu Hz)",
                          sampleRate, params.nSamplingRate);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 05e171c..9bee5df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -64,6 +64,8 @@
 
     private static final int INET_CONDITION_THRESHOLD = 50;
 
+    private static final boolean SHOW_SYNC_ICON = false;
+
     private final Context mContext;
     private final StatusBarManager mService;
     private final Handler mHandler = new Handler();
@@ -195,6 +197,7 @@
     }
 
     private final void updateSyncState(Intent intent) {
+        if (!SHOW_SYNC_ICON) return;
         boolean isActive = intent.getBooleanExtra("active", false);
         boolean isFailing = intent.getBooleanExtra("failing", false);
         mService.setIconVisibility("sync_active", isActive);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 88a05b2..01f5a6f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -985,6 +985,10 @@
     mNewParameters.clear();
     // do not lock the mutex in destructor
     releaseWakeLock_l();
+    if (mPowerManager != 0) {
+        sp<IBinder> binder = mPowerManager->asBinder();
+        binder->unlinkToDeath(mDeathRecipient);
+    }
 }
 
 void AudioFlinger::ThreadBase::exit()
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1361fd6..41d7a90 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -112,6 +112,11 @@
     mSurfaceTexture->abandon();
 }
 
+void Layer::setName(const String8& name) {
+    LayerBase::setName(name);
+    mSurfaceTexture->setName(name);
+}
+
 sp<ISurface> Layer::createSurface()
 {
     class BSurface : public BnSurface, public LayerCleaner {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index ff389ae..82e3521 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -74,6 +74,7 @@
     virtual bool isProtected() const;
     virtual void onRemoved();
     virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
+    virtual void setName(const String8& name);
 
     // LayerBaseClient interface
     virtual wp<IBinder> getSurfaceTextureBinder() const;
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 268ba2d..7f62145 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -81,7 +81,7 @@
                 Region          transparentRegion;
             };
 
-            void setName(const String8& name);
+    virtual void setName(const String8& name);
             String8 getName() const;
 
             // modify current state