常用命令

LEETCODE

hasmap

unordered_map<int, int> map
int index, value;
map.find(value) != map.end()
map[index] = value;

vector

vector<int> result;
int index, value;
result.push_back(value);
reverse(result.begin(),result.end());

stack

stack<int> stack;
int index, value;
stack.empty();
stack.push(value);
stack.top();
stack.pop();

拉取代码

单独下载一个project
git clone http://myrepo.xxx.com/project/.git ,这样在当前目录下得到一个project子目录
例如下载alps/frameworks/av

<project name="mtk_N/alps/external/skia" path="alps/external/skia" />

对应的命令为:

git clone  ssh://xxxx@myrepo.xxx.com:29418/mtk_N/alps/external/skia/.git alps/external/skia
git branch -a,列出所有分支名称如下:
remotes/origin/dev
remotes/origin/release
git checkout origin/dev -b dev,作用是checkout远程的dev分支,在本地起名为dev分支,并切换到本地的dev分支

下载整个代码库

repo init -u ssh://yourname@myrepo.xxx.com:29418/mtk_N/alps/manifest -b <BRANCH> -m <MANIFEST>

这里-m和-b的含义是:
注意到manifest.git本身也是一个git project
-b指定的是使用这个git project的哪个branch
-m指定的是,下载该git project中的哪个文件(应该是首先切换了branch,然后再下载该文件)。

开始抓取代码

repo sync

选项:
-j : 多任务,一般8核心可以开到16任务,过多会起反作用
-c: 只下载当前分支代码
-d: 让工程回退到manifest指定的版本
-f: 如果某个工程同步失败,继续同步

批量创建本地分支
repo start [–all | …]
刚克隆下来的代码是没有分支的,repo start实际是对git checkout –b 命令的封装。为指定的项目或所有项目(若使用—all参数),以清单文件中为设定的分支,创建特性分支。这条指令与git checkout –b 还是有很大的区别的,git checkout –b 是在当前所在的分支的基础上创建特性分支,而repo start是在清单文件设定分支的基础上创建特性分支。

Example:
  repo start  stable  --all

git branch命令

查看分支

–list < pattern> 匹配查找,展示名称符合pattern的分支
-a 所有分支:本地分支,远程追踪分支
-r 远程追踪分支
–contains < commit> 包含某次提交的所有分支

创建分支

git branch < branchName>
-t –track
git branch -t b1 b2 以b2为upstream创建b1分支

重命名分支

-m –move < old> < new>

跟踪分支

-u
–set-upstream-to

删除分支

-d 删除分支
-D 强制删除
-rd 删除远程跟踪分支

本地删除远程分支

Pushing an empty < src> allows you to delete the < dst> ref from the remote repository.
git push 的src参数为空会删除远程分支
git push –prune 没有本地对应分支的远程分支
git push -d 删除远程分支

Camera分析LOG开关

打开拍照相关的log

//查看相机信息
adb shell setprop vendor.debug.camera.log 1
//查看拍照信息
adb shell setprop vendor.debug.camera.capture.log 1
//查看HAL3A信息
adb shell setprop vendor.debug.hal3av3.log 1
//查看feature信息
adb shell setprop vendor.debug.camera.featuresetting.log 1

查找包含字符串的文件

find . -name *.h -type f -print | xargs grep "libaudio_param_parser" --color
grep -rn "libaudio_param_parser" *

查询当前磁盘容量

du -sh : 查看当前目录总共占的容量。而不单独列出各子项占用的容量 
du -lh --max-depth=1 : 查看当前目录下一级子文件和子目录占用的磁盘容量。

编译命令

sudo apt-get install libswitch-perl
make -j4 2>&1|tee make.log

关闭开机向导

adb shell pm disable com.google.android.setupwizard

替换系统文件

最新的adb 工具包才支持adb disable-verity命令,如果是Linux开发环境,则可使用工程编译结果目录out/host/linux-x86/bi下的adb执行文件

adb root 
adb disable-verity 
adb reboot
adb root 
adb remount 

动态开启framework日志

//必须是usedebug版本才可以
adb shell setprop log.tag.AudioService.MOD D
adb shell setprop log.tag.AudioService.VOL D
adb shell setprop log.tag.AudioManager D
adb shell stop
adb shell start

替换库文件调试脚本

#!/bin/sh
echo "mm"
mmm vendor/mediatek/proprietary/hardware/audio/nxp/
echo "root"
adb root
adb remount
echo "push"
adb push out/target/product/tk6757_66_n1/system/lib/libtfa9891_interface.so /system/lib/
adb push out/target/product/tk6757_66_n1/system/lib64/libtfa9891_interface.so /system/lib64/
echo "reboot sleep"
adb reboot
sleep 30
echo "root"
adb root
adb remount
echo "logcat"
adb logcat | grep Tfa98xxx

按时间命名文件

#!/bin/sh
echo "mm"
mmm speex/
adb push out/target/product/tk6757_66_n1/system/bin/speextest /system/bin/
adb push /mnt/hgfs/share_linux/采访功能/8k/echo.wav /sdcard/
adb push /mnt/hgfs/share_linux/采访功能/8k/ref.wav /sdcard/
adb shell rm /sdcard/out.pcm
echo "bin"
adb shell speextest
adb pull /sdcard/out.pcm /mnt/hgfs/share_linux/采访功能/8K_out_$(date -d "today" +"%Y%m%d_%H%M%S").pcm
echo "end"

修改编译的虚拟内存

alps/prebuilts/sdk/tools/jack_server_setup.mk
ifneq ($(ANDROID_JACK_VM_ARGS),)
jack_vm_args := $(ANDROID_JACK_VM_ARGS) -Xmx4096m
else
jack_vm_args := -Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m
endif
available_jack_jars := $(wildcard $(LOCAL_PATH)/jacks/jack-*.jar)

dump数据

void AudioTrackDump::dump(const char *filepath, void *buffer, int count, const char *property)
{
    int ret;
    char value[256];
    property_get(property, value, "0");
    int bflag = atoi(value);
    if (bflag) {
        ret = checkPath(filepath);
        if (ret < 0) {
            ALOGE("dump fail!!!");
        } else {
            FILE *fp = fopen(filepath, "ab+");
            if (fp != NULL) {
                fwrite(buffer, 1, count, fp);
                fclose(fp);
            } else {
                ALOGE("dump %s fail", property);
            }
        }
    }
}
int AudioTrackDump::checkPath(const char *path)
{
    char tmp[256];
    int i = 0;
    while (*path) {
        tmp[i] = *path;
        if (*path == '/' && i) {
            tmp[i] = '\0';
            if (access(tmp, F_OK) != 0) {
                if (mkdir(tmp, 0770) == -1) {
                    ALOGE("mkdir error! %s",(char*)strerror(errno));
                    return -1;
                }
            }
            tmp[i] = '/';
        }
        i++;
        path++;
    }
    return 0;
}

堆栈打印

Linux Kernel
Kernel里最简单,直接有几现成的函数可以使用:
dump_stack() 这个函数打出当前堆栈和函数调用backtrace后接着运行WARN_ON(x) 这个函数跟dump_stack打出来。
打印出来的结果都在kernel log命令就可以看到了

Native C++
Android在新版(至少5.0, 6.0)里加入了CallStack类,这个类可以打出当前的backtrace。用法很简单:

1. 前面确保包含头文件 #include “utils/CallStack.h”;
2. Android.mk的库依赖列表(LOCAL_SHARED_LIBRARIES)里包含libutils,一般都已经包含了;
3. 然后在要打印堆栈处加入android::CallStack cs(“haha”);“haha”是在logcat输出的TAG,这里可以自己定义。
如果上下文已经在android namespace里,”android::”前缀就不必加了。Native C++的输出log可以在logcat里看到。
注意,在网上的一些文档里说要这么用:
```
CallStack stack;
stack.update();
stack.dump();
```
这样做已经不行了,在新版Android里编译不过。

Java
Java最详细,连文件名和行号都打出来了:

Exception e = new Exception("haha"); 
e.printStackTrace(); 

追踪出错地址

prebuilts/tools/gcc-sdk/addr2line -e out/target/product/z4dtg/obj/EXECUTABLES/xxxxx_intermediates/LINKED/xxxxxxxx  0x00007165

Ubuntu下安装最新OpenJdk1.8

1、sudo add-apt-repository ppa:openjdk-r/ppa
2、sudo apt-get update
3、sudo apt-get install openjdk-8-jdk
4、执行:sudo update-alternatives –config java,选择java的版本
5、执行:sudo update-alternatives –config javac,选择javac的版本

Fastboot

adb reboot bootloader
fastboot devices
fastboot oem unlock
fastboot oem unlock-go
fastboot flash boot boot.img
fastboot flash system system.img
fastboot reboot

Ubuntu上ADB devices找不到设备

1. 用lsusb命令查询usb设备id,其中Device 027是我的手机设备,usb id为2717。
2. 进入~/.android/目录,创建adb_usb.ini文件;
3. 编辑adb_usb.ini文件,将设备的usb id添加到文件里 
4. adb kill-server杀死adb服务;
5. 最后,用adb devices重新查找设备,就可以找到了;

ubuntu配置adb环境变量

1、sudo  gedit   ~/.bashrc 
2、将下面的两句加到上面打开的文件里 
   export ANDROID_HOME=/home/sdk文件路径
   export PATH=$PATH:$ANDROID_HOME/platform-tools
3、重启电脑,大功告成!!

Jack故障处理

//编译卡住
./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin stop-server
./prebuilts/sdk/tools/jack-admin start-server

//Out of memory
修改文件jack_server_setup.mk under prebuilts\sdk\tools
ANDROID_JACK_VM_ARGS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g"
./prebuilts/sdk/tools/jack-admin stop-server
./prebuilts/sdk/tools/jack-admin start-server

拉取多媒体库

adb shell content query --uri content://media/external/file > external_file.txt
adb shell content query --uri content://media/external/images/media > external_images.txt
adb shell content query --uri content://media/external/audio/media > external_audio.txt
adb shell content query --uri content://media/external/video/media > external_video.txt
adb shell content query --uri content://media/external/video/thumbnails > external_thumbnails.txt

git下git diff用法

1、生成patch(在代码修改后没有commit之前的状态执行,进入想生成patch的目录即可)

 git diff > patch_3

2、打patch,方法和linux的diff一样

#patch -p0 < patch_3

 git apply patch_3  //也可用这个命令打patch

根据进程名字杀死进程

ps -ef | grep procedure_name | grep -v grep | awk '{print $2}' | xargs kill -9

虚拟机挂载虚拟磁盘

mkdir workspace
mkdir workspace2

sudo gedit /etc/fstab
/dev/sdb1       /home/user/workspace2      ext4    defaults       0       0
/dev/sdc1       /home/user/workspace      ext4    defaults       0       0

修改用户名和邮箱

sudo git config --global user.name "yourname"

sudo git config --global user.email yourname@xxx.com.cn

生成秘钥

ssh-keygen

计算函数执行时间

方式一
#include<time.h>
nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
MY_LOGD("consumingTime = %f", double((end-start)/1000000));
方式二
auto start = std::chrono::steady_clock::now();
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end - start;
uint64_t finalsize = sstat.st_size;
ALOGV("Got a file over MTP. Time: %fs, Size: %" PRIu64 ", Rate: %f bytes/s",
            diff.count(), finalsize, ((double) finalsize) / diff.count());

如何打开pr_debug调试信息

$cat /proc/sys/kernel/printk
7      4       1       7
$echo 8 > /proc/sys/kernel/printk
$cat /proc/sys/kernel/printk
8      4       1       7

查看 读写SD卡权限

判断APP运行时权限如下:

adb remount;//挂载
adb shell;//进入shell
ps | grep fmradio;//查找FMRadio的PID,前提是手机打开FMRadio,插入耳机
cd proc/4830;//进入PID对应的信息文件中
cat status;//查看进程信息

发现此时,FMRadio对于的组权限如下:

com.android.fmradio Groups: 1013 3002 3003 9997 50010
com.android.soundrecorder Groups: 1015 1023 3003 9997 50105

根据系统权限的定义,有兴趣的同学可以去看一下这个文件
system/core/include/private/android_filesystem_config.h
分析这些Gid发现:
1015 为sdcard_rw,1023 为media_rw权限

源码文件:frameworks/base/data/etc/platform.xml
这个文件中定义了底层权限组GID和高层权限名字之间的对应关系
其实,在这个文件已经定义过了

手机数据区文件:data/system/packages.xml
这个文件由PackageManagerService.Java生成,里面记录了系统当中安装的APK的所有属性,权限等信息。L之前,当系统中的APK安装、删除、升级时,文件就会被更新。L之后,重启才会重新扫描更新该文件。

C++替换字符串

std::string srt2 = (const char*)path;
std::string tmps2 = "/mnt/media_rw/";
if(srt2.find("/storage/") != std::string::npos  &&
        srt2.find("/storage/emulated/") == std::string::npos){
    tmps2 = tmps2 + srt2.substr(9);
    path.set(tmps2.c_str());
 }
  1. 截取子串
 s.substr(pos, n)    截取s中从pos开始(包括0)的n个字符的子串,并返回
 s.substr(pos)        截取s中从从pos开始(包括0)到末尾的所有字符的子串,并返回
  1. 替换子串
s.replace(pos, n, s1)    用s1替换s中从pos开始(包括0)的n个字符的子串
  1. 查找子串
 s.find(s1)         查找s中第一次出现s1的位置,并返回(包括0)
 s.rfind(s1)        查找s中最后次出现s1的位置,并返回(包括0)
 s.find_first_of(s1)       查找在s1中任意一个字符在s中第一次出现的位置,并返回(包括0)
 s.find_last_of(s1)       查找在s1中任意一个字符在s中最后一次出现的位置,并返回(包括0)
 s.fin_first_not_of(s1)         查找s中第一个不属于s1中的字符的位置,并返回(包括0)
 s.fin_last_not_of(s1)         查找s中最后一个不属于s1中的字符的位置,并返回(包括0)

读取二进制文件

#include <iostream>
#include <fstream>

filebuf *pbuf;
ifstream filestr;
int size = 0;
char * buffer = NULL;
filestr.open ("test.cng", ios::binary);
if (filestr.fail()){
       return;
}
pbuf = filestr.rdbuf();
size = pbuf->pubseekoff(0, ios::end, ios::in);
pbuf->pubseekpos (0, ios::in);
buffer = new char[size];
pbuf->sgetn(buffer, size);
filestr.close();
delete []buffer;

CTS命令

无法执行CTS命令
去out 目錄下將out/host/linux-x86/bin/aapt放到某個目錄下(如:/tools/bin/aapt),將該目錄(如:/tools/bin/aapt) 添加到 PATH 中去。

export PATH=$PATH:~/workspace/tp706_p/alps/out/host/linux-x86/bin

执行GTS测试

run gts -s 0123456789ABCDEF -m GtsMediaTestCases -t com.google.android.media.gts.WidevineH264PlaybackTests#testClearWithUHD30 --abi arm64-v8a --skip-preconditions

执行GSI测试

run cts-on-gsi​​ -s 3901A18303900273 -m CtsMediaTestCases -t android.media.cts.RingtoneManagerTest#testStopPreviousRingtone --abi arm64-v8a --skip-preconditions

测试命令

full run 全部测试命令:run cts --plan CTS -s device serial
测试自己添加的计划命令: run cts --subplan name
测试整个 package 命令: run cts -m package_name
测试单项命令:run cts -m package_name -t module_name+case_name
继续测试命令:run cts -r session_ID

查看命令

查看测试结果命令 : l r
查看测试时间多长命令: l i
查看多少个设备连接命令: l d
查看当前测试窗口正在执行的命令: l c
查看有多少个 module 的命令:l m

其他命令或者参数

强制退出命令 kill
禁止重启命令 --disable-reboot
跳过预设环境命令 --skip-preconditions
跳过某项 package 命令 --exclude-filter+package_name
只测试某项 package 命令 --include-filter+ package_name
测试某台样机的参数 -s 或--serial+serial_name
几台样机同时测试的命令 --shards+number

以上都是写简单常用的命令,用 run cts –help-all 可以显示其他更详细的命令

Init.rc妙用及语法说明

Service

service < name> < pathname> [ < argument> ]*
< option>
< option>

常用Options(用于修饰service)
1、critical 表示这是一个关键的service,4分钟内退出4次,则系统重启进入recovery mode。
2、disabled 这个服务不会随着它的类启动而自动启动,必须明确指定服务名称启动。
3、setenv 设置环境变量。
4、socket [ [ [ ] ] ] 创建一个socket接口/dev/socket/,使本地service和java可以通信。详见
http://blog.csdn.net/eliot_shao/article/details/53159989
5、user 执行service之前改变用户名。
6、group [ ]* 执行service之前改变用户组。
7、oneshot 当service退出后不会重启。
8、class 为service指定一个类名,具有相同类名的service可以一起启动和停止。
9、onrestart 启动一个Command,当service重新启动的时候。

service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm

Actions

on < trigger>
< command>
< command>
< command>

常用Triggers说明:
1、boot eg: on boot 这是第一个触发的,当init进程启动时候。

on boot
  export PATH /sbin:/system/sbin:/system/bin
  export LD_LIBRARY_PATH /system/lib

  mkdir /dev
  mkdir /proc
  mkdir /sys

2、= when the property is set to the specific value

on property:vts.native_server.on=1
   stop audioserver
on property:vts.native_server.on=0
   start audioserver
service audioserver /system/bin/audioserver
   class core
   user audioserver

3、device-added- device-removed-
当一个设备节点被删除或者添加的时候,触发。

on device-added-/dev/compass=1
start akmd
on device-removed-/dev/compass=0
stop akmd
service akmd /sbin/akmd
disabled
user akmd
group akmd

4、service-exited- 当制定的service退出的时候触发。
Commands
1、exec [ ]* Fork and execute a program ().
2、export

export PATH /sbin:/system/sbin:/system/bin

3、import 解析init配置文件,扩展当前的init.rc配置
4、chdir 改变当前的工作路径
5、chmod 改变文件的访问权限
6、chown 改变文件拥有者和组
7、class_start 启动某个class

on nonencrypted
class_start main
class_start late_start

8、class_stop 停止某个class
9、enable 使能一个service 如果他是disable的。
10、insmod 安装模块
11、mkdir [mode] [owner] [group] 创建文件夹
12、mount [ ]* 挂载设备到某个目录
13、setenforce 0|1 设置SELinux system-wide的状态
14、setprop 设置system property
15、start 启动service
16、stop 停止service
17、wait [ ] 等待某个文件的出现
18、write 向文件写入字符串

write /proc/cpu/alignment 4

HIDL 接口

软件包位于 hardware/interfaces 或 vendor/ 目录下(少数例外情况除外)。hardware/interfaces 顶层会直接映射到 android.hardware 软件包命名空间;版本是软件包(而不是接口)命名空间下的子目录。
hidl-gen 编译器会将 .hal 文件编译成一组 .h 和 .cpp 文件。这些自动生成的文件可用来编译客户端/服务器实现链接到的共享库。用于编译此共享库的 Android.bp 文件由 hardware/interfaces/update-makefiles.sh 脚本自动生成。每次将新软件包添加到 hardware/interfaces 或在现有软件包中添加/移除 .hal 文件时,您都必须重新运行该脚本,以确保生成的共享库是最新的。

HIDL 软件包中自动生成的文件会链接到与软件包同名的单个共享库(例如 android.hardware.samples@1.0)。该共享库还会导出单个标头 IFoo.h,用于包含在客户端和服务器中。绑定式模式使用 hidl-gen 编译器并以 IFoo.hal 接口文件作为输入,它具有以下自动生成的文件:
在这里插入图片描述)

Android SELinux avc dennied权限问题解决方法

https://blog.csdn.net/tung214/article/details/72734086
1、调试确认SELinux问题
为了澄清是否因为SELinux导致的问题,可先执行:

setenforce 0 (临时禁用掉SELinux)
getenforce  (得到结果为Permissive)

如果问题消失了,基本可以确认是SELinux造成的权限问题,需要通过正规的方式来解决权限问题。

遇到权限问题,在logcat或者kernel的log中一定会打印avc denied提示缺少什么权限,可以通过命令过滤出所有的avc denied,再根据这些log各个击破:

cat /proc/kmsg | grep avc 
或
dmesg | grep avc

例如:

audit(0.0:67): avc: denied { write } for path="/dev/block/vold/93:96" dev="tmpfs" ino=1263 scontext=u:r:kernel:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0

可以看到有avc denied,且最后有permissive=0,表示不允许。

2、复合权限
有时候avc denied的log不是一次性暴露所有权限问题,要等解决一个权限问题之后,才会暴露另外一个权限问题。比如提示缺少某个目录的read权限,加入read之后,才显示缺少write权限,要一次次一次试,一次一次加,时间成本极大。
针对dir缺少的任何权限,建议赋予create_dir_perms,基本涵盖对dir的所有权限,比如:
{ open search write read rename create rmdir getattr }等等。
针对file缺少的任何权限,建议赋予rwx_file_perms,基本涵盖对file的所有权限,比如:
包含{ open read write open execute getattr create ioctl }等等。

3、万能公式
通过这四个案例,我们可以总结出一般规律,
以第案例4为例:

audit(1441759284.810:5): avc: denied { read } for pid=1494 comm="sdcard" name="0" dev="nandk" ino=245281 scontext=u:r:sdcardd:s0 tcontext=u:object_r:system_data_file:s0 tclass=dir permissive=0

某个scontext对某个tclass类型的tcontext缺乏某个权限,我们需要允许这个权限:
我们的log重新排列一下,

scontext = u:r:sdcardd
tcontex t= u:object_r:system_data_file:s0
tclass = dir
avc: denied { read }

得到万能套用公式如下:
在scontext所指的.te文件(例如sdcardd.te)中加入类似如下allowe内容:

allow  sdcardd  system_data_file:dir  read;  或者
allow  sdcardd  system_data_file:dir  rw_dir_perms;

新设备节点增加访问权限

驱动创建了一个新的设备节点,即使权限是777,android层也是没有访问权限的。
下面以一个/dev/wifi_bt节点为示范,让此节点被用户空间的system_server进程访问。

  1. 编辑devicesoftwinner/astar-common/sepolicy/device.te,仿照这个文件里的写法,定义一个dev_type类型的wifi_bt_device设备:
type misc_block_device, dev_type;
type private_block_device, dev_type;
//新增
type wf_bt_device, dev_type;  
  1. 编辑file_contexts.te,将/dev/wf_bt节点声明为第1步定义的wf_bt_device:
/dev/block/by-name/misc         u:object_r:misc_block_device:s0
/dev/block/by-name/alog         u:object_r:log_block_device:s0
/dev/block/by-name/private      u:object_r:private_block_device:s0
// 新增
/dev/wf_bt              u:object_r:wf_bt_device:s0  
  1. 在system_server.te,根据dmesg | grep avc允许system_server对wf_bt_device这个节点可读可写:
allow system_server qtaguid_proc:file rw_file_perms;  
allow system_server qtaguid_device:chr_file rw_file_perms;  
//新增
allow system_server wf_bt_device:chr_file rw_file_perms;  

其他进程如需访问/dev/wf_bt节点,依样画葫芦,增加对wf_bt_device的权限即可。

新目录增加访问权限

创建了一个新的目录,即使权限是777,android层也是没有访问权限的。
下面以一个/data/audio_param目录为示范,让此节点被用户空间的system_server进程访问。

  1. 编辑devicesoftwinner/astar-common/sepolicy/file.te,仿照这个文件里的写法,定义一个dev_type类型的data_audioparma_file设备:
type misc_block_device, dev_type;
type private_block_device, dev_type;
//新增
type data_audioparma_file, file_type, data_file_type, core_data_file_type;
  1. 编辑file_contexts.te,将/data/audio_param目录声明为第1步定义的data_audioparma_file:
/dev/block/by-name/misc         u:object_r:misc_block_device:s0
/dev/block/by-name/alog         u:object_r:log_block_device:s0
/dev/block/by-name/private      u:object_r:private_block_device:s0
// 新增
/data/audio_param(/.*)?     u:object_r:data_audioparma_file:s0
  1. 在system_server.te,根据dmesg | grep avc允许system_server对 /data/audio_param这个目录可读可写:
allow system_server qtaguid_proc:file rw_file_perms;  
allow system_server qtaguid_device:chr_file rw_file_perms;  
//新增
allow system_server data_audioparma_file:dir create_dir_perms;
allow system_server data_audioparma_file:file create_file_perms;

新建.te安全策略文件方法

以上基本是对已经存在的进程增加权限,但对第三方进程改如何新增一个全新的te文件并赋予权限呢?
以写mac地址的setmacaddr执行文件为例(这个执行档android原生不存在,自行添加的):
在init.xxx.rc中如下服务:

service engsetmacaddr  /system/bin/setmacaddr  /data/misc/wifi/wifimac.txt
   class main
   disabled
oneshot
  1. 在device/softwinner/astar-common/sepolicy/file_contexts中,参考其他进程声明一个scontext:
/system/bin/install-recovery.sh u:object_r:install_recovery_exec:s0
/system/bin/dex2oat     u:object_r:dex2oat_exec:s0
/system/bin/patchoat    u:object_r:dex2oat_exec:s0
/system/bin/setmacaddr u:object_r:engsetmacaddr_exec:s0

指定setmacaddr的路径,并指定一个名字,一定要以service名+_exec结尾

2.参考其.te文件在device/softwinner/astar-common/sepolicy/file_contexts 创建engsetmacaddr.te文件,内容如下:

type engsetmacaddr, domain;
type engsetmacaddr_exec, exec_type, file_type;
init_daemon_domain(engsetmacaddr)
allow engsetmacaddr  vfat:dir { search write add_name create};
allow engsetmacaddr  vfat:file { create read write open };
allow engsetmacaddr  engsetmacaddr:capability dac_override;
allow engsetmacaddr  shell_exec:file { execute read open execute_no_trans};
allow engsetmacaddr  system_data_file:dir { write add_name remove_name };
allow engsetmacaddr  system_data_file:file { create execute_no_trans write open setattr};
allow engsetmacaddr  system_file:file { execute_no_trans};

以上赋予的权限全部是根据avc denied的log缺什么一步一步补什么来的。

如何配置策略

https://blog.csdn.net/tww85/article/details/52451606
编译出来的策略文件在哪?
ODM策略编译出来的策略文件在out/…/vendor/etc/selinux目录下
vendor_file_contexts vendor_hwservice_contexts vendor_property_contexts vendor_seapp_contexts vndservice_contexts
原生策略编译出来的策略文件在out/…/system/etc/selinux目录下
plat_file_contexts plat_hwservice_contexts plat_property_contexts plat_seapp_contexts plat_service_contexts

需要先了解系统针对客体和主体提供了哪些设置属性和操作。
external/sepolicy/security_classes 定义了客体的基本类型,比如下面的

# for userspace object managers
class security
class process
class system
class capability
#//file-related classes
class filesystem
class file
class dir
class fd
class lnk_file
class chr_file
class blk_file
class sock_file 

external/sepolicy/access_vectors 文件列出来各种客体类型所拥有的属性,比如下面的file类型和dir 类型,类型间可以有集成关系。

common file
{
ioctl
read
write
create
getattr
setattr
lock
relabelfrom
relabelto
append
unlink
link
rename
execute
swapon
quotaon
mounton
}
class dir
inherits file
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}

external/sepolicy/global_macros全局宏变量定义文件,也就是用一个宏变量同时表示几个属性。如下例子

define(`x_file_perms', `{ getattr execute execute_no_trans }')
define(`r_file_perms', `{ getattr open read ioctl lock }')
define(`w_file_perms', `{ open append write }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
define(`ra_file_perms', `{ r_file_perms append }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
define(`link_file_perms', `{ getattr link unlink rename }')
define(`create_file_perms', `{ create setattr rw_file_perms link_file_perms }')

external/sepolicy/te_macros 宏规则变量定义文件,也就是用一个变量来表示连续执行几条规则。如下例子

define(`domain_trans', `
// Old domain may exec the file and transition to the new domain.
allow $1 $2:file { getattr open read execute };
allow $1 $3:process transition;
//New domain is entered by executing the file.
allow $3 $2:file { entrypoint open read execute getattr };
//New domain can send SIGCHLD to its caller.
allow $3 $1:process sigchld;
//Enable AT_SECURE, i.e. libc secure mode.
dontaudit $1 $3:process noatsecure;
//XXX dontaudit candidate but requires further study.
allow $1 $3:process { siginh rlimitinh };
')

external/sepolicy/file_contexts 文件安全上下文定义文件。就是说对于一个文件或者目录,它的安全上下文应该在这里定义,如果没有定义,那么默认和父目录的安全上下文一样。
比如说我们在data目录下建了一个log目录存放系统运行时的log,在file.te中新增data_log_file,log目录的安全上下文是

u:object_r:data_log_file:s0

那么就应该在file_contexts文件里做如下定义:

/data/log(/.*)?u:object_r:data_log_file:s0

external/sepolicy/property_contexts 属性安全上下文定义文件。比如说在propety.te中新加了一个persist.log. * 开头的属性,那么就需要给它添加对应的安全上下文,如果不添加或者添加的上下文不对,那么在的某个进程里写入时就写不进去。比如做了如下定义,那么是具有system_prop域安全上下文,只能在system进程里修改值,在shell里是不能访问的。

persist.log.        u:object_r:system_prop:s0

如果希望在shell里能修改值,就应该这么写

persist.log.        u:object_r:shell_prop:s0 

当然如果通过修改相关*.te 文件也能实现,但是不是很规范。
external/sepolicy/property.te 文件允许我们定义自己的prop 类型域,还有seapp_contexts、service_contexts 文件等,都是类似的,都可以根据需要修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值