Merge change 25943 into eclair

* changes:
  Fixed bug that wipes out the phone numbers in the call log.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6f6e3cd..97dad56 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -258,7 +258,7 @@
              temporary hack until we add better framework support. -->
         <activity
             android:name=".ui.FastTrackActivity"
-            android:theme="@style/FullyTranslucent">
+            android:theme="@style/FullyTranslucent.FastTrack">
 
             <intent-filter>
                 <action android:name="com.android.contacts.action.FAST_TRACK" />
diff --git a/res/anim/dummy_animation.xml b/res/anim/dummy_animation.xml
new file mode 100644
index 0000000..5b42f24
--- /dev/null
+++ b/res/anim/dummy_animation.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<translate
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromXDelta="0"
+    android:toXDelta="0"
+    android:duration="@android:integer/config_shortAnimTime" />
diff --git a/res/anim/fasttrack_above_enter.xml b/res/anim/fasttrack_above_enter.xml
new file mode 100644
index 0000000..dc2d053
--- /dev/null
+++ b/res/anim/fasttrack_above_enter.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <scale android:interpolator="@android:anim/decelerate_interpolator"
+            android:fromXScale="0.75" android:toXScale="1.0"
+            android:fromYScale="0.75" android:toYScale="1.0"
+            android:pivotX="50%" android:pivotY="100%"
+            android:duration="@android:integer/config_shortAnimTime" />
+    <alpha android:interpolator="@android:anim/decelerate_interpolator"
+            android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/res/anim/fasttrack_above_exit.xml b/res/anim/fasttrack_above_exit.xml
new file mode 100644
index 0000000..dd34f87
--- /dev/null
+++ b/res/anim/fasttrack_above_exit.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@android:anim/accelerate_interpolator">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+            android:fromYScale="1.0" android:toYScale=".5"
+            android:pivotX="50%" android:pivotY="100%"
+            android:duration="@android:integer/config_shortAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/res/anim/fasttrack_below_enter.xml b/res/anim/fasttrack_below_enter.xml
new file mode 100644
index 0000000..9a1a577
--- /dev/null
+++ b/res/anim/fasttrack_below_enter.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <scale android:interpolator="@android:anim/decelerate_interpolator"
+            android:fromXScale="0.75" android:toXScale="1.0"
+            android:fromYScale="0.75" android:toYScale="1.0"
+            android:pivotX="50%" android:pivotY="0%"
+            android:duration="@android:integer/config_shortAnimTime" />
+    <alpha android:interpolator="@android:anim/decelerate_interpolator"
+            android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/res/anim/fasttrack_below_exit.xml b/res/anim/fasttrack_below_exit.xml
new file mode 100644
index 0000000..7587c7a
--- /dev/null
+++ b/res/anim/fasttrack_below_exit.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@android:anim/accelerate_interpolator">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+            android:fromYScale="1.0" android:toYScale=".5"
+            android:pivotX="50%" android:pivotY="0%"
+            android:duration="@android:integer/config_shortAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/res/values/ids.xml b/res/values/ids.xml
index 7a5bba8..dbed28a 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -31,6 +31,7 @@
     <item type="id" name="dialog_import_export" />
 
     <!-- For ImportVCardActivity -->
+    <item type="id" name="dialog_searching_vcard" />
     <item type="id" name="dialog_sdcard_not_found" />
     <item type="id" name="dialog_vcard_not_found" />
     <item type="id" name="dialog_select_import_type" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index b656160..ad44b34 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -48,6 +48,14 @@
         <item name="android:windowContentOverlay">@null</item>
     </style>
 
+    <style name="FullyTranslucent.FastTrack">
+        <!-- This is a hack because we want to be able to animate away the
+             FastTrack window, and we close its containing activity at the
+             same time.  So put in a dummy animation so this guy sticks around
+             while the fast track window is animating. -->
+        <item name="android:windowAnimationStyle">@style/DummyAnimation</item>
+    </style>
+
     <style name="FastTrack">
         <item name="android:windowFrame">@null</item>
         <item name="android:windowBackground">@android:color/transparent</item>
@@ -59,4 +67,18 @@
         -->
     </style>
 
+    <style name="FastTrackAboveAnimation">
+        <item name="android:windowEnterAnimation">@anim/fasttrack_above_enter</item>
+        <item name="android:windowExitAnimation">@anim/fasttrack_above_exit</item>
+    </style>
+
+    <style name="FastTrackBelowAnimation">
+        <item name="android:windowEnterAnimation">@anim/fasttrack_below_enter</item>
+        <item name="android:windowExitAnimation">@anim/fasttrack_below_exit</item>
+    </style>
+
+    <style name="DummyAnimation">
+        <item name="android:windowExitAnimation">@anim/dummy_animation</item>
+    </style>
+
 </resources>
diff --git a/src/com/android/contacts/ImportVCardActivity.java b/src/com/android/contacts/ImportVCardActivity.java
index ad544c5..a3d5de5 100644
--- a/src/com/android/contacts/ImportVCardActivity.java
+++ b/src/com/android/contacts/ImportVCardActivity.java
@@ -95,12 +95,14 @@
     private static final String LOG_TAG = "ImportVCardActivity";
     private static final boolean DO_PERFORMANCE_PROFILE = false;
 
-    private ProgressDialog mProgressDialog;
     private Handler mHandler = new Handler();
     private Account mAccount;
 
+    private ProgressDialog mProgressDialogForScanVCard;
+
     private List<VCardFile> mAllVCardFileList;
     private VCardReadThread mVCardReadThread;
+    private ProgressDialog mProgressDialogForReadVCard;
 
     private class CancelListener
         implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
@@ -185,11 +187,11 @@
             // Even in such cases, some should be done.
             try {
                 if (mCanonicalPath != null) {  // Read one file
-                    mProgressDialog.setProgressNumberFormat("");
-                    mProgressDialog.setProgress(0);
+                    mProgressDialogForReadVCard.setProgressNumberFormat("");
+                    mProgressDialogForReadVCard.setProgress(0);
 
                     // Count the number of VCard entries
-                    mProgressDialog.setIndeterminate(true);
+                    mProgressDialogForReadVCard.setIndeterminate(true);
                     long start;
                     if (DO_PERFORMANCE_PROFILE) {
                         start = System.currentTimeMillis();
@@ -224,18 +226,18 @@
                         return;
                     }
 
-                    mProgressDialog.setProgressNumberFormat(
+                    mProgressDialogForReadVCard.setProgressNumberFormat(
                             getString(R.string.reading_vcard_contacts));
-                    mProgressDialog.setIndeterminate(false);
-                    mProgressDialog.setMax(counter.getCount());
+                    mProgressDialogForReadVCard.setIndeterminate(false);
+                    mProgressDialogForReadVCard.setMax(counter.getCount());
                     String charset = detector.getEstimatedCharset();
                     doActuallyReadOneVCard(mCanonicalPath, null, charset, true, detector,
                             mErrorFileNameList);
                 } else {  // Read multiple files.
-                    mProgressDialog.setProgressNumberFormat(
+                    mProgressDialogForReadVCard.setProgressNumberFormat(
                             getString(R.string.reading_vcard_files));
-                    mProgressDialog.setMax(mSelectedVCardFileList.size());
-                    mProgressDialog.setProgress(0);
+                    mProgressDialogForReadVCard.setMax(mSelectedVCardFileList.size());
+                    mProgressDialogForReadVCard.setProgress(0);
                     
                     for (VCardFile vcardFile : mSelectedVCardFileList) {
                         if (mCanceled) {
@@ -255,12 +257,12 @@
                         String charset = detector.getEstimatedCharset();
                         doActuallyReadOneVCard(canonicalPath, mAccount,
                                 charset, false, detector, mErrorFileNameList);
-                        mProgressDialog.incrementProgressBy(1);
+                        mProgressDialogForReadVCard.incrementProgressBy(1);
                     }
                 }
             } finally {
                 mWakeLock.release();
-                mProgressDialog.dismiss();
+                mProgressDialogForReadVCard.dismiss();
                 // finish() is called via ErrorDisplayer() on failure.
                 if (shouldCallFinish) {
                     if (mErrorFileNameList == null || mErrorFileNameList.isEmpty()) {
@@ -301,7 +303,7 @@
             }
             builder.addEntryHandler(new EntryCommitter(mResolver));
             if (showEntryParseProgress) {
-                builder.addEntryHandler(new ProgressShower(mProgressDialog,
+                builder.addEntryHandler(new ProgressShower(mProgressDialogForReadVCard,
                         context.getString(R.string.reading_vcard_message),
                         ImportVCardActivity.this,
                         mHandler));
@@ -352,7 +354,7 @@
             } catch (IOException e) {
                 Log.e(LOG_TAG, "IOException was emitted: " + e.getMessage());
 
-                mProgressDialog.dismiss();
+                mProgressDialogForReadVCard.dismiss();
 
                 if (errorFileNameList != null) {
                     errorFileNameList.add(canonicalPath);
@@ -387,12 +389,16 @@
             return true;
         }
 
-        public void onCancel(DialogInterface dialog) {
+        public void cancel() {
             mCanceled = true;
             if (mVCardParser != null) {
                 mVCardParser.cancel();
             }
         }
+
+        public void onCancel(DialogInterface dialog) {
+            cancel();
+        }
     }
 
     private class ImportTypeSelectedListener implements
@@ -523,7 +529,8 @@
                 mAllVCardFileList = null;
             }
 
-            mProgressDialog.dismiss();
+            mProgressDialogForScanVCard.dismiss();
+            mProgressDialogForScanVCard = null;
 
             if (mGotIOException) {
                 mHandler.post(new Runnable() {
@@ -686,14 +693,16 @@
     }
 
     private Dialog getReadingVCardDialog() {
-        String title = getString(R.string.reading_vcard_title);
-        String message = getString(R.string.reading_vcard_message);
-        mProgressDialog = new ProgressDialog(this);
-        mProgressDialog.setTitle(title);
-        mProgressDialog.setMessage(message);
-        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-        mProgressDialog.setOnCancelListener(mVCardReadThread);
-        return mProgressDialog;
+        if (mProgressDialogForReadVCard == null) {
+            String title = getString(R.string.reading_vcard_title);
+            String message = getString(R.string.reading_vcard_message);
+            mProgressDialogForReadVCard = new ProgressDialog(this);
+            mProgressDialogForReadVCard.setTitle(title);
+            mProgressDialogForReadVCard.setMessage(message);
+            mProgressDialogForReadVCard.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+            mProgressDialogForReadVCard.setOnCancelListener(mVCardReadThread);
+        }
+        return mProgressDialogForReadVCard;
     }
 
     @Override
@@ -717,6 +726,16 @@
     @Override
     protected Dialog onCreateDialog(int resId) {
         switch (resId) {
+            case R.id.dialog_searching_vcard: {
+                if (mProgressDialogForScanVCard != null) {
+                    return mProgressDialogForScanVCard;
+                } else {
+                    // It may happen in the complicated situation.
+                    // TODO: Investigate on this.
+                    Log.e(LOG_TAG, "Cached ProgressDialog object is null, which should not happen.");
+                    break;
+                }
+            }
             case R.id.dialog_sdcard_not_found: {
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
                     .setTitle(R.string.no_sdcard_title)
@@ -746,6 +765,7 @@
                 return getVCardFileSelectDialog(false);
             }
             case R.id.dialog_reading_vcard: {
+                // mVCardReadThread.start() must be called before.
                 return getReadingVCardDialog();
             }
             case R.id.dialog_io_exception: {
@@ -764,6 +784,19 @@
         return super.onCreateDialog(resId);
     }
 
+    @Override
+    protected void onStop() {
+        super.onStop();
+        if (mVCardReadThread != null) {
+            // The Activity is no longer visible. Stop the thread.
+            // TODO: The Activity may be destroyed without this method being called.
+            mVCardReadThread.cancel();
+            mVCardReadThread = null;
+        }
+    }
+
+    /* public methods */
+
     /**
      * Tries to start importing VCard. If there's no SDCard available,
      * an error dialog is shown. If there is, start scanning using another thread
@@ -775,13 +808,14 @@
         if (!file.exists() || !file.isDirectory() || !file.canRead()) {
             showDialog(R.id.dialog_sdcard_not_found);
         } else {
+            File sdcardDirectory = new File("/sdcard");
             String title = getString(R.string.searching_vcard_title);
             String message = getString(R.string.searching_vcard_message);
-
-            mProgressDialog = ProgressDialog.show(this, title, message, true, false);
-            VCardScanThread thread = new VCardScanThread(file);
-            mProgressDialog.setOnCancelListener(thread);
+            mProgressDialogForScanVCard = ProgressDialog.show(this, title, message, true, false);
+            VCardScanThread thread = new VCardScanThread(sdcardDirectory);
+            mProgressDialogForScanVCard.setOnCancelListener(thread);
             thread.start();
+            showDialog(R.id.dialog_searching_vcard);
         }
     }
 }
diff --git a/src/com/android/contacts/ui/FastTrackWindow.java b/src/com/android/contacts/ui/FastTrackWindow.java
index 630ecc4..d4aad19 100644
--- a/src/com/android/contacts/ui/FastTrackWindow.java
+++ b/src/com/android/contacts/ui/FastTrackWindow.java
@@ -310,12 +310,14 @@
             // edge with top of anchor area, and adjusting to inset arrow.
             showArrow(R.id.arrow_down, mAnchor.centerX());
             l.y = mAnchor.top - blockHeight + mShadowHeight;
+            l.windowAnimations = R.style.FastTrackAboveAnimation;
 
         } else {
             // Otherwise show upwards callout, aligning block top with bottom of
             // anchor area, and adjusting to inset arrow.
             showArrow(R.id.arrow_up, mAnchor.centerX());
             l.y = mAnchor.bottom - mShadowHeight;
+            l.windowAnimations = R.style.FastTrackBelowAnimation;
 
         }
 
@@ -338,6 +340,14 @@
             return;
         }
 
+        boolean hadDecor = mDecor != null;
+        
+        if (hadDecor) {
+            mWindowManager.removeView(mDecor);
+            mDecor = null;
+            mWindow.closeAllPanels();
+        }
+
         // Completely hide header from current mode
         mHeader.setVisibility(View.GONE);
 
@@ -360,16 +370,13 @@
         mHasSocial = false;
         mHasActions = false;
 
-        if (mDecor == null || !mShowing) {
+        if (!hadDecor || !mShowing) {
             Log.d(TAG, "not showing, ignore");
             return;
         }
 
-        mWindowManager.removeView(mDecor);
-        mDecor = null;
-        mWindow.closeAllPanels();
         mShowing = false;
-
+        
         // Notify any listeners that we've been dismissed
         if (mDismissListener != null) {
             mDismissListener.onDismiss(this);