当前位置: 首页 > news >正文

aosp13增加摄像头控制功能实现

A13中,可以要求做一个开关来控制摄像头是否可用,约束所有使用摄像头的应用。思路:设置中增加开关设置一个属性值,在摄像头调用实现层增该值判断即可        

一 开关的开发:

设置-安全中增加开关选项

代码部分:

Settings/res/xml/security_dashboard_settings.xml

//........忽略代码  
  <Preference
        android:order="100"
        android:key="security_advanced_settings"
        android:title="@string/security_advanced_settings"
        android:summary="@string/summary_placeholder"
        android:fragment="com.android.settings.security.SecurityAdvancedSettings"
        settings:controller="com.android.settings.security.SecurityAdvancedSettingsController"
        settings:keywords="@string/security_advanced_settings_keywords" />
    <Preference
        android:order="90"
        android:title="@string/apk_install_setting">
            <intent
            android:targetPackage="com.android.settings"
            android:targetClass="com.android.settings.security.ApkInstallActivity" />
    </Preference>
    + <Preference
    +    android:order="80"
    +    android:title="@string/custom_function_control_setting">
    +        <intent
    +        android:targetPackage="com.android.settings"
    +      +android:targetClass="com.android.settings.security.CustomFunctionSettingActivity" />
 +   </Preference> 
</PreferenceScreen>

 新增界面,如下,自定义属性字段,可以参考上一篇文章Android SystemProperties 读写机制详解和案例使用 。就是使用开关组件读写属性

package com.android.settings.security;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.app.Activity;
import java.io.IOException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.android.settings.R;
import android.provider.Settings;
import android.widget.Toast;
import android.text.TextUtils;
import android.os.SystemProperties;

import android.widget.CompoundButton;
import android.content.Context;

import android.widget.Switch;

/**
 * 自定义功能开关
 */
public class CustomFunctionSettingActivity extends Activity implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {

    private Switch cameraSwbtn;    
    private static final String CAMERA_ENABLE_KEY = "persist.sys.flyscale.cam"; 

    private Context mContext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mContext = this;
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_function_control);
        cameraSwbtn = findViewById(R.id.swbtn_camera);
        cameraSwbtn.setOnCheckedChangeListener(this);
        String propValue = SystemProperties.get(CAMERA_ENABLE_KEY, "1"); // 默认启用

        // String cameraEnable = Settings.Global.getString(getContentResolver(), Settings.Global.CUSTOM_FUNCTION_CAMERA_ENABLE);
        if ("1".equals(propValue)) {
          cameraSwbtn.setChecked(true);
        }else {
          cameraSwbtn.setChecked(false);

        }	
        cameraSwbtn.setOnClickListener(this);
    }


    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // switch (buttonView.getId()) {
        //     case R.id.toggle_button:
        //         Toast.makeText(this, "toggle state changed : " + isChecked, Toast.LENGTH_SHORT).show();
        //         break;
        //     case R.id.switch_button:
        //         Toast.makeText(this, "wlan state changed : " + isChecked, Toast.LENGTH_SHORT).show();
        //         break;
        //     default:
        //         Toast.makeText(this, "no state changed", Toast.LENGTH_SHORT).show();
 
        // }
        if (buttonView== null) {
            return;


        }
        
    }

    @Override
    public void onClick(View v) {
	    if (  v == cameraSwbtn) {
                boolean isChecked = cameraSwbtn.isChecked();
                saveValue(isChecked);
            if (isChecked) {
                Toast.makeText(mContext, R.string.custom_function_camera_change_enable,Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(mContext, R.string.custom_function_camera_change_disable,Toast.LENGTH_SHORT).show();
            }

        }
        
    }

    private void saveValue(boolean enabled) {
        String  value = "0";
        if (enabled) {
           value = "1";
        }else {
            value = "0";
        }
        try {
            SystemProperties.set(CAMERA_ENABLE_KEY, enabled ? "1" : "0");
        } catch (Exception e) {
            Log.e("CustomFunction", "Failed to set property", e);
        }
       // Settings.Global.putString(getContentResolver(), Settings.Global.CUSTOM_FUNCTION_CAMERA_ENABLE,value);

    }
}

布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:text="@string/custom_function_control_setting"
        android:textSize="24dp"
        android:layout_margin="10dp"
        android:gravity="center"
        android:textColor="@android:color/black"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:layout_marginTop="30dp"
    android:orientation="horizontal">

      <TextView
        android:textSize="20dp"
        android:layout_marginLeft="10dp"
        android:text="@string/custom_function_control_camera_title"
        android:gravity="center"
        android:textColor="@android:color/black"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>            
        <View android:layout_height="1dp"
             android:layout_weight="1"
            android:layout_width="0dp"/>
        <Switch
            android:id="@+id/swbtn_camera"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:switchMinWidth="0dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="20dp"
            android:showText="false"
            android:switchPadding="10dp"
            android:textOff="close"
            android:textOn="open" />

</LinearLayout>

</LinearLayout>

二 摄像头控制逻辑添加:

//framework/av/services/camera/libcameraservice/CameraService.cpp 下

/**
    * 控制摄像头开关是否允许使用
    */
   const bool USING_CAMERA_ENABLE_LOCK = false;

。。。。。。。。。。。。忽略代码
Status CameraService::connectDevice(
        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
        const String16& cameraId,
        const String16& clientPackageName,
        const std::optional<String16>& clientFeatureId,
        int clientUid, int oomScoreOffset, int targetSdkVersion,
        /*out*/
        sp<hardware::camera2::ICameraDeviceUser>* device) {

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    String16 clientPackageNameAdj = clientPackageName;
    int callingPid = CameraThreadState::getCallingPid();
    bool systemNativeClient = false;
    if (doesClientHaveSystemUid() && (clientPackageNameAdj.size() == 0)) {
        std::string systemClient =
                StringPrintf("client.pid<%d>", CameraThreadState::getCallingPid());
        clientPackageNameAdj = String16(systemClient.c_str());
        systemNativeClient = true;
    }

    if (oomScoreOffset < 0) {
        String8 msg =
                String8::format("Cannot increase the priority of a client %s pid %d for "
                        "camera id %s", String8(clientPackageNameAdj).string(), callingPid,
                        id.string());
        ALOGE("%s: %s", __FUNCTION__, msg.string());
        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
    }
    
  +  if (USING_CAMERA_ENABLE_LOCK) {
  +      if (!isFlyscaleCameraEnabled()) {
  +          String8 msg =
  +              String8::format("flyscale camera not allow,Camera disabled by device +policy");
 +       ALOGE("%s: %s", __FUNCTION__, msg.string());
 +       return STATUS_ERROR(ERROR_DISABLED, msg.string());
 +       }
 +
 +   }

    if (CameraServiceProxyWrapper::isCameraDisabled()) {
        String8 msg =
                String8::format("Camera disabled by device policy");
        ALOGE("%s: %s", __FUNCTION__, msg.string());
        return STATUS_ERROR(ERROR_DISABLED, msg.string());
    }

    // enforce system camera permissions
    if (oomScoreOffset > 0 &&
            !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid())) {
        String8 msg =
                String8::format("Cannot change the priority of a client %s pid %d for "
                        "camera id %s without SYSTEM_CAMERA permissions",
                        String8(clientPackageNameAdj).string(), callingPid, id.string());
        ALOGE("%s: %s", __FUNCTION__, msg.string());
        return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.string());
    }
。。。。。。。。。。。。。忽略代码

OVER~

相关文章:

  • C#MVC项目引用Swagger的详细步骤
  • C++指针(二)
  • DAOS系统架构-组件
  • Mamba原理及在low-level vision的工作[持续更新]
  • 14-大模型微调和训练之-Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析(二分类))
  • opencv-python基础
  • 如何让老电脑运行快些(极限榨干老电脑硬件)
  • 傅利叶发布首款开源人形机器人N1:开发者可实现完整复刻
  • 科普:关系图谱中的网络特征如何输入到模型中?
  • 华为RH2288H V3服务器极速重装:从RedHat到openEuler 24超详细重装指南
  • 2025ArkTS基础UI(一)——Column、Row、Text、Button组件
  • 主服务器和子服务器之间通过NFS实现文件夹共享
  • 【数据结构】集合框架、时间复杂度和空间复杂度
  • 同时打开多个Microchip MPLAB X IDE
  • JAVA虚拟机(JVM)学习
  • vue 实战:百度音乐项目
  • 网络机顶盒OTT业务HTTPS网络包分析:Wireshark抓包与解析技术指南
  • 每日一题(小白)模拟娱乐篇27
  • router.js 中使用国际化
  • 【AI论文】OLMoTrace:将语言模型输出追溯到万亿个训练标记
  • 做企业平台的网站/seo是什么服务器
  • 设计网站推广方案/网络营销策划案范本
  • wordpress主页图片不显示/南京seo优化公司
  • 注册公司网站源码/百度搜首页
  • 做网站唐山/常用于网站推广的营销手段是
  • 临沂网站建设培训学校/杭州推广公司排名