Merge "fix [3258603] 'Quadrant' benchmark crashes inside eglQueryContext on GB/Crespo" into gingerbread
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7563831..a370b33 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -143,7 +143,7 @@
      * tied to the lifetime of the process rather than the current component.
      *
      * <p>Consider for example how this interacts with
-     * {@ #registerReceiver(BroadcastReceiver, IntentFilter)}:
+     * {@link #registerReceiver(BroadcastReceiver, IntentFilter)}:
      * <ul>
      * <li> <p>If used from an Activity context, the receiver is being registered
      * within that activity.  This means that you are expected to unregister
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index ad3c1bb..f5c79e7 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -37,4 +37,5 @@
     int write(int nativeHandle, in NdefMessage msg);
     int makeReadOnly(int nativeHandle);
     int getModeHint(int nativeHandle);
-}
\ No newline at end of file
+    int formatNdef(int nativeHandle, in byte[] key);
+}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 2f6b3a5..36de915 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -21,6 +21,7 @@
 import android.nfc.technology.MifareUltralight;
 import android.nfc.technology.NfcV;
 import android.nfc.technology.Ndef;
+import android.nfc.technology.NdefFormatable;
 import android.nfc.technology.NfcA;
 import android.nfc.technology.NfcB;
 import android.nfc.technology.NfcF;
@@ -157,6 +158,9 @@
                 case TagTechnology.NDEF: {
                     return new Ndef(adapter, this, tech, extras);
                 }
+                case TagTechnology.NDEF_FORMATABLE: {
+                    return new NdefFormatable(adapter, this, tech, extras);
+                }
                 case TagTechnology.NFC_F: {
                     return new NfcF(adapter, this, extras);
                 }
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index 1e3da2a..c856646 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -47,12 +47,22 @@
     /** @hide */
     public static final String EXTRA_NDEF_MSG = "ndefmsg";
 
+    /** @hide */
+    public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength";
+
+    private final int maxNdefSize;
+
     /**
      * Internal constructor, to be used by NfcAdapter
      * @hide
      */
     public Ndef(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
         super(adapter, tag, tech);
+        if (extras != null) {
+            maxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
+        } else {
+            maxNdefSize = 0;  //TODO: throw exception
+        }
     }
 
     /**
@@ -95,7 +105,7 @@
      * Get maximum NDEF message size in bytes
      */
     public int getSize() {
-        throw new UnsupportedOperationException();
+        return maxNdefSize;
     }
 
     /**
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
index 7c4f9ab..3ed37a5 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -56,7 +56,37 @@
      * Formats a tag as NDEF, if possible. You may supply a first
      * NdefMessage to be written on the tag.
      */
-    public void format(NdefMessage firstMessage) throws IOException {
-      throw new UnsupportedOperationException();
+    public void format(NdefMessage firstMessage) throws IOException, FormatException {
+        try {
+            byte[] DEFAULT_KEY = {(byte)0xFF,(byte)0xFF,(byte)0xFF,
+                                  (byte)0xFF,(byte)0xFF,(byte)0xFF};
+            int serviceHandle = mTag.getServiceHandle();
+            int errorCode = mTagService.formatNdef(serviceHandle, DEFAULT_KEY);
+            switch (errorCode) {
+                case ErrorCodes.SUCCESS:
+                    break;
+                case ErrorCodes.ERROR_IO:
+                    throw new IOException();
+                case ErrorCodes.ERROR_INVALID_PARAM:
+                    throw new FormatException();
+                default:
+                    // Should not happen
+                    throw new IOException();
+            }
+            errorCode = mTagService.write(serviceHandle, firstMessage);
+            switch (errorCode) {
+                case ErrorCodes.SUCCESS:
+                    break;
+                case ErrorCodes.ERROR_IO:
+                    throw new IOException();
+                case ErrorCodes.ERROR_INVALID_PARAM:
+                    throw new FormatException();
+                default:
+                    // Should not happen
+                    throw new IOException();
+            }
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index bc6d6d2..abc88e8 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3077,13 +3077,18 @@
                 }
             }
 
-            void readExcessivePowerFromParcelLocked(Parcel in) {
+            boolean readExcessivePowerFromParcelLocked(Parcel in) {
                 final int N = in.readInt();
                 if (N == 0) {
                     mExcessivePower = null;
-                    return;
+                    return true;
                 }
 
+                if (N > 10000) {
+                    Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
+                    return false;
+                }
+                
                 mExcessivePower = new ArrayList<ExcessivePower>();
                 for (int i=0; i<N; i++) {
                     ExcessivePower ew = new ExcessivePower();
@@ -3092,6 +3097,7 @@
                     ew.usedTime = in.readLong();
                     mExcessivePower.add(ew);
                 }
+                return true;
             }
 
             void writeToParcelLocked(Parcel out) {
@@ -4687,7 +4693,7 @@
             }
             
             int NW = in.readInt();
-            if (NW > 10000) {
+            if (NW > 100) {
                 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
                 return;
             }
@@ -4705,7 +4711,7 @@
             }
 
             int NP = in.readInt();
-            if (NP > 10000) {
+            if (NP > 1000) {
                 Slog.w(TAG, "File corrupt: too many sensors " + NP);
                 return;
             }
@@ -4718,7 +4724,7 @@
             }
 
             NP = in.readInt();
-            if (NP > 10000) {
+            if (NP > 1000) {
                 Slog.w(TAG, "File corrupt: too many processes " + NP);
                 return;
             }
@@ -4729,6 +4735,10 @@
                 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
                 p.mStarts = p.mLoadedStarts = in.readInt();
                 int NSB = in.readInt();
+                if (NSB > 100) {
+                    Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
+                    return;
+                }
                 p.mSpeedBins = new SamplingCounter[NSB];
                 for (int i=0; i<NSB; i++) {
                     if (in.readInt() != 0) {
@@ -4736,7 +4746,9 @@
                         p.mSpeedBins[i].readSummaryFromParcelLocked(in);
                     }
                 }
-                p.readExcessivePowerFromParcelLocked(in);
+                if (!p.readExcessivePowerFromParcelLocked(in)) {
+                    return;
+                }
             }
 
             NP = in.readInt();
@@ -4749,6 +4761,10 @@
                 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
                 p.mWakeups = p.mLoadedWakeups = in.readInt();
                 final int NS = in.readInt();
+                if (NS > 1000) {
+                    Slog.w(TAG, "File corrupt: too many services " + NS);
+                    return;
+                }
                 for (int is = 0; is < NS; is++) {
                     String servName = in.readString();
                     Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 08cf515..7dbb145 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1211,6 +1211,8 @@
                         }
 
                         // fall through
+                    } else {
+                        continue;
                     }
                 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a18f473..3a8690e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -466,6 +466,18 @@
     return true;
 }
 
+void Layer::updateBuffersOrientation()
+{
+    sp<GraphicBuffer> buffer(getBypassBuffer());
+    if (buffer != NULL && mOrientation != buffer->transform) {
+        ClientRef::Access sharedClient(mUserClientRef);
+        SharedBufferServer* lcblk(sharedClient.get());
+        if (lcblk) { // all buffers need reallocation
+            lcblk->reallocateAll();
+        }
+    }
+}
+
 uint32_t Layer::doTransaction(uint32_t flags)
 {
     const Layer::State& front(drawingState());
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9ff5716..cb62558 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -83,6 +83,8 @@
     virtual void onRemoved();
     virtual bool setBypass(bool enable);
 
+    void updateBuffersOrientation();
+
     inline sp<GraphicBuffer> getBypassBuffer() const {
         return mBufferManager.getActiveBuffer(); }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5e9e06c..af0f95a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -725,8 +725,12 @@
 {
     // if this layer is already the bypass layer, do nothing
     sp<Layer> cur(mBypassLayer.promote());
-    if (mBypassLayer == layer)
+    if (mBypassLayer == layer) {
+        if (cur != NULL) {
+            cur->updateBuffersOrientation();
+        }
         return;
+    }
 
     // clear the current bypass layer
     mBypassLayer.clear();