前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Android 9.0 对后台程序使用Mic、Camera做了限制?

Android 9.0 对后台程序使用Mic、Camera做了限制?

作者头像
小驰行动派
发布2024-12-05 13:47:47
发布2024-12-05 13:47:47
14800
代码可运行
举报
文章被收录于专栏:Android Camera开发Android Camera开发
运行总次数:0
代码可运行

01、发现问题

在android9.0 上修改原生的SnapdragonCamera 应用,需要修改成能支持后台录像,也就是Activity处于OnPause状态的时候,还是在录像(现在市面上支持后台录像的应用,基本都是在后台service中去开启录像,这个就不在本文的讨论场景了)。

原先的代码预览采用的surfaceView,后面修改成了使用textureView。不过发现按home键退出返回到桌面的时候,后台只能录制1分钟的视频,然后上报了camera error 3的错误。

这个error 3的错误,就是camera关闭了,camera 处于不可用状态下上报的异常。

02、问题分析

1 )根据上报的error来入手,这个error是从hardware层上报,经过CameraService.cpp,然后notify给上层,我们先来看下Camera error状态有哪些:

目前我们遇到的这个error 3,就是camera disable了,那就是那里把camera给关了。

2)第一步,我先在应用代码添加了日志,确认了上层没有自动关闭camera的操作。

接下来第二步是在CameraService.cpp中notifyError 的地方添加多点日志打印,确认是哪里回调的error信息。

根据打印的信息,跟踪下相关代码,发现CameraService这边在接收到uid 相关状态发生了变化的时候,是自动做了notify error 3,然后执行了disconnect Camera的操作。

代码语言:javascript
代码运行次数:0
复制
void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
        bool active, bool insert) {
    ...
//判断到uid处于非active状态,然后执行了上报error3,并disconnect camera
    if (wasActive != isActive && !isActive) {
        sp<CameraService> service = mService.promote();
        if (service != nullptr) {
            service->blockClientsForUid(uid);
        }
    }
}

void CameraService::blockClientsForUid(uid_t uid) {
    const auto clients = mActiveClientManager.getAll();
    for (auto& current : clients) {
        if (current != nullptr) {
            const auto basicClient = current->getValue();
            if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) {
                basicClient->block();
            }
        }
    }
}

void CameraService::BasicClient::block() {
    ...
    notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
    disconnect();
}


void CameraService::Client::notifyError(int32_t errorCode,
        const CaptureResultExtras& resultExtras) {
    (void) resultExtras;
    if (mRemoteCallback != NULL) {
        int32_t api1ErrorCode = CAMERA_ERROR_RELEASED;
        if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED) {
            api1ErrorCode = CAMERA_ERROR_DISABLED;
        }
        mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, api1ErrorCode, 0);
    } else {
        ALOGE("mRemoteCallback is NULL!!");
    }
}

3)根据上面的信息,网上查了下相关资料(https://blog.csdn.net/leonxu_sjtu/article/details/82787997),android 9.0上的确对后台程序使用mic、camera做了限制,如果uid处于idle状态,则会断开相应的硬件设备连接。

03、修改方案

因为我们可以修改framework层代码,所以在CameraService.cpp中把自动断开camera连接的地方给屏蔽掉.

自定义property属性ro.backgroundrecord.enable ,然后根据property属性值来判断是否需要屏蔽Android9.0的这个限制。

代码语言:javascript
代码运行次数:0
复制
+++ b/frameworks/av/services/camera/libcameraservice/CameraService.cpp

@@ -2425,7 +2425,15 @@ void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
     if (deleted) {
         sp<CameraService> service = mService.promote();
         if (service != nullptr) {
-            service->blockClientsForUid(uid);
+            char value[PROPERTY_VALUE_MAX];
+            property_get("ro.backgroundrecord.enable", value, "0");
+            int32_t enable = atoi(value);

+            if(enable){
+              ALOGV("---- enable background record,not need to block uid!!!");
+            }else{
+              service->blockClientsForUid(uid);
+            }
         }
     }
 }

《Android Camera开发入门》、《Camx初认识》已经上架,可以点击了解 -> 小驰成长圈 |期待见证彼此的成长

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-12-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小驰行动派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01、发现问题
  • 02、问题分析
  • 03、修改方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档