Merge "beging np2 extension check work."
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 45f361e..29f388a 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -167,9 +167,9 @@
     /** @hide */
     public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff;
 
-    // Always log queries which take 100ms+; shorter queries are
+    // Always log queries which take 500ms+; shorter queries are
     // sampled accordingly.
-    private static final int SLOW_THRESHOLD_MILLIS = 100;
+    private static final int SLOW_THRESHOLD_MILLIS = 500;
     private final Random mRandom = new Random();  // guarded by itself
 
     public ContentResolver(Context context) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 8fd8e28..c13dd23 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -208,11 +208,11 @@
 
     // Things related to query logging/sampling for debugging
     // slow/frequent queries during development.  Always log queries
-    // which take 100ms+; shorter queries are sampled accordingly.
+    // which take 500ms+; shorter queries are sampled accordingly.
     // Commit statements, which are typically slow, are logged
     // together with the most recently executed SQL statement, for
     // disambiguation.
-    private static final int QUERY_LOG_TIME_IN_MILLIS = 100;
+    private static final int QUERY_LOG_TIME_IN_MILLIS = 500;
     private static final int QUERY_LOG_SQL_LENGTH = 64;
     private static final String COMMIT_SQL = "COMMIT;";
     private final Random mRandom = new Random();
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index c939e3f..2b3b98d 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -28,8 +28,6 @@
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.Interpolator;
-
 
 /**
  * An abstract base class for spinner widgets. SDK users will probably not
@@ -38,24 +36,21 @@
  * @attr ref android.R.styleable#AbsSpinner_entries
  */
 public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> {
-
     SpinnerAdapter mAdapter;
 
     int mHeightMeasureSpec;
     int mWidthMeasureSpec;
     boolean mBlockLayoutRequests;
+
     int mSelectionLeftPadding = 0;
     int mSelectionTopPadding = 0;
     int mSelectionRightPadding = 0;
     int mSelectionBottomPadding = 0;
-    Rect mSpinnerPadding = new Rect();
-    View mSelectedView = null;
-    Interpolator mInterpolator;
+    final Rect mSpinnerPadding = new Rect();
 
-    RecycleBin mRecycler = new RecycleBin();
+    final RecycleBin mRecycler = new RecycleBin();
     private DataSetObserver mDataSetObserver;
 
-
     /** Temporary frame to hold a child View's frame rectangle */
     private Rect mTouchFrame;
 
@@ -95,7 +90,6 @@
         setWillNotDraw(false);
     }
 
-
     /**
      * The Adapter is used to provide the data which backs this Spinner.
      * It also provides methods to transform spinner items based on their position
@@ -190,7 +184,7 @@
         boolean needsMeasuring = true;
         
         int selectedPosition = getSelectedItemPosition();
-        if (selectedPosition >= 0 && mAdapter != null) {
+        if (selectedPosition >= 0 && mAdapter != null && selectedPosition < mAdapter.getCount()) {
             // Try looking in the recycler. (Maybe we were measured once already)
             View view = mRecycler.get(selectedPosition);
             if (view == null) {
@@ -237,7 +231,6 @@
         mWidthMeasureSpec = widthMeasureSpec;
     }
 
-    
     int getChildHeight(View child) {
         return child.getMeasuredHeight();
     }
@@ -254,26 +247,17 @@
     }
     
     void recycleAllViews() {
-        int childCount = getChildCount();
+        final int childCount = getChildCount();
         final AbsSpinner.RecycleBin recycleBin = mRecycler;
+        final int position = mFirstPosition;
 
         // All views go in recycler
-        for (int i=0; i<childCount; i++) {
+        for (int i = 0; i < childCount; i++) {
             View v = getChildAt(i);
-            int index = mFirstPosition + i;
+            int index = position + i;
             recycleBin.put(index, v);
         }  
     }
-    
-    @Override
-    void handleDataChanged() {
-        // FIXME -- this is called from both measure and layout.
-        // This is harmless right now, but we don't want to do redundant work if
-        // this gets more complicated
-       super.handleDataChanged();
-    }
-    
-  
 
     /**
      * Jump directly to a specific item in the adapter data.
@@ -284,7 +268,6 @@
                 position <= mFirstPosition + getChildCount() - 1;
         setSelectionInt(position, shouldAnimate);
     }
-    
 
     @Override
     public void setSelection(int position) {
@@ -335,8 +318,6 @@
         }
     }
 
- 
-
     @Override
     public SpinnerAdapter getAdapter() {
         return mAdapter;
@@ -452,7 +433,7 @@
     }
 
     class RecycleBin {
-        private SparseArray<View> mScrapHeap = new SparseArray<View>();
+        private final SparseArray<View> mScrapHeap = new SparseArray<View>();
 
         public void put(int position, View v) {
             mScrapHeap.put(position, v);
@@ -469,12 +450,7 @@
             }
             return result;
         }
-        
-        View peek(int position) {
-            // System.out.print("Looking for " + position);
-            return mScrapHeap.get(position);
-        }
-        
+
         void clear() {
             final SparseArray<View> scrapHeap = mScrapHeap;
             final int count = scrapHeap.size();
diff --git a/core/res/res/layout/alert_dialog.xml b/core/res/res/layout/alert_dialog.xml
index 7ae68f9..25a41f8 100644
--- a/core/res/res/layout/alert_dialog.xml
+++ b/core/res/res/layout/alert_dialog.xml
@@ -80,7 +80,8 @@
             android:paddingTop="2dip"
             android:paddingBottom="12dip"
             android:paddingLeft="14dip"
-            android:paddingRight="10dip">
+            android:paddingRight="10dip"
+            android:overscrollMode="ifContentScrolls">
             <TextView android:id="@+id/message"
                 style="?android:attr/textAppearanceMedium"
                 android:layout_width="match_parent"
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index f8bc7ab..974075d 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -96,6 +96,7 @@
         kRequiresFlushBeforeShutdown         = 64,
         kDefersOutputBufferAllocation        = 128,
         kDecoderLiesAboutNumberOfChannels    = 256,
+        kInputBufferSizesAreBogus            = 512,
     };
 
     struct BufferInfo {
diff --git a/media/jni/android_media_ResampleInputStream.cpp b/media/jni/android_media_ResampleInputStream.cpp
index f248557..d965d9a 100644
--- a/media/jni/android_media_ResampleInputStream.cpp
+++ b/media/jni/android_media_ResampleInputStream.cpp
@@ -92,7 +92,7 @@
          jint jNpoints) {
     
     // safety first!
-    if (nFir21 + jNpoints > BUF_SIZE) {
+    if (nFir21 + jNpoints * 2 > BUF_SIZE) {
         throwException(env, "java/lang/IllegalArgumentException",
                 "FIR+data too long %d", nFir21 + jNpoints);
         return;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 6cf7cff..4075ec1 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -298,6 +298,10 @@
         quirks |= kRequiresAllocateBufferOnOutputPorts;
     }
 
+    if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
+        quirks |= kInputBufferSizesAreBogus;
+    }
+
     return quirks;
 }
 
@@ -561,7 +565,8 @@
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
     CHECK_EQ(err, OK);
 
-    if (def.nBufferSize < size) {
+    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
+        || (def.nBufferSize < size)) {
         def.nBufferSize = size;
     }
 
@@ -574,7 +579,12 @@
     CHECK_EQ(err, OK);
 
     // Make sure the setting actually stuck.
-    CHECK(def.nBufferSize >= size);
+    if (portIndex == kPortIndexInput
+            && (mQuirks & kInputBufferSizesAreBogus)) {
+        CHECK_EQ(def.nBufferSize, size);
+    } else {
+        CHECK(def.nBufferSize >= size);
+    }
 }
 
 status_t OMXCodec::setVideoPortFormatType(
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 9ca060d..ff8757d 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -401,6 +401,33 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+struct SharedVideoRenderer : public VideoRenderer {
+    SharedVideoRenderer(void *libHandle, VideoRenderer *obj)
+        : mLibHandle(libHandle),
+          mObj(obj) {
+    }
+
+    virtual ~SharedVideoRenderer() {
+        delete mObj;
+        mObj = NULL;
+
+        dlclose(mLibHandle);
+        mLibHandle = NULL;
+    }
+
+    virtual void render(
+            const void *data, size_t size, void *platformPrivate) {
+        return mObj->render(data, size, platformPrivate);
+    }
+
+private:
+    void *mLibHandle;
+    VideoRenderer *mObj;
+
+    SharedVideoRenderer(const SharedVideoRenderer &);
+    SharedVideoRenderer &operator=(const SharedVideoRenderer &);
+};
+
 sp<IOMXRenderer> OMX::createRenderer(
         const sp<ISurface> &surface,
         const char *componentName,
@@ -411,11 +438,7 @@
 
     VideoRenderer *impl = NULL;
 
-    static void *libHandle = NULL;
-
-    if (!libHandle) {
-        libHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
-    }
+    void *libHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
 
     if (libHandle) {
         typedef VideoRenderer *(*CreateRendererFunc)(
@@ -434,6 +457,16 @@
         if (func) {
             impl = (*func)(surface, componentName, colorFormat,
                     displayWidth, displayHeight, encodedWidth, encodedHeight);
+
+            if (impl) {
+                impl = new SharedVideoRenderer(libHandle, impl);
+                libHandle = NULL;
+            }
+        }
+
+        if (libHandle) {
+            dlclose(libHandle);
+            libHandle = NULL;
         }
     }
 
diff --git a/services/java/com/android/server/status/StorageNotification.java b/services/java/com/android/server/status/StorageNotification.java
index 3b79049..e0b288d 100644
--- a/services/java/com/android/server/status/StorageNotification.java
+++ b/services/java/com/android/server/status/StorageNotification.java
@@ -36,6 +36,7 @@
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -46,6 +47,8 @@
 public class StorageNotification extends StorageEventListener {
     private static final String TAG = "StorageNotification";
 
+    private static final boolean POP_UMS_ACTIVITY_ON_CONNECT = true;
+
     /**
      * Binder context for this service
      */
@@ -239,12 +242,28 @@
             Intent intent = new Intent();
             intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+            final boolean adbOn = 1 == Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.ADB_ENABLED,
+                0);
+
             PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
             setUsbStorageNotification(
                     com.android.internal.R.string.usb_storage_notification_title,
                     com.android.internal.R.string.usb_storage_notification_message,
                     com.android.internal.R.drawable.stat_sys_data_usb,
                     false, true, pi);
+
+            if (POP_UMS_ACTIVITY_ON_CONNECT && !adbOn) {
+                // We assume that developers don't want to enable UMS every
+                // time they attach a device to a USB host. The average user,
+                // however, is looking to charge the phone (in which case this
+                // is harmless) or transfer files (in which case this coaches
+                // the user about how to complete that task and saves several
+                // steps).
+                mContext.startActivity(intent);
+            }
         } else {
             setUsbStorageNotification(0, 0, 0, false, false, null);
         }
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 31cf6a7..9f8e57f 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -22,10 +22,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.ServiceManager;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -37,7 +34,7 @@
 
     protected PhoneBase phone;
     protected AdnRecordCache adnCache;
-    protected Object mLock = new Object();
+    protected final Object mLock = new Object();
     protected int recordSize[];
     protected boolean success;
     protected List<AdnRecord> records;
@@ -80,8 +77,7 @@
                     ar = (AsyncResult)msg.obj;
                     synchronized (mLock) {
                         if (ar.exception == null) {
-                            records = (List<AdnRecord>)
-                                    ((ArrayList<AdnRecord>) ar.result);
+                            records = (List<AdnRecord>) ar.result;
                         } else {
                             if(DBG) logd("Cannot load ADN records");
                             if (records != null) {
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
index 19900c8..1ac2da3 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
@@ -39,6 +39,11 @@
     }
 
     protected void finalize() {
+        try {
+            super.finalize();
+        } catch (Throwable throwable) {
+            Log.e(LOG_TAG, "Error while finalizing:", throwable);
+        }
         Log.d(LOG_TAG, "PhoneSubInfo finalized");
     }
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
index 78e89d5..6e12f24a 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
@@ -16,22 +16,10 @@
 
 package com.android.internal.telephony.cdma;
 
-import android.content.pm.PackageManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.Message;
-import android.os.ServiceManager;
-import android.telephony.PhoneNumberUtils;
 import android.util.Log;
 
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
 import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.PhoneProxy;
-
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * RuimPhoneBookInterfaceManager to provide an inter-process communication to
@@ -42,20 +30,6 @@
 public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
     static final String LOG_TAG = "CDMA";
 
-
-    Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-
-            switch(msg.what) {
-                default:
-                    mBaseHandler.handleMessage(msg);
-                    break;
-            }
-        }
-    };
-
     public RuimPhoneBookInterfaceManager(CDMAPhone phone) {
         super(phone);
         adnCache = phone.mRuimRecords.getAdnCache();
@@ -67,6 +41,11 @@
     }
 
     protected void finalize() {
+        try {
+            super.finalize();
+        } catch (Throwable throwable) {
+            Log.e(LOG_TAG, "Error while finalizing:", throwable);
+        }
         if(DBG) Log.d(LOG_TAG, "RuimPhoneBookInterfaceManager finalized");
     }
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
index 9439359..cfcfd98 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
@@ -30,6 +30,7 @@
 import com.android.internal.telephony.SmsRawData;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
@@ -89,6 +90,11 @@
     }
 
     protected void finalize() {
+        try {
+            super.finalize();
+        } catch (Throwable throwable) {
+            Log.e(LOG_TAG, "Error while finalizing:", throwable);
+        }
         if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized");
     }
 
@@ -143,7 +149,7 @@
     public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
         //NOTE smsc not used in RUIM
         if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
-                "pdu=("+ pdu + ")");
+                "pdu=("+ Arrays.toString(pdu) + ")");
         enforceReceiveAndSend("Copying message to RUIM");
         synchronized(mLock) {
             mSuccess = false;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
index 076da6b..feb508a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
@@ -16,22 +16,10 @@
 
 package com.android.internal.telephony.gsm;
 
-import android.content.pm.PackageManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.Message;
-import android.os.ServiceManager;
-import android.telephony.PhoneNumberUtils;
 import android.util.Log;
 
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
 import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.PhoneProxy;
-
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * SimPhoneBookInterfaceManager to provide an inter-process communication to
@@ -42,20 +30,6 @@
 public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
     static final String LOG_TAG = "GSM";
 
-
-    Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-
-            switch(msg.what) {
-                default:
-                    mBaseHandler.handleMessage(msg);
-                    break;
-            }
-        }
-    };
-
     public SimPhoneBookInterfaceManager(GSMPhone phone) {
         super(phone);
         adnCache = phone.mSIMRecords.getAdnCache();
@@ -67,6 +41,11 @@
     }
 
     protected void finalize() {
+        try {
+            super.finalize();
+        } catch (Throwable throwable) {
+            Log.e(LOG_TAG, "Error while finalizing:", throwable);
+        }
         if(DBG) Log.d(LOG_TAG, "SimPhoneBookInterfaceManager finalized");
     }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
index 875d8d0..2028ca4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
@@ -25,10 +25,10 @@
 import com.android.internal.telephony.IccConstants;
 import com.android.internal.telephony.IccSmsInterfaceManager;
 import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneProxy;
 import com.android.internal.telephony.SmsRawData;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
@@ -65,8 +65,7 @@
                     ar = (AsyncResult)msg.obj;
                     synchronized (mLock) {
                         if (ar.exception == null) {
-                            mSms  = (List<SmsRawData>)
-                                    buildValidRawData((ArrayList<byte[]>) ar.result);
+                            mSms  = buildValidRawData((ArrayList<byte[]>) ar.result);
                         } else {
                             if(DBG) log("Cannot load Sms records");
                             if (mSms != null)
@@ -88,6 +87,11 @@
     }
 
     protected void finalize() {
+        try {
+            super.finalize();
+        } catch (Throwable throwable) {
+            Log.e(LOG_TAG, "Error while finalizing:", throwable);
+        }
         if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized");
     }
 
@@ -106,7 +110,7 @@
     updateMessageOnIccEf(int index, int status, byte[] pdu) {
         if (DBG) log("updateMessageOnIccEf: index=" + index +
                 " status=" + status + " ==> " +
-                "("+ pdu + ")");
+                "("+ Arrays.toString(pdu) + ")");
         enforceReceiveAndSend("Updating message on SIM");
         synchronized(mLock) {
             mSuccess = false;
@@ -118,7 +122,7 @@
                 mPhone.mCM.deleteSmsOnSim(index, response);
             } else {
                 byte[] record = makeSmsRecordData(status, pdu);
-                ((SIMFileHandler)mPhone.getIccFileHandler()).updateEFLinearFixed(
+                mPhone.getIccFileHandler().updateEFLinearFixed(
                         IccConstants.EF_SMS,
                         index, record, null, response);
             }
@@ -142,7 +146,8 @@
      */
     public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
         if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
-                "pdu=("+ pdu + "), smsm=(" + smsc +")");
+                "pdu=("+ Arrays.toString(pdu) +
+                "), smsm=(" + Arrays.toString(smsc) +")");
         enforceReceiveAndSend("Copying message to SIM");
         synchronized(mLock) {
             mSuccess = false;
@@ -175,8 +180,7 @@
                 "Reading messages from SIM");
         synchronized(mLock) {
             Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
-            ((SIMFileHandler)mPhone.getIccFileHandler()).loadEFLinearFixedAll(IccConstants.EF_SMS,
-                    response);
+            mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
 
             try {
                 mLock.wait();