[MTK] 第三方应用打开Camera, preview方向不对
文摘 MediaTek 2022-01-12 阅读:11075问题描述:
打开第三方应用,preview方向不符合预期。
问题排查:
1.安装ctsVerifier.apk,测试里面的Camera->Camera Formats,check出问题的那颗摄像头preview的方向是否是正确的。
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)若正确,go to 2.
2. 确认第三方应用preview是走api几,关键log:CameraService: CameraService::connect call (PID -1 "com.tencent.mobileqq", camera ID 1) for HAL version default and Camera API version 1
1)如果preview走的是api1
App Call setDisplayOrientation(int) to ensure correct orientation of preview. 最终set preview方向到nativewindow的地方在这里:
frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
1644 status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1645 int transform = Parameters::degToTransform(degrees,
1646 mCameraFacing == CAMERA_FACING_FRONT);
1647 if (transform == -1) {
1648 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1649 __FUNCTION__, mCameraId, degrees);
1650 return BAD_VALUE;
1651 }
1652 SharedParameters::Lock l(mParameters);
1653 if (transform != l.mParameters.previewTransform &&
1654 getPreviewStreamId() != NO_STREAM) {
1655 mDevice->setStreamTransform(getPreviewStreamId(), transform);
1656 }
1657 l.mParameters.previewTransform = transform;
1658 return OK;
1659 }
可以在[commandSetDisplayOrientationL]这里加log确认第三方应用传来的[degrees]和mirror是多少。
1.1)如果是同一个app都有问题,可以在这里加包名强制调整degrees。patch用下:
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index b043c0b557..22de4db7b2 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -63,7 +63,8 @@ Camera2Client::Camera2Client(const sp& cameraService,
mParameters(api1CameraId, cameraFacing)
{
ATRACE_CALL();
+ mclientPackageName = clientPackageName;
+ALOGE("mclientPackageName=%s",String8(mclientPackageName).string());
SharedParameters::Lock l(mParameters);
l.mParameters.state = Parameters::DISCONNECTED;
}
@@ -1655,8 +1656,17 @@ status_t Camera2Client::commandStopSmoothZoomL() {
ALOGE("%s: Unimplemented!", __FUNCTION__);
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.fjg.android.scan")){ //修改包名
+ ALOGE("adjust app degrees %d to currentDumpProp=%d",degrees,currentDumpProp);
+ degrees = currentDumpProp;
+
+ }
+ #endif
int transform = Parameters::degToTransform(degrees,
mCameraFacing == CAMERA_FACING_FRONT);
if (transform == -1) {
@@ -1670,6 +1680,8 @@ status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
mDevice->setStreamTransform(getPreviewStreamId(), transform);
}
l.mParameters.previewTransform = transform;
+ ALOGE(" %s: Camera %d: setting %d as display orientation value,facing:%d",
+ __FUNCTION__, mCameraId, degrees,mCameraFacing);
return OK;
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 03ca44a421..56f11a09a8 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -240,6 +240,7 @@ private:
int32_t mLatestFailedRequestId = -1;
status_t waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout);
status_t waitUntilCurrentRequestIdLocked();
+ String16 mclientPackageName;
};
}; // namespace android
修改思路是:在framework层根据app package name调整preview orientation。
测试方法:
adb root
adb remount
adb shell setenforce 0
adb shell setprop camera.debug.api1.preview.degrees 180 //取0、90、180、270中一个。
打开camera测试
1.2)如果同一个app的不同activity方向不同,可以通过activity名字区分,修改在java层是因为这里面可以区分是哪个activity,patch如下:
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 87192d885085..d43aaa5c3daf 100755
--- a/core/java/android/app/ActivityThread.java
+++ b/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.e("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/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 25279b31b5d1..56360697dd2d 100644
--- a/core/java/android/hardware/Camera.java
+++ b/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);
修改思路是:对于特定的activity,通过set property调整app get到的sensor角度,从而间接影响app set下来的preview的orientation。
测试方法:
adb root
adb remount
adb shell setenforce 0
adb shell setprop vendor.camerajava.ori 180 //取0、90、180、270中一个。
打开camera测试
2)preview走的是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];