Merge change 8098 into donut

* changes:
  cast is floor. Use round instead.  This fixes a few layout issues (that was due to smaller widnow size)
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 444f222..9432755 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -788,6 +788,11 @@
         final SearchManager searchManager = (SearchManager) mContext
                 .getSystemService(Context.SEARCH_SERVICE);
 
+        // can't start search without an associated activity (e.g a system dialog)
+        if (!searchManager.hasIdent()) {
+            return false;
+        }
+
         // associate search with owner activity if possible (otherwise it will default to
         // global search).
         final ComponentName appName = mOwnerActivity == null ? null
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index c98d966..0631ad5 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1536,6 +1536,10 @@
         mService = ISearchManager.Stub.asInterface(
                 ServiceManager.getService(Context.SEARCH_SERVICE));
     }
+
+    /*package*/ boolean hasIdent() {
+        return mIdent != 0;
+    }
     
     /*package*/ void setIdent(int ident) {
         if (mIdent != 0) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b0dbfcb..a5f298c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4513,6 +4513,9 @@
      * and {@link #FILL_IN_COMPONENT} to override the restriction where the
      * corresponding field will not be replaced if it is already set.
      *
+     * <p>Note: The component field will only be copied if {@link #FILL_IN_COMPONENT} is explicitly
+     * specified.
+     *
      * <p>For example, consider Intent A with {data="foo", categories="bar"}
      * and Intent B with {action="gotit", data-type="some/thing",
      * categories="one","two"}.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d8ed4f0..3fab692 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2443,7 +2443,13 @@
         }
 
         if (ss.error != null) {
-            setError(ss.error);
+            final CharSequence error = ss.error;
+            // Display the error later, after the first layout pass
+            post(new Runnable() {
+                public void run() {
+                    setError(error);
+                }
+            });
         }
     }
 
@@ -3263,7 +3269,9 @@
             final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
                     null);
 
-            mPopup = new ErrorPopup(err, 200, 50);
+            final float scale = getResources().getDisplayMetrics().density;
+            mPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f),
+                    (int) (50 * scale + 0.5f));
             mPopup.setFocusable(false);
             // The user is entering text, so the input method is needed.  We
             // don't want the popup to be displayed on top of it.
@@ -3317,11 +3325,12 @@
          * The "25" is the distance between the point and the right edge
          * of the background
          */
+        final float scale = getResources().getDisplayMetrics().density;
 
         final Drawables dr = mDrawables;
         return getWidth() - mPopup.getWidth()
                 - getPaddingRight()
-                - (dr != null ? dr.mDrawableSizeRight : 0) / 2 + 25;
+                - (dr != null ? dr.mDrawableSizeRight : 0) / 2 + (int) (25 * scale + 0.5f);
     }
 
     /**
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index c96cd4f..79418bd 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -53,6 +53,7 @@
     public static final String TITLE_USER_CERT = "User Certificate";
     public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
     public static final String TITLE_PRIVATE_KEY = "Private Key";
+    public static final int INCORRECT_PKCS12_PASSPHRASE = -100;
 
     private static final String TAG = "CertTool";
     private static final String UNKNOWN = "Unknown";
@@ -143,30 +144,47 @@
         intent.putExtra(KEY_NAMESPACE + "1", namespace);
     }
 
-    public int addPkcs12Keystore(byte[] p12Data, String password,
-            String keyname) {
-        int handle, i = 0;
+    private int extractAndStoreKeysFromPkcs12(int handle, String keyname) {
+        int ret, i = 0;
         String pemData;
-        Log.i("CertTool", "addPkcs12Keystore()");
 
-        if ((handle = getPkcs12Handle(p12Data, password)) == 0) return -1;
         if ((pemData = getPkcs12Certificate(handle)) != null) {
-            sKeystore.put(USER_CERTIFICATE, keyname, pemData);
+            if ((ret = sKeystore.put(USER_CERTIFICATE, keyname, pemData)) != 0) {
+                return ret;
+            }
         }
         if ((pemData = getPkcs12PrivateKey(handle)) != null) {
-            sKeystore.put(USER_KEY, keyname, pemData);
+            if ((ret = sKeystore.put(USER_KEY, keyname, pemData)) != 0) {
+                return ret;
+            }
         }
         while ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
             if (i++ > 0) {
-                sKeystore.put(CA_CERTIFICATE, keyname + i, pemData);
+                if ((ret = sKeystore.put(CA_CERTIFICATE, keyname + i, pemData)) != 0) {
+                    return ret;
+                }
             } else {
-                sKeystore.put(CA_CERTIFICATE, keyname, pemData);
+                if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
+                    return ret;
+                }
             }
         }
-        freePkcs12Handle(handle);
         return 0;
     }
 
+    public int addPkcs12Keystore(byte[] p12Data, String password,
+            String keyname) {
+        int handle, ret;
+        Log.i("CertTool", "addPkcs12Keystore()");
+
+        if ((handle = getPkcs12Handle(p12Data, password)) == 0) {
+            return INCORRECT_PKCS12_PASSPHRASE;
+        }
+        ret = extractAndStoreKeysFromPkcs12(handle, keyname);
+        freePkcs12Handle(handle);
+        return ret;
+    }
+
     public synchronized void addCertificate(byte[] data, Context context) {
         int handle;
         Intent intent = null;
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 82067be..8c83fad 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -65,9 +65,9 @@
 // ----------------------------------------------------------------------------
 class SynthProxyJniStorage {
     public :
-        //jclass                    tts_class;
         jobject                   tts_ref;
         TtsEngine*                mNativeSynthInterface;
+        void*                     mEngineLibHandle;
         AudioTrack*               mAudioOut;
         AudioSystem::stream_type  mStreamType;
         uint32_t                  mSampleRate;
@@ -77,9 +77,9 @@
         size_t                    mBufferSize;
 
         SynthProxyJniStorage() {
-            //tts_class = NULL;
             tts_ref = NULL;
             mNativeSynthInterface = NULL;
+            mEngineLibHandle = NULL;
             mAudioOut = NULL;
             mStreamType = DEFAULT_TTS_STREAM_TYPE;
             mSampleRate = DEFAULT_TTS_RATE;
@@ -91,11 +91,17 @@
         }
 
         ~SynthProxyJniStorage() {
+            //LOGV("entering ~SynthProxyJniStorage()");
             killAudio();
             if (mNativeSynthInterface) {
                 mNativeSynthInterface->shutdown();
                 mNativeSynthInterface = NULL;
             }
+            if (mEngineLibHandle) {
+                //LOGE("~SynthProxyJniStorage(): before close library");
+                int res = dlclose(mEngineLibHandle);
+                LOGE_IF( res != 0, "~SynthProxyJniStorage(): dlclose returned %d", res);
+            }
             delete mBuffer;
         }
 
@@ -138,13 +144,13 @@
                     0, 0, 0, 0); // not using an AudioTrack callback
 
             if (mAudioOut->initCheck() != NO_ERROR) {
-              LOGI("AudioTrack error");
+              LOGE("createAudioOut(): AudioTrack error");
               delete mAudioOut;
               mAudioOut = NULL;
             } else {
               //LOGI("AudioTrack OK");
               mAudioOut->start();
-              LOGI("AudioTrack started");
+              LOGV("AudioTrack started");
             }
         }
 };
@@ -259,16 +265,18 @@
 
     void *engine_lib_handle = dlopen(nativeSoLibNativeString,
             RTLD_NOW | RTLD_LOCAL);
-    if (engine_lib_handle==NULL) {
-       LOGI("engine_lib_handle==NULL");
+    if (engine_lib_handle == NULL) {
+       LOGE("android_tts_SynthProxy_native_setup(): engine_lib_handle == NULL");
        // TODO report error so the TTS can't be used
     } else {
         TtsEngine *(*get_TtsEngine)() =
             reinterpret_cast<TtsEngine* (*)()>(dlsym(engine_lib_handle, "getTtsEngine"));
 
         pJniStorage->mNativeSynthInterface = (*get_TtsEngine)();
+        pJniStorage->mEngineLibHandle = engine_lib_handle;
 
         if (pJniStorage->mNativeSynthInterface) {
+            Mutex::Autolock l(engineMutex);
             pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB);
         }
     }
@@ -287,11 +295,29 @@
 static void
 android_tts_SynthProxy_native_finalize(JNIEnv *env, jobject thiz, jint jniData)
 {
-    if (jniData) {
-        SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
-        env->DeleteGlobalRef(pSynthData->tts_ref);
-        delete pSynthData;
+    //LOGV("entering android_tts_SynthProxy_finalize()");
+    if (jniData == 0) {
+        //LOGE("android_tts_SynthProxy_native_finalize(): invalid JNI data");
+        return;
     }
+
+    Mutex::Autolock l(engineMutex);
+
+    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+    env->DeleteGlobalRef(pSynthData->tts_ref);
+    delete pSynthData;
+
+    env->SetIntField(thiz, javaTTSFields.synthProxyFieldJniData, 0);
+}
+
+
+static void
+android_tts_SynthProxy_shutdown(JNIEnv *env, jobject thiz, jint jniData)
+{
+    //LOGV("entering android_tts_SynthProxy_shutdown()");
+
+    // do everything a call to finalize would
+    android_tts_SynthProxy_native_finalize(env, thiz, jniData);
 }
 
 
@@ -604,24 +630,6 @@
 }
 
 
-static void
-android_tts_SynthProxy_shutdown(JNIEnv *env, jobject thiz, jint jniData)
-{
-    if (jniData == 0) {
-        LOGE("android_tts_SynthProxy_shutdown(): invalid JNI data");
-        return;
-    }
-
-    Mutex::Autolock l(engineMutex);
-
-    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
-    if (pSynthData->mNativeSynthInterface) {
-        pSynthData->mNativeSynthInterface->shutdown();
-        pSynthData->mNativeSynthInterface = NULL;
-    }
-}
-
-
 static jobjectArray
 android_tts_SynthProxy_getLanguage(JNIEnv *env, jobject thiz, jint jniData)
 {
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index cfefcb7..e52ba80 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -174,6 +174,7 @@
         cleanUpPlayer();
 
         sNativeSynth.shutdown();
+        sNativeSynth = null;
 
         // Unregister all callbacks.
         mCallbacks.kill();
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index 26322f4..87bd780 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -161,6 +161,7 @@
 
     synchronized void onDisconnect(boolean cleanUpServices) {
         try {
+            Log.d(TAG, "       disconnecting VPN...");
             mState = VpnState.DISCONNECTING;
             broadcastConnectivity(VpnState.DISCONNECTING);
             mNotification.showDisconnect();
@@ -217,6 +218,8 @@
                 synchronized (VpnService.this) {
                     if (mState == VpnState.CONNECTING) {
                         Log.d(TAG, "       connecting timed out !!");
+                        mError = newConnectingError(
+                                new IOException("Connecting timed out"));
                         onError();
                     }
                 }