AudioService使用的数据库类型
时间: 2024-04-26 19:24:00 浏览: 104
在Android系统中,`AudioService` 使用了 SQLite 数据库来存储音量相关的信息。具体来说,`AudioService` 中使用了两个数据库:
1. `settings.db`:这个数据库中存储了系统的音量设置,包括铃声音量、通知音量、媒体音量、闹钟音量、系统音量等。
2. `audio_policy_configuration.xml`:这个文件通过 XML 格式存储了音频流的配置项,包括音频流的类型、对应的硬件设备、音频输出格式、音量范围等。
这两个数据库文件都存储在Android系统的/data/data/com.android.providers.settings/databases目录下。
相关问题
请逐行分析下AudioService.java中setMode函数
好的,我来分析一下AudioService.java中setMode函数的代码。首先,这个函数的作用是设置音频模式,具体而言,就是设置音频流的使用场景(比如是听音乐、打电话、玩游戏等),这会影响到音频系统的参数设置,比如音量、音效等。下面是这个函数的代码:
```
public int setMode(int mode, IBinder cb, String callingPackageName) {
if (DEBUG_MODE) {
Log.d(TAG, "setMode(" + mode + ")");
}
// Ensure the calling package name is valid, if specified.
if (callingPackageName != null) {
final int oldUid = Binder.getCallingUid();
final int newUid = getUidForPackage(callingPackageName);
if (newUid != oldUid && !isPrivileged(Binder.getCallingPid(), oldUid)) {
Log.e(TAG, "Cannot set mode from non privileged app: " + callingPackageName);
return AudioManager.MODE_INVALID;
}
}
// Permission check.
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS)
!= PackageManager.PERMISSION_GRANTED) {
Log.w(TAG, "MODIFY_AUDIO_SETTINGS Permission Denial: setMode()");
return AudioManager.MODE_INVALID;
}
if (mode == AudioManager.MODE_INVALID) {
return AudioManager.MODE_INVALID;
}
int newModeOwnerPid = Binder.getCallingPid();
int newModeOwnerUid = Binder.getCallingUid();
synchronized (mSetModeDeathHandlers) {
if (cb == null) {
// synchronous call, clear death handler
mSetModeDeathHandlers.remove(newModeOwnerPid);
} else {
// asynchronous call, set death handler
try {
cb.linkToDeath(new SetModeDeathHandler(newModeOwnerPid, newModeOwnerUid, cb),
0 /* flags */);
} catch (RemoteException e) {
Log.w(TAG, "setMode() could not link to " + cb + " binder death");
return AudioManager.MODE_INVALID;
}
mSetModeDeathHandlers.put(newModeOwnerPid,
new SetModeDeathHandler(newModeOwnerPid, newModeOwnerUid, cb));
}
}
return onSetMode(mode, newModeOwnerPid, newModeOwnerUid, callingPackageName);
}
```
接下来逐行解释:
1. `if (DEBUG_MODE) { Log.d(TAG, "setMode(" + mode + ")"); }`
这个if语句判断是否需要打印调试信息。如果需要,则调用Log.d()函数输出调试信息,包括当前设置的音频模式(mode)。
2. `if (callingPackageName != null) { ... }`
这个if语句判断是否提供了调用者的包名。如果提供了,则检查调用者是否有足够的权限进行操作。具体而言,如果调用者不是系统特权应用程序(privileged app),则不允许设置音频模式,会返回错误码AudioManager.MODE_INVALID。
3. `if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS) != PackageManager.PERMISSION_GRANTED) { ... }`
这个if语句检查当前调用者是否有修改音频设置的权限。如果没有,则返回错误码AudioManager.MODE_INVALID。
4. `if (mode == AudioManager.MODE_INVALID) { return AudioManager.MODE_INVALID; }`
这个if语句检查传入的音频模式是否合法。如果不合法,则直接返回错误码AudioManager.MODE_INVALID。
5. `int newModeOwnerPid = Binder.getCallingPid(); int newModeOwnerUid = Binder.getCallingUid();`
这两行代码获取当前调用者的进程ID和用户ID。
6. `synchronized (mSetModeDeathHandlers) { ... }`
这个synchronized语句块用于对mSetModeDeathHandlers对象加锁,保证多线程安全。mSetModeDeathHandlers是一个HashMap对象,用于存储SetModeDeathHandler对象(一个自定义的类,用于处理音频模式设置时Binder线程的死亡通知),以PID为键值。
7. `if (cb == null) { mSetModeDeathHandlers.remove(newModeOwnerPid); } else { ... }`
这个if语句判断是否需要设置死亡通知。如果不需要,则从mSetModeDeathHandlers中移除对应的SetModeDeathHandler对象。否则,需要将该对象添加到mSetModeDeathHandlers中,并且注册Binder线程的死亡通知。
8. `return onSetMode(mode, newModeOwnerPid, newModeOwnerUid, callingPackageName);`
最后,调用onSetMode函数处理音频模式设置。具体的实现在AudioService的子类AudioServiceInternal中。
请逐行分析下Android T 的AudioService.java中setMode函数
好的,让我来逐行分析下Android T的AudioService.java中setMode函数。
```java
/**
* @see AudioManager#setMode(int)
*/
public void setMode(int mode, IBinder cb, String callingPackageName) {
enforceModifyAudioRoutingPermission();
synchronized (mConnectedDevices) {
final int newModeOwnerPid = Binder.getCallingPid();
final int newModeOwnerUid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
final boolean modeOwnerChanged = (mModeOwnerPid != newModeOwnerPid
|| mModeOwnerUid != newModeOwnerUid);
try {
setModeInt(mode, cb, callingPackageName, modeOwnerChanged, newModeOwnerPid,
newModeOwnerUid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
```
这个函数的作用是设置音频模式,它是实现了AudioManager类的setMode方法。
函数的第一个参数mode是要设置的音频模式。
函数的第二个参数cb是一个Binder对象,它可以在AudioFocusManager中使用,用来管理音频焦点。
函数的第三个参数callingPackageName是调用这个函数的应用程序的包名。
接下来是函数的实现。
首先,它调用enforceModifyAudioRoutingPermission()方法来检查是否有修改音频路由的权限。
然后,它使用synchronized关键字同步了mConnectedDevices,这是一个存储连接的设备信息的集合。
接着,它获取了调用这个函数的应用程序的PID和UID,以及清除了调用者的身份验证标识符。
接下来,它检查是否有新的模式所有者,并设置了一个用于检测模式所有者更改的标志。
最后,它调用了setModeInt方法来实际设置音频模式,传递了所有必要的参数,并在结束时恢复了调用者的身份验证标识符。
至此,Android T的AudioService.java中setMode函数的分析就结束了。
阅读全文