Merge "Fix 'back to the first-level when recording'." into ics-mr1
diff --git a/res/drawable-hdpi/ic_gallery_play.png b/res/drawable-hdpi/ic_gallery_play.png
index 2ba9514..44e0c4e 100644
--- a/res/drawable-hdpi/ic_gallery_play.png
+++ b/res/drawable-hdpi/ic_gallery_play.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_gallery_play.png b/res/drawable-mdpi/ic_gallery_play.png
index 38010cf..19c4a79 100644
--- a/res/drawable-mdpi/ic_gallery_play.png
+++ b/res/drawable-mdpi/ic_gallery_play.png
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/ic_recording_indicator.png b/res/drawable-sw600dp-mdpi/ic_recording_indicator.png
deleted file mode 100644
index 9d168f1..0000000
--- a/res/drawable-sw600dp-mdpi/ic_recording_indicator.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_gallery_play.png b/res/drawable-xhdpi/ic_gallery_play.png
index 45c586b..f677b26 100644
--- a/res/drawable-xhdpi/ic_gallery_play.png
+++ b/res/drawable-xhdpi/ic_gallery_play.png
Binary files differ
diff --git a/res/drawable/border_preview.xml b/res/drawable/border_preview.xml
deleted file mode 100644
index 5835e2f..0000000
--- a/res/drawable/border_preview.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true" android:drawable="@drawable/ic_snapshot_border" />
-    <item android:drawable="@android:color/black" />
-</selector>
-
diff --git a/res/layout-sw600dp/mode_picker.xml b/res/layout-sw600dp/mode_picker.xml
index a77485d..cd562c8 100644
--- a/res/layout-sw600dp/mode_picker.xml
+++ b/res/layout-sw600dp/mode_picker.xml
@@ -38,18 +38,21 @@
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:scaleType="center"
+                    android:background="@drawable/bg_pressed"
                     android:src="@drawable/ic_switch_camera_holo_light" />
             <com.android.camera.ui.RotateImageView android:id="@+id/mode_video"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:scaleType="center"
+                    android:background="@drawable/bg_pressed"
                     android:src="@drawable/ic_switch_video_holo_light" />
             <com.android.camera.ui.RotateImageView android:id="@+id/mode_panorama"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:scaleType="center"
+                    android:background="@drawable/bg_pressed"
                     android:src="@drawable/ic_switch_pan_holo_light" />
         </LinearLayout>
 </com.android.camera.ModePicker>
diff --git a/res/layout-sw600dp/preview_frame_video.xml b/res/layout-sw600dp/preview_frame_video.xml
index 4e59c90..aab1ee1 100644
--- a/res/layout-sw600dp/preview_frame_video.xml
+++ b/res/layout-sw600dp/preview_frame_video.xml
@@ -22,11 +22,15 @@
     <com.android.camera.PreviewFrameLayout android:id="@+id/frame"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_centerInParent="true"
-            android:background="@drawable/border_preview">
+            android:layout_centerInParent="true">
         <SurfaceView android:id="@+id/camera_preview"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent" />
+        <FrameLayout android:id="@+id/preview_border"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone"
+            android:background="@drawable/ic_snapshot_border" />
         <com.android.camera.ui.RotateLayout android:id="@+id/recording_time_rect"
                 style="@style/ViewfinderLableLayout">
             <include layout="@layout/viewfinder_labels_video" android:id="@+id/labels_w1024" />
diff --git a/res/layout/camera.xml b/res/layout/camera.xml
index 939007a..19ce5f1 100644
--- a/res/layout/camera.xml
+++ b/res/layout/camera.xml
@@ -15,7 +15,6 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
         android:id="@+id/app_root"
         android:orientation="vertical"
         android:layout_width="match_parent"
diff --git a/res/layout/panorama.xml b/res/layout/panorama.xml
index d56cca0..1ff7601 100644
--- a/res/layout/panorama.xml
+++ b/res/layout/panorama.xml
@@ -22,5 +22,4 @@
 
     <include layout="@layout/pano_capture" />
     <include layout="@layout/pano_review" />
-    <include layout="@layout/pano_rotate_dialog" />
 </RelativeLayout>
diff --git a/res/layout/preview_frame_video.xml b/res/layout/preview_frame_video.xml
index 992eb46..43d1b5a 100644
--- a/res/layout/preview_frame_video.xml
+++ b/res/layout/preview_frame_video.xml
@@ -22,11 +22,15 @@
     <com.android.camera.PreviewFrameLayout android:id="@+id/frame"
             android:layout_height="match_parent"
             android:layout_width="match_parent"
-            android:layout_centerInParent="true"
-            android:background="@drawable/border_preview">
+            android:layout_centerInParent="true">
         <SurfaceView android:id="@+id/camera_preview"
-                android:layout_height="match_parent"
-                android:layout_width="match_parent" />
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+        <FrameLayout android:id="@+id/preview_border"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone"
+            android:background="@drawable/ic_snapshot_border" />
         <com.android.camera.ui.RotateLayout android:id="@+id/recording_time_rect"
                 style="@style/ViewfinderLableLayout">
 
diff --git a/res/layout/pano_rotate_dialog.xml b/res/layout/rotate_dialog.xml
similarity index 76%
rename from res/layout/pano_rotate_dialog.xml
rename to res/layout/rotate_dialog.xml
index 456bb02..3ca5283 100644
--- a/res/layout/pano_rotate_dialog.xml
+++ b/res/layout/rotate_dialog.xml
@@ -15,13 +15,16 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/rotate_dialog_root_layout"
+        android:clickable="true"
         android:gravity="center"
+        android:visibility="gone"
+        android:background="#55000000"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
     <com.android.camera.ui.RotateLayout
             android:id="@+id/rotate_dialog_layout"
-            android:visibility="gone"
             android:gravity="center"
             android:layout_gravity="center"
             android:layout_width="wrap_content"
@@ -87,16 +90,31 @@
                         android:showDividers="beginning"
                         android:dividerPadding="0dip">
 
-                    <Button android:id="@+id/rotate_dialog_button"
-                            style="@android:style/Widget.Holo.Button.Borderless"
-                            android:gravity="center"
-                            android:text="@string/review_ok"
-                            android:maxLines="2"
-                            android:minHeight="48dp"
-                            android:textSize="14sp"
-                            android:onClick="onAlertDialogButtonClicked"
+                    <LinearLayout
                             android:layout_width="match_parent"
-                            android:layout_height="wrap_content" />
+                            android:layout_height="wrap_content"
+                            android:gravity="center"
+                            android:orientation="horizontal">
+
+                        <Button android:id="@+id/rotate_dialog_button2"
+                                style="@android:style/Widget.Holo.Button.Borderless"
+                                android:gravity="center"
+                                android:maxLines="2"
+                                android:minHeight="48dp"
+                                android:textSize="14sp"
+                                android:layout_weight="1"
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content" />
+                        <Button android:id="@+id/rotate_dialog_button1"
+                                style="@android:style/Widget.Holo.Button.Borderless"
+                                android:gravity="center"
+                                android:maxLines="2"
+                                android:minHeight="48dp"
+                                android:textSize="14sp"
+                                android:layout_weight="1"
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content" />
+                    </LinearLayout>
                 </LinearLayout>
             </LinearLayout>
         </FrameLayout>
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index ed3f5da..a8f4d7b 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -30,8 +30,8 @@
         <item name="android:background">@drawable/bg_pressed</item>
     </style>
     <style name="ReviewControlIcon">
-        <item name="android:layout_width">75dp</item>
-        <item name="android:layout_height">50dp</item>
+        <item name="android:layout_height">32dp</item>
+        <item name="android:layout_width">32dp</item>
         <item name="android:gravity">center</item>
         <item name="android:layout_centerHorizontal">true</item>
         <item name="android:clickable">true</item>
@@ -41,8 +41,10 @@
     <style name="ReviewControlText">
         <item name="android:layout_height">wrap_content</item>
         <item name="android:layout_width">wrap_content</item>
+        <item name="android:paddingLeft">2dp</item>
         <item name="android:paddingRight">10dp</item>
-        <item name="android:textSize">16sp</item>
+        <item name="android:textSize">12sp</item>
+        <item name="android:textStyle">bold</item>
     </style>
     <style name="ReviewThumbnail">
         <item name="android:layout_width">86dp</item>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index f341e8c..d595c60 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -21,7 +21,8 @@
     <color name="recording_time_elapsed_text">#FFFFFFFF</color>
     <color name="recording_time_remaining_text">#FFFF0033</color>
     <color name="on_viewfinder_label_background_color">#77333333</color>
-    <color name="review_control_pressed_color">#FF6899FF</color>
+    <color name="review_control_pressed_color">#FF33B5E5</color>
+    <color name="review_control_pressed_fan_color">#3F33B5E5</color>
     <color name="icon_disabled_color">#DD777777</color>
     <color name="time_lapse_arc">#FFC5C5C5</color>
     <color name="dark_gray">#151515</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d1cde99..6fb9243 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -71,7 +71,7 @@
     <string name="review_cancel">CANCEL</string>
 
     <!-- button in review mode indicating that the taken photo/video is OK to be attached/uploaded [CHAR LIMIT=10] -->
-    <string name="review_ok">OK</string>
+    <string name="review_ok">DONE</string>
 
     <!-- button in review mode indicate the user want to retake another photo/video for attachment [CHAR LIMIT=10] -->
     <string name="review_retake">RETAKE</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index bc3c301..e1b30f5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -19,6 +19,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <style name="ThemeCamera" parent="android:Theme.Holo.NoActionBar.Fullscreen">
+        <item name="android:windowBackground">@android:color/black</item>
+        <item name="android:colorBackground">@android:color/black</item>
+        <item name="android:colorBackgroundCacheHint">@android:color/black</item>
     </style>
     <style name="OnScreenHintTextAppearance">
         <item name="android:textColor">@android:color/primary_text_dark</item>
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 1bd759b..9c7bbfe 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -63,6 +63,7 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.animation.AnimationUtils;
 import android.widget.TextView;
@@ -146,6 +147,7 @@
     private View mPreviewPanel;  // The container of PreviewFrameLayout.
     private PreviewFrameLayout mPreviewFrameLayout;
     private View mPreviewFrame;  // Preview frame area.
+    private RotateDialogController mRotateDialog;
 
     // A popup window that contains a bigger thumbnail and a list of apps to share.
     private SharePopup mSharePopup;
@@ -189,7 +191,7 @@
      *
      * TODO: consider publishing by moving into MediaStore.
      */
-    private final static String EXTRA_QUICK_CAPTURE =
+    private static final String EXTRA_QUICK_CAPTURE =
             "android.intent.extra.quickCapture";
 
     // The display rotation in degrees. This is only valid when mCameraState is
@@ -699,8 +701,6 @@
                     + mPictureDisplayedToJpegCallbackTime + "ms");
 
             if (!mIsImageCaptureIntent) {
-                enableCameraControls(true);
-
                 startPreview();
                 startFaceDetection();
             }
@@ -739,12 +739,8 @@
 
             mAutoFocusTime = System.currentTimeMillis() - mFocusStartTime;
             Log.v(TAG, "mAutoFocusTime = " + mAutoFocusTime + "ms");
+            setCameraState(IDLE);
             mFocusManager.onAutoFocus(focused);
-            // If focus completes and the snapshot is not started, enable the
-            // controls.
-            if (mFocusManager.isFocusCompleted()) {
-                enableCameraControls(true);
-            }
         }
     }
 
@@ -954,6 +950,20 @@
         }
     }
 
+    private void setCameraState(int state) {
+        mCameraState = state;
+        switch (state) {
+            case SNAPSHOT_IN_PROGRESS:
+            case FOCUSING:
+                enableCameraControls(false);
+                break;
+            case IDLE:
+            case PREVIEW_STOPPED:
+                enableCameraControls(true);
+                break;
+        }
+    }
+
     @Override
     public boolean capture() {
         // If we are already in the middle of taking a snapshot then ignore.
@@ -962,7 +972,6 @@
         }
         mCaptureStartTime = System.currentTimeMillis();
         mPostViewPictureCallbackTime = 0;
-        enableCameraControls(false);
         mJpegImageData = null;
 
         // Set rotation and gps data.
@@ -973,7 +982,7 @@
 
         mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback,
                 mPostViewPictureCallback, new JpegPictureCallback(loc));
-        mCameraState = SNAPSHOT_IN_PROGRESS;
+        setCameraState(SNAPSHOT_IN_PROGRESS);
         return true;
     }
 
@@ -1052,6 +1061,8 @@
             mThumbnailView.setVisibility(View.VISIBLE);
         }
 
+        mRotateDialog = new RotateDialogController(this, R.layout.rotate_dialog);
+
         mPreferences.setLocalId(this, mCameraId);
         CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
 
@@ -1225,7 +1236,7 @@
     private void setOrientationIndicator(int orientation) {
         Rotatable[] indicators = {mThumbnailView, mModePicker, mSharePopup,
                 mIndicatorControlContainer, mZoomControl, mFocusIndicator, mFaceView,
-                mReviewCancelButton, mReviewDoneButton};
+                mReviewCancelButton, mReviewDoneButton, mRotateDialog};
         for (Rotatable indicator : indicators) {
             if (indicator != null) indicator.setOrientation(orientation);
         }
@@ -1440,7 +1451,6 @@
         if (mOpenCameraFail || mCameraDisabled) return;
 
         mPausing = false;
-
         mJpegPictureCallbackTime = 0;
         mZoomValue = 0;
 
@@ -1559,15 +1569,13 @@
     public void autoFocus() {
         mFocusStartTime = System.currentTimeMillis();
         mCameraDevice.autoFocus(mAutoFocusCallback);
-        mCameraState = FOCUSING;
-        enableCameraControls(false);
+        setCameraState(FOCUSING);
     }
 
     @Override
     public void cancelAutoFocus() {
         mCameraDevice.cancelAutoFocus();
-        mCameraState = IDLE;
-        enableCameraControls(true);
+        setCameraState(IDLE);
         setCameraParameters(UPDATE_PARAM_PREFERENCE);
     }
 
@@ -1713,7 +1721,7 @@
             mCameraDevice.setFaceDetectionListener(null);
             mCameraDevice.setErrorCallback(null);
             mCameraDevice = null;
-            mCameraState = PREVIEW_STOPPED;
+            setCameraState(PREVIEW_STOPPED);
             mFocusManager.onCameraReleased();
         }
     }
@@ -1774,7 +1782,7 @@
         }
 
         mZoomState = ZOOM_STOPPED;
-        mCameraState = IDLE;
+        setCameraState(IDLE);
         mFocusManager.onPreviewStarted();
 
         if (mSnapshotOnIdle) {
@@ -1788,7 +1796,7 @@
             mCameraDevice.cancelAutoFocus(); // Reset the focus.
             mCameraDevice.stopPreview();
         }
-        mCameraState = PREVIEW_STOPPED;
+        setCameraState(PREVIEW_STOPPED);
         mFocusManager.onPreviewStopped();
     }
 
@@ -2029,8 +2037,6 @@
 
     private void hidePostCaptureAlert() {
         if (mIsImageCaptureIntent) {
-            enableCameraControls(true);
-
             int[] pickIds = {R.id.btn_retake, R.id.btn_done};
             for (int id : pickIds) {
                 Util.fadeOut(findViewById(id));
@@ -2161,10 +2167,11 @@
                 restorePreferences();
             }
         };
-        MenuHelper.confirmAction(this,
+        mRotateDialog.showAlertDialog(
                 getString(R.string.confirm_restore_title),
                 getString(R.string.confirm_restore_message),
-                runnable);
+                getString(android.R.string.ok), runnable,
+                getString(android.R.string.cancel), null);
     }
 
     private void restorePreferences() {
diff --git a/src/com/android/camera/ModePicker.java b/src/com/android/camera/ModePicker.java
index ccde71d..b79baa5 100644
--- a/src/com/android/camera/ModePicker.java
+++ b/src/com/android/camera/ModePicker.java
@@ -223,10 +223,13 @@
     }
 
     private void updateModeState() {
-        // Grey-out the unselected icons.
-        for (int i = 0; i < MODE_NUM; ++i) {
-            highlightView(mModeSelectionIcon[i], (i == mCurrentMode));
+        // Grey-out the unselected icons for Phone UI.
+        if (mCurrentModeFrame != null) {
+            for (int i = 0; i < MODE_NUM; ++i) {
+                highlightView(mModeSelectionIcon[i], (i == mCurrentMode));
+            }
         }
+
         // Update the current mode icons on the Phone UI. The selected mode
         // should be in the center of the current mode icon bar.
         if (mCurrentModeFrame != null) {
diff --git a/src/com/android/camera/PreviewFrameLayout.java b/src/com/android/camera/PreviewFrameLayout.java
index 8429259..c16961a 100644
--- a/src/com/android/camera/PreviewFrameLayout.java
+++ b/src/com/android/camera/PreviewFrameLayout.java
@@ -16,9 +16,12 @@
 
 package com.android.camera;
 
+import com.android.camera.R;
+
 import android.app.Activity;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.view.View;
 import android.util.AttributeSet;
 import android.widget.RelativeLayout;
 /**
@@ -52,10 +55,10 @@
     }
 
     public void showBorder(boolean enabled) {
-        setActivated(enabled);
+        findViewById(R.id.preview_border).setVisibility(
+                enabled ? View.VISIBLE : View.INVISIBLE);
     }
 
-
     @Override
     protected void onMeasure(int widthSpec, int heightSpec) {
         int previewWidth = MeasureSpec.getSize(widthSpec);
diff --git a/src/com/android/camera/RotateDialogController.java b/src/com/android/camera/RotateDialogController.java
new file mode 100644
index 0000000..d91ba13
--- /dev/null
+++ b/src/com/android/camera/RotateDialogController.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2011 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 com.android.camera;
+
+import com.android.camera.ui.Rotatable;
+import com.android.camera.ui.RotateLayout;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.ProgressBar;
+
+public class RotateDialogController implements Rotatable {
+
+    private static final String TAG = "RotateDialogController";
+    private static final long ANIM_DURATION = 150;  // millis
+
+    private Activity mActivity;
+    private int mLayoutResourceID;
+    private View mDialogRootLayout;
+    private RotateLayout mRotateDialog;
+    private View mRotateDialogTitleLayout;
+    private View mRotateDialogButtonLayout;
+    private TextView mRotateDialogTitle;
+    private ProgressBar mRotateDialogSpinner;
+    private TextView mRotateDialogText;
+    private TextView mRotateDialogButton1;
+    private TextView mRotateDialogButton2;
+
+    private Animation mFadeInAnim, mFadeOutAnim;
+
+    public RotateDialogController(Activity a, int layoutResource) {
+        mActivity = a;
+        mLayoutResourceID = layoutResource;
+    }
+
+    private void inflateDialogLayout() {
+        if (mDialogRootLayout == null) {
+            ViewGroup layoutRoot = (ViewGroup) mActivity.getWindow().getDecorView();
+            LayoutInflater inflater = mActivity.getLayoutInflater();
+            View v = inflater.inflate(mLayoutResourceID, layoutRoot);
+            mDialogRootLayout = v.findViewById(R.id.rotate_dialog_root_layout);
+            mRotateDialog = (RotateLayout) v.findViewById(R.id.rotate_dialog_layout);
+            mRotateDialogTitleLayout = v.findViewById(R.id.rotate_dialog_title_layout);
+            mRotateDialogButtonLayout = v.findViewById(R.id.rotate_dialog_button_layout);
+            mRotateDialogTitle = (TextView) v.findViewById(R.id.rotate_dialog_title);
+            mRotateDialogSpinner = (ProgressBar) v.findViewById(R.id.rotate_dialog_spinner);
+            mRotateDialogText = (TextView) v.findViewById(R.id.rotate_dialog_text);
+            mRotateDialogButton1 = (Button) v.findViewById(R.id.rotate_dialog_button1);
+            mRotateDialogButton2 = (Button) v.findViewById(R.id.rotate_dialog_button2);
+
+            mFadeInAnim = AnimationUtils.loadAnimation(
+                    mActivity, android.R.anim.fade_in);
+            mFadeOutAnim = AnimationUtils.loadAnimation(
+                    mActivity, android.R.anim.fade_out);
+            mFadeInAnim.setDuration(ANIM_DURATION);
+            mFadeOutAnim.setDuration(ANIM_DURATION);
+        }
+    }
+
+    @Override
+    public void setOrientation(int orientation) {
+        inflateDialogLayout();
+        mRotateDialog.setOrientation(orientation);
+    }
+
+    public void resetRotateDialog() {
+        inflateDialogLayout();
+        mRotateDialogTitleLayout.setVisibility(View.GONE);
+        mRotateDialogSpinner.setVisibility(View.GONE);
+        mRotateDialogButton1.setVisibility(View.GONE);
+        mRotateDialogButton2.setVisibility(View.GONE);
+        mRotateDialogButtonLayout.setVisibility(View.GONE);
+    }
+
+    private void fadeOutDialog() {
+        mDialogRootLayout.startAnimation(mFadeOutAnim);
+        mDialogRootLayout.setVisibility(View.GONE);
+    }
+
+    private void fadeInDialog() {
+        mDialogRootLayout.startAnimation(mFadeInAnim);
+        mDialogRootLayout.setVisibility(View.VISIBLE);
+    }
+
+    public void dismissDialog() {
+        if (mDialogRootLayout != null && mDialogRootLayout.getVisibility() != View.GONE) {
+            fadeOutDialog();
+        }
+    }
+
+    public void showAlertDialog(String title, String msg, String button1Text,
+                final Runnable r1, String button2Text, final Runnable r2) {
+        resetRotateDialog();
+
+        mRotateDialogTitle.setText(title);
+        mRotateDialogTitleLayout.setVisibility(View.VISIBLE);
+
+        mRotateDialogText.setText(msg);
+
+        if (button1Text != null) {
+            mRotateDialogButton1.setText(button1Text);
+            mRotateDialogButton1.setVisibility(View.VISIBLE);
+            mRotateDialogButton1.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (r1 != null) r1.run();
+                    dismissDialog();
+                }
+            });
+            mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
+        }
+        if (button2Text != null) {
+            mRotateDialogButton2.setText(button2Text);
+            mRotateDialogButton2.setVisibility(View.VISIBLE);
+            mRotateDialogButton2.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (r2 != null) r2.run();
+                    dismissDialog();
+                }
+            });
+            mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
+        }
+
+        fadeInDialog();
+    }
+
+    public void showWaitingDialog(String msg) {
+        resetRotateDialog();
+
+        mRotateDialogText.setText(msg);
+        mRotateDialogSpinner.setVisibility(View.VISIBLE);
+
+        fadeInDialog();
+    }
+
+}
diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java
index ab220de..8b9c65a 100755
--- a/src/com/android/camera/panorama/PanoramaActivity.java
+++ b/src/com/android/camera/panorama/PanoramaActivity.java
@@ -25,6 +25,7 @@
 import com.android.camera.ModePicker;
 import com.android.camera.OnClickAttr;
 import com.android.camera.R;
+import com.android.camera.RotateDialogController;
 import com.android.camera.ShutterButton;
 import com.android.camera.SoundPlayer;
 import com.android.camera.Storage;
@@ -35,11 +36,8 @@
 import com.android.camera.ui.RotateLayout;
 import com.android.camera.ui.SharePopup;
 
-import android.app.Dialog;
-import android.app.ProgressDialog;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.res.AssetFileDescriptor;
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
@@ -50,7 +48,6 @@
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 import android.graphics.YuvImage;
-import android.hardware.Camera;
 import android.hardware.Camera.Parameters;
 import android.hardware.Camera.Size;
 import android.hardware.Sensor;
@@ -63,23 +60,18 @@
 import android.os.SystemProperties;
 import android.util.Log;
 import android.view.Gravity;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.OrientationEventListener;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
-import android.widget.Button;
 import android.widget.ImageView;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
 import java.io.File;
 import java.util.List;
-import java.util.Vector;
 
 /**
  * Activity to handle panorama capturing.
@@ -131,15 +123,6 @@
     private ShutterButton mShutterButton;
     private Object mWaitObject = new Object();
 
-    private RotateLayout mRotateDialog;
-    private View mRotateDialogTitleLayout;
-    private View mRotateDialogButtonLayout;
-    private TextView mRotateDialogTitle;
-    private View mRotateDialogTitleSeperator;
-    private ProgressBar mRotateDialogSpinner;
-    private TextView mRotateDialogText;
-    private TextView mRotateDialogButton;
-
     private String mPreparePreviewString;
     private String mDialogTitle;
     private String mDialogOkString;
@@ -196,6 +179,8 @@
     private int mDeviceOrientation;
     private int mOrientationCompensation;
 
+    private RotateDialogController mRotateDialog;
+
     private class MosaicJpeg {
         public MosaicJpeg(byte[] data, int width, int height) {
             this.data = data;
@@ -316,8 +301,14 @@
                         if (mPausing) {
                             resetToPreview();
                         } else {
-                            showAlertDialog(
-                                    mDialogTitle, mDialogPanoramaFailedString, mDialogOkString);
+                            mRotateDialog.showAlertDialog(
+                                    mDialogTitle, mDialogPanoramaFailedString,
+                                    mDialogOkString, new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            resetToPreview();
+                                        }},
+                                    null, null);
                         }
                         break;
                     case MSG_RESET_TO_PREVIEW:
@@ -334,12 +325,6 @@
         };
     }
 
-    @OnClickAttr
-    public void onAlertDialogButtonClicked(View v) {
-        dismissDialog();
-        resetToPreview();
-    }
-
     private void setupCamera() {
         openCamera();
         Parameters parameters = mCameraDevice.getParameters();
@@ -604,7 +589,7 @@
         mSurfaceTexture.setOnFrameAvailableListener(null);
 
         if (!aborted && !mThreadRunning) {
-            showWaitingDialog(mPreparePreviewString);
+            mRotateDialog.showWaitingDialog(mPreparePreviewString);
             runBackgroundThread(new Thread() {
                 @Override
                 public void run() {
@@ -716,14 +701,7 @@
 
         mPanoLayout = findViewById(R.id.pano_layout);
 
-        mRotateDialog = (RotateLayout) findViewById(R.id.rotate_dialog_layout);
-        mRotateDialogTitleLayout = findViewById(R.id.rotate_dialog_title_layout);
-        mRotateDialogButtonLayout = findViewById(R.id.rotate_dialog_button_layout);
-        mRotateDialogTitle = (TextView) findViewById(R.id.rotate_dialog_title);
-        mRotateDialogTitleSeperator = (View) findViewById(R.id.rotate_dialog_title_divider);
-        mRotateDialogSpinner = (ProgressBar) findViewById(R.id.rotate_dialog_spinner);
-        mRotateDialogText = (TextView) findViewById(R.id.rotate_dialog_text);
-        mRotateDialogButton = (Button) findViewById(R.id.rotate_dialog_button);
+        mRotateDialog = new RotateDialogController(this, R.layout.rotate_dialog);
 
         if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
             Rotatable[] rotateLayout = {
@@ -733,7 +711,9 @@
                     (Rotatable) findViewById(R.id.pano_saving_progress_bar_layout),
                     (Rotatable) findViewById(R.id.pano_review_cancel_button_layout),
                     (Rotatable) mRotateDialog,
-                    (Rotatable) mCaptureIndicator};
+                    (Rotatable) mCaptureIndicator,
+                    (Rotatable) mModePicker,
+                    (Rotatable) mThumbnailView};
             for (Rotatable r : rotateLayout) {
                 r.setOrientation(270);
             }
@@ -845,41 +825,6 @@
         reportProgress();
     }
 
-    private void resetRotateDialog() {
-        mRotateDialogTitleLayout.setVisibility(View.GONE);
-        mRotateDialogSpinner.setVisibility(View.GONE);
-        mRotateDialogButtonLayout.setVisibility(View.GONE);
-    }
-
-    private void dismissDialog() {
-        if (mRotateDialog.getVisibility() != View.INVISIBLE) {
-            mRotateDialog.setVisibility(View.INVISIBLE);
-        }
-    }
-
-    private void showAlertDialog(String title, String msg, String buttonText) {
-        resetRotateDialog();
-
-        mRotateDialogTitle.setText(title);
-        mRotateDialogTitleLayout.setVisibility(View.VISIBLE);
-
-        mRotateDialogText.setText(msg);
-
-        mRotateDialogButton.setText(buttonText);
-        mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
-
-        mRotateDialog.setVisibility(View.VISIBLE);
-    }
-
-    private void showWaitingDialog(String msg) {
-        resetRotateDialog();
-
-        mRotateDialogText.setText(msg);
-        mRotateDialogSpinner.setVisibility(View.VISIBLE);
-
-        mRotateDialog.setVisibility(View.VISIBLE);
-    }
-
     private void runBackgroundThread(Thread thread) {
         mThreadRunning = true;
         thread.start();
@@ -887,7 +832,7 @@
 
     private void onBackgroundThreadFinished() {
         mThreadRunning = false;
-        dismissDialog();
+        mRotateDialog.dismissDialog();
     }
 
     private void cancelHighResComputation() {
diff --git a/src/com/android/camera/ui/IndicatorControlWheel.java b/src/com/android/camera/ui/IndicatorControlWheel.java
index 4e0e5f4..3b8bea4 100644
--- a/src/com/android/camera/ui/IndicatorControlWheel.java
+++ b/src/com/android/camera/ui/IndicatorControlWheel.java
@@ -24,6 +24,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.graphics.RectF;
 import android.os.Handler;
 import android.os.SystemClock;
@@ -65,6 +66,7 @@
     private static final int TIME_LAPSE_ARC_WIDTH = 6;
 
     private final int HIGHLIGHT_COLOR;
+    private final int HIGHLIGHT_FAN_COLOR;
     private final int TIME_LAPSE_ARC_COLOR;
 
     // The center of the shutter button.
@@ -115,6 +117,7 @@
         super(context, attrs);
         Resources resources = context.getResources();
         HIGHLIGHT_COLOR = resources.getColor(R.color.review_control_pressed_color);
+        HIGHLIGHT_FAN_COLOR = resources.getColor(R.color.review_control_pressed_fan_color);
         TIME_LAPSE_ARC_COLOR = resources.getColor(R.color.time_lapse_arc);
 
         setWillNotDraw(false);
@@ -419,19 +422,35 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        // Draw highlight.
-        float delta = mStrokeWidth * 0.5f;
-        float radius = (float) (mWheelRadius + mStrokeWidth * 0.5 + EDGE_STROKE_WIDTH);
-        mBackgroundRect.set(mCenterX - radius, mCenterY - radius, mCenterX + radius,
-                 mCenterY + radius);
-
         int selectedIndex = getSelectedIndicatorIndex();
 
         // Draw the highlight arc if an indicator is selected or being pressed.
-       if (selectedIndex >= 0) {
+        if (selectedIndex >= 0) {
             int degree = (int) Math.toDegrees(mChildRadians[selectedIndex]);
+            float innerR = (float) mShutterButtonRadius;
+            float outerR = (float) (mShutterButtonRadius + mStrokeWidth +
+                    EDGE_STROKE_WIDTH * 0.5);
+
+            // Construct the path of the fan-shaped semi-transparent area.
+            Path fanPath = new Path();
+            mBackgroundRect.set(mCenterX - innerR, mCenterY - innerR,
+                    mCenterX + innerR, mCenterY + innerR);
+            fanPath.arcTo(mBackgroundRect, -degree + HIGHLIGHT_DEGREES / 2,
+                    -HIGHLIGHT_DEGREES);
+            mBackgroundRect.set(mCenterX - outerR, mCenterY - outerR,
+                    mCenterX + outerR, mCenterY + outerR);
+            fanPath.arcTo(mBackgroundRect, -degree - HIGHLIGHT_DEGREES / 2,
+                    HIGHLIGHT_DEGREES);
+            fanPath.close();
+
             mBackgroundPaint.setStrokeWidth(HIGHLIGHT_WIDTH);
-            mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND);
+            mBackgroundPaint.setStrokeCap(Paint.Cap.SQUARE);
+            mBackgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+            mBackgroundPaint.setColor(HIGHLIGHT_FAN_COLOR);
+            canvas.drawPath(fanPath, mBackgroundPaint);
+
+            // Draw the highlight edge
+            mBackgroundPaint.setStyle(Paint.Style.STROKE);
             mBackgroundPaint.setColor(HIGHLIGHT_COLOR);
             canvas.drawArc(mBackgroundRect, -degree - HIGHLIGHT_DEGREES / 2,
                     HIGHLIGHT_DEGREES, false, mBackgroundPaint);