From 786ff4f4ca2374bdd9177f2e24b503d43e7a3b93 Mon Sep 17 00:00:00 2001
From: liyujie <2352380935@qq.com>
Date: Thu, 28 Aug 2025 12:04:21 +0000
Subject: [PATCH] [4/4]解决USB摄像头打开相机预览界面绿屏

---
 android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandler.java                               |    8 +
 android/packages/apps/Camera2/src/com/android/camera/settings/CameraSettingsActivity.java                 |   47 +++++-
 android/packages/apps/Camera2/src/com/android/camera/VideoModule.java                                     |    4 
 android/packages/apps/Camera2/src/com/android/camera/settings/SettingsUtil.java                           |    5 
 android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionSetting.java                      |   22 ++
 android/packages/apps/Camera2/res/xml/camera_preferences.xml                                              |   12 +
 android/packages/apps/Camera2/src/com/android/camera/settings/PictureSizeLoader.java                      |   24 ++
 android/packages/apps/Camera2/src/com/android/camera/processing/imagebackend/TaskCompressImageToJpeg.java |   32 ++--
 android/packages/apps/Camera2/res/values/arrays.xml                                                       |   37 ++++-
 android/packages/apps/Camera2/src/com/android/camera/ButtonManager.java                                   |   89 ++++++++++--
 android/packages/apps/Camera2/src/com/android/camera/settings/Keys.java                                   |   12 +
 android/packages/apps/Camera2/res/values/strings.xml                                                      |   13 +
 android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandlerImpl.java                           |   15 ++
 android/packages/apps/Camera2/src/com/android/camera/CaptureModule.java                                   |   52 +++++++
 android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionUtil.java                         |   14 +
 android/packages/apps/Camera2/res/values-zh-rCN/strings.xml                                               |    7 +
 16 files changed, 328 insertions(+), 65 deletions(-)

diff --git a/android/packages/apps/Camera2/res/values-zh-rCN/strings.xml b/android/packages/apps/Camera2/res/values-zh-rCN/strings.xml
index abcceaa..5019d34 100755
--- a/android/packages/apps/Camera2/res/values-zh-rCN/strings.xml
+++ b/android/packages/apps/Camera2/res/values-zh-rCN/strings.xml
@@ -68,6 +68,7 @@
     <string name="error_cannot_connect_camera" msgid="2713059773224193128">"无法连接到相机。"</string>
     <string name="error_camera_disabled" msgid="5582398275657419692">"由于安全规范的限制,相机已被禁用。"</string>
     <string name="error_media_storage_failure" msgid="7711687330673245629">"保存您的照片或视频时出现问题。"</string>
+    <string name="error_cannot_start_recording_failur">"录像异常,当前设备不支持该录像参数"</string>
     <string name="error_permissions" msgid="3454167403425651254">"此应用缺少运行所需的必要权限。请检查您的权限设置。"</string>
     <string name="reason_storage_failure" msgid="6818898304774654969">"照片存储失败。"</string>
     <string name="wait" msgid="765601745709933047">"请稍候…"</string>
@@ -77,10 +78,12 @@
     <string name="time_lapse_title" msgid="3267978566401228497">"延时录影"</string>
     <string name="feedback_description_camera_access" msgid="419090951070170132">"该应用无法连接到相机"</string>
     <string name="feedback_description_save_photo" msgid="8658767358989083228">"照片或视频没有保存到设备中。"</string>
+    <string name="feedback_description_start_recording">无法启动录像</string>
     <string name="capturing" msgid="5255164204641920893">"正在拍摄"</string>
     <string name="pref_camera_id_title" msgid="4680648115225411185">"选择摄像头"</string>
     <string name="pref_camera_id_entry_back" msgid="6386943973628160510">"后置"</string>
     <string name="pref_camera_id_entry_front" msgid="6233067010315787044">"前置"</string>
+    <string name="pref_camera_id_entry_external" msgid="6233067010315787044">"外置"</string>
     <string name="pref_camera_save_location_title" msgid="2344235620113384017">"保存位置信息"</string>
     <string name="pref_camera_location_label" msgid="8695441802378057719">"位置信息"</string>
     <string name="pref_camera_timer_title" msgid="4728838281741571323">"倒计时器"</string>
@@ -156,6 +159,7 @@
     <string name="pref_camera_hdr_label" msgid="1918040375414771185">"HDR"</string>
     <string name="pref_camera_id_label_back" msgid="1645608049757733858">"前置摄像头"</string>
     <string name="pref_camera_id_label_front" msgid="349308803062874842">"后置摄像头"</string>
+    <string name="pref_camera_id_label_external" msgid="349308803062874842">"USB外置摄像头"</string>
     <string name="dialog_ok" msgid="774141340500181131">"确定"</string>
     <string name="dialog_cancel" msgid="692365061128351656">"取消"</string>
     <string name="dialog_report" msgid="7616428760369876209">"报告"</string>
@@ -319,6 +323,7 @@
     <string name="torch_off_desc" msgid="8304675202998742618">"手电筒已关闭"</string>
     <string name="camera_id_back_desc" msgid="3566327490758890635">"后置摄像头"</string>
     <string name="camera_id_front_desc" msgid="7497517948130254220">"前置摄像头"</string>
+    <string name="camera_id_external_desc" msgid="7497517948130254220">"USB外置摄像头"</string>
     <string name="grid_lines_off_desc" msgid="2022385817190451353">"网格线已关闭"</string>
     <string name="grid_lines_on_desc" msgid="4601540461914364817">"网格线已开启"</string>
     <string name="countdown_timer_off" msgid="1663008439564495948">"倒计时器已关闭"</string>
@@ -345,6 +350,8 @@
     <string name="setting_back_camera_video" msgid="5220819479408164689">"后置摄像头视频"</string>
     <string name="setting_front_camera_photo" msgid="4131886734622868637">"前置摄像头照片"</string>
     <string name="setting_front_camera_video" msgid="2178799452805359752">"前置摄像头视频"</string>
+    <string name="setting_external_camera_photo" msgid="4131886734622868637">"USB外置摄像头照片"</string>
+    <string name="setting_external_camera_video" msgid="2178799452805359752">"USB外置摄像头视频"</string>
     <string name="setting_default_camera" msgid="6954076799301004779">"默认相机"</string>
     <string name="setting_google_help_and_feedback" msgid="2079580537079242775">"帮助和反馈"</string>
     <string name="processing_hdr_plus" msgid="9160093263037540304">"正在处理HDR+…"</string>
diff --git a/android/packages/apps/Camera2/res/values/arrays.xml b/android/packages/apps/Camera2/res/values/arrays.xml
old mode 100755
new mode 100644
index e67efb4..7c83922
--- a/android/packages/apps/Camera2/res/values/arrays.xml
+++ b/android/packages/apps/Camera2/res/values/arrays.xml
@@ -190,28 +190,48 @@
         <item>@drawable/ic_switch_camera_external</item>
     </array>
 
-    <array name="camera_id_icons_without_external" translatable="false">
-        <item>@drawable/ic_switch_camera_back</item>
-        <item>@drawable/ic_switch_camera_front</item>
-    </array>
-
     <array name="camera_id_icons_with_external" translatable="false">
         <item>@drawable/ic_switch_camera_back</item>
         <item>@drawable/ic_switch_camera_front</item>
         <item>@drawable/ic_switch_camera_external</item>
     </array>
 
-    <array name="camera_id_icons_with_front_external" translatable="false">
+    <array name="camera_id_icons_with_double_external" translatable="false">
+        <item>@drawable/ic_switch_camera_back</item>
+        <item>@drawable/ic_switch_camera_front</item>
+        <item>@drawable/ic_switch_camera_external</item>
+        <item>@drawable/ic_switch_camera_external</item>
+    </array>
+
+    <array name="camera_id_icons_external_double" translatable="false">
+        <item>@drawable/ic_switch_camera_external</item>
+        <item>@drawable/ic_switch_camera_external</item>
+    </array>
+
+    <array name="camera_id_icon_back_with_external" translatable="false">
         <item>@drawable/ic_switch_camera_back</item>
         <item>@drawable/ic_switch_camera_external</item>
     </array>
 
-    <array name="camera_id_icons_with_back_external" translatable="false">
+    <array name="camera_id_icon_back_with_double_external" translatable="false">
+        <item>@drawable/ic_switch_camera_back</item>
+        <item>@drawable/ic_switch_camera_external</item>
+        <item>@drawable/ic_switch_camera_external</item>
+    </array>
+
+    <array name="camera_id_icon_front" translatable="false">
         <item>@drawable/ic_switch_camera_front</item>
         <item>@drawable/ic_switch_camera_external</item>
     </array>
 
-    <array name="camera_id_icons_with_only_external" translatable="false">
+    <array name="camera_id_icon_front_with_external" translatable="false">
+        <item>@drawable/ic_switch_camera_front</item>
+        <item>@drawable/ic_switch_camera_external</item>
+    </array>
+
+    <array name="camera_id_icon_front_with_double_external" translatable="false">
+        <item>@drawable/ic_switch_camera_front</item>
+        <item>@drawable/ic_switch_camera_external</item>
         <item>@drawable/ic_switch_camera_external</item>
     </array>
 
@@ -220,7 +240,6 @@
       <item>@string/camera_id_front_desc</item>
       <item>@string/camera_id_external_desc</item>
     </array>
-
 
     <array name="camera_id_largeicons" translatable="false">
         <item>@drawable/ic_switch_camera_back</item>
diff --git a/android/packages/apps/Camera2/res/values/strings.xml b/android/packages/apps/Camera2/res/values/strings.xml
index 6231db8..d8c4ead 100755
--- a/android/packages/apps/Camera2/res/values/strings.xml
+++ b/android/packages/apps/Camera2/res/values/strings.xml
@@ -136,6 +136,9 @@
     <!-- message for the dialog showing that the user's photo could not be saved [CHAR LIMIT=NONE] -->
     <string name="error_media_storage_failure">There was a problem saving your photo or video.</string>
 
+    <!-- message for the dialog showing that the user's photo could not be saved [CHAR LIMIT=NONE] -->
+    <string name="error_cannot_start_recording_failure">The recording parameters are not compatible with this camera.</string>
+
     <!-- message for the dialog showing that the app does not have sufficient permissions [CHAR LIMIT=NONE] -->
     <string name="error_permissions">The app does not have critical permissions needed to run. Please check your permissions settings.</string>
 
@@ -163,6 +166,9 @@
     <!-- Default feedback that is entered in the Feedback textview for issues related to saving photos. [CHAR LIMIT=NONE] -->
     <string name="feedback_description_save_photo">Photo or video did not save to the device.</string>
 
+    <!-- Default feedback that is entered in the Feedback textview for issues related to recording. [CHAR LIMIT=NONE] -->
+    <string name="feedback_description_start_recording">Can not start recording because of video settings</string>
+
     <!-- Screen display message during image capture to indicate that the capture is in progress, like during HDR+. [CHAR LIMIT=20] -->
     <string name="capturing">Capturing</string>
 
@@ -172,6 +178,9 @@
     <string name="pref_camera_id_default" translatable="false">0</string>
 
     <!-- Named indexes into the array of camera facing entries -->
+    <!--string name="pref_camera_id_index_back" translatable="false">1</string>
+    <string name="pref_camera_id_index_front" translatable="false">2</string-->
+
     <string name="pref_camera_id_index_back" translatable="false">1</string>
     <string name="pref_camera_id_index_front" translatable="false">2</string>
     <string name="pref_camera_id_index_external" translatable="false">2</string>
@@ -840,6 +849,10 @@
     <string name="setting_front_camera_photo">Front camera photo</string>
     <!-- Camera settings title for front camera video resolution. [CHAR LIMIT=25] -->
     <string name="setting_front_camera_video">Front camera video</string>
+    <!-- Camera settings title for external camera photo resolution. [CHAR LIMIT=25] -->
+    <string name="setting_external_camera_photo">External camera photo</string>
+    <!-- Camera settings title for external camera video resolution. [CHAR LIMIT=25] -->
+    <string name="setting_external_camera_video">External camera video</string>
 
     <!-- Text shown in camera settings list for selecting the camera mode that will be used by default when the app starts [CHAR LIMIT=25] -->
     <string name="setting_default_camera">Default Camera</string>
diff --git a/android/packages/apps/Camera2/res/xml/camera_preferences.xml b/android/packages/apps/Camera2/res/xml/camera_preferences.xml
old mode 100755
new mode 100644
index 7713967..3cca9ce
--- a/android/packages/apps/Camera2/res/xml/camera_preferences.xml
+++ b/android/packages/apps/Camera2/res/xml/camera_preferences.xml
@@ -36,6 +36,12 @@
           android:entryValues="@array/pref_camera_picturesize_entryvalues"
           android:key="pref_camera_picturesize_front_key"
           android:title="@string/setting_front_camera_photo" />
+      <!-- EXTERNAL camera PHOTO resolution -->
+      <ListPreference
+          android:defaultValue="@string/pref_camera_picturesize_default"
+          android:entryValues="@array/pref_camera_picturesize_entryvalues"
+          android:key="pref_camera_picturesize_external_key"
+          android:title="@string/setting_external_camera_photo" />
     </PreferenceCategory>
     <PreferenceCategory android:title="@string/mode_video" >
 
@@ -51,6 +57,12 @@
           android:entryValues="@array/pref_video_quality_entryvalues"
           android:key="pref_video_quality_front_key"
           android:title="@string/setting_front_camera_video" />
+      <!-- EXTERNAL camera VIDEO resolution -->
+      <ListPreference
+          android:defaultValue="@string/pref_video_quality_small"
+          android:entryValues="@array/pref_video_quality_entryvalues"
+          android:key="pref_video_quality_external_key"
+          android:title="@string/setting_external_camera_video" />
     </PreferenceCategory>
   </PreferenceScreen>
 
diff --git a/android/packages/apps/Camera2/src/com/android/camera/ButtonManager.java b/android/packages/apps/Camera2/src/com/android/camera/ButtonManager.java
old mode 100755
new mode 100644
index 4a37e47..5d72131
--- a/android/packages/apps/Camera2/src/com/android/camera/ButtonManager.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/ButtonManager.java
@@ -33,6 +33,12 @@
 import com.android.camera.widget.ModeOptions;
 import com.android.camera2.R;
 
+import android.util.Log;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import com.android.camera.one.OneCamera.Facing;
+
 /**
  * A  class for generating pre-initialized
  * {@link #android.widget.ImageButton}s.
@@ -51,6 +57,10 @@
     public static final int BUTTON_GRID_LINES = 10;
     public static final int BUTTON_EXPOSURE_COMPENSATION = 11;
     public static final int BUTTON_COUNTDOWN = 12;
+
+    public static final int ZERO_CAMERA = 0;
+    public static final int ONE_CAMERA = 1;
+    public static final int TWO_CAMERAS = 2;
 
     /** For two state MultiToggleImageButtons, the off index. */
     public static final int OFF = 0;
@@ -101,7 +111,8 @@
 
     private final AppController mAppController;
 
-    private static final String ANDROID_UVC_PROPERTY = "ro.camera.uvcfacing";
+    private CameraManager mCameraManager;
+    private static String TAG = "ButtonManager";
 
     /**
      * Get a new global ButtonManager.
@@ -114,6 +125,7 @@
 
         mSettingsManager = app.getSettingsManager();
         mSettingsManager.addListener(this);
+        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
     }
 
     /**
@@ -361,27 +373,66 @@
                 initializeHdrPlusFlashButton(button, cb, preCb, R.array.camera_flashmode_icons);
                 break;
             case BUTTON_CAMERA:
-                String uvcProperty = SystemProperties.get(ANDROID_UVC_PROPERTY, "");
-                if(uvcProperty.equals("null") || uvcProperty.equals("")){
-                    initializeCameraButton(button, cb,
-                            preCb, R.array.camera_id_icons);
+                String[] cameraIds = new String[]{};
+                int front_num = 0;
+                int back_num = 0;
+                int external_num = 0;
+                try {
+                    cameraIds = mCameraManager.getCameraIdList();
+                    for (String cameraId : cameraIds) {
+                        CameraCharacteristics characteristics = mCameraManager
+                            .getCameraCharacteristics(cameraId);
+                        if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
+                                CameraCharacteristics.LENS_FACING_FRONT) {
+                            front_num = front_num + 1;
+                        } else if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
+                                CameraCharacteristics.LENS_FACING_BACK) {
+                            back_num = back_num + 1;
+                        } else if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
+                                CameraCharacteristics.LENS_FACING_EXTERNAL) {
+                            external_num = external_num + 1;
+                        }
+                    }
                 }
-                else if (uvcProperty.equals("back")) {
-                    initializeCameraButton(button, cb,
-                            preCb, R.array.camera_id_icons_with_front_external);
+                catch (CameraAccessException ex) {
+                    Log.e(TAG, "Unable to read camera list.", ex);
                 }
-                else if (uvcProperty.equals("front")) {
-                    initializeCameraButton(button, cb,
-                            preCb, R.array.camera_id_icons_with_back_external);
+                if (front_num == ONE_CAMERA && back_num == ZERO_CAMERA) {
+                    if (external_num == ONE_CAMERA) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icon_front_with_external);
+                    } else if (external_num == TWO_CAMERAS) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icon_front_with_double_external);
+                    }
+                } else if (front_num == ZERO_CAMERA && back_num == ONE_CAMERA) {
+                    if (external_num == ONE_CAMERA) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icon_back_with_external);
+                    } else if (external_num == TWO_CAMERAS) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icon_back_with_double_external);
+                    }
+                } else if (front_num == ONE_CAMERA && back_num == ONE_CAMERA) {
+                    if (external_num == ZERO_CAMERA) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icons);
+                    } else if (external_num == ONE_CAMERA) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icons_with_external);
+                    } else if (external_num == TWO_CAMERAS) {
+                        initializeCameraButton(button, cb,
+                                preCb, R.array.camera_id_icons_with_double_external);
+                    }
+                } else {
+                    switch (cameraIds.length) {
+                        case TWO_CAMERAS:
+                            initializeCameraButton(button, cb,
+                                    preCb, R.array.camera_id_icons_external_double);
+                            break;
+                    }
                 }
-                else if (uvcProperty.equals("external")) {
-                    initializeCameraButton(button, cb,
-                            preCb, R.array.camera_id_icons_with_external);
-                }
-                else if (uvcProperty.equals("external-only")) {
-                    initializeCameraButton(button, cb,
-                            preCb, R.array.camera_id_icons_with_only_external);
-                }
+
                 break;
             case BUTTON_HDR_PLUS:
                 initializeHdrPlusButton(button, cb, preCb, R.array.pref_camera_hdr_plus_icons);
diff --git a/android/packages/apps/Camera2/src/com/android/camera/CaptureModule.java b/android/packages/apps/Camera2/src/com/android/camera/CaptureModule.java
index fa4802d..f8b6d1f 100755
--- a/android/packages/apps/Camera2/src/com/android/camera/CaptureModule.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/CaptureModule.java
@@ -23,6 +23,9 @@
 import android.graphics.RectF;
 import android.graphics.SurfaceTexture;
 import android.location.Location;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
 import android.media.MediaActionSound;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -354,6 +357,7 @@
     public CaptureModule(AppController appController) {
         this(appController, false);
     }
+    private CameraManager mCameraManager;
 
     /** Constructs a new capture module. */
     public CaptureModule(AppController appController, boolean stickyHdr) {
@@ -414,6 +418,7 @@
         mCameraHandler = new Handler(thread.getLooper());
         mActivity = activity;
         mOneCameraOpener = mAppController.getCameraOpener();
+        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
 
         try {
             mOneCameraManager = OneCameraModule.provideOneCameraManager();
@@ -429,6 +434,29 @@
         Log.d(TAG,"SettingsManager cameraID = " +
                 mSettingsManager.getInteger(mAppController.getModuleScope(),
                 Keys.KEY_CAMERA_ID) + " facing = " + mCameraFacing);
+
+        int cameraId = mSettingsManager.getInteger(mAppController.getModuleScope(),
+                Keys.KEY_CAMERA_ID);
+        try {
+            String[] cameraIds = mCameraManager.getCameraIdList();
+            Log.d(TAG, "cameraIds len = " + cameraIds.length);
+            boolean foundCameraId = false;
+            for (String currentCameraId : cameraIds) {
+                Log.d(TAG,"Enumerate cameraId = " + currentCameraId);
+                if (Integer.parseInt(currentCameraId) == cameraId) {
+                    Log.d(TAG, "find exists currentCameraId matches first camera id");
+                    foundCameraId = true;
+                    break;
+                }
+            }
+            if (!foundCameraId && cameraIds.length > 0) {
+                cameraId = Integer.parseInt(cameraIds[0]);
+                Log.d(TAG,"cameraId sets to first id of cameraIds: " + cameraId);
+            }
+        } catch (CameraAccessException ex) {
+            Log.w(TAG, "Unable to get camera ID", ex);
+        }
+
         mShowErrorAndFinish = !updateCameraCharacteristics();
         if (mShowErrorAndFinish) {
             return;
@@ -1398,6 +1426,30 @@
         boolean useHdr = mHdrPlusEnabled && mCameraFacing == Facing.BACK;
 
         CameraId cameraId = mOneCameraManager.findFirstCameraFacing(mCameraFacing);
+
+        int settingsCameraId = mSettingsManager.getInteger(mAppController.getModuleScope(), Keys.KEY_CAMERA_ID);
+                //check if settingsCameraId exists now
+        try {
+            String[] cameraIds = mCameraManager.getCameraIdList();
+            boolean foundCameraId = false;
+            for (String currentCameraId : cameraIds) {
+                Log.d(TAG,"Enumerate cameraId = " + currentCameraId);
+                if (Integer.parseInt(currentCameraId) == settingsCameraId) {
+                    Log.d(TAG, "find exists currentCameraId matches first camera id");
+                    foundCameraId = true;
+                    if (Integer.parseInt(cameraId.getValue()) != settingsCameraId) {
+                        cameraId = CameraId.from(String.valueOf(settingsCameraId));
+                    }
+                    break;
+                }
+            }
+            if (!foundCameraId && cameraIds.length > 0) {
+                cameraId = CameraId.from(String.valueOf(cameraIds[0]));
+                Log.d(TAG,"cameraId sets to first id of cameraIds: " + cameraId);
+            }
+        } catch (CameraAccessException ex) {
+            Log.w(TAG, "Unable to get camera ID", ex);
+        }
         final String settingScope = SettingsManager.getCameraSettingScope(cameraId.getValue());
 
         OneCameraCaptureSetting captureSetting;
diff --git a/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandler.java b/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandler.java
old mode 100755
new mode 100644
index 4d548c4..338bef7
--- a/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandler.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandler.java
@@ -48,6 +48,10 @@
         MEDIA_STORAGE_FAILURE(
                 R.string.error_media_storage_failure,
                 R.string.feedback_description_save_photo,
+                false),
+        CAMERA_VIDEO_QUALITY_FAILURE(
+                R.string.error_cannot_start_recording_failure,
+                R.string.feedback_description_start_recording,
                 false);
 
         private final int mDialogMsgId;
@@ -144,6 +148,10 @@
      */
     public void onCameraDisabledFailure();
 
+     /**
+      * Handles error where the camera is fail start recording.
+      */
+    public void onRecordingFailure();
 
     /**
      * Handles a fatal error, e.g. by displaying the appropriate dialog and
diff --git a/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandlerImpl.java b/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandlerImpl.java
old mode 100755
new mode 100644
index 802abc6..1afe8fa
--- a/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandlerImpl.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/FatalErrorHandlerImpl.java
@@ -122,4 +122,19 @@
         CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
                 finishActivity, ex);
     }
+    @Override
+    public void onRecordingFailure() {
+        Exception ex = new Exception();
+        // Log a stack trace to be sure we can track the source.
+        Log.e(TAG, "Handling Camera recording Error:", ex);
+
+        UsageStatistics.instance().cameraFailure(
+                eventprotos.CameraFailure.FailureReason.UNKNOWN_REASON, null,
+                UsageStatistics.NONE, UsageStatistics.NONE);
+
+        Reason reason = Reason.CAMERA_VIDEO_QUALITY_FAILURE;
+        boolean finishActivity = reason.doesFinishActivity();
+        CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
+                finishActivity, ex);
+    }
 }
diff --git a/android/packages/apps/Camera2/src/com/android/camera/VideoModule.java b/android/packages/apps/Camera2/src/com/android/camera/VideoModule.java
old mode 100755
new mode 100644
index c77308c..7725146
--- a/android/packages/apps/Camera2/src/com/android/camera/VideoModule.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/VideoModule.java
@@ -745,7 +745,7 @@
         // We need to convert it to int manually.
         SettingsManager settingsManager = mActivity.getSettingsManager();
         String videoQualityKey = isCameraFrontFacing() ? Keys.KEY_VIDEO_QUALITY_FRONT
-            : Keys.KEY_VIDEO_QUALITY_BACK;
+            : isCameraBackFacing() ? Keys.KEY_VIDEO_QUALITY_BACK : Keys.KEY_VIDEO_QUALITY_EXTERNAL;
         String videoQuality = settingsManager
                 .getString(SettingsManager.SCOPE_GLOBAL, videoQualityKey);
         int quality = SettingsUtil.getVideoQuality(videoQuality, mCameraId);
@@ -1396,7 +1396,7 @@
                         mMediaRecorder.start(); // Recording is now started
                     } catch (RuntimeException e) {
                         Log.e(TAG, "Could not start media recorder. ", e);
-                        mAppController.getFatalErrorHandler().onGenericCameraAccessFailure();
+                        mAppController.getFatalErrorHandler().onRecordingFailure();
                         releaseMediaRecorder();
                         // If start fails, frameworks will not lock the camera for us.
                         mCameraDevice.lock();
diff --git a/android/packages/apps/Camera2/src/com/android/camera/processing/imagebackend/TaskCompressImageToJpeg.java b/android/packages/apps/Camera2/src/com/android/camera/processing/imagebackend/TaskCompressImageToJpeg.java
old mode 100755
new mode 100644
index 528591f..169c2e6
--- a/android/packages/apps/Camera2/src/com/android/camera/processing/imagebackend/TaskCompressImageToJpeg.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/processing/imagebackend/TaskCompressImageToJpeg.java
@@ -203,25 +203,25 @@
                             imageHeight,
                             img.proxy.getFormat(), safeCrop);
 
-                    if(requiresCropOperation(img.proxy, safeCrop)) {
-                        // Crop the image
-                        resultImage = new TaskImage(
-                                exifDerivedRotation,
-                                safeCrop.width(),
-                                safeCrop.height(),
-                                img.proxy.getFormat(), null);
+                    //if(requiresCropOperation(img.proxy, safeCrop)) {
+                    //    // Crop the image
+                    //    resultImage = new TaskImage(
+                    //            exifDerivedRotation,
+                    //            safeCrop.width(),
+                    //            safeCrop.height(),
+                    //            img.proxy.getFormat(), null);
 
-                        byte[] croppedResult = decompressCropAndRecompressJpegData(
-                                compressedData.array(), safeCrop,
-                                getJpegCompressionQuality());
+                    //    byte[] croppedResult = decompressCropAndRecompressJpegData(
+                    //            compressedData.array(), safeCrop,
+                    //            getJpegCompressionQuality());
 
-                        compressedData = ByteBuffer.allocate(croppedResult.length);
-                        compressedData.put(ByteBuffer.wrap(croppedResult));
-                        compressedData.rewind();
-                    } else {
-                        // Pass-though the JPEG data
+                    //    compressedData = ByteBuffer.allocate(croppedResult.length);
+                    //    compressedData.put(ByteBuffer.wrap(croppedResult));
+                    //    compressedData.rewind();
+                    //} else {
+                    //    // Pass-though the JPEG data
                         resultImage = inputImage;
-                    }
+                    //}
                 } finally {
                     // Release the image now that you have a usable copy in
                     // local memory
diff --git a/android/packages/apps/Camera2/src/com/android/camera/settings/CameraSettingsActivity.java b/android/packages/apps/Camera2/src/com/android/camera/settings/CameraSettingsActivity.java
old mode 100755
new mode 100644
index 15307c0..59ced65
--- a/android/packages/apps/Camera2/src/com/android/camera/settings/CameraSettingsActivity.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/settings/CameraSettingsActivity.java
@@ -203,13 +203,31 @@
             loadSizes();
 
             // Send loaded sizes to additional preferences.
-            CameraSettingsActivityHelper.onSizesLoaded(this, mPictureSizes.backCameraSizes,
-                    new ListPreferenceFiller() {
-                        @Override
-                        public void fill(List<Size> sizes, ListPreference preference) {
-                            setEntriesForSelection(sizes, preference);
-                        }
-                    });
+            if (!mPictureSizes.backCameraSizes.isEmpty()) {
+                CameraSettingsActivityHelper.onSizesLoaded(this, mPictureSizes.backCameraSizes,
+                        new ListPreferenceFiller() {
+                            @Override
+                            public void fill(List<Size> sizes, ListPreference preference) {
+                                setEntriesForSelection(sizes, preference);
+                            }
+                        });
+            } else if (!mPictureSizes.frontCameraSizes.isEmpty()) {
+                CameraSettingsActivityHelper.onSizesLoaded(this, mPictureSizes.frontCameraSizes,
+                        new ListPreferenceFiller() {
+                            @Override
+                            public void fill(List<Size> sizes, ListPreference preference) {
+                                setEntriesForSelection(sizes, preference);
+                            }
+                        });
+            } else {
+                CameraSettingsActivityHelper.onSizesLoaded(this, mPictureSizes.externalCameraSizes,
+                        new ListPreferenceFiller() {
+                            @Override
+                            public void fill(List<Size> sizes, ListPreference preference) {
+                                setEntriesForSelection(sizes, preference);
+                            }
+                        });
+            }
 
             // Make sure to hide settings for cameras that don't exist on this
             // device.
@@ -309,6 +327,12 @@
                 recursiveDelete(resolutions,
                         findPreference(Keys.KEY_VIDEO_QUALITY_FRONT));
             }
+            if (mPictureSizes.externalCameraSizes.isEmpty()) {
+                recursiveDelete(resolutions,
+                        findPreference(Keys.KEY_PICTURE_SIZE_EXTERNAL));
+                recursiveDelete(resolutions,
+                        findPreference(Keys.KEY_VIDEO_QUALITY_EXTERNAL));
+            }
         }
 
         /**
@@ -382,10 +406,14 @@
                 setEntriesForSelection(mPictureSizes.backCameraSizes, listPreference);
             } else if (listPreference.getKey().equals(Keys.KEY_PICTURE_SIZE_FRONT)) {
                 setEntriesForSelection(mPictureSizes.frontCameraSizes, listPreference);
+            } else if (listPreference.getKey().equals(Keys.KEY_PICTURE_SIZE_EXTERNAL)) {
+                setEntriesForSelection(mPictureSizes.externalCameraSizes, listPreference);
             } else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_BACK)) {
                 setEntriesForSelection(mPictureSizes.videoQualitiesBack.orNull(), listPreference);
             } else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_FRONT)) {
                 setEntriesForSelection(mPictureSizes.videoQualitiesFront.orNull(), listPreference);
+            } else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_EXTERNAL)) {
+                setEntriesForSelection(mPictureSizes.videoQualitiesExternal.orNull(), listPreference);
             }
         }
 
@@ -405,10 +433,15 @@
             } else if (listPreference.getKey().equals(Keys.KEY_PICTURE_SIZE_FRONT)) {
                 setSummaryForSelection(mPictureSizes.frontCameraSizes,
                         listPreference);
+            } else if (listPreference.getKey().equals(Keys.KEY_PICTURE_SIZE_EXTERNAL)) {
+                setSummaryForSelection(mPictureSizes.externalCameraSizes,
+                        listPreference);
             } else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_BACK)) {
                 setSummaryForSelection(mPictureSizes.videoQualitiesBack.orNull(), listPreference);
             } else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_FRONT)) {
                 setSummaryForSelection(mPictureSizes.videoQualitiesFront.orNull(), listPreference);
+            } else if (listPreference.getKey().equals(Keys.KEY_VIDEO_QUALITY_EXTERNAL)) {
+                setSummaryForSelection(mPictureSizes.videoQualitiesExternal.orNull(), listPreference);
             } else {
                 listPreference.setSummary(listPreference.getEntry());
             }
diff --git a/android/packages/apps/Camera2/src/com/android/camera/settings/Keys.java b/android/packages/apps/Camera2/src/com/android/camera/settings/Keys.java
old mode 100755
new mode 100644
index fe71118..b4d5caa
--- a/android/packages/apps/Camera2/src/com/android/camera/settings/Keys.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/settings/Keys.java
@@ -130,7 +130,7 @@
             context.getString(R.string.pref_camera_focusmode_default),
             context.getResources().getStringArray(R.array.pref_camera_focusmode_entryvalues));
 
-        String videoQualityBackDefaultValue = context.getString(R.string.pref_video_quality_large);
+        String videoQualityBackDefaultValue = context.getString(R.string.pref_video_quality_small);
         // TODO: We tweaked the default setting based on model string which is not ideal. Detecting
         // CamcorderProfile capability is a better way to get this job done. However,
         // |CamcorderProfile.hasProfile| needs camera id info. We need a way to provide camera id to
@@ -149,13 +149,21 @@
         }
 
         settingsManager.setDefaults(KEY_VIDEO_QUALITY_FRONT,
-            context.getString(R.string.pref_video_quality_large),
+            context.getString(R.string.pref_video_quality_small),
             context.getResources().getStringArray(R.array.pref_video_quality_entryvalues));
         if (!settingsManager.isSet(SettingsManager.SCOPE_GLOBAL, Keys.KEY_VIDEO_QUALITY_FRONT)) {
             settingsManager.setToDefault(SettingsManager.SCOPE_GLOBAL,
                                          Keys.KEY_VIDEO_QUALITY_FRONT);
         }
 
+        settingsManager.setDefaults(KEY_VIDEO_QUALITY_EXTERNAL,
+            context.getString(R.string.pref_video_quality_small),
+            context.getResources().getStringArray(R.array.pref_video_quality_entryvalues));
+        if (!settingsManager.isSet(SettingsManager.SCOPE_GLOBAL, Keys.KEY_VIDEO_QUALITY_EXTERNAL)) {
+            settingsManager.setToDefault(SettingsManager.SCOPE_GLOBAL,
+                                         Keys.KEY_VIDEO_QUALITY_EXTERNAL);
+        }
+
         settingsManager.setDefaults(KEY_JPEG_QUALITY,
             context.getString(R.string.pref_camera_jpeg_quality_normal),
             context.getResources().getStringArray(
diff --git a/android/packages/apps/Camera2/src/com/android/camera/settings/PictureSizeLoader.java b/android/packages/apps/Camera2/src/com/android/camera/settings/PictureSizeLoader.java
old mode 100755
new mode 100644
index 582d77f..f261213
--- a/android/packages/apps/Camera2/src/com/android/camera/settings/PictureSizeLoader.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/settings/PictureSizeLoader.java
@@ -49,17 +49,22 @@
     public static class PictureSizes {
         public final List<Size> backCameraSizes;
         public final List<Size> frontCameraSizes;
+        public final List<Size> externalCameraSizes;
         public final Optional<SelectedVideoQualities> videoQualitiesBack;
         public final Optional<SelectedVideoQualities> videoQualitiesFront;
-
+        public final Optional<SelectedVideoQualities> videoQualitiesExternal;
         PictureSizes(List<Size> backCameraSizes,
                 List<Size> frontCameraSizes,
+                List<Size> externalCameraSizes,
                 Optional<SelectedVideoQualities> videoQualitiesBack,
-                Optional<SelectedVideoQualities> videoQualitiesFront) {
+                Optional<SelectedVideoQualities> videoQualitiesFront,
+                Optional<SelectedVideoQualities> videoQualitiesExternal) {
             this.backCameraSizes = backCameraSizes;
             this.frontCameraSizes = frontCameraSizes;
+            this.externalCameraSizes = externalCameraSizes;
             this.videoQualitiesBack = videoQualitiesBack;
             this.videoQualitiesFront = videoQualitiesFront;
+            this.videoQualitiesExternal = videoQualitiesExternal;
         }
     }
 
@@ -111,17 +116,24 @@
      * We then calculate the resolutions that should be available and in the end
      * filter it in case a resolution is on the blacklist for this device.
      */
+
     public PictureSizes computePictureSizes() {
         List<Size> backCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_BACK);
         List<Size> frontCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_FRONT);
+        List<Size> externalCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_EXTERNAL);
         Optional<SelectedVideoQualities> videoQualitiesBack =
-                computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_BACK);
+            computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_BACK);
         Optional<SelectedVideoQualities> videoQualitiesFront =
-                computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_FRONT);
-        return new PictureSizes(backCameraSizes, frontCameraSizes, videoQualitiesBack,
-                videoQualitiesFront);
+            computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_FRONT);
+        Optional<SelectedVideoQualities> videoQualitiesExternal =
+            computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_EXTERNAL);
+        return new PictureSizes(backCameraSizes, frontCameraSizes, externalCameraSizes,
+                videoQualitiesBack,
+                videoQualitiesFront,
+                videoQualitiesExternal);
     }
 
+
     private List<Size> computeSizesForCamera(CameraDeviceSelector facingSelector) {
         List<Size> sizes;
         int cameraId = SettingsUtil.getCameraId(mCameraDeviceInfo, facingSelector);
diff --git a/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionSetting.java b/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionSetting.java
old mode 100755
new mode 100644
index 964b970..3ea3d3f
--- a/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionSetting.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionSetting.java
@@ -144,7 +144,6 @@
                 pictureSize.width() > 0 && pictureSize.height() > 0;
 
         if (!isPictureSizeSettingSet || isPictureSizeBlacklisted || !isPictureSizeFromSettingsValid) {
-            final Rational aspectRatio = ResolutionUtil.ASPECT_RATIO_4x3;
 
             OneCameraCharacteristics cameraCharacteristics =
                     mOneCameraManager.getOneCameraCharacteristics(cameraId);
@@ -153,8 +152,25 @@
                     ResolutionUtil.filterBlackListedSizes(
                             cameraCharacteristics.getSupportedPictureSizes(ImageFormat.JPEG),
                             blacklist);
-            final Size fallbackPictureSize =
-                    ResolutionUtil.getLargestPictureSize(aspectRatio, supportedPictureSizes);
+            for (Size size: supportedPictureSizes) {
+                Log.v(TAG, "supportedPictureSizes size w = " + size.getWidth() +" h = " + size.getHeight());
+            }
+
+            //provide 4x3 and 16x9 selections, compare them and choose larger one.
+            //The chosen size must achieve 16bit aligned requirement.
+            Size fallbackPictureSize;
+            Size LargestPictureSize_4x3 =
+                ResolutionUtil.getLargestPictureSize(ResolutionUtil.ASPECT_RATIO_4x3,
+                        supportedPictureSizes);
+            Size LargestPictureSize_16x9 =
+                ResolutionUtil.getLargestPictureSize(ResolutionUtil.ASPECT_RATIO_16x9,
+                        supportedPictureSizes);
+            if (LargestPictureSize_4x3.getWidth() > LargestPictureSize_16x9.getWidth()) {
+                fallbackPictureSize = LargestPictureSize_4x3;
+            } else {
+                fallbackPictureSize = LargestPictureSize_16x9;
+            }
+
             mSettingsManager.set(
                     SettingsManager.SCOPE_GLOBAL,
                     pictureSizeSettingKey,
diff --git a/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionUtil.java b/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionUtil.java
old mode 100755
new mode 100644
index 73586d0..d4182ba
--- a/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionUtil.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/settings/ResolutionUtil.java
@@ -359,6 +359,16 @@
         return Math.abs(ar1.toDouble() - ar2.toDouble()) < ASPECT_RATIO_TOLERANCE;
     }
 
+    public static boolean is16BitAligned(Size size) {
+        int width = size.getWidth();
+        int height = size.getHeight();
+        if (((width & 15) == 0) && ((height & 15) == 0)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Selects the maximal resolution for the given desired aspect ratio from all available
      * resolutions.  If no resolution exists for the desired aspect ratio, return a resolution
@@ -392,9 +402,11 @@
         for (Size size : sizes) {
             Rational aspectRatio = getAspectRatio(size);
             // Skip if the aspect ratio is not desired.
-            if (!hasSameAspectRatio(aspectRatio, desiredAspectRatio)) {
+            if (!hasSameAspectRatio(aspectRatio, desiredAspectRatio) ||
+                !is16BitAligned(size)) {
                 continue;
             }
+
             int pixelNum = size.getWidth() * size.getHeight();
             if (pixelNum > maxPixelNumWithAspect) {
                 maxPixelNumWithAspect = pixelNum;
diff --git a/android/packages/apps/Camera2/src/com/android/camera/settings/SettingsUtil.java b/android/packages/apps/Camera2/src/com/android/camera/settings/SettingsUtil.java
old mode 100755
new mode 100644
index f83fb8b..ecf6521
--- a/android/packages/apps/Camera2/src/com/android/camera/settings/SettingsUtil.java
+++ b/android/packages/apps/Camera2/src/com/android/camera/settings/SettingsUtil.java
@@ -513,4 +513,9 @@
         public boolean useCamera(CameraDeviceInfo.Characteristics info) {
             return info.isFacingFront();
         }};
+    public static final CameraDeviceSelector CAMERA_FACING_EXTERNAL = new CameraDeviceSelector() {
+        @Override
+        public boolean useCamera(CameraDeviceInfo.Characteristics info) {
+            return info.isFacingExternal();
+        }};
 }

--
Gitblit v1.6.2