最近了解到Google 在Android12上新增了权限指示器,可以在信号栏的右侧显示当前访问录音机和Camera的应用,点击后可以跳转到相应应用的权限界面,消费者可以控制权限的开启和关闭。国内手机厂商最近几年都在增加隐私看板供能,消费者可以看到相机、录音机被其他应用访问的记录,包含次数、时长等信息。
尤其Android 14,强制要求在信号区增加隐私指示器,可见安卓在隐私保护上的决心。
我估计手动控制权限的开启和关闭,并不是这个特性和核心。关键是Google或者说安卓系统愿意把权限的调用暴露给普通的消费者,本身这个态度带来的社会效应,至少让消费者最担心的声音和图像的泄露问题,得到了缓解。
本文主要是探讨起技术实现原理:
google官方文档链接如下,中英文还是略微有些区别,注意甄别https://source.android.com/docs/core/permissions/privacy-indicators
里面关键的图:
上图可见,核心的交互模块是AppOps,AppOps并不是Android12的新事物,早在Android 4.0就有了,其内部核心的几个类,
AppOpsManager
IAppOpsService.aidl
AppOpsService
AppOpsCheckingServiceImpl
普通的安卓应用可以调用下述接口,监听Ops的访问记录
appOpsManager.startWatchingMode(AppOpsManager.OPSTR_READ_MEDIA_AUDIO, null /* all packages */, mModeListener);
其中,第二个参数,传null代表,监听所有应用,也可以传具体的包名
当关心的包名,访问了具体的Ops,监听者就会收到回调。
调试手段:
adb shell dumpsys appops可以把ops服务的内部状态dump出来
具体解释如下:
Op mode watchers:
Op COARSE_LOCATION:
#0: ModeCallback{7f9fe97 watchinguid=-1 flags=0x0 op=FINE_LOCATION from uid=u0a144 pid=4204}
#1: ModeCallback{82529b5 watchinguid=-1 flags=0x1 op=COARSE_LOCATION from uid=1000 pid=2265}
#2: ModeCallback{926d7c2 watchinguid=-1 flags=0x0 op=READ_WRITE_HEALTH_DATA from uid=1000 pid=2265}
#3: ModeCallback{da82a52 watchinguid=-1 flags=0x1 op=MONITOR_LOCATION from uid=u0a21 pid=4702}
#4: ModeCallback{efa62b9 watchinguid=-1 flags=0x1 op=FINE_LOCATION from uid=u0a21 pid=4702}
Op FINE_LOCATION:
#0: ModeCallback{59f601b watchinguid=-1 flags=0x1 op=FINE_LOCATION from uid=1000 pid=2265}
#1: ModeCallback{7f9fe97 watchinguid=-1 flags=0x0 op=FINE_LOCATION from uid=u0a144 pid=4204}
#2: ModeCallback{926d7c2 watchinguid=-1 flags=0x0 op=READ_WRITE_HEALTH_DATA from uid=1000 pid=2265}
这是按具体的ops排列,打印出所有的监听者,可以配合ps -A命令查看具体的pid是哪个进程
Package mode watchers:
Pkg com.microsoft.appmanager:
#0: ModeCallback{5f879b8 watchinguid=-1 flags=0x0 op=SYSTEM_ALERT_WINDOW from uid=1000 pid=5190}
Pkg com.youku.phone:
#0: ModeCallback{4e42e95 watchinguid=-1 flags=0x0 op=SYSTEM_ALERT_WINDOW from uid=1000 pid=5190}
#1: ModeCallback{cd0ffac watchinguid=-1 flags=0x0 op=REQUEST_INSTALL_PACKAGES from uid=1000 pid=5190}
这是按具体的包名排列,打印出所有的监听者,可以配合ps -A命令查看具体的pid是哪个进程
Uid u0a237:
state=cch
capability=------
appWidgetVisible=false
POST_NOTIFICATION: mode=ignore
LEGACY_STORAGE: mode=allow
Package com.alphainventor.filemanager:
WAKE_LOCK (allow):
null=[
Access: [top-s] 2023-11-14 11:33:19.924 (-7d1h1m54s148ms) duration=+42ms
]
READ_EXTERNAL_STORAGE (allow):
null=[
Access: [top-s] 2023-11-14 11:33:16.111 (-7d1h1m57s961ms)
]
这是按具体的Uid(包名),打印出最近的访问记录