Android RK356X TVSettings USB调试开关

Android RK356X TVSettings USB调试开关

    • 平台
    • 概述
    • 操作-打开USB调试
    • 实现源码
    • 补充说明

平台

在这里插入图片描述

RK3568 + Android 11

概述

RK3568 是瑞芯微(Rockchip)推出的一款高性能处理器,支持 USB OTG(On-The-Go)和 USB Host 功能。USB OTG 和 Host 的切换功能是 RK3568 的一项重要特性,允许设备在不同的 USB 角色之间动态切换,从而实现更灵活的应用场景。

USB OTG 和 Host 的切换功能

  1. USB OTG(On-The-Go)
    USB OTG 是一种允许设备在主机(Host)和设备(Device)之间动态切换的功能。通过 OTG 功能,RK3568 可以在以下两种模式之间切换:
    • 主机模式(Host Mode):RK3568 作为主机,连接其他 USB 设备(如 U 盘、键盘、鼠标等),并控制数据传输。

    • 设备模式(Device Mode):RK3568 作为从设备,连接到主机(如 PC),被主机控制和数据传输。

  2. 动态切换
    RK3568 支持在运行时动态切换 USB OTG 和 Host 模式,无需重新启动设备或重新插拔 USB 线缆。这种切换功能依赖于硬件设计和软件驱动的支持。


应用场景
USB OTG 和 Host 的切换功能在以下场景中有广泛应用:

  1. 移动设备
    • 在智能手机、平板电脑等设备中,OTG 功能允许用户通过 USB 连接外部设备(如 U 盘、键盘、鼠标等),扩展设备的功能。

    • 例如,用户可以将手机作为主机,连接 U 盘进行文件传输,或者连接键盘和鼠标进行办公。

  2. 嵌入式设备
    • 在嵌入式系统中,RK3568 的 OTG 功能可以用于连接各种 USB 设备,如打印机、摄像头、传感器等。

    • 通过动态切换,设备可以在主机和从机模式之间切换,适应不同的应用需求。

  3. 工业控制
    • 在工业自动化领域,RK3568 可以作为主机连接传感器、控制器等设备,也可以作为从机连接到上位机(如 PC)进行数据采集和监控。

    • 动态切换功能使得设备可以根据任务需求灵活调整角色。

  4. 车载系统
    • 在车载娱乐系统或导航设备中,OTG 功能可以用于连接外部存储设备(如 U 盘)播放媒体文件,或者连接诊断工具进行系统维护。

    • 动态切换功能使得设备可以同时支持多种连接方式。

  5. 物联网设备
    • 在物联网设备中,RK3568 可以通过 OTG 功能连接各种传感器或执行器,实现数据采集和控制。

    • 通过动态切换,设备可以根据网络环境或任务需求调整角色。

  6. 调试和开发
    • 在开发阶段,OTG 功能可以用于连接调试工具(如 JTAG 调试器)或烧录固件。

    • 动态切换功能使得开发者可以方便地在不同模式之间切换,提高开发效率。


技术实现
RK3568 的 USB OTG 和 Host 切换功能依赖于以下硬件和软件支持:
• 硬件支持:RK3568 集成了 USB OTG 控制器,支持动态角色切换。

• 软件驱动:需要操作系统(如 Linux)提供相应的驱动程序和工具,支持 OTG 功能的动态切换。

• 外部电路设计:需要设计合适的 USB 接口电路,支持 OTG 功能(如 ID 引脚检测)。

操作-打开USB调试

设置 > 设备偏好设置 > 开发者选项 > USB 连接状态

在这里插入图片描述

实现源码

packages/apps/TvSettings/Settings/src/com/android/tv/settings/system/development/DevelopmentFragment.java

import com.android.tv.settings.dialog.UsbModeSettings;
/*** Displays preferences for application developers.*/
public class DevelopmentFragment extends SettingsPreferenceFragmentimplements Preference.OnPreferenceChangeListener,EnableDevelopmentDialog.Callback, OemUnlockDialog.Callback, AdbDialog.Callback {private static final String TAG = "DevelopmentSettings";private static final String ENABLE_DEVELOPER = "development_settings_enable";private static final String ENABLE_ADB = "enable_adb";private static final String ENABLE_USB = "enable_usb";//...省略代码...@Overridepublic void onCreatePreferences(Bundle savedInstanceState, String rootKey) {mLogdSizeController = new LogdSizePreferenceController(getActivity());mLogpersistController = new LogpersistPreferenceController(getActivity(), getLifecycle());mUsbModeSetting = new UsbModeSettings(getPreferenceManager().getContext());if (!mUm.isAdminUser()|| mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)|| Settings.Global.getInt(mContentResolver,Settings.Global.DEVICE_PROVISIONED, 0) == 0) {// Block access to developer options if the user is not the owner, if user policy// restricts it, or if the device has not been provisionedmUnavailable = true;addPreferencesFromResource(R.xml.development_prefs_not_available);return;}addPreferencesFromResource(R.xml.development_prefs);final PreferenceScreen preferenceScreen = getPreferenceScreen();// Don't add to prefs lists or it'll disable itself when switched offmEnableDeveloper = (SwitchPreference) findPreference(ENABLE_DEVELOPER);final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);mEnableAdb = findAndInitSwitchPref(ENABLE_ADB);mEnableUsb = findAndInitSwitchPref(ENABLE_USB);mEnableInternetAdb = findAndInitSwitchPref(ENABLE_INTERNET_ADB);mEnableAbc = findAndInitSwitchPref(ENABLE_ABC);mEnableUsb.setChecked(mUsbModeSetting.getDefaultValue());if (mEnableUsb.isChecked()){mEnableUsb.setSummary(R.string.usb_connect_to_computer);} else {mEnableUsb.setSummary(R.string.usb_disconnect_to_computer);}//...省略代码....}

packages/apps/TvSettings/Settings/src/com/android/tv/settings/dialog/UsbModeSettings.java

package com.android.tv.settings.dialog;import com.android.tv.settings.R;import android.content.Context;
import android.os.Handler;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import android.os.storage.StorageManager;
import android.os.storage.StorageEventListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.SystemProperties;
import android.text.TextUtils;import android.util.Log;public class UsbModeSettings {private static final String TAG = "UsbModeSettings";// 0 otg 1 host 2 peripheralpublic static final String HOST_MODE = new String("host");public static final String SLAVE_MODE = new String("otg");public static final String PROP_FAKE_DATA_ROLE = "persist.fake_data_role";private static final String FILE_NAME_RK3399 = "/sys/kernel/debug/usb@fe800000/rk_usb_force_mode";private static final String FILE_NAME_RK3328 = "/sys/devices/platform/ff450000.syscon/ff450000.syscon:usb2-phy@100/otg_mode";private static final String FILE_NAME_RK3229 = "/sys/devices/platform/11000000.syscon/11000000.syscon:usb2-phy@760/otg_mode";private static final String FILE_NAME_RK356X = "/sys/devices/platform/fe8a0000.usb2-phy/otg_mode";private File file = null;private StorageManager mStorageManager = null;private String mMode = "";private String mSocName = "";private Context mContext;private boolean mLock = false;public UsbModeSettings(Context context) {mContext = context;mSocName = SystemProperties.get("sys.rk.soc");if (TextUtils.isEmpty(mSocName)) {mSocName = SystemProperties.get("ro.board.platform");}if(!TextUtils.isEmpty(mSocName) && mSocName.contains("rk3399")){file = new File(FILE_NAME_RK3399);}else{file = new File(FILE_NAME_RK3328);}file = getFile();mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);boolean ret = checkFile();String mode = ReadFromFile(file);if(ret && !TextUtils.isEmpty(mode)) {mMode = mode;}}private File getFile() {String fileName = FILE_NAME_RK3328;if (!TextUtils.isEmpty(mSocName) && mSocName.contains("rk3399")) {fileName = FILE_NAME_RK3399;} else if (!TextUtils.isEmpty(mSocName) && (mSocName.contains("rk322x") || mSocName.contains("rk3128h"))) {fileName = FILE_NAME_RK3229;} else if (!TextUtils.isEmpty(mSocName) && mSocName.contains("rk356x")) {fileName = FILE_NAME_RK356X;} else {fileName = FILE_NAME_RK3328;}return new File(fileName);}public boolean getDefaultValue() {if (isRk3368()) {//通过prop和init来设置otg模式return getFakeDataRole();}if (checkFile()) {Log.d("UsbModeSelect", "/data/otg.cfg not exist,but temp file exist");if (isRk3368()) {return getFakeDataRole();}if (mMode.equals(HOST_MODE)) {return false;} else {return true;}} else {mMode = HOST_MODE;return false;}}private String ReadFromFile(File file) {if (checkFile()) {try {FileInputStream fin = new FileInputStream(file);BufferedReader reader = new BufferedReader(new InputStreamReader(fin));String config = reader.readLine();fin.close();return config;} catch (IOException e) {Log.i(TAG, "ReadFromFile exception:" + e);e.printStackTrace();}}return null;}private void Write2File(File file, String mode) {if (!checkFile() || (mode == null))return;Log.d("UsbModeSelect", "Write2File,write mode = " + mode);try {FileOutputStream fout = new FileOutputStream(file);PrintWriter pWriter = new PrintWriter(fout);pWriter.println(mode);pWriter.flush();pWriter.close();fout.close();} catch (IOException re) {}}public void onUsbModeClick(String mode) {if (isRk3368()) {setPropFakeDataRole(mode);return;}if (mLock)return;mLock = true;mMode = mode;synchronized (this) {Log.d("UsbModeSettings", "synchronized start");new Thread(mUsbSwitch).start();}}private Runnable mUsbSwitch = new Runnable() {public synchronized void run() {Log.d("UsbModeSettings", "mUsbSwitch Runnable() in*******************");if (mStorageManager != null) {if (mMode == HOST_MODE) {mStorageManager.disableUsbMassStorage();Log.d("UsbModeSettings", "mStorageManager.disableUsbMassStorage()*******************");Write2File(file, mMode);} else {Write2File(file, mMode);Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()  in *******************");mStorageManager.enableUsbMassStorage();Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()   out*******************");}}Log.d("UsbModeSettings", "mUsbSwitch Runnable() out*******************");mLock = false;}};private boolean checkFile() {if (file == null) {Log.e(TAG, "file is null pointer");return false;}String fileName = file.getName();if (!file.exists()) {Log.e(TAG, fileName + " not exist!!!");return false;}if (!file.canRead()) {Log.e(TAG, fileName + " can't read!!!");return false;}if (!file.canWrite()) {Log.e(TAG, fileName + " can't write!!!");return false;}return true;}// 判断是否为3368芯片private boolean isRk3368() {if (!TextUtils.isEmpty(mSocName) && mSocName.contains("rk3368")) {return true;} else {return false;}}private boolean getFakeDataRole() {String fakeDataRole = SystemProperties.get(PROP_FAKE_DATA_ROLE, SLAVE_MODE);Log.d(TAG, "prop fakeDataRole = " + fakeDataRole);if (!TextUtils.isEmpty(fakeDataRole) && fakeDataRole.equals(SLAVE_MODE)) {return true;} else {return false;}}// 将mode转换为Int值,3368的mode为0,1,2private void setPropFakeDataRole(String mode) {Log.d(TAG, "setprop mode = " + mode);SystemProperties.set(PROP_FAKE_DATA_ROLE, mode);}
}

补充说明

  1. 以上源码接口需要system及以上权限
  2. StorageManager部分接口可以通过反射获得.

提取关键代码:

    @Overridepublic void onClick(View v) {StorageManager mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);File file = new File(FILE_NAME_RK356X);//切换为 OTG (USB 调试)if(R.id.btOtg == v.getId()) {Write2File(file, SLAVE_MODE);Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()  in *******************");enableUsbMassStorage(mStorageManager);Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()   out*******************");} else if(R.id.btHost == v.getId()) {//切换为HOSTdisableUsbMassStorage(mStorageManager);Log.d("UsbModeSettings", "mStorageManager.disableUsbMassStorage()*******************");Write2File(file, HOST_MODE);}}//写入 USB的模式: otg 或 hostprivate void Write2File(File file, String mode) {if (!new File(FILE_NAME_RK356X).exists() || (mode == null))return;Log.d("UsbModeSelect", "Write2File,write mode = " + mode);try {FileOutputStream fout = new FileOutputStream(file);PrintWriter pWriter = new PrintWriter(fout);pWriter.println(mode);pWriter.flush();pWriter.close();fout.close();} catch (IOException re) {}}//反射接口void enableUsbMassStorage(StorageManager sm){try {Method enableUsbMassStorage = sm.getClass().getMethod("enableUsbMassStorage");enableUsbMassStorage.invoke(sm);} catch (Exception e){e.printStackTrace();}}void disableUsbMassStorage(StorageManager sm){try {Method disableUsbMassStorage = sm.getClass().getMethod("disableUsbMassStorage");disableUsbMassStorage.invoke(sm);} catch (Exception e){e.printStackTrace();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/902381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft Edge for linux debian

下载地址 https://www.microsoft.com/en-us/edge/download?formMA13FJ 安装 # 下载安装包 wget https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/microsoft-edge-stable_135.0.3179.85-1_amd64.deb?brandM102 # 安装 sudo dpkg -i microsoft…

typedef MVS_API CLISTDEF0IDX(ViewScore, IIndex) ViewScoreArr;

查找 MVS_API 定义 我们没有在 List.h 文件中找到 MVS_API 的定义。MVS_API 很可能在 MVS 库的其他地方定义。一般来说,MVS_API 是控制 OpenMVS 库导入导出的宏,通常会出现在 MVS 的头文件中。为了回答这个问题,我可以提供 MVS 代码中常见的…

5.4/Q1,GBD数据库最新文章解读

文章题目:The global burden of high BMI among adolescents between 1990 and 2021 DOI:10.1038/s43856-025-00838-2 中文标题:1990 年至 2021 年青少年高 BMI 的全球负担 发表杂志:Commun Med 影响因子:1区&#xff…

【形式化验证基础】活跃属性Liveness Property和安全性质(Safety Property)介绍

文章目录 一、Liveness Property1、概念介绍2、形式化定义二、Safety Property1. 定义回顾2. 核心概念解析3. 为什么强调“有限前缀”4. 示例说明4.1 示例1:交通信号灯系统4.2 示例2:银行账户管理系统5. 实际应用的意义三. 总结一、Liveness Property 1、概念介绍 在系统的…

Redis面试——常用命令

一、String (1)设置值相关命令 1.1.1 SET 功能:设置一个键值对,如果键已存在则覆盖旧值语法: SET key value [EX seconds] [PX milliseconds] [NX|XX]EX seconds:设置键的过期时间为 seconds 秒 PX milli…

【Unity】使用Cinemachine+CharacterController实现第三人称视角下的角色视角、移动和跳跃控制

1.初始配置 安装Cinemachine插件给角色添加CharacterConroller创建Cinemachine-->Free Look Camera在Free Look Camera中调整参数,Y Axis勾选Inver,X Axis取消勾选InverFree Look Camera要看向角色 跟随角色(自行设置,我就不…

深入理解 DML 和 DQL:SQL 数据操作与查询全解析

深入理解 DML 和 DQL:SQL 数据操作与查询全解析 在数据库管理中,SQL(结构化查询语言)是操作和查询数据的核心工具。其中,DML(Data Manipulation Language,数据操作语言) 和 DQL&…

MongoDB数据库的安装到入门使用详细讲解

本篇文章主要讲解MongoDB的安装使用教程及基础的数据库管理和操作能力的讲解,通过本篇文章您可以快速的掌握对MongDB数据库的基本认识及,基础开发能力。 一、MongoDB介绍 MongoDB是一款免费开源的非关系型数据库,该数据库适应于复杂关系的存储和管理,非常适合数据结构复杂…

git提交实现文件或目录忽略

前言 开发中使用git下载项目代码开发,存在不需要提交文件或目录,这里记录下ideajava项目开发添加以下配置可忽略不需要提交文件,以方便我们提交代码时,查看及提交文件只涉及项目代码修改文件。 git提交实现文件或目录忽略 .gitignore 文件的内容列出了在…

go语言的八股文

1.go语言触发异常的场景有哪些 运行时错误 1.空指针解引用:尝试访问一个未初始化的指针指向的内存,会导致程序崩溃并触发异常。 2.数组越界访问:试图访问数组中不存在的索引,比如数组长度为5,却尝试访问索引为10的元素…

Ubuntu安装MySQL步骤及注意事项

一、安装前准备 1. 系统更新:在安装 MySQL 之前,确保你的 Ubuntu 系统软件包是最新的,这能避免因软件包版本问题导致的安装错误,并获取最新的安全补丁。打开终端,执行以下两条命令: sudo apt update sudo …

【愚公系列】《Python网络爬虫从入门到精通》054-Scrapy 文件下载

🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! &#x1f…

2025最新︱中国信通院静态应用程序安全测试(SAST)工具能力评估,悬镜安全灵脉AI通过评估!

背景 研发运营安全(DevSecOps)从研发运营(DevOps)的概念延伸和演变而来,其核心理念是将安全贯穿从开发到运营的软件开发生命周期的每一个环节,在每个阶段自动实施安全措施,从而实现快速开发交付…

辛格迪客户案例 | 浙江高跖医药委托生产质量管理协同(OWL MAH)项目

一、案例概述 浙江高跖医药科技股份有限公司是一家集“研、产、销”为一体的专业化药品持证企业。高跖医药自成立之初就建立并运行着一套相对完善的质量管理体系,涵盖了药品的研发、生产监管及销售。高跖医药于2022年选择实施了辛格迪的“委托生产质量管理协同解决…

【NLP 65、实践 ⑯ 基于Agent优化文章】

羁绊由我而起,痛苦也由我承担 —— 25.4.18 一、⭐【核心函数】定义大模型调用函数 call_large_model prompt:用户传入的提示词(如 “请分析这篇作文的主题”),指导模型执行任务 client:Zhipu…

【锂电池SOH估计】BP神经网络锂电池健康状态估计,锂电池SOH估计(Matlab完整源码和数据)

目录 效果一览程序获取程序内容研究内容基于BP神经网络的锂电池健康状态估计研究摘要关键词1. 引言1.1 研究背景1.2 研究意义1.3 研究目标2. 文献综述2.1 锂电池SOH估计理论基础2.2 传统SOH估计方法2.3 基于BP神经网络的SOH估计研究进展2.4 研究空白与创新点3. BP神经网络原理3…

2025第十六届蓝桥杯python B组满分题解(详细)

目录 前言 A: 攻击次数 解题思路: 代码: B: 最长字符串 解题思路: 代码: C: LQ图形 解题思路: 代码: D: 最多次数 解题思路: 代码: E: A * B Problem 解题思路&…

第十二节:原理深挖-React Fiber架构核心思想

链表结构、时间切片(Time Slicing) 优先级调度实现(如用户输入>网络请求) React Fiber架构深度解析:从链表到优先级调度的革命性升级 一、Fiber架构核心设计思想 React Fiber是React 16的底层协调算法重构&#x…

你学会了些什么211201?--http基础知识

概念 HTTP–Hyper Text Transfer Protocol,超文本传输协议;是一种建立在TCP上的无状态连接(短连接)。 整个基本的工作流程是:客户端发送一个HTTP请求(Request ),这个请求说明了客户端…

MCU开发学习记录8 - 基本定时器学习与实践(HAL库) - 定时器DMA循环模式修改ARR值、定时器中断方式修改ARR值 - STM32CubeMX

名词解释: TRGO:Trigger Out General Purpose Output ARR:Auto-reload PSC:Prescaler CNT:Counter EGR:event generation register 本文将介绍基本定时器的概念、相关函数以及STM32CubeMX生成定时器的配置…