Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92
其实这个问题的本质是音频引起的,但是一开始我往Camera方向查找了,因为测试报给我是说是Camera打开失败,于是我就搜关键字,查看Log:
07-31 19:31:33.962 1152 1236 I CameraService: CameraService::connect call (PID 1073 "com.xxx.msgservice", camera ID 0) for HAL version default and Camera API version 1
07-31 19:31:33.962 1152 1236 E CameraService: 1111 CameraService::connect X (PID 1073) rejected (cannot connect from device user 0, currently allowed device users: )
07-31 19:31:33.962 1152 1236 E CameraService: CameraService::connect X (PID 1073) rejected (cannot connect from device user 0, currently allowed device users: )
提示Camera打开无权限,apk用的api版本是23不会有Anroid6.0的权限问题,而之前apk使用也正常的,本着研究的精神,追查了下currently allowed device users对应的值是多少。
其实记录这个内容也是想提及一下多用户的内容,等以后有时间再研究吧,这里就看看调用流程。
SystemServer在启动过程中会调用ActivityManagerService的systemReady()函数,
systemReady -> ActivityManagerService.java
mSystemServiceManager.startUser ->
startUser -> SystemServiceManager.java
service.onStartUser -> //调动各个Service包括CameraService在内, mCurrentUserId正是当前的用户id
onStartUser -> CameraService.java
switchUserLocked ->
notifyMediaserverLocked -> //注意参数是USER_SWITCHED
mCameraServiceRaw.notifySystemEvent //通过binder调用native层的CameraService
doUserSwitch -> CameraService.cpp
mAllowedUsers = std::move(newAllowedUsers); //这时mAllowedUsers被新的userid替换
另一边,当Camera Client去连接Camera Service想打开Camera时,需要先申请权限:
status_t CameraService::validateConnectLocked(const String8& cameraId, /*inout*/int& clientUid)
const {
// Only allow clients who are being used by the current foreground device user, unless calling
// from our own process.
//可以看到mAllowedUsers.find(clientUserId)和mAllowedUsers.end()比较
//前者传进来是当前user为0, 而mAllowedUsers.end()理论根据你前面正常流程得到的userid也为0.
//如果不相等,那么就申请权限失败而导致Camera无法打开了。
if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
"device user %d, currently allowed device users: %s)", callingPid, clientUserId,
toString(mAllowedUsers).string());
return PERMISSION_DENIED;
}
}
以上部分是用户的switch过程,正常情况应该是成功的,那么问题出在哪里呢?
系统开机mediaserver默认会先去打开关闭测试一次Camera,所以我在两次打开时加了打印当前mAllowedUsers的log:
07-31 19:31:29.940 215 215 I CameraService: CameraService::connect call (PID 215 "media", camera ID 1) for HAL version default and Camera API version 1
07-31 19:31:29.940 215 215 E CameraService: 1111 CameraService::connect X (PID 215) rejected (cannot connect from device user 0, currently allowed device users: 0)
07-31 19:31:29.940 215 215 E CameraService: getCameraPriorityFromProcState: Received invalid process state -1 from ActivityManagerService!
而到调用apk的时候,mAllowedUsers的值为空了,如最前面的log所示。查看两者中间的log,发现Audio模块好多error log:
07-31 19:31:30.770 215 318 E alsa_mixer: mixer_open() Can not open /dev/snd/controlC0 for card 0
07-31 19:31:30.770 215 318 D alsa_route: route_set_controls() set route 0
07-31 19:31:30.770 215 318 E alsa_route: route_set_controls() mMixer is NULL!
怀疑Audio模块加载有问题,查看kernel log:
[ 2.177151] RT5631 Audio Codec 0.01 alsa 1.0.26
[ 2.177799] RT5631 probe error
[ 2.177813] rt5631: probe of 2-001a failed with error -11
[ 2.178268] rockchip-spdif ff8b0000.rockchip-spdif: spdif ready.
[ 2.178457] of_get_named_gpio_flags exited with status 231
[ 2.178516] rockchip-rt5631 rockchip-rt5631.26: ASoC: CODEC (null) not registered
果然加载没成功,看上去应该是硬件问题了~
一个Audio模块加载失败引发的表面Camera用户权限申请失败问题。
来源:CSDN
作者:KrisFei
链接:https://blog.csdn.net/kris_fei/article/details/76468028