Merge change Id8b28e4f into eclair

* changes:
  fix [2225964] Android runtime restarted in surfaceflinger/BlurFilter.cpp
diff --git a/api/current.xml b/api/current.xml
index 936e67e..b4161ae 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -14970,6 +14970,71 @@
 >
 </method>
 </interface>
+<class name="AccountManagerResponse"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onError"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="errorCode" type="int">
+</parameter>
+<parameter name="errorMessage" type="java.lang.String">
+</parameter>
+</method>
+<method name="onResult"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="android.os.Bundle">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</class>
 <class name="AccountsException"
  extends="java.lang.Exception"
  abstract="false"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index ca8660c..642c943 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -86,9 +86,9 @@
         DUMP("/proc/wakelocks");
         PRINT("");
         PRINT("------ PROCESSES ------");
-        EXEC("ps");
+        EXEC1("ps", "-P");
         PRINT("------ PROCESSES AND THREADS ------");
-        EXEC2("ps", "-t", "-p");
+        EXEC3("ps", "-t", "-p", "-P");
         PRINT("------ LIBRANK ------");
         EXEC_XBIN("librank");
         PRINT("------ BINDER FAILED TRANSACTION LOG ------");
@@ -362,4 +362,3 @@
         DUMP(path);
     }
 }
-
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 6862e5a..b99b6d7 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -61,6 +61,15 @@
     run_command(&c, TIMEOUT);   \
 }
 
+#define EXEC1(cmd, a1)          \
+{                               \
+    static struct Command c = { \
+        "/system/bin/" cmd,     \
+        { cmd, a1, 0 }          \
+    };                          \
+    run_command(&c, TIMEOUT);   \
+}
+
 #define EXEC2(cmd, a1, a2)      \
 {                               \
     static struct Command c = { \
@@ -70,6 +79,15 @@
     run_command(&c, TIMEOUT);   \
 }
 
+#define EXEC3(cmd, a1, a2, a3)      \
+{                                   \
+    static struct Command c = {     \
+        "/system/bin/" cmd,         \
+        { cmd, a1, a2, a3, 0 }      \
+    };                              \
+    run_command(&c, TIMEOUT);       \
+}
+
 #define EXEC4(cmd, a1, a2, a3, a4)  \
 {                                   \
     static struct Command c = {     \
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 0efeb1d..be2bdbe 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -88,7 +88,7 @@
  * The activity must then call {@link AccountAuthenticatorResponse#onResult} or
  * {@link AccountAuthenticatorResponse#onError} when it is complete.
  * <li> If the authenticator cannot synchronously process the request and return a result then it
- * may choose to return null and then use the {@link AccountManagerResponse} to send the result
+ * may choose to return null and then use the AccountManagerResponse to send the result
  * when it has completed the request.
  * </ul>
  * <p>
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 46dc895..9765496 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -321,7 +321,8 @@
      */
     public String peekAuthToken(final Account account, final String authTokenType) {
         if (account == null) {
-            throw new IllegalArgumentException("the account must not be null");
+            Log.e(TAG, "peekAuthToken: the account must not be null");
+            return null;
         }
         if (authTokenType == null) {
             return null;
@@ -346,7 +347,8 @@
      */
     public void setPassword(final Account account, final String password) {
         if (account == null) {
-            throw new IllegalArgumentException("the account must not be null");
+            Log.e(TAG, "the account must not be null");
+            return;
         }
         try {
             mService.setPassword(account, password);
@@ -365,7 +367,8 @@
      */
     public void clearPassword(final Account account) {
         if (account == null) {
-            throw new IllegalArgumentException("the account must not be null");
+            Log.e(TAG, "the account must not be null");
+            return;
         }
         try {
             mService.clearPassword(account);
@@ -388,10 +391,12 @@
      */
     public void setUserData(final Account account, final String key, final String value) {
         if (account == null) {
-            throw new IllegalArgumentException("the account must not be null");
+            Log.e(TAG, "the account must not be null");
+            return;
         }
         if (key == null) {
-            throw new IllegalArgumentException("the key must not be null");
+            Log.e(TAG, "the key must not be null");
+            return;
         }
         try {
             mService.setUserData(account, key, value);
@@ -602,11 +607,14 @@
             final String authTokenType, final String[] requiredFeatures,
             final Bundle addAccountOptions,
             final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
-        if (accountType == null) {
-            throw new IllegalArgumentException();
-        }
         return new AmsTask(activity, handler, callback) {
             public void doWork() throws RemoteException {
+                if (accountType == null) {
+                    Log.e(TAG, "the account must not be null");
+                    // to unblock caller waiting on Future.get()
+                    set(new Bundle()); 
+                    return;
+                }
                 mService.addAcount(mResponse, accountType, authTokenType,
                         requiredFeatures, activity != null, addAccountOptions);
             }
@@ -616,9 +624,13 @@
     public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
             final String type, final String[] features,
             AccountManagerCallback<Account[]> callback, Handler handler) {
-        if (type == null) throw new IllegalArgumentException("type is null");
         return new Future2Task<Account[]>(handler, callback) {
             public void doWork() throws RemoteException {
+                if (type == null) {
+                    Log.e(TAG, "Type is null");
+                    set(new Account[0]);
+                    return;
+                }
                 mService.getAccountsByFeatures(mResponse, type, features);
             }
             public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
@@ -785,7 +797,7 @@
             //noinspection ThrowableInstanceNeverThrow
 //            Log.e(TAG, "calling this from your main thread can lead to deadlock and/or ANRs",
 //                    new Exception());
-            // TODO(fredq) remove the log and throw this exception when the callers are fixed
+            // TODO remove the log and throw this exception when the callers are fixed
 //            throw new IllegalStateException(
 //                    "calling this from your main thread can lead to deadlock");
         }
@@ -1338,11 +1350,13 @@
      */
     public void removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
         if (listener == null) {
-            throw new IllegalArgumentException("the listener is null");
+            Log.e(TAG, "Missing listener");
+            return;
         }
         synchronized (mAccountsUpdatedListeners) {
             if (!mAccountsUpdatedListeners.containsKey(listener)) {
-                throw new IllegalStateException("this listener was not previously added");
+                Log.e(TAG, "Listener was not previously added");
+                return;
             }
             mAccountsUpdatedListeners.remove(listener);
             if (mAccountsUpdatedListeners.isEmpty()) {
diff --git a/core/java/android/accounts/AccountManagerResponse.java b/core/java/android/accounts/AccountManagerResponse.java
index 25371fd..1cd6a74 100644
--- a/core/java/android/accounts/AccountManagerResponse.java
+++ b/core/java/android/accounts/AccountManagerResponse.java
@@ -22,16 +22,17 @@
 import android.os.RemoteException;
 
 /**
- * Object that wraps calls to an {@link android.accounts.IAccountManagerResponse} object.
- * @hide
+ * Used by Account Authenticators to return a response.
  */
 public class AccountManagerResponse implements Parcelable {
     private IAccountManagerResponse mResponse;
 
+    /** @hide */
     public AccountManagerResponse(IAccountManagerResponse response) {
         mResponse = response;
     }
 
+    /** @hide */
     public AccountManagerResponse(Parcel parcel) {
         mResponse =
                 IAccountManagerResponse.Stub.asInterface(parcel.readStrongBinder());
@@ -53,14 +54,17 @@
         }
     }
 
+    /** @hide */
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeStrongBinder(mResponse.asBinder());
     }
 
+    /** @hide */
     public static final Creator<AccountManagerResponse> CREATOR =
             new Creator<AccountManagerResponse>() {
         public AccountManagerResponse createFromParcel(Parcel source) {
@@ -71,4 +75,4 @@
             return new AccountManagerResponse[size];
         }
     };
-}
\ No newline at end of file
+}
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 9c60141..4f59c4e 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -429,14 +429,6 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            if (account == null) {
-                try {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "null account");
-                } catch (RemoteException e) {
-                    // it doesn't matter if we are unable to deliver this error
-                }
-                return;
-            }
             new RemoveAccountSession(response, account).bind();
         } finally {
             restoreCallingIdentity(identityToken);
@@ -706,22 +698,6 @@
 
         long identityToken = clearCallingIdentity();
         try {
-            try {
-                if (account == null) {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                            "account is null");
-                    return;
-                }
-                if (authTokenType == null) {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                            "authTokenType is null");
-                    return;
-                }
-            } catch (RemoteException e) {
-                // it doesn't matter if we can't deliver this error
-                return;
-            }
-
             // if the caller has permission, do the peek. otherwise go the more expensive
             // route of starting a Session
             if (permissionGranted) {
@@ -887,16 +863,6 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            try {
-                if (authTokenType == null) {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                            "authTokenType is null");
-                    return;
-                }
-            } catch (RemoteException e) {
-                // it doesn't matter if we can't deliver this error
-                return;
-            }
             new Session(response, accountType, expectActivityLaunch) {
                 public void run() throws RemoteException {
                     mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
@@ -922,16 +888,6 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            try {
-                if (account == null) {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                            "account is null");
-                    return;
-                }
-            } catch (RemoteException e) {
-                // it doesn't matter if we can't deliver this error
-                return;
-            }
             new Session(response, account.type, expectActivityLaunch) {
                 public void run() throws RemoteException {
                     mAuthenticator.confirmCredentials(this, account, options);
@@ -952,16 +908,6 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            try {
-                if (account == null) {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                            "account is null");
-                    return;
-                }
-            } catch (RemoteException e) {
-                // it doesn't matter if we can't deliver this error
-                return;
-            }
             new Session(response, account.type, expectActivityLaunch) {
                 public void run() throws RemoteException {
                     mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
@@ -984,16 +930,6 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            try {
-                if (accountType == null) {
-                    response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
-                            "accountType is null");
-                    return;
-                }
-            } catch (RemoteException e) {
-                // it doesn't matter if we can't deliver this error
-                return;
-            }
             new Session(response, accountType, expectActivityLaunch) {
                 public void run() throws RemoteException {
                     mAuthenticator.editProperties(this, mAccountType);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ff48583..3fc676b 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -597,14 +597,6 @@
     /**
      * Picks RFCOMM channels until none are left.
      * Avoids reserved channels.
-     * Ideally we would pick random channels, but in the current implementation
-     * we start with the channel that is the hash of the UUID, and try every
-     * available channel from there. This means that in most cases a given
-     * uuid will use the same channel. This is a workaround for a Bluez SDP
-     * bug where we are not updating the cache when the channel changes for a
-     * uuid.
-     * TODO: Fix the Bluez SDP caching bug, and go back to random channel
-     * selection
      */
     private static class RfcommChannelPicker {
         private static final int[] RESERVED_RFCOMM_CHANNELS =  new int[] {
@@ -637,19 +629,12 @@
             }
             mUuid = uuid;
         }
-        /* Returns next channel, or -1 if we're out */
+        /* Returns next random channel, or -1 if we're out */
         public int nextChannel() {
-            int channel = mUuid.hashCode();  // always pick the same channel to try first
-            Integer channelInt;
-            while (mChannels.size() > 0) {
-                channelInt = new Integer(channel);
-                if (mChannels.remove(channelInt)) {
-                    return channel;
-                }
-                channel = (channel % BluetoothSocket.MAX_RFCOMM_CHANNEL) + 1;
+            if (mChannels.size() == 0) {
+                return -1;
             }
-
-            return -1;
+            return mChannels.remove(sRandom.nextInt(mChannels.size()));
         }
     }
 
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 0467516..ca36df2 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -545,8 +545,12 @@
                         "only updates, deletes, and asserts can have selections");
             }
             mSelection = selection;
-            mSelectionArgs = new String[selectionArgs.length];
-            System.arraycopy(selectionArgs, 0, mSelectionArgs, 0, selectionArgs.length);
+            if (selectionArgs == null) {
+                mSelectionArgs = null;
+            } else {
+                mSelectionArgs = new String[selectionArgs.length];
+                System.arraycopy(selectionArgs, 0, mSelectionArgs, 0, selectionArgs.length);
+            }
             return this;
         }
 
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index 0f8dff1..455449e 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -1,6 +1,7 @@
 #include "GraphicsJNI.h"
 #include "SkMaskFilter.h"
 #include "SkBlurMaskFilter.h"
+#include "SkTableMaskFilter.h"
 
 #include <jni.h>
 
@@ -39,6 +40,19 @@
         ThrowIAE_IfNull(env, filter);
         return filter;
     }
+
+    static SkMaskFilter* createTable(JNIEnv* env, jobject, jbyteArray jtable) {
+        AutoJavaByteArray autoTable(env, jtable, 256);
+        return new SkTableMaskFilter((const uint8_t*)autoTable.ptr());
+    }
+
+    static SkMaskFilter* createClipTable(JNIEnv* env, jobject, int min, int max) {
+        return SkTableMaskFilter::CreateClip(min, max);
+    }
+
+    static SkMaskFilter* createGammaTable(JNIEnv* env, jobject, float gamma) {
+        return SkTableMaskFilter::CreateGamma(gamma);
+    }
 };
 
 static JNINativeMethod gMaskFilterMethods[] = {
@@ -53,6 +67,12 @@
     { "nativeConstructor",  "([FFFF)I", (void*)SkMaskFilterGlue::createEmboss    }
 };
 
+static JNINativeMethod gTableMaskFilterMethods[] = {
+    { "nativeNewTable", "([B)I", (void*)SkMaskFilterGlue::createTable    },
+    { "nativeNewClip",  "(II)I", (void*)SkMaskFilterGlue::createClipTable    },
+    { "nativeNewGamma", "(F)I", (void*)SkMaskFilterGlue::createGammaTable    }
+};
+
 #include <android_runtime/AndroidRuntime.h>
 
 #define REG(env, name, array)                                                                       \
@@ -67,6 +87,7 @@
     REG(env, "android/graphics/MaskFilter", gMaskFilterMethods);
     REG(env, "android/graphics/BlurMaskFilter", gBlurMaskFilterMethods);
     REG(env, "android/graphics/EmbossMaskFilter", gEmbossMaskFilterMethods);
+    REG(env, "android/graphics/TableMaskFilter", gTableMaskFilterMethods);
     
     return 0;
 }
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7c627c1..d8c2234 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -51,7 +51,7 @@
 #undef __KERNEL__
 #endif
 
-#define POLICY_DEBUG 1
+#define POLICY_DEBUG 0
 
 using namespace android;
 
diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java
new file mode 100644
index 0000000..a8a7ff0
--- /dev/null
+++ b/graphics/java/android/graphics/TableMaskFilter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+/**
+ * @hide
+ */
+public class TableMaskFilter extends MaskFilter {
+
+    public TableMaskFilter(byte[] table) {
+        if (table.length < 256) {
+            throw new RuntimeException("table.length must be >= 256");
+        }
+        native_instance = nativeNewTable(table);
+    }
+    
+    private TableMaskFilter(int ni) {
+        native_instance = ni;
+    }
+    
+    public static TableMaskFilter CreateClipTable(int min, int max) {
+        return new TableMaskFilter(nativeNewClip(min, max));
+    }
+    
+    public static TableMaskFilter CreateGammaTable(float gamma) {
+        return new TableMaskFilter(nativeNewGamma(gamma));
+    }
+
+    private static native int nativeNewTable(byte[] table);
+    private static native int nativeNewClip(int min, int max);
+    private static native int nativeNewGamma(float gamma);
+}
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 6590503..82a8e51 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -33,14 +33,13 @@
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
 
-#include "gralloc_priv.h"   // needed for msm / copybit
-
 namespace android {
 
 // ---------------------------------------------------------------------------
 
 const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
 const char* const LayerBuffer::typeID = "LayerBuffer";
+gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
 
 // ---------------------------------------------------------------------------
 
@@ -60,6 +59,16 @@
     LayerBaseClient::onFirstRef();
     mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
             const_cast<LayerBuffer *>(this));
+
+    hw_module_t const* module = (hw_module_t const*)sGrallocModule;
+    if (!module) {
+        // NOTE: technically there is a race here, but it shouldn't
+        // cause any problem since hw_get_module() always returns
+        // the same value.
+        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+            sGrallocModule = (gralloc_module_t const *)module;
+        }
+    }
 }
 
 sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
@@ -243,30 +252,36 @@
     : mBufferHeap(buffers)
 {
     NativeBuffer& src(mNativeBuffer);
-    
-    src.crop.l = 0;
-    src.crop.t = 0;
-    src.crop.r = buffers.w;
-    src.crop.b = buffers.h;
-    
-    src.img.w       = buffers.hor_stride ?: buffers.w;
-    src.img.h       = buffers.ver_stride ?: buffers.h;
-    src.img.format  = buffers.format;
-    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+    src.img.handle = 0;
 
-    // FIXME: gross hack, we should never access private_handle_t from here,
-    // but this is needed by msm drivers
-    private_handle_t* hnd = new private_handle_t(
-            buffers.heap->heapID(), buffers.heap->getSize(), 0);
-    hnd->offset = offset;
-    src.img.handle = hnd;
+    gralloc_module_t const * module = LayerBuffer::getGrallocModule();
+    if (module && module->perform) {
+        int err = module->perform(module,
+                GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
+                buffers.heap->heapID(), buffers.heap->getSize(),
+                offset, buffers.heap->base(),
+                &src.img.handle);
+
+        if (err == NO_ERROR) {
+            src.crop.l = 0;
+            src.crop.t = 0;
+            src.crop.r = buffers.w;
+            src.crop.b = buffers.h;
+
+            src.img.w       = buffers.hor_stride ?: buffers.w;
+            src.img.h       = buffers.ver_stride ?: buffers.h;
+            src.img.format  = buffers.format;
+            src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+        }
+    }
 }
 
 LayerBuffer::Buffer::~Buffer()
 {
     NativeBuffer& src(mNativeBuffer);
-    if (src.img.handle)
-        delete (private_handle_t*)src.img.handle;
+    if (src.img.handle) {
+        native_handle_delete(src.img.handle);
+    }
 }
 
 // ============================================================================
@@ -437,9 +452,7 @@
     }
 
     if (err != NO_ERROR) {
-        // OpenGL fall-back
-        GLuint w = 0;
-        GLuint h = 0;
+        // slower fallback
         GGLSurface t;
         t.version = sizeof(GGLSurface);
         t.width  = src.crop.r;
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 438b711..47482f4 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -91,6 +91,11 @@
         copybit_rect_t    crop;
     };
 
+    static gralloc_module_t const* sGrallocModule;
+    static gralloc_module_t const* getGrallocModule() {
+        return sGrallocModule;
+    }
+
     class Buffer : public LightRefBase<Buffer> {
     public:
         Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 6698e00..f9bfe6c 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -246,8 +246,10 @@
     virtual status_t    readyToRun();
     virtual void        onFirstRef();
 
+public:     // hack to work around gcc 4.0.3 bug
     const GraphicPlane&     graphicPlane(int dpy) const;
           GraphicPlane&     graphicPlane(int dpy);
+private:
 
             void        waitForEvent();
 public:     // hack to work around gcc 4.0.3 bug
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 84be874..9d2c779 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -225,7 +225,10 @@
 sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid)
 {
 #ifndef NO_OPENCORE
-    sp<MediaRecorderClient> recorder = new MediaRecorderClient(pid);
+    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid);
+    wp<MediaRecorderClient> w = recorder;
+    Mutex::Autolock lock(mLock);
+    mMediaRecorderClients.add(w);
 #else
     sp<MediaRecorderClient> recorder = NULL;
 #endif
@@ -233,6 +236,13 @@
     return recorder;
 }
 
+void MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client)
+{
+    Mutex::Autolock lock(mLock);
+    mMediaRecorderClients.remove(client);
+    LOGV("Delete media recorder client");
+}
+
 sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid)
 {
     sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid);
@@ -460,6 +470,13 @@
             sp<Client> c = mClients[i].promote();
             if (c != 0) c->dump(fd, args);
         }
+        for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
+            result.append(" MediaRecorderClient\n");
+            sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
+            snprintf(buffer, 255, "  pid(%d)\n\n", c->mPid);
+            result.append(buffer);
+        }
+
         result.append(" Files opened and/or mapped:\n");
         snprintf(buffer, SIZE, "/proc/%d/maps", myTid());
         FILE *f = fopen(buffer, "r");
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 7d2e611..43c4915 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -35,6 +35,7 @@
 class IMediaRecorder;
 class IMediaMetadataRetriever;
 class IOMX;
+class MediaRecorderClient;
 
 #define CALLBACK_ANTAGONIZER 0
 #if CALLBACK_ANTAGONIZER
@@ -175,6 +176,7 @@
 
     // IMediaPlayerService interface
     virtual sp<IMediaRecorder>  createMediaRecorder(pid_t pid);
+    void    removeMediaRecorderClient(wp<MediaRecorderClient> client);
     virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid);
 
     // House keeping for media player clients
@@ -280,6 +282,7 @@
 
     mutable     Mutex                       mLock;
                 SortedVector< wp<Client> >  mClients;
+                SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
                 int32_t                     mNextConnId;
 };
 
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index e54f20d..95ee3e4 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -32,7 +32,10 @@
 #include <media/PVMediaRecorder.h>
 #include <utils/String16.h>
 
+#include <media/AudioTrack.h>
+
 #include "MediaRecorderClient.h"
+#include "MediaPlayerService.h"
 
 namespace android {
 
@@ -80,6 +83,7 @@
     Mutex::Autolock lock(mLock);
     if (mRecorder == NULL)	{
         LOGE("recorder is not initialized");
+        return NO_INIT;
     }
     return mRecorder->setVideoSource((video_source)vs);
 }
@@ -93,6 +97,7 @@
     Mutex::Autolock lock(mLock);
     if (mRecorder == NULL)  {
         LOGE("recorder is not initialized");
+        return NO_INIT;
     }
     return mRecorder->setAudioSource((audio_source)as);
 }
@@ -271,15 +276,18 @@
     if (mRecorder != NULL) {
         delete mRecorder;
         mRecorder = NULL;
+        wp<MediaRecorderClient> client(this);
+        mMediaPlayerService->removeMediaRecorderClient(client);
     }
     return NO_ERROR;
 }
 
-MediaRecorderClient::MediaRecorderClient(pid_t pid)
+MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid)
 {
     LOGV("Client constructor");
     mPid = pid;
     mRecorder = new PVMediaRecorder();
+    mMediaPlayerService = service;
 }
 
 MediaRecorderClient::~MediaRecorderClient()
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 6a1c2d5..6260441 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -24,6 +24,7 @@
 
 class PVMediaRecorder;
 class ISurface;
+class MediaPlayerService;
 
 class MediaRecorderClient : public BnMediaRecorder
 {
@@ -53,12 +54,13 @@
 private:
     friend class                 MediaPlayerService;  // for accessing private constructor
 
-                                 MediaRecorderClient(pid_t pid);
+                                 MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid);
     virtual 		         ~MediaRecorderClient();
 
     pid_t			 mPid;
     Mutex			 mLock;
     PVMediaRecorder              *mRecorder;
+    sp<MediaPlayerService>       mMediaPlayerService;
 };
 
 }; // namespace android
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 4b9e59b..d73d6dd 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -74,6 +74,7 @@
     static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
         return 0;
     }
+public:
     copybit_rect_t r;
 };
 
@@ -421,6 +422,19 @@
                 (enables & GGL_ENABLE_DITHER) ?
                         COPYBIT_ENABLE : COPYBIT_DISABLE);
         clipRectRegion it(c);
+
+        LOGD("dst={%d, %d, %d, %p, %p}, "
+             "src={%d, %d, %d, %p, %p}, "
+             "drect={%d,%d,%d,%d}, "
+             "srect={%d,%d,%d,%d}, "
+             "it={%d,%d,%d,%d}, " ,
+             dst.w, dst.h, dst.format, dst.base, dst.handle,
+             src.w, src.h, src.format, src.base, src.handle,
+             drect.l, drect.t, drect.r, drect.b,
+             srect.l, srect.t, srect.r, srect.b,
+             it.r.l, it.r.t, it.r.r, it.r.b
+        );
+
         err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
     }
     if (err != NO_ERROR) {
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3efb678..c22c21b 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -1641,8 +1641,13 @@
         if (dp == 0) {
             return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
         }
-        // since we don't have a way to know which implementation to call,
-        // we're calling all of them
+
+        /* Since we don't have a way to know which implementation to call,
+         * we're calling all of them. If at least one of the implementation
+         * succeeded, this is a success.
+         */
+
+        EGLint currentError = eglGetError();
 
         EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS];
         bool success = false;
@@ -1659,9 +1664,24 @@
                 }
             }
         }
-        if (!success)
+
+        if (!success) {
+            // failure, if there was an error when we entered this function,
+            // the error flag must not be updated.
+            // Otherwise, the error is whatever happened in the implementation
+            // that faulted.
+            if (currentError != EGL_SUCCESS) {
+                setError(currentError, EGL_NO_IMAGE_KHR);
+            }
             return EGL_NO_IMAGE_KHR;
-        
+        } else {
+            // In case of success, we need to clear all error flags
+            // (especially those caused by the implementation that didn't
+            // succeed). TODO: we could avoid this if we knew this was
+            // a "full" success (all implementation succeeded).
+            eglGetError();
+        }
+
         egl_image_t* result = new egl_image_t(dpy, ctx);
         memcpy(result->images, implImages, sizeof(implImages));
         return (EGLImageKHR)result;
diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp
index e62fe03..992a10c 100644
--- a/opengl/tests/linetex/linetex.cpp
+++ b/opengl/tests/linetex/linetex.cpp
@@ -68,31 +68,28 @@
      
      glBindTexture(GL_TEXTURE_2D, 0);
      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
      glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
      glDisable(GL_DITHER);
      glDisable(GL_BLEND);
      glEnable(GL_TEXTURE_2D);
      glColor4f(1,1,1,1);
 
-     const uint32_t t32[] = {
-             0xFFFFFFFF, 0xFF0000FF, 0xFF00FF00, 0xFFFF0000,
-             0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 0xFF000000
-     };
+     const uint16_t t16[64] = { 0xFFFF, 0xF800, 0x07E0, 0x001F };
 
      const GLfloat vertices[4][2] = {
-             { 0,  0 },
-             { w,  h }
+             { w/2,  0 },
+             { w/2,  h }
      };
 
      const GLfloat texCoords[4][2] = {
              { 0,  0 },
-             { 1,  0 }
+             { 1,  1 }
      };
 
-     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, t32);
+     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 4, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t16);
 
      glViewport(0, 0, w, h);
      glMatrixMode(GL_PROJECTION);