首先安装谷歌GMS测试CTSV的apk:ctsVerifier.apk,在测试里面的Camera->Camera Formats里面检查设备的摄像头方向是否正确
1.如果不正确,说明sensor orientation配置错误,需要修改sensor orientation确保cts方向正常,修改方法如下:
vendor/mediatek/proprietary/custom/{项目}/hal/imgsensor_src/cfg_setting_imgsensor.cpp
{
.sensorIdx = IMGSENSOR_SENSOR_IDX_MAIN,
.mclk = eMclk_1,
.port = EMipiPort_CSI1,
.dir = CUSTOM_CFG_DIR_REAR,
.bitOrder = CUSTOM_CFG_BITORDER_9_2,
.orientation = 270,//修改这里
.horizontalFov = 67,
.verticalFov = 49,
.PadPclkInv = 0,
},
修改是否生效可以通过dump metadata确认:adb shell dumpsys media.camera -v 2 > metadata.txt,在metadata.txt里搜索"Facing|Orientation"关键字。2.如果是正确的,接下来看后续操作,首先查看第三方应用preview走得是api几,这个用adb shell logcat抓一下,关键log:CameraService: CameraService::connect call (PID -1 "com.tencent.mobileqq", camera ID 1) for HAL version default and Camera API version 1
2.1如果是走的api1,最终set preview方向到nativewindow的地方在这里:frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
int transform = Parameters::degToTransform(degrees,
mCameraFacing == CAMERA_FACING_FRONT);
if (transform == -1) {
ALOGE("%s: Camera %d: Error setting %d as display orientation value",
__FUNCTION__, mCameraId, degrees);
return BAD_VALUE;
}
SharedParameters::Lock l(mParameters);
if (transform != l.mParameters.previewTransform &&
getPreviewStreamId() != NO_STREAM) {
mDevice->setStreamTransform(getPreviewStreamId(), transform);
}
l.mParameters.previewTransform = transform;
return OK;
}
可以在这里加log,查看第三方应用传来的degrees和mirror是多少,更改APP摄像头方向还分为两部分: 2.1.1同一个apk的方向都有问题,那就加一个包名过滤设置degrees的值,方法如下:
diff --git a/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp b/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
old mode 100644
new mode 100755
index 68dc7f8900b..689e364286d
--- a/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -73,6 +73,8 @@ Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
mRotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_NONE;
mRotateAndCropIsSupported = false;
mRotateAndCropPreviewTransform = 0;
+ mclientPackageName = clientPackageName;
+ ALOGE("mclientPackageName=%s",String8(mclientPackageName).string());
SharedParameters::Lock l(mParameters);
l.mParameters.state = Parameters::DISCONNECTED;
@@ -1681,7 +1683,16 @@ status_t Camera2Client::commandStopSmoothZoomL() {
return OK;
}
+#include <cutils/properties.h>
status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
+ #if 1
+ int32_t currentDumpProp = property_get_int32("camera.debug.api1.preview.degrees",0);
+ if(!strcmp((String8)mclientPackageName.string(),"com.qi.takephotoquestion")){//修改包名
+ ALOGE("adjust app degrees %d to currentDumpProp=%d",degrees,currentDumpProp);
+ degrees = currentDumpProp;
+ }
+ #endif
+ ALOGI("%s: degrees = %d, mirror = %d", __FUNCTION__, degrees, mCameraFacing == CAMERA_FACING_FRONT);
int transform = Parameters::degToTransform(degrees,
mCameraFacing == CAMERA_FACING_FRONT);
if (transform == -1) {
diff --git a/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.h b/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.h
old mode 100644
new mode 100755
index c8dfc466255..189368ed5ad
--- a/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/alps_mssi/frameworks/av/services/camera/libcameraservice/api1/Camera2Client.h
@@ -254,6 +254,7 @@ private:
int32_t mLatestFailedRequestId = -1;
status_t waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout);
status_t waitUntilCurrentRequestIdLocked();
+ String16 mclientPackageName;
};
}; // namespace android
测试方法如下:
adb root
adb remount
adb shell setenforce 0
adb shell setprop camera.debug.api1.preview.degrees 180 //取0、90、180、270中一个。
打开camera测试
调试好自己想要的方向之后,再回头把那个值改了就可以了 2.1.2同一个apk的不同activity的方向,可以通过activity名字区分,方法如下:
diff --git a/framework/base/core/java/android/app/ActivityThread.java b/framework/base/core/java/android/app/ActivityThread.java
index 87192d885085..d43aaa5c3daf 100755
--- a/framework/base/core/java/android/app/ActivityThread.java
+++ b/framework/base/core/java/android/app/ActivityThread.java
@@ -7705,6 +7705,15 @@ public final class ActivityThread extends ClientTransactionHandler {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
+ public String currentActivityName() {
+ String classname =null;
+ ActivityManager manager = (ActivityManager) getSystemContext().getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.RunningTaskInfo info = manager.getRunningTasks(1).get(0);
+ classname = info.topActivity.getClassName();
+ Log.d("ActivityThread","currentActivityName classname="+classname);
+ return classname;
+ }
+
/**
* Call various initializer APIs in mainline modules that need to be called when each process
* starts.
diff --git a/framework/base/core/java/android/hardware/Camera.java b/framework/base/core/java/android/hardware/Camera.java
index 25279b31b5d1..56360697dd2d 100644
--- a/framework/base/core/java/android/hardware/Camera.java
+++ b/framework/base/core/java/android/hardware/Camera.java
@@ -55,6 +55,7 @@ import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
@@ -306,6 +307,25 @@ public class Camera {
} catch (RemoteException e) {
Log.e(TAG, "Audio service is unavailable for queries");
}
+
+ String packageName = ActivityThread.currentOpPackageName();
+ String activityName = ActivityThread.currentActivityThread().currentActivityName();
+ Log.i("Camerajava", "Original cameraInfo.orientation = " + cameraInfo.orientation+",cameraInfo.facing="+cameraInfo.facing);
+ Log.i("Camerajava", "getCameraInfo currentOpPackageName = " + packageName);
+ Log.i("Camerajava", "getCameraInfo activitiName = " + activityName);
+ if(! packageName.equals("com.mediatek.camera")) {
+ if(packageName.equals("com.tencent.mobileqq")) { //修改包名
+ if(activityName.equals("com.tencent.av.ui.AVActivity")) { //修改activity名字
+ if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT){
+ Log.i("Camerajava", "getCameraInfo bef cameraInfo.orientation = " + cameraInfo.orientation);
+ int ori = android.os.SystemProperties.getInt("vendor.camerajava.ori", 270);
+ Log.i("Camerajava", "getCameraInfo ori = " + ori);
+ cameraInfo.orientation = ori;
+ }
+ }
+ }
+ }
+
}
private native static void _getCameraInfo(int cameraId, CameraInfo cameraInfo);
测试方法:
adb root
adb remount
adb shell setenforce 0
adb shell setprop vendor.camerajava.ori 180 //取0、90、180、270中一个。
打开camera测试
2.2如果走的是api2 app无需set preview方向,是framework层自行根据sensor orientation、facing计算nativewindow的transform值。
frameworks/av/camera/CameraUtils.cpp
status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
/*out*/int32_t* transform) {
... int orientation = entry.data.i32[0];
这个方法是我在mtk系统中用过的,其他平台的我没试过,不知道可不可以,仅供大家参考,跟各位大佬学习