工作笔记

//耳机判断

1. android系统启动完成会发送Intent.ACTION_BOOT_COMPLETED事件,我们在 base/services/java/com/android/server/WiredAccessoryObserver.java中可以看到类似代码
linux-3.0/drivers/switch/ switch_headset.c中会根据无耳机,三段耳机,四段耳机和四段耳机是否有hook键按下4个状态更新state的值为0 ,1, 2,3,并且切换机台
MIC和耳机
private static final String uEventInfo[][] = { {"DEVPATH=/devices/virtual/switch/h2w",
                                            "/sys/class/switch/h2w/state",
                                            "/sys/class/switch/h2w/name"},
                                           {"DEVPATH=/devices/virtual/switch/usb_audio",
                                            "/sys/class/switch/usb_audio/state",
                                           "/sys/class/switch/usb_audio/name"},
                                           {"DEVPATH=/devices/virtual/switch/hdmi",
                                            "/sys/class/switch/hdmi/state",
                                             "/sys/class/switch/hdmi/name"} };
大体流程是用定时器每200ms检查一次是否有耳机插入,如果有4段耳机,延时30ms检查hook key是否按下,这样,如果旧的state和新的state不相等,就用uevent上报状态改变
事件
可参考电路图P11的说明:
检测耳机插入:
1、0V-0.2V 则判定为3节耳机;
2、1V-2.5V 则判定为4节耳机;
3、检测为4接耳机后如果ADC再次检测为0V则认为HOOK见按下。


2. 在drivers/media/pa中的是提供借口给上层做外音和内音切换的,也就是如FM,播放器等都会检测耳机是否插入,以进行外音和内音切换,看看其中的代码:
       pa_dev_class = class_create(THIS_MODULE, "pa_cls");//这一句运行后,会创建虚拟文件系统/sys/class/pa_cls
139     device_create(pa_dev_class, NULL,dev_num, NULL, "pa_dev");//这一句运行后,会创建节点/dev/pa_dev
141     printk("[pa_drv] init end!!!\n");
他对应的framework层代码在device/softwinner/common/hardware/audio/audio_hw.c中
而file_operations结构体和节点对应起来则是通过如下的关系,如touch中:
ret= register_chrdev(I2C_MAJOR,"aw_i2c_ts",&aw_i2c_ts_fops );//I2C_MAJOR是自己定义的主设备号
接着调用:device_create(i2c_dev_class, &client->adapter->dev, MKDEV(I2C_MAJOR,client->adapter->nr), NULL, "aw_i2c_ts%d", client->adapter->nr);这样
就关联起来了


3. 两种定时器的使用:
   1.   static struct hrtimer vibe_timer;
INIT_WORK(&vibrator_work, update_vibrator);
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
{
schedule_work(&vibrator_work);
}
  hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
vibe_timer.function = vibrator_timer_func;
这样在你想要启动定时器的函数中调用如下语句:
hrtimer_start(&vibe_timer,
ktime_set(value / 1000, (value % 1000) * 1000000), //ktime_set的第一个参数单位时秒,第二个单位是纳秒
HRTIMER_MODE_REL);
schedule_work(&vibrator_work);//hrtimer_start后调用一次schedule_work,时间到后,再调用一次schedule_work,这样在两次schedule_work中可以做如控制按键灯
亮灭等动作,具体例子可参考drivers/misc/sun4i-vibrator.c
这个定时器还提供了一些查询功能,如可以查询定时器当前是否激活的,定时器当前的剩余时间等,如下面的函数:
static int vibrator_get_time(struct timed_output_dev *dev)
{
struct timespec time_tmp;
if (hrtimer_active(&vibe_timer)) {//判断是否激活
ktime_t r = hrtimer_get_remaining(&vibe_timer);//取得定时器剩余时间
time_tmp = ktime_to_timespec(r);//时间单位转换,他和上面的ktime_set相当于相反过程的转换
//return r.tv.sec * 1000 + r.tv.nsec/1000000;
return time_tmp.tv_sec* 1000 + time_tmp.tv_nsec/1000000;//返回的单位是毫秒
} else
return 0;
}
   2.   struct timer_list timer;
static void earphone_hook_handle(unsigned long data)
{
mod_timer(&switch_data->timer, jiffies + msecs_to_jiffies(200));
}
init_timer(&timer);
timer.function = &earphone_hook_handle;
timer.data = (unsigned long)switch_data;
add_timer(&switch_data->timer);//这一句之后已经启动定时器了




4. 声卡的设备节点在/proc/asound/card0,创建过程为snd_card_create -> snd_ctl_create
创建sys节点snd_card_register-> device_create(sound_class, card->dev, MKDEV(0, 0), card, "card%i", card->number) 
sound_class = class_create(THIS_MODULE, "sound");
sound_class->devnode = sound_devnode;
其中:
static char *sound_devnode(struct device *dev, mode_t *mode)
{
    if (MAJOR(dev->devt) == SOUND_MAJOR)
return NULL;
    return kasprintf(GFP_KERNEL, "snd/%s", dev_name(dev));
}   
这样声卡的class出现在/class/sys/sound/中,sound_devnode就决定了设备节点出现在/dev/snd/中,用户空间操作的就是/dev/snd/中的设备节点。
接着调用snd_device_register_all函数注册前面挂接在card->device链表中的所有设备:
185 int snd_device_register_all(struct snd_card *card)
186 {   
187     struct snd_device *dev;
188     int err;
189  
190     if (snd_BUG_ON(!card))
191         return -ENXIO;
192     list_for_each_entry(dev, &card->devices, list) {
193         if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
194             if ((err = dev->ops->dev_register(dev)) < 0)
195                 return err;
196             dev->state = SNDRV_DEV_REGISTERED;
197         }
198     }
199     return 0;
200 }
我们看看设备是如何挂在card->device链表中的:
snd_card_sun4i_codec_pcm -> snd_pcm_new -> snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)),其中ops结构体为:
720     static struct snd_device_ops ops = {
721         .dev_free = snd_pcm_dev_free,
722         .dev_register = snd_pcm_dev_register,
723         .dev_disconnect = snd_pcm_dev_disconnect,
724     };
snd_pcm_dev_register为:
976 static int snd_pcm_dev_register(struct snd_device *device)
977 {
978     int cidx, err;
979     struct snd_pcm_substream *substream;
980     struct snd_pcm_notify *notify;
981     char str[16];
982     struct snd_pcm *pcm;
983     struct device *dev;
984 
985     if (snd_BUG_ON(!device || !device->device_data))
986         return -ENXIO;
987     pcm = device->device_data;
988     mutex_lock(&register_mutex);
989     err = snd_pcm_add(pcm);
990     if (err) {
991         mutex_unlock(&register_mutex);
992         return err;
993     }
994     for (cidx = 0; cidx < 2; cidx++) {
995         int devtype = -1;
996         if (pcm->streams[cidx].substream == NULL)
997             continue;
998         switch (cidx) {
999         case SNDRV_PCM_STREAM_PLAYBACK:
1000             sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);//这里就是设备节点的名字
1001             devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
1002             break;
1003         case SNDRV_PCM_STREAM_CAPTURE:
1004             sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);//这里就是设备节点的名字
1005             devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
1006             break;
1007         }
1008         /* device pointer to use, pcm->dev takes precedence if
1009          * it is assigned, otherwise fall back to card's device
1010          * if possible */
1011         dev = pcm->dev;
1012         if (!dev)
1013             dev = snd_card_get_device_link(pcm->card);
1014         /* register pcm */
1015         err = snd_register_device_for_dev(devtype, pcm->card,
1016                           pcm->device,
1017                           &snd_pcm_f_ops[cidx],
1018                           pcm, str, dev);//在这个函数中,最终调用device_create(sound_class, device, MKDEV(major, minor),private_data, 
     //"%s", name);来创建设备
1019         if (err < 0) {
1020             list_del(&pcm->list);
1021             mutex_unlock(&register_mutex);
1022             return err;
1023         }
1024         snd_add_device_sysfs_file(devtype, pcm->card, pcm->device,
1025                       &pcm_attrs);


看看我的设备节点名称:
$ cd /dev/snd
$ ls -l
crw-rw----+ 1 root audio 116, 8 2011-02-23 21:38 controlC0
crw-rw----+ 1 root audio 116, 4 2011-02-23 21:38 midiC0D0
crw-rw----+ 1 root audio 116, 7 2011-02-23 21:39 pcmC0D0c
crw-rw----+ 1 root audio 116, 6 2011-02-23 21:56 pcmC0D0p
crw-rw----+ 1 root audio 116, 5 2011-02-23 21:38 pcmC0D1p
crw-rw----+ 1 root audio 116, 3 2011-02-23 21:38 seq
crw-rw----+ 1 root audio 116, 2 2011-02-23 21:38 timer
controlC0 -->                 用于声卡的控制,例如通道选择,混音,麦克风的控制等
midiC0D0  -->                 用于播放midi音频
pcmC0D0c  -->                 用于录音的pcm设备
pcmC0D0p  -->                 用于播放的pcm设备
seq       -->                 音序器
timer     -->                 定时器
其中,C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback,这些都是alsa-driver中的命名规则。从上面的列表可以看出,我
的声卡下挂了6个设备,根据声卡的实际能力,驱动实际上可以挂上更多种类的设备,在include/sound/core.h中,定义了以下设备类型,通常,我们更关心的是pcm和control
这两种设备。
对于sound/core/control.c文件
#ifdef CONFIG_COMPAT
#include "control_compat.c"
#else
#define snd_ctl_ioctl_compat    NULL
#endif
下面的"controlC%i"声卡对应的控制节点fops的compat_ioctl,当没有定义CONFIG_COMPAT时,将被置为NULL
hal层的IOCTRL会对应KERNEL层的core/control.c文件
frameworks/base/services/java/com/android/server/WiredAccessoryObserver.java会监听耳机拔插事件
而打开hal层audio_hw.c的JNI层代码在frameworks/base/services/audioflinger/AudioFlinger.cpp中
audio_hw.c是按照hardware/libhardware/include/hardware/audio.h定义的接口实现就行了


5. getprop 命令可以查看系统属性状态

6.运行JAVA代码:
javac xxx.java(xxx为类的名字)
java xxx.class














7.编译时候提示,You have tried to change the API from what has been previously approved.


To make these errors go away, you have two choices:
  1) You can add "@hide" javadoc comments to the methods, etc. listed in the
     errors above.


  2) You can update current.txt by executing the following command:
make update-api


     To submit the revised current.txt to the main Android repository,
     you will need approval.
******************************
如果你是想要让这个新增的API只能内部使用,则加上 /** {@hide} */,如我的代码:frameworks/base/core/java/android/os中新增了IHelloService.aidl这个服务,如下
为其中的内容:
 1 package android.os;
 2 
 3 /** {@hide} */
 4 interface IHelloService {
 5     void setVal(int val, String path);
 6     int getVal(String path);
 7 }
还有新增JNI层的一些用法:
66         {"init_native", "()Z", (void*)hello_init}, //无型参,Z表示返回值为boolean型
67         {"setVal_native", "(ILjava/lang/String;)V", (void*)hello_setVal},// I表示第一个型参为int,Ljava/lang/String表示第二个型参为String,
68         {"getVal_native", "(Ljava/lang/String;)I", (void*)hello_getVal},
由上面可以知道hello_setVal对应的HAL层原型为hello_setVal(int, char *), 在JNI中还要将String转换为char*才能使用,语法如下:
28     /*通过硬件抽象层定义的硬件访问接口读取硬件寄存器val的值*/
29     static jint hello_getVal(JNIEnv* env, jobject clazz, jstring path) {
30        const  char *extraInfoStr = env->GetStringUTFChars(path, NULL);//将String转换为char*
31         int val = 0;
32         if(!hello_device) {
33             LOGI("Hello JNI: device is not open.");
34             return val;
35         }
36         hello_device->get_val(hello_device, &val, extraInfoStr);
37 
38         LOGI("Hello JNI: get value %d from device.", val);
39         env->ReleaseStringUTFChars(path, extraInfoStr);//用完后要释放
40 
41         return val;
42     }






8. 系统build.prop文件属性的读取文件在base/core/java/android/os/SystemProperties.java,属性接口在frameworks/base/core/java/android/os/Build.java中


9.A10申请外部中断的步骤:
 中断号的定义在drivers/input/touchscreen/ctp_platform_ops.h中:
 #define PIO_BASE_ADDRESS (0xf1c20800)//这是外部所有IO口中断的入口
 #define PIOA_CFG1_REG    (PIO_BASE_ADDRESS+0x4)
 #define PIOA_DATA        (PIO_BASE_ADDRESS+0x10)  
 #define DELAY_PERIOD     (5)
 #define SW_INT_IRQNO_PIO                28
 #define PIO_INT_STAT_OFFSET          (0x214)
   #define CTP_IRQ_NO          (IRQ_EINT21)


309 static int ctp_judge_int_occur(void)
310 {
311     //int reg_val[3];
312     int reg_val;
313     int ret = -1;
314 
315     reg_val = readl(gpio_addr + PIO_INT_STAT_OFFSET);//偏移PIO_INT_STAT_OFFSET处的地址就是外部IO口中断的状态寄存器
316     if(reg_val&(1<<(CTP_IRQ_NO))){//CTP_IRQ_NO=IRQ_EINT21,就是TP的中断脚EINT21,配置脚本中有 ctp_int_port   = port:PH21<6><default>
317         ret = 0;
318     }
319     return ret;
320 }


1681 static irqreturn_t ft5x_ts_interrupt(int irq, void *dev_id)
1682 {
1683     struct ft5x_ts_data *ft5x_ts = dev_id;
1684 
1685 //  print_int_info("==========------ft5x_ts TS Interrupt-----============\n");
1686     if(!ctp_ops.judge_int_occur()){ //要判断是外部哪一个IO口所引起的中断
1687 //      print_int_info("==IRQ_EINT21=\n");
1688         ctp_ops.clear_penirq();
1689         if (!work_pending(&ft5x_ts->pen_event_work))
1690         {
1691 //          print_int_info("Enter work\n");
1692             queue_work(ft5x_ts->ts_workqueue, &ft5x_ts->pen_event_work);
1693         }
1694     }else{
1695 //      print_int_info("Other Interrupt\n");
1696         return IRQ_NONE;
1697     }
1698 
1699     return IRQ_HANDLED;
1700 }


1895     err = request_irq(SW_INT_IRQNO_PIO, ft5x_ts_interrupt, IRQF_TRIGGER_FALLING | IRQF_SHARED, "ft5x_ts", ft5x_ts);


10.格式化userdata分区名字的方法在init.sun4i.rc中修改即可,如代码:format_userdata /dev/block/nandi IPND5,IPND5即为电脑中看到的盘符名字








11.全志平台的关机代码在drivers/power/axp_power/axp-mfd.c中:
311     /* PM hookup */
312     if(!pm_power_off)
313         pm_power_off = axp_power_off;axp_power_off定义如下:


static void axp_power_off(void)
{
uint8_t val;


#if defined (CONFIG_AW_AXP18)
axp_set_bits(&axp->dev, POWER18_ONOFF, 0x80);
#endif


#if defined (CONFIG_AW_AXP19)
axp_set_bits(&axp->dev, POWER19_OFF_CTL, 0x80);
#endif


#if defined (CONFIG_AW_AXP20)
if(pmu_pwroff_vol >= 2600 && pmu_pwroff_vol <= 3300){
if (pmu_pwroff_vol > 3200){
val = 0x7;
}
else if (pmu_pwroff_vol > 3100){
val = 0x6;
}
else if (pmu_pwroff_vol > 3000){
val = 0x5;
}
else if (pmu_pwroff_vol > 2900){
val = 0x4;
}
else if (pmu_pwroff_vol > 2800){
val = 0x3;
}
else if (pmu_pwroff_vol > 2700){
val = 0x2;
}
else if (pmu_pwroff_vol > 2600){
val = 0x1;
}
else
val = 0x0;


axp_update(&axp->dev, POWER20_VOFF_SET, val, 0x7);
}
val = 0xff;
if (!use_cou){
axp_read(&axp->dev, POWER20_COULOMB_CTL, &val);
val &= 0x3f;
axp_write(&axp->dev, POWER20_COULOMB_CTL, val);
val |= 0x80;
val &= 0xbf;
axp_write(&axp->dev, POWER20_COULOMB_CTL, val);
}
   //led auto
   axp_clr_bits(&axp->dev,0x32,0x38);
axp_clr_bits(&axp->dev,0xb9,0x80);


   printk("[axp] send power-off command!\n");
   mdelay(20);
   if(power_start != 1){
axp_read(&axp->dev, POWER20_STATUS, &val);//读取是否处于充电状态,如果是,则reset,进入uboot充电
if(val & 0xF0){
    axp_read(&axp->dev, POWER20_MODE_CHGSTATUS, &val);
    if(val & 0x20){//判断电池在的话才进入充电
    printk("[axp] set flag!\n");
axp_write(&axp->dev, POWER20_DATA_BUFFERC, 0x0f);
    mdelay(20);
    printk("[axp] reboot!\n");
    arch_reset(0,NULL);
    printk("[axp] warning!!! arch can't ,reboot, maybe some error happend!\n");
    }
}
}
   axp_write(&axp->dev, POWER20_DATA_BUFFERC, 0x00);
   mdelay(20);
axp_set_bits(&axp->dev, POWER20_OFF_CTL, 0x80);//就是写1到寄存器32H,表示关闭除LDO1外的所有电源,请看AXP209手册P34
   mdelay(20);
   printk("[axp] warning!!! axp can't power-off, maybe some error happend!\n");


#endif
}
而arch_reset(0,NULL);的代码位于arch/arm/mach-sun4i/include/mach/system.h中,利用的是看门狗复位:
39 static inline void arch_reset(char mode, const char *cmd)
40 {
41     /* use watch-dog to reset system */
42     #define WATCH_DOG_CTRL_REG  (SW_VA_TIMERC_IO_BASE + 0x0094)//SW_VA_TIMERC_IO_BASE是虚拟地址
43     *(volatile unsigned int *)WATCH_DOG_CTRL_REG = 0;
44     __delay(100000);
45     *(volatile unsigned int *)WATCH_DOG_CTRL_REG = 3;
46     while(1);
47 }




12.codec控制设置:
Number of controls: 32
ctl typenumname                                     value
0 INT1Master Playback Volume                   59     //音量大小设置
1 BOOL1Playback PAMUTE SWITCH                   On//声音输出总开关,打开才有声音输出,看手册P258 PAMUTE
2 BOOL1Playback MIXPAS                          Off//输入的声音或者经过混音器输出的声音输出的开关,如3G的语音就是要打开,看手册
  // P258 MIXPAS
3 BOOL1Playback DACPAS                          On//输入的声音不经混音器直接输出,如播放音乐时要打开,看手册P258 DACPAS
// 但也可以选择声音从混音器输出,关掉3,使能2、5、6、7和15即可
4 INT1Mic Output Mix                           0//MIC1、2输入的左右声道是否打开到混音器中一起输出到外音
5 BOOL1Ldac Right Mixer                         Off//输入的声音经过混音器混音时(对应手册DACMISX开关),左声道混音,右没声音
6 BOOL1Rdac Right Mixer                         Off//输入的声音经过混音器混音时(对应手册DACMISX开关),右声道混音,左没声音
7 BOOL1Ldac Left Mixer                          Off//输入的声音经过混音器混音时(对应手册DACMISX开关),左声道、左声道的混音
8 BOOL1FmR Switch                               Off//FM到混音器是否打开,如收音时要打开,但这样上层无法控制音量
9 BOOL1FmL Switch                               Off//FM到混音器是否打开,如收音时要打开,但这样上层无法控制音量
10 BOOL1LineR Switch                             Off//线路输入到混音器是否打开,如3G通话要打开,而播放音乐不是线路输入,不用打开
11 BOOL1LineL Switch                             Off//线路输入到混音器是否打开,如3G通话要打开,而播放音乐不是线路输入,不用打开
12 INT1MIC output volume                        3//MIC到混音器输出的增益,
13 INT1Fm output Volume                         3//FM到混音器输出的增益,
14 BOOL1Line output Volume                       On//线路输入到混音器的增益,只有两个等级,-1.5db和0db
15 BOOL1MIX Enable                               Off//混音器使能
16 BOOL1DACALEN Enable                           On//数字到模拟的输出是否是能,如音乐要打开,但3G通话是直接旁路输出不用打开
17 BOOL1DACAREN Enable                           On//数字到模拟的输出是否是能,如音乐要打开,但3G通话是直接旁路输出不用打开
18 BOOL1PA Enable                                On//PA使能,只有PA打开,才有声音输出
19 BOOL1dither enable                            Off//手册没有说明
20 BOOL1Mic1outn Enable                          Off//MIC是否直接输出,如3G通话MIC直接输出到3G模块中
21 INT1LINEIN APM Volume                        7//线路模拟输入的增益,有7个增益等级,只是线路的增益,不会影响去他输入源的增益
22 BOOL1Line-in-r function define                Off//输入信号差分是能,如3G通话时候要使能,否则2G卡会受到干扰,有噪音
23 INT1ADC Input source                         0//模拟到数字转换的输入源选择,可以有3G线路,FM输入,MIC输入等选择
24 INT1Capture Volume                           3//模拟到数字转换的增益,有8个等级,0-7(这是总的线路增益,影响到FM,MIC,
// 线路等输入源)
25 INT1Mic2 gain Volume                         2//MIC2增益打开的情况下,输入增益的等级设置,没有用到这一路
26 INT1Mic1 gain Volume                         2//MIC2增益打开的情况下,输入增益的设置,有4个等级,3G通话时候有增益的话会有噪音
27 BOOL1VMic enable                              On//MIC电源,用MIC时候就要打开
28 BOOL1Mic2 amplifier enable                    Off//MIC2输入增益是否打开
29 BOOL1Mic1 amplifier enable                    On//MIC2输入增益是否打开
30 BOOL1ADCL enable                              Off//模拟到数字的左声道是否打开,如录音时候有耳麦或则没有耳麦都就要打开
31 BOOL1ADCR enable                              Off//模拟到数字的左声道是否打开,如录音时候有耳麦或则没有耳麦都就要打开






13. camera的设置:
drivers/media/video/sun4i_csi目录下对应有csi0 、csi1两个文件夹,分别是两个摄像头对应的平台代码,他们对应的节点为/dev/video0前置ov5640, /dev/video1 
后置ov2655或者ov2643,sun4i_drv_csi.c中控制camera的主要是csi_power_en脚和csi_stby脚,其中两个camera的csi_power_en相同,在csi_open函数中会打开电源上电,
但打开后马上用 v4l2_subdev_call(dev->sd,core, s_power, CSI_SUBDEV_STBY_ON);来进入standby 模式,只有在摄像头切换中,启用它后调用
static int internal_s_input(struct csi_dev *dev, unsigned int i)函数,在该函数中使用v4l2_subdev_call(dev->sd,core, s_power, CSI_SUBDEV_STBY_OFF);
才真正工作,所以两个摄像头同时只有一个工作,另一个处于standby模式






14. property_get/property_set会从以下文件读取属性:
1: /default.prop


2: /system/build.prop


3: /system/default.prop


4: /data/local.prop










15.android的电量警告和严重电量警告的设置在/frameworks/base/core/res/res/values/config.xml中,在frameworks/base/services/java/com/android/server/
BatteryService.java中读取这些值,而关机电量是在BatteryService.java文件中判断,在update函数中被调用,如下:


208     private final void shutdownIfNoPower()
{                                                                                                              
209         // shut down gracefully if our battery is critically low and we are not powered.
210         // wait until the system has booted before attempting to display the shutdown dialog.
211         if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) {//mBatteryLevel为0就关机
212             Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
213             intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
214             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
215             mContext.startActivity(intent);
216         }
217     }
















16.APK签名机制:
<uses-sdk android:minSdkVersion="7" android:sharedUserId="android.uid.system"/>
java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk 










17. 按键事件的上报,如果要上报某一个键值,要用set_bit来设置,否则不上报该键值,如:
for (i = 0; i < KEY_MAX_CNT; i++)
           set_bit(sun4i_scankeycodes[i], sun4ikbd_dev->keybit);








18.camera拍照的各种声音播放在frameworks/base/core/java/android/hardware/CameraSound.java中实现










19. JNI_OnLoad函数是在android VM执行*so中的System.loadLibrary函数时候执行的,所以一般在该函数中做一些初始化设置和返回JNI版本,












20. u-boot流程:
头文件在include/configs/sun4i.h中
从arch/arm/cpu/armv7/start.S开始
跳到arch/arm/lib/board.c,








21. android源代码中编译jar包的方法:
在需要导出jar包的目录下新建android,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE_TAGS := optionalLOCAL_MODULE :=my_fmradio
  include $(BUILD_JAVA_LIBRARY)




22. android背光调节代码路线:
packages/apps/Settings/src/com/android/settings/BrightnessPreference.java -> setBrightness(myState.progress + mScreenBrightnessDim);
 private void setBrightness(int brightness)
 {                                                                                                              
try {
   IPowerManager power = IPowerManager.Stub.asInterface(
           ServiceManager.getService("power"));
   if (power != null) {
       power.setBacklightBrightness(brightness);
   }
} catch (RemoteException doe) {
   
}
  }
调用IPowerManager类接口,实现在frameworks/base/services/java/com/android/server/PowerManagerService.java
brightness = Math.max(brightness, mScreenBrightnessDim);
mLcdLight.setBrightness(brightness);
mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
mButtonLight.setBrightness(brightness);
可以看到,不但是设置了LCD的背光,如果有,键盘,按键的背光设置了,其中的private LightsService.Light mLcdLight;所以看到目录下的LightsService.java
public void setBrightness(int brightness, int brightnessMode) ->  setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode) ->
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);


看看JNI层的实现,进入frameworks/base/services/jni/com_android_server_LightsService.cpp
这里看看JNI是如何找到HAL层的 hw_module_t结构体的:
hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);//这里传进去的是二维指针,才能返回HAL层的指针哦,关于这个不多说


看看hw_get_module的定义,在hardware/libhardware/hardware.c中:
hw_get_module -> hw_get_module_by_class:
   for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
        if (i < HAL_VARIANT_KEYS_COUNT) {
            if (property_get(variant_keys[i], prop, NULL) == 0) {
                continue;
            }
            snprintf(path, sizeof(path), "%s/%s.%s.so",
                     HAL_LIBRARY_PATH2, name, prop);
            if (access(path, R_OK) == 0) break;


            snprintf(path, sizeof(path), "%s/%s.%s.so",


               HAL_LIBRARY_PATH1,name,prop);                                                                                                          
            if (access(path, R_OK) == 0) break;
        } else {
            snprintf(path, sizeof(path), "%s/%s.default.so",
                     HAL_LIBRARY_PATH1, name);
            if (access(path, R_OK) == 0) break;
        }
    }
查找并加载hal层的so库,最后load(class_id, path, module);用dlopen动态加载so库,这里会比较打开的so库中id的名字和传进来的是否一样,如果都是"lights",才能加
载成功。

看看so库的实现,进入HAL层,在device/softwinner/crane-common/hardware/libhardware/lights/lights.c中:
这里打开的是dev->fd = open("/dev/disp", O_RDONLY);
他在kernel中对应的文件为:drivers/video/sun4i/disp/dev_disp.c





23. 编译,分析uboot:
./build.sh -p sun4i_crane 
或者  make sun4i
board_init_r 从汇编跳到C入口,入口在文件arch/arm/lib/board.c中


启动用到的三个设置环境命令:
include/configs/sun4i.h中:
bootcmd=run setargs boot_normal;
board/allwinner/a10-evb/a10-evb.c -> check_android_misc()中
setenv("bootcmd", "run setargs boot_recovery");
setenv("bootcmd", "run setargs boot_fastboot");
他们分别为:
boot_normal=nand read 50000000 boot; boota 50000000//nand对应cmd_nand命令,会查找boot分区,把它读到RAM地址0x50000000中
boot_recovery=nand read 50000000 recovery; boota 50000000//nand对应cmd_nand命令,会查找recovery分区,把它读到RAM地址0x50000000中
boot_fastboot=fastboot//启动cmd_fastboot命令,等待USB发送fastboot命令到来






24. 编译kernel
./build.sh -p sun4i_crane










25. binder通讯机制的理解:
1. rocessState::ProcessState()  
   : mDriverFD(open_driver())  
   , mVMStart(MAP_FAILED)  
   , mManagesContexts(false)  
   , mBinderContextCheckFunc(NULL)  
   , mBinderContextUserData(NULL)  
   , mThreadPoolStarted(false)  
   , mThreadPoolSeq(1)  
这里打开的可以是service的fd,也是和servicemanager通讯的FD,和进程相关,一个进程映射一个FD就可以了,service要把自己添加到servicemanager中,就是打开该
fd,但也传进了另外一个参数mHandle(0),表示自己是要和servicemanager通讯,并且把自己的binder实体也传进去,以便挂在servicemanager端,然后service也是利用该FD
等待和client的通讯,整个系统一共有20多处打开FD的LOG。而service等待client数据并且处理数据的地方是下面这两句:
   ProcessState::self()->startThreadPool();
   IPCThreadState::self()->joinThreadPool();
就是启动线程等待client的请求
2. 每个进程都有自己的defaultServiceManager(),如frameworks/base/media/mediaserver/main_mediaserver.cpp这个编译出来的执行文件就是一个单独的进程:
int main(int argc, char** argv)
{
   sp<ProcessState> proc(ProcessState::self());
   sp<IServiceManager> sm = defaultServiceManager();                 
   LOGI("ServiceManager: %p", sm.get());
   AudioFlinger::instantiate();
   MediaPlayerService::instantiate();
   CameraService::instantiate();
   AudioPolicyService::instantiate();
   ProcessState::self()->startThreadPool();
   IPCThreadState::self()->joinThreadPool();
}
其他的进程会有自己独立的defaultServiceManager(),这一点从加入的log打印出来有20多个就可以证明:
34 sp<IServiceManager> defaultServiceManager()                                                                                                
35 {
36     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
37     
38     {
39         AutoMutex _l(gDefaultServiceManagerLock);
40         if (gDefaultServiceManager == NULL) {
41                     LOGI("luis:go to here");//打印出来有20多个
42             gDefaultServiceManager = interface_cast<IServiceManager>(
43                 ProcessState::self()->getContextObject(NULL));
44         }
45     }
3. service传输的数据要拷贝到内核空间的MMAP共享的空间,servicemaneger和client则通过指针就可以保存可操作MMAP空间这些数据,所以MMAP只有一次数据拷贝,一就是
binder进程的通讯只有一次数据拷贝
4. client要从servicemanager获得service接口,也要打开一个FD才能与servicemanager通讯,它也调用IPCThreadState::talkWithDriver这个与binder驱动交互,但打开
的FD是这个进程打开defaultServiceManager时候,函数创建ProcessState对象时,在ProcessState构造函数通过open文件操作函数打开设备文件/dev/binder时设置好的FD,
而且传进来的handle值为0,表示目标Binder对象是ServiceManager,但它自己并不像service一样有binder传给servicemanager,而相反,要从servicemanager中取得一个
binder实体的handle










26. init.sun4i.rc中format_userdata /dev/block/nandi IPND5格式化UMS分区,他对应的命令在system/core/init/builtins.c中:
int do_format_userdata(int argc, char **argv)
{   
   const char *devicePath = argv[1];   
   char bootsector[512];
   char lable[32];
   int fd; 
   int num;
   pid_t child;
   int status;
   
   fd = open(devicePath, O_RDONLY);
   if( fd <= 0 ) { 
ERROR("open device error :%s", strerror(errno));    
return 1;
   }   
   memset(bootsector, 0, 512);
   read(fd, bootsector, 512);
   close(fd);
   if( (bootsector[510]==0x55) && (bootsector[511]==0xaa) ) 
   {   
ERROR("dont need format %s", devicePath);   
return 1;
   }   
   else // 格式化
   {   
ERROR("start format %s", devicePath);
child = fork();    
if (child == 0) {
   ERROR("fork to format %s", devicePath);
   execl("/system/bin/logwrapper","/system/bin/logwrapper","/system/bin/newfs_msdos","-F","32","-O","android","-c","8", "-L",argv[2],argv
   [1], NULL); 
                    exit(-1);
}
ERROR("wait for format %s", devicePath);
while (waitpid(-1, &status, 0) != child) ;
ERROR("format %s ok", devicePath); 
return 1;
   }
}




27. sensor的代码结构:
frameworks/base/services/sensorservice/SensorService.cpp中
void SensorService::onFirstRef()
67 {
68     LOGD("nuSensorService starting...");
69 
70     SensorDevice& dev(SensorDevice::getInstance());//取得sensor列表,就是调用hw_get_module加载so库,
switch (list[i].type) {
87                     case SENSOR_TYPE_ORIENTATION:
88                         orientationIndex = i;
89                         break;
90                     case SENSOR_TYPE_GYROSCOPE:
91                         hasGyro = true;
92                         break;
93                     case SENSOR_TYPE_GRAVITY:
94                     case SENSOR_TYPE_LINEAR_ACCELERATION://根据type来判断是那种类型的sensor,所以我们在device下的so库中要注意该类型的赋值
95                     case SENSOR_TYPE_ROTATION_VECTOR:
96                         virtualSensorsNeeds &= ~(1<<list[i].type);
97                         break;






28. 上层读取input事件时,一般是通过约定的名字来确定到底和/dev/input下的哪一个设备关联,如imapx15的gsensor,hardware/bosch_sensors/sensors.cpp中,
         打开/dev/input目录后,遍历所有设备,根据约定的字符名字匹配:
539          if(ioctl(d06_read_fd, EVIOCGNAME(sizeof(name)),name) > 0)
540         {                                                                                                          
541             ALOGD("devname=%s\n",devname);
542             ALOGD("name=%s\n",name);
543             if(!strcmp(name,INPUT_NAME_ACC))//"DMT_Gsensor"))
544             {
545                 ALOGD("%s:name=%s,fd=%d\n",__func__,name,d06_read_fd);
546                 break;
547             }
而在底层的driver中有:
291     /* Set InputDevice Name */
292     input->name = INPUT_NAME_ACC;
这样就能匹配成功啦








29. infotmic的LCD配置:
路径在drivers/InfotmMedia/lcd_api/source中,新增自己的c配置文件,填写手册中的配置在结构体lcdc_config_t中
在drivers/InfotmMedia/lcd_api/source/lcd_cfg.h中增加新增的文件
而在drivers/InfotmMedia/external/project/ids_drv_i800/ids.c中,会对item文件进行解析,以确认到底用那个LCD配置


28. javah生成JNI文件,其他一切都是浮云
在eclipse中编译好apk后,我的package为 com.example.javajni,class为HellojniActivity,看看生成的bin目录:
├── bin
│   ├── AndroidManifest.xml
│   ├── classes
│   │   ├── com
│   │   │   └── example
│   │   │       └── javajni
│   │   │           ├── BuildConfig.class
│   │   │           ├── HellojniActivity.class
│   │   │           ├── R$attr.class
│   │   │           ├── R.class
│   │   │           ├── R$drawable.class
│   │   │           ├── R$id.class
│   │   │           ├── R$layout.class
│   │   │           ├── R$menu.class
│   │   │           ├── R$string.class
│   │   │           └── R$style.class
│   │   └── com_example_javajni_HellojniActivity.h
我们要在bin/classs目录下运行javah命令,如下javah -classpath ./ -jni com.example.javajni.HellojniActivity,这样才能根据后面的参数找到com/example/
javajni目录下的HellojniActivity.class文件




29. kernel的makefile中链接.a库的写法:
 1 obj-$(CONFIG_TOUCHSCREEN_AW5306)                += aw5306_ts.o                                                                              
 2 aw5306_ts-objs := AW5306_ts.o AW5306_userpara.o $@libAW5306.a
 libAW5306.a就是该目录下的一个库








30. allwiner的touch I2C注册过程:
主要是在i2c_driver 中定义了 AW5306_ts_driver.detect = ctp_ops.ts_detect,这样在注册时候会回掉detect函数,该函数做的事情就是判断I2C挂在那条线上
495 int ctp_detect(struct i2c_client *client, struct i2c_board_info *info)                                        
496 {
497     struct i2c_adapter *adapter = client->adapter;
498 
499     if(twi_id == adapter->nr)
500     {
501         pr_info("%s: Detected chip %s at adapter %d, address 0x%02x\n",
502              __func__, CTP_NAME, i2c_adapter_id(adapter), client->addr);
503 
504         strlcpy(info->type, CTP_NAME, I2C_NAME_SIZE);
505         return 0;
506     }else{
507         return -ENODEV;
508     }
509 }  
如果和config中定义的是同一组I2C,则把名字拷贝,这样就能match了


31. 让机器永不休眠并且没有锁屏界面:
frameworks/base/packages/SettingsProvider/res/values/defaults.xml中修改def_screen_off_timeout为-1
frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java中mExternallyEnabled设置为false








32.ND6的以太网服务分析frameworks/base/目录下:
首先在ethernet/java/android/net/ethernet中定义了aidl文件:
EthernetDevInfo.aidl //定义Parcelable传输对象流
EthernetDevInfo.java  
EthernetManager.java  
EthernetMonitor.java  
EthernetNative.java  
EthernetStateTracker.java  
IEthernetManager.aidl //定义服务接口函数interface IEthernetManager
看到IEthernetManager.aidl就知道有服务要实现这写接口函数,它在frameworks/base/services/java/com/android/server/EthernetService.java中:
public class EthernetService<syncronized> extends IEthernetManager.Stub{........}
而这个服务在services/java/com/android/server/ConnectivityService.java中注册添加:
521   ServiceManager.addService(Context.ETHERNET_SERVICE, ethService);
这样以后我们就可以用getService的方法来获得该服务了。
回来看EthernetManager.java中的函数,它定义了对外提供访问的共有函数:
95     public EthernetDevInfo getSavedConfig() {
96         try {
97             return mService.getSavedConfig();
98         } catch (RemoteException e) {
99             Slog.i(TAG, "Can not get eth config");
100         }
101         return null;
102     }
可以看到都是同过调用mService的方法,而mService正是我们上面的ETHERNET_SERVICE,它在那里获得呢?看文件:
core/java/android/app/ContextImpl.java
487         if (Items.ItemExist("eth.model") == 1) {
488             registerService(ETHERNET_SERVICE, new ServiceFetcher() {
489                 public Object createService(ContextImpl ctx) {
490                     IBinder b = ServiceManager.getService(ETHERNET_SERVICE);                                       
491                     if (b == null)
492                     {
493                         Log.w(TAG, "Error getting service name:" + ETHERNET_SERVICE);
494                     }
495                     IEthernetManager service = IEthernetManager.Stub.asInterface(b);
496                     return new EthernetManager(service, ctx.mMainThread.getHandler());
497                 }});
498             }
果然是通过ServiceManager.getService(ETHERNET_SERVICE)来获得的,而且注册了EthernetManager服务,这样我们的应用中用getSystemService方法即可获得一个
EthernetManager.java中的对象了,当然还要把EthernetManager.java中的函数等声明为公开,应用程序才能调用得到,api/current.txt中:
12765   public class EthernetManager {                                                                                   
12766     ctor public EthernetManager(android.net.ethernet.IEthernetManager, android.os.Handler);
12767     method public java.lang.String[] getDeviceNameList();
12768     method public android.net.ethernet.EthernetDevInfo getSavedConfig();
12769     method public int getState();
12770     method public int getTotalInterface();
12771     method public boolean isConfigured();
12772     method public void updateDevInfo(android.net.ethernet.EthernetDevInfo);
12773     field public static final int ETHERNET_DEVICE_SCAN_RESULT_READY = 0; // 0x0
12774     field public static final java.lang.String ETHERNET_STATE_CHANGED_ACTION = "android.net.ethernet.ETHERNET_STATE_CHANGED";
12775     field public static final int ETHERNET_STATE_DISABLED = 1; // 0x1
12776     field public static final int ETHERNET_STATE_ENABLED = 2; // 0x2
12777     field public static final int ETHERNET_STATE_UNKNOWN = 0; // 0x0
12778     field public static final java.lang.String EXTRA_ETHERNET_STATE = "ETHERNET_state";
12779     field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
12780     field public static final java.lang.String EXTRA_PREVIOUS_ETHERNET_STATE = "previous_ETHERNET_state";
12781     field public static final java.lang.String NETWORK_STATE_CHANGED_ACTION = "android.net.ethernet.STATE_CHANGE";
12782     field public static final java.lang.String TAG = "EthernetManager";
12783   }
这样,应用中getSystemService(Context.ETHERNET_SERVICE)即可获得服务














33.frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java中power key的处理分析:
2994             case KeyEvent.KEYCODE_POWER: {
...........
3023                     interceptPowerKeyDown(!isScreenOn || hungUp //处理按键按下去的动作
3024                             || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);




interceptPowerKeyDown函数如下:
605     private void interceptPowerKeyDown(boolean handled) {                                                  
606         mPowerKeyHandled = handled;
607         if (!handled) {
608             mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());//表示长按多久后弹出关机确认对话框
609         }
610     }
接着:
3028                     if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {//处理按键抬起的动作
3029                         result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
3030                     }
interceptPowerKeyUp函数如下:
612     private boolean interceptPowerKeyUp(boolean canceled) {                                         
613         if (!mPowerKeyHandled) {
614             mHandler.removeCallbacks(mPowerLongPress);//如果还没有弹出关机确认对话框,取消掉它
615             return !canceled;
616         }
617         return false;
618     }










34. Audio java部分代码流程(4.1.2 version):
在frameworks/base/media/java/android/media中:
IAudioService.aidl提供了所有对外的接口函数,如下:
interface IAudioService {
   
   void adjustVolume(int direction, int flags);


   void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags);
   
   void adjustStreamVolume(int streamType, int direction, int flags);
   
   void setStreamVolume(int streamType, int index, int flags);
   
   void setStreamSolo(int streamType, boolean state, IBinder cb);
 
   void setStreamMute(int streamType, boolean state, IBinder cb);


   boolean isStreamMute(int streamType);


   int getStreamVolume(int streamType);
   
   int getStreamMaxVolume(int streamType);
   
   int getLastAudibleStreamVolume(int streamType);


   void setRingerMode(int ringerMode);
.......................
}
这些函数的实现在服务AudioService.java中:
public class AudioService extends IAudioService.Stub {
........
}
该服务在services/java/com/android/server/SystemServer.java中注册进servicemanager中:
492             try {
493                 Slog.i(TAG, "Audio Service");
494                 ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));                               
495             } catch (Throwable e) {
496                 reportWtf("starting Audio Service", e);
497             }
这样在frameworks中可以通过ServiceManager.getService(Context.AUDIO_SERVICE)来获得该服务。
而AudioManager.java则实现这些函数了对外应用的接口,比如:
496     public void adjustVolume(int direction, int flags) {
497         IAudioService service = getService(); //
498         try {
499             service.adjustVolume(direction, flags);
500         } catch (RemoteException e) {
501             Log.e(TAG, "Dead object in adjustVolume", e);
502         }
503     }
这里的getService()获得的是前面的AudioService,如下:
365     private static IAudioService getService()                                                                              
366     {
367         if (sService != null) {
368             return sService;
369         }
370         IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
371         sService = IAudioService.Stub.asInterface(b);
372         return sService;
373     }
要把AudioManager.java中的对外公开,则要在 core/java/android/app/ContextImpl.java中注册:
281         registerService(AUDIO_SERVICE, new ServiceFetcher() {                                                   
282                 public Object createService(ContextImpl ctx) {
283                     return new AudioManager(ctx);
284                 }});
而且,还要把这些函数变量等在api/current.txt中声明:
10353   public class AudioManager {
10354     method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
10355     method public void adjustStreamVolume(int, int, int);                                           
10356     method public void adjustSuggestedStreamVolume(int, int, int);
10357     method public void adjustVolume(int, int);
10358     method public int getMode();
10359     method public java.lang.String getParameters(java.lang.String);
10360     method public int getRingerMode();
10361     method public deprecated int getRouting(int);
10362     method public int getStreamMaxVolume(int);
10363     method public int getStreamVolume(int);
10364     method public int getVibrateSetting(int);
10365     method public boolean isBluetoothA2dpOn();
这样在应用中用(AudioManager) getSystemService(Context.AUDIO_SERVICE);即可获得服务,从而使用AudioManager.java中的方法
然后看看比如setStreamVolume是如何从java调用到底层的:
1、应用调用比如mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
2、AudioManager.java调用public void setStreamVolume(int streamType, int index, int flags){};
3、AudioService.java调用public void setStreamVolume(int streamType, int index, int flags){},在该函数中调用
 setStreamVolumeInt(mStreamVolumeAlias[streamType],                                                                                       
831                                    index,
832                                    device,
833                                    false,
834                                    true);
--------->
1002                 sendMsg(mAudioHandler,
1003                         MSG_PERSIST_VOLUME,
1004                         SENDMSG_QUEUE,
1005                         PERSIST_LAST_AUDIBLE,
1006                         device,
1007                         streamState,
1008                         PERSIST_DELAY);
而mAudioHandler = new AudioHandler(),看看这个AudioHandler类:private class AudioHandler extends Handler {};-------->
所以调用该类重写的handleMessage方法--------->
2940         @Override
2941         public void handleMessage(Message msg) {
2942
2943             switch (msg.what) {
2944 
2945                 case MSG_SET_DEVICE_VOLUME:
2946                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
2947                     break;
setDeviceVolume---------> mStreamStates[streamType].applyDeviceVolume(getDeviceForStream(streamType));---------->
AudioSystem.setStreamVolumeIndex--------->
setStreamVolumeIndex的定义在AudioSystem.java中-------->public static native int setStreamVolumeIndex(int stream, int index, int device); 
setStreamVolumeIndex的JNI实现在base/core/jni/android_media_AudioSystem.cpp中---------->
178 static int
179 android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,                                                                 
180                                                jobject thiz,
181                                                jint stream,
182                                                jint index,
183                                                jint device)
184 {
185     return check_AudioSystem_Command(
186             AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
187                                               index,
188                                               (audio_devices_t)device));
189 }
AudioSystem类在av/media/libmedia/AudioSystem.cpp中--------->
666 status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream,
667                                            int index,
668                                            audio_devices_t device)
669 {
670     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
671     if (aps == 0) return PERMISSION_DENIED;
672     return aps->setStreamVolumeIndex(stream, index, device);
673 }
到这里就要涉及到进程间通讯binder的使用了,我们看AudioSystem::get_audio_policy_service()的实现:
514 const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service()
515 {
516     gLock.lock();
517     if (gAudioPolicyService == 0) {
518         sp<IServiceManager> sm = defaultServiceManager();//取得BpServiceManager,通过这个代理可以调用BnServiceManager::onTransact,最后和
    //ServiceManager通讯
519         sp<IBinder> binder;
520         do {
521             binder = sm->getService(String16("media.audio_policy"));//从ServiceManager获得远程AudioPolicyService的句柄
522             if (binder != 0)
523                 break;
524             ALOGW("AudioPolicyService not published, waiting...");
525             usleep(500000); // 0.5 s
526         } while (true);
527         if (gAudioPolicyServiceClient == NULL) {
528             gAudioPolicyServiceClient = new AudioPolicyServiceClient();
529         }
530         binder->linkToDeath(gAudioPolicyServiceClient);
531         gAudioPolicyService = interface_cast<IAudioPolicyService>(binder);               
532         gLock.unlock();
533     } else {
534         gLock.unlock();
535     }
536     return gAudioPolicyService;
537 }
上面531行interface_cast<IAudioPolicyService>(binder),interface_cast是一个模版,在frameworks/native/include/binder/IInterface.h中定义如下:
42 inline sp<INTERFACE> interface_cast(const sp<IBinder>&obj)               
43 {
44     return INTERFACE::asInterface(obj);
45 }
展开后是IAudioPolicyService::asInterface(obj);而IAudioPolicyService::asInterface的实现在frameworks/av/include/media/IAudioPolicyService.h中,通过宏
DECLARE_META_INTERFACE(AudioPolicyService)展开后得到的,DECLARE_META_INTERFACE定义在IInterface.h中:
74 #define DECLARE_META_INTERFACE(INTERFACE)                               \
75     static const android::String16 descriptor;                          \
76     static android::sp<I##INTERFACE> asInterface(                       \
77             const android::sp<android::IBinder>& obj);                  \
78     virtual const android::String16& getInterfaceDescriptor() const;    \
79     I##INTERFACE();                                                     \
80     virtual ~I##INTERFACE();
76行展开即可得到IAudioPolicyService::asInterface的定义,而这个定义的实现也是在IInterface.h,通过宏来定义的:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
........................
89     android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
90             const android::sp<android::IBinder>& obj)                   \
91     {                                                                   \
92         android::sp<I##INTERFACE> intr;                                 \
93         if (obj != NULL) {                                              \
94             intr = static_cast<I##INTERFACE*>(                          \
95                 obj->queryLocalInterface(                               \
96                         I##INTERFACE::descriptor).get());               \
97             if (intr == NULL) {                                         \
98                 intr = new Bp##INTERFACE(obj);                          \
99             }                                                           \
100         }                                                               \
101         return intr;                                                    \
102     }


展开后最终是生成调用new BpAudioPolicyService(new BpBinder(handle)),这里的handle是一个句柄;这样我们最终得到了AudioPolicyService的代理BpAudioPolicyService,通过它就可以和 
AudioPolicyService的本地接口BnAudioPolicyService通讯了
回到前面的AudioSystem.cpp,取得代理BpAudioPolicyService后调用aps->setStreamVolumeIndex,所以进入IAudioPolicyService.cpp:
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>:
233     virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,                                                           
234                                           int index,
235                                           audio_devices_t device)
236     {
237         Parcel data, reply;
238         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
239         data.writeInt32(static_cast <uint32_t>(stream));
240         data.writeInt32(index);
241         data.writeInt32(static_cast <uint32_t>(device));
242         remote()->transact(SET_STREAM_VOLUME, data, &reply);
243         return static_cast <status_t> (reply.readInt32());
244     }
242行的remote是通过继承关系BpAudioPolicyService -> BpInterface -> BpRefBase,在类BpRefBase中定义的:
inline  IBinder*        remote()                { return mRemote; }
  IBinder* const          mRemote;
这里mRemote声明为const,可见它是静态不变,只赋值一次,它是在前面获取远程服务AudioPolicyService时候创建的BpBinder对象(主要是打开了binder驱动,获得FD描述符,并且内
存映射了空间),所以调用BpBinder.cpp的transact函数:
159 status_t BpBinder::transact(
160     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
161 {
162     // Once a binder has died, it will never come back to life.
163     if (mAlive) {
164         status_t status = IPCThreadState::self()->transact(
165             mHandle, code, data, reply, flags);
166         if (status == DEAD_OBJECT) mAlive = 0;
167         return status;
168     }
169 
170     return DEAD_OBJECT;
171 }
从164行,调用IPCThreadState.cpp的transact,这里就是最终和binder驱动打交道的地方了,165行通过的mHandle,底层binder驱动知道了传输数据的目标地址为mediaserver进
程,并且调整远程mediaserver用户空间buffer在内核中指向的位置,最终指向客户端内存映射的数据的位置,远程服务端就可以不用再次拷贝数据,直接从用户空间就可以读取客户端
的数据了, 这样remote()->transact(SET_STREAM_VOLUME, data, &reply)就通过binder传递到BnAudioPolicyService中了,这样就调用IAudioPolicyService.cpp的
BnAudioPolicyService::onTransact函数来处理该请求(但由于继承关系最终是派发到Bn的派生类AudioPolicyService::onTransact来处理,不过我们后面也会发现派生类又调回Bn类
的onTransact去处理,很有意思啊),我们看看BnAudioPolicyService是如何获得remote()->transact(SET_STREAM_VOLUME, data, &reply)的请求的,这样要从
AudioPolicyService是如何将自己的服务添加到servicemanager中的说起,在frameworks/av/media/mediaserver/main_mediaserver.cpp中:
34 int main(int argc, char** argv)
35 {
36     sp<ProcessState> proc(ProcessState::self());
37     sp<IServiceManager> sm = defaultServiceManager();
38     ALOGI("ServiceManager: %p", sm.get());
39     AudioFlinger::instantiate();
40     MediaPlayerService::instantiate();
41     CameraService::instantiate();
42     AudioPolicyService::instantiate();                                                                                        
43     ProcessState::self()->startThreadPool();
44     IPCThreadState::self()->joinThreadPool();
45 } 
36行,由于main_mediaserver.cpp是编译成一个可执行文件,就是它的启动是作为服务在一个独立的进程中运行了,Main_MediaServer主函数由init.rc在启动时调用,先明白这点,
然后看:
frameworks/native/libs/binder/ProcessState.cpp:
74 sp<ProcessState> ProcessState::self()
75 {
76     Mutex::Autolock _l(gProcessMutex);
77     if (gProcess != NULL) {
78         return gProcess;
79     }
80     gProcess = new ProcessState;
81     return gProcess;
82 }
从77行可知,这是一个单例模式,在这个进程中以后再调用这个函数的话,就直接返回78行,这里我们第一次进来,所以跑到80行,进入ProcessState构造函数:
335 ProcessState::ProcessState()
336     : mDriverFD(open_driver())
337     , mVMStart(MAP_FAILED)
338     , mManagesContexts(false)
339     , mBinderContextCheckFunc(NULL)
340     , mBinderContextUserData(NULL)
341     , mThreadPoolStarted(false)
342     , mThreadPoolSeq(1)
343 {   
344     if (mDriverFD >= 0) {
345         // XXX Ideally, there should be a specific define for whether we
346         // have mmap (or whether we could possibly have the kernel module
347         // availabla).
348 #if !defined(HAVE_WIN32_IPC)
349         // mmap the binder, providing a chunk of virtual address space to receive transactions.
350         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
.................................
}
336行打开Binder设备文件/dev/binder,并将打开设备文件描述符保存在成员变量mDriverFD中;350行mmap来把设备文件/dev/binder映射到内存中,这样我们就有了一块共享内存。
回到main_mediaserver.cpp,37行defaultServiceManager(),在frameworks/native/libs/binder/IServiceManager.cpp中:
34 sp<IServiceManager> defaultServiceManager()                                                                          
35 {   
36     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
37     
38     {
39         AutoMutex _l(gDefaultServiceManagerLock);
40         if (gDefaultServiceManager == NULL) {
41             gDefaultServiceManager = interface_cast<IServiceManager>(
42                 ProcessState::self()->getContextObject(NULL));
43         }
44     }
45 
46     return gDefaultServiceManager;
47 }
和前面一样,也是一个单例模式,第一次进来肯定为NULL,所以进入41行,ProcessState::self()前面已经运行过一次,直接调用getContextObject(NULL),注意传进来的是NULL
参数,表示和ServiceManager通讯:
89 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
90 {
91     return getStrongProxyForHandle(0);                                                                                              
92 }
getStrongProxyForHandle(0)最终会调用new BpBinder(0),这样我们就得到了ServiceManager的代理BpBinder,回到IServiceManager.cpp的41行,就变成了
interface_cast<IServiceManager>(new BpBinder(0)),interface_cast在前面已经分析过,所以最后变成new BpServiceManager(new BpBinder(0))。
接着进入main_mediaserver.cpp42行AudioPolicyService::instantiate(),先看看frameworks/av/services/audioflinger/AudioPolicyService.h中的继承关系:
37 class AudioPolicyService :
38     public BinderService<AudioPolicyService>,                                                                             
39     public BnAudioPolicyService,
40 //    public AudioPolicyClientInterface,
41     public IBinder::DeathRecipient
AudioPolicyService并没有实现instantiate方法,而是继承BinderService得到的,该类在frameworks/native/include/binder/BinderService.h中:
33 template<typename SERVICE>
34 class BinderService                                                                                                            
35 {
36 public:
37     static status_t publish(bool allowIsolated = false) {
38         sp<IServiceManager> sm(defaultServiceManager());
39         return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
40     }
41 
42     static void publishAndJoinThreadPool(bool allowIsolated = false) {
43         sp<IServiceManager> sm(defaultServiceManager());
44         sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
45         ProcessState::self()->startThreadPool();
46         IPCThreadState::self()->joinThreadPool();
47     }
48     
49     static void instantiate() { publish(); }
50     
51     static status_t shutdown() {
52         return NO_ERROR;
53     }
54 };
这是一个类模版,最终调用39行,得到sm->addService(String16(AudioPolicyService::getServiceName()), new AudioPolicyService(), false)即:
BpServiceManager(new BpBinder(0))->addService(String16("media.audio_policy", new AudioPolicyService(), false),进入BpServiceManger::addService的实现,这个
函数实现在frameworks/native/libs/binder/IServiceManager.cpp:
154     virtual status_t addService(const String16& name, const sp<IBinder>&service, bool allowIsolated)
156     {
157         Parcel data, reply;
158         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
159         data.writeString16(name);
160         data.writeStrongBinder(service);
161         data.writeInt32(allowIsolated ? 1 : 0);
162         status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
163         return err == NO_ERROR ? reply.readExceptionCode() : err;
164     }
这里162行remote流程和前面分析的差不多,最终调用IPCThreadState.cpp的transact,这里就是最终和binder驱动打交道的地方了,binder即为前面main_mediaserver.cpp中36行
ProcessState::ProcessState打开的驱动,用这块共享内存和servicemanager打交道,在底层的内核空间binder驱动会根据传进来的mHandle值判断目标服务地址,这里的
mHandle为0,所以调整servermanager的buffer指向本地内存共享空间,接着往下看main_mediaserver.cpp的43行ProcessState::self()-
>startThreadPool(),
在frameworks/native/libs/binder/ProcessState.cpp中:
136 void ProcessState::startThreadPool()
137 {
138     AutoMutex _l(mLock);
139     if (!mThreadPoolStarted) {
140         mThreadPoolStarted = true;
141         spawnPooledThread(true);                                                                                                             
142     }
143 }
看141行:
286 void ProcessState::spawnPooledThread(bool isMain)                                                                        
287 {
288     if (mThreadPoolStarted) {
289         int32_t s = android_atomic_add(1, &mThreadPoolSeq);
290         char buf[16];
291         snprintf(buf, sizeof(buf), "Binder_%X", s);
292         ALOGV("Spawning new pooled thread, name=%s\n", buf);
293         sp<Thread> t = new PoolThread(isMain);
294         t->run(buf);
295     }
296 }
293行创建了线程,PoolThread类继承列thread类,ProcessState.cpp中::
56 class PoolThread : public Thread
57 {
58 public:
59     PoolThread(bool isMain)
60         : mIsMain(isMain)
61     {
62     }
63 
64 protected:
65     virtual bool threadLoop()                                                                                                    
66     {
67         IPCThreadState::self()->joinThreadPool(mIsMain);
68         return false;
69     }
70 
71     const bool mIsMain;
72 };
294行执行线程,thread在frameworks/native/libs/utils/Threads.cpp中,这样run函数最终调用子类的threadLoop函数,看67行,调用的和main_mediaserver.cpp的44行一样,
进入IPCThreadState.cpp中,result = talkWithDriver()等待client请求,最终会调用 executeCommand(cmd)函数来处理请求,而在executeCommand函数
中,最终会调用BBinder::transact来真正处理Client的请求,接下来再看一下BBinder::transact的实现,frameworks/native/libs/binder/Binder.cpp中:
97 status_t BBinder::transact(
98     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
99 {
100     data.setDataPosition(0);
101 
102     status_t err = NO_ERROR;
103     switch (code) {
104         case PING_TRANSACTION:                                                                                              
105             reply->writeInt32(pingBinder());
106             break;
107         default:
108             err = onTransact(code, data, reply, flags);
109             break;
110     }
111 
112     if (reply != NULL) {
113         reply->setDataPosition(0);
114     }
115 
116     return err;
117 }
108行,调用onTransact方法,由于这里的继承关系,在前面分析main_mediaserver.cpp的42行AudioPolicyService::instantiate()就知道,这里创建的是AudioPolicyService类,
这样由于虚函数onTransact的继承关系,最终调用了AudioPolicyService的onTransact方法,AudioPolicyService.cpp中:
610 status_t AudioPolicyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
612 {
613     return BnAudioPolicyService::onTransact(code, data, reply, flags);
614 }
613行调用的还是基类BnAudioPolicyService的方法.
到这里BpAudioPolicyService和BnAudioPolicyService的binder通讯关系就完成了,回到前面IAudioPolicyService.cpp中的242行
remote()->transact(SET_STREAM_VOLUME, data, &reply);这里传进来的是SET_STREAM_VOLUME,所以调用BnAudioPolicyService::onTransact:
512         case SET_STREAM_VOLUME:{                                                                                         
513             CHECK_INTERFACE(IAudioPolicyService, data, reply);
514             audio_stream_type_t stream =
515                     static_cast <audio_stream_type_t>(data.readInt32());
516             int index = data.readInt32();
517             audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
518             reply->writeInt32(static_cast <uint32_t>(setStreamVolumeIndex(stream,
519                                                                           index,
520                                                                           device)));
521             return NO_ERROR;
522         } break;
518行AudioPolicyService覆盖了BpAudioPolicyService的setStreamVolumeIndex方法,所以最终调用了AudioPolicyService.cpp的setStreamVolumeIndex方法:
380 status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
381                                                   int index,
382                                                   audio_devices_t device)
383 {
384     if (mpAudioPolicy == NULL) {
385         return NO_INIT;
386     }
387     if (!settingsAllowed()) {
388         return PERMISSION_DENIED;
389     }
390     if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
391         return BAD_VALUE;
392     }
393 
394     if (mpAudioPolicy->set_stream_volume_index_for_device) {                                                           
395         return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
396                                                                 stream,
397                                                                 index,
398                                                                 device);
399     } else {
400         return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
401     }
402 }
总结上面binder的通讯机制,理解了类之间的继承派生关系,也就能把来龙去脉弄清楚,主要还是熟悉C++才行,还有要理解binder通讯的设计原理,即每个服务或者想要获得服务的进
程都会打开binder节点,并且内存映射有一块空间,binder驱动根据传进来的handle判断数据要传送的目的地,从而调整目的地用户空间buffer指针在内核中的位置指向要传送的数据,
目的地读取buffer即可得到数据了,通过这样的浅拷贝即可实现进程间传输数据只用拷贝一次即可的原理。继续从AudioPolicyService.cpp往下走。先看它的构造函数:
 58 AudioPolicyService::AudioPolicyService()
 59     : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
 60 {
 61     char value[PROPERTY_VALUE_MAX];
 62     const struct hw_module_t *module;
 63     int forced_val;
 64     int rc;
 65 
 66     Mutex::Autolock _l(mLock);
 67 
 68     // start tone playback thread
 69     mTonePlaybackThread = new AudioCommandThread(String8(""));
 70     // start audio commands thread
 71     mAudioCommandThread = new AudioCommandThread(String8("ApmCommand"));
 72 
 73     /* instantiate the audio policy manager */
 74     rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
 75     if(rc)                                                                                                           
 76         return;
 77 
 78     rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
 79     ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
 80     if (rc)
 81         return;
 82 
 83     rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
 84                                                &mpAudioPolicy);
 85     ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
 86     if (rc)
 87         return;
 88 
 89     rc = mpAudioPolicy->init_check(mpAudioPolicy);
 90     ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
 91     if (rc)
 92         return;
.......................
}
74行AUDIO_POLICY_HARDWARE_MODULE_ID定义在libhardware/include/hardware/audio_policy.h中,
#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy"
根据hw_get_module的判断关系,看hardware/libhardware_legacy/audio/Android.mk可知,最终调用的是audio_policy.default.so,通过hw_get_module函数的
load(class_id, path, module)打开audio_policy.default.so并返回句柄,接着78行audio_policy_dev_open,在libhardware/include/hardware/audio_policy.h
424 static inline int audio_policy_dev_open(const hw_module_t* module,
425                                     struct audio_policy_device** device)
426 {
427     return module->methods->open(module, AUDIO_POLICY_INTERFACE,
428                                  (hw_device_t**)device);
429 }
这样就调用了hardware/libhardware_legacy/audio/audio_policy_hal.cpp的open方法:
406 static int legacy_ap_dev_open(const hw_module_t* module, const char* name, hw_device_t** device)
408 {
409     struct legacy_ap_device *dev;
411     if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
412         return -EINVAL;
414     dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));                                                    
415     if (!dev)
416         return -ENOMEM;
418     dev->device.common.tag = HARDWARE_DEVICE_TAG;
419     dev->device.common.version = 0;
420     dev->device.common.module = const_cast<hw_module_t*>(module);
421     dev->device.common.close = legacy_ap_dev_close;
422     dev->device.create_audio_policy = create_legacy_ap;
423     dev->device.destroy_audio_policy = destroy_legacy_ap;
425     *device = &dev->device.common;
427     return 0;
428 }
结构体legacy_ap_device定义:
40 struct legacy_ap_device {                                                                                                                     
41     struct audio_policy_device device;
42 };
结构体audio_policy_device定义:
410 struct audio_policy_device {                                                                                                  
411     struct hw_device_t common;
412 
413     int (*create_audio_policy)(const struct audio_policy_device *device,
414                                struct audio_policy_service_ops *aps_ops,
415                                void *service,
416                                struct audio_policy **ap);
417 
418     int (*destroy_audio_policy)(const struct audio_policy_device *device,
419                                 struct audio_policy *ap);
420 };
所以这里open的425行*device = &dev->device.common赋值的虽然是结构体audio_policy_device的成员common的地址,但是common位于结构体首地址,也就是相当于返回了
audio_policy_device结构体的地址。所以接着AudioPolicyService.cpp的83行调用的是audio_policy_device的create_audio_policy,它指向create_legacy_ap函数:
311 static int create_legacy_ap(const struct audio_policy_device *device,
312                             struct audio_policy_service_ops *aps_ops,
313                             void *service,
314                             struct audio_policy **ap)
315 {
316     struct legacy_audio_policy *lap;
317     int ret;
318 
319     if (!service || !aps_ops)
320         return -EINVAL;
321 
322     lap = (struct legacy_audio_policy *)calloc(1, sizeof(*lap));
323     if (!lap)
324         return -ENOMEM;
325 
326     lap->policy.set_device_connection_state = ap_set_device_connection_state;
327     lap->policy.get_device_connection_state = ap_get_device_connection_state;
328     lap->policy.set_phone_state = ap_set_phone_state;
329     lap->policy.set_ringer_mode = ap_set_ringer_mode;
330     lap->policy.set_force_use = ap_set_force_use;
331     lap->policy.get_force_use = ap_get_force_use;
332     lap->policy.set_can_mute_enforced_audible = ap_set_can_mute_enforced_audible;
334     lap->policy.init_check = ap_init_check;
335     lap->policy.get_output = ap_get_output;
336     lap->policy.start_output = ap_start_output;
337     lap->policy.stop_output = ap_stop_output;
338     lap->policy.release_output = ap_release_output;
339     lap->policy.get_input = ap_get_input;
340     lap->policy.start_input = ap_start_input;
341     lap->policy.stop_input = ap_stop_input;
342     lap->policy.release_input = ap_release_input;
343     lap->policy.init_stream_volume = ap_init_stream_volume;
344     lap->policy.set_stream_volume_index = ap_set_stream_volume_index;
345     lap->policy.get_stream_volume_index = ap_get_stream_volume_index;                                                                  
346     lap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device;
347     lap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device;
348     lap->policy.get_strategy_for_stream = ap_get_strategy_for_stream;
349     lap->policy.get_devices_for_stream = ap_get_devices_for_stream;
350     lap->policy.get_output_for_effect = ap_get_output_for_effect;
351     lap->policy.register_effect = ap_register_effect;
352     lap->policy.unregister_effect = ap_unregister_effect;
353     lap->policy.set_effect_enabled = ap_set_effect_enabled;
354     lap->policy.is_stream_active = ap_is_stream_active;
355     lap->policy.dump = ap_dump;
356 
357     lap->service = service;
358     lap->aps_ops = aps_ops;
359     lap->service_client =
360         new AudioPolicyCompatClient(aps_ops, service);
361     if (!lap->service_client) {
362         ret = -ENOMEM;
363         goto err_new_compat_client;
364     }
365 
366     lap->apm = createAudioPolicyManager(lap->service_client);
367     if (!lap->apm) {
368         ret = -ENOMEM;
369         goto err_create_apm;
370     }
371 
372     *ap = &lap->policy;
373     return 0;
374 
375 err_create_apm:
376     delete lap->service_client;
377 err_new_compat_client:
378     free(lap);
379     *ap = NULL;
380     return ret;
381 }
372行可知,这样mpAudioPolicy指针就指向了lap->policy方法。回到前面AudioPolicyService::setStreamVolumeIndex的394行调用audio_policy_hal.cpp方法:
232 static int ap_set_stream_volume_index_for_device(struct audio_policy *pol,                                                   
233                                       audio_stream_type_t stream,
234                                       int index,
235                                       audio_devices_t device)
236 {
237     struct legacy_audio_policy *lap = to_lap(pol);
238     return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
239                                           index,
240                                           device);
241 }
237行结构体legacy_audio_policy定义:
44 struct legacy_audio_policy {                                                                                                  
45     struct audio_policy policy;//即为mpAudioPolicy
46 
47     void *service;
48     struct audio_policy_service_ops *aps_ops;
49     AudioPolicyCompatClient *service_client;
50     AudioPolicyInterface *apm;
51 };
lap->apm的赋值在前面create_legacy_ap函数的366行,看createAudioPolicyManager,hardware/libhardware_legacy/audio/AudioPolicyManagerDefault.cpp中:
24 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
25 {
26     return new AudioPolicyManagerDefault(clientInterface);                                                                           
27 }
----->hardware/libhardware_legacy/audio/AudioPolicyManagerDefault.h:
25 class AudioPolicyManagerDefault: public AudioPolicyManagerBase
26 {
28 public:
29                 AudioPolicyManagerDefault(AudioPolicyClientInterface *clientInterface)                                           
30                 : AudioPolicyManagerBase(clientInterface) {}
31 
32         virtual ~AudioPolicyManagerDefault() {}
33 
34 };
看基类AudioPolicyManagerBase,hardware/libhardware_legacy/include/hardware_legacy/AudioPolicyManagerBase.h的定义,终于找到了setStreamVolumeIndex方法,
在AudioPolicyManagerBase.cpp中:
953 status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index, audio_devices_t device)
956 {
958     if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
959         return BAD_VALUE;
960     }
961     if (!audio_is_output_device(device)) {
962         return BAD_VALUE;
963     }
965     // Force max volume if stream cannot be muted
966     if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
971     // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
972     // clear all device specific values
973     if (device == AUDIO_DEVICE_OUT_DEFAULT) {
974         mStreams[stream].mIndexCur.clear();
975     }
976     mStreams[stream].mIndexCur.add(device, index);
978     // compute and apply stream volume on all outputs according to connected device
979     status_t status = NO_ERROR;
980     for (size_t i = 0; i < mOutputs.size(); i++) {
981         audio_devices_t curDevice =
982                 getDeviceForVolume((audio_devices_t)mOutputs.valueAt(i)->device());
983         if (device == curDevice) {
984             status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
985             if (volStatus != NO_ERROR) {
986                 status = volStatus;
987             }
988         }
989     }
990     return status;
991 }
看984行checkAndSetVolume函数:
2683 status_t AudioPolicyManagerBase::checkAndSetVolume(int stream,
2684                                                    int index,
2685                                                    audio_io_handle_t output,
2686                                                    audio_devices_t device,
2687                                                    int delayMs,
2688                                                    bool force)
2689 {
....................
2722             if (stream == AudioSystem::BLUETOOTH_SCO) {
2723                 mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs);
2724             }
2725         }
2726 
2727         mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
...................
2747 }
这里mpClientInterface是在AudioPolicyManagerBase构造函数中赋值的,就是create_legacy_ap函数360行AudioPolicyCompatClient,方法在AudioPolicyCompatClient.cpp:
120 status_t AudioPolicyCompatClient::setStreamVolume(                                                                                 
121                                              AudioSystem::stream_type stream,
122                                              float volume,
123                                              audio_io_handle_t output,
124                                              int delayMs)
125 {
126     return mServiceOps->set_stream_volume(mService, (audio_stream_type_t)stream,
127                                           volume, output, delayMs);
128 }
这里是在构造函数中赋值的,看AudioPolicyCompatClient.h:
 32 class AudioPolicyCompatClient : public AudioPolicyClientInterface {
 33 public:
 34     AudioPolicyCompatClient(struct audio_policy_service_ops *serviceOps,                                                                          
 35                             void *service) :
 36             mServiceOps(serviceOps) , 
mService(service) {}
从36行可知,构造时候就已经赋值了,所以调用的是create_legacy_ap函数312行传进来的的型参aps_ops的set_stream_volume,它的赋值在
frameworks/av/services/audioflinger/AudioPolicyService.cpp中:
1538     struct audio_policy_service_ops aps_ops = {
1539         open_output           : aps_open_output,
1540         open_duplicate_output : aps_open_dup_output,
1541         close_output          : aps_close_output,
1542         suspend_output        : aps_suspend_output,
1543         restore_output        : aps_restore_output,
1544         open_input            : aps_open_input,
1545         close_input           : aps_close_input,
1546         set_stream_volume     : aps_set_stream_volume,                                                                 
1547         set_stream_output     : aps_set_stream_output,
1548         set_parameters        : aps_set_parameters,
1549         get_parameters        : aps_get_parameters,
1550         start_tone            : aps_start_tone,
1551         stop_tone             : aps_stop_tone,
1552         set_voice_volume      : aps_set_voice_volume,
1553         move_effects          : aps_move_effects,
1554         load_hw_module        : aps_load_hw_module,
1555         open_output_on_module : aps_open_output_on_module,
1556         open_input_on_module  : aps_open_input_on_module,
1557     };
------------>
1503 static int aps_set_stream_volume(void *service, audio_stream_type_t stream,                                                      
1504                                      float volume, audio_io_handle_t output,
1505                                      int delay_ms)
1506 {
1507     AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1508 
1509     return audioPolicyService->setStreamVolume(stream, volume, output,
1510                                                delay_ms);
1511 }
这里1507行的service即create_legacy_ap 360行传进来的service,也就是AudioPolicyService.cpp构造函数中83行的this指针,饶了半天居然还是调用了AudioPolicyService.cpp
的setStreamVolume,噢,My Lady GaGa!
看看setStreamVolume的实现:
1006 int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,                             
1007                                         float volume,
1008                                         audio_io_handle_t output,
1009                                         int delayMs)
1010 {
1011     return (int)mAudioCommandThread->volumeCommand(stream, volume,
1012                                                    output, delayMs);
1013 }
一看就知道是个线程之类的东西了,AudioCommandThread继承了Thread类,看看volumeCommand的实现:
 800 status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,                              
 801                                                                float volume,
 802                                                                audio_io_handle_t output,
 803                                                                int delayMs)
 804 {
 805     status_t status = NO_ERROR;
 806 
 807     AudioCommand *command = new AudioCommand();
 808     command->mCommand = SET_VOLUME;
 809     VolumeData *data = new VolumeData();
 810     data->mStream = stream;
 811     data->mVolume = volume;
 812     data->mIO = output;
 813     command->mParam = data;
 814     if (delayMs == 0) {
 815         command->mWaitStatus = true;
 816     } else {
 817         command->mWaitStatus = false;
 818     }
 819     Mutex::Autolock _l(mLock);
 820     insertCommand_l(command, delayMs);
 821     ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
 822             stream, volume, output);
 823     mWaitWorkCV.signal();
 824     if (command->mWaitStatus) {
 825         command->mCond.wait(mLock);
 826         status =  command->mStatus;
 827         mWaitWorkCV.signal();
 828     }
 829     return status;
 830 }
820行insertCommand_l,加入线程队列中,看看线程的执行函数threadLoop:
bool AudioPolicyService::AudioCommandThread::threadLoop()
{
681                 case SET_VOLUME: {
682                     VolumeData *data = (VolumeData *)command->mParam;
683                     ALOGV("AudioCommandThread() processing set volume stream %d, \
684                             volume %f, output %d", data->mStream, data->mVolume, data->mIO);
685                     command->mStatus = AudioSystem::setStreamVolume(data->mStream,
686                                                                     data->mVolume,
687                                                                     data->mIO);
688                     if (command->mWaitStatus) {
689                         command->mCond.signal();
690                         mWaitWorkCV.wait(mLock);
691                     }
692                     delete data;
693                     }break;


}
685行,我们又回到AudioSystem.cpp中来啦:
123 status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value,                                        
124         audio_io_handle_t output)
125 {
126     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
127     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
128     if (af == 0) return PERMISSION_DENIED;
129     af->setStreamVolume(stream, value, output);
130     return NO_ERROR;
131 }
129行,我们终于要进入AudioFlinger.cpp中啦,先看126行,get_audio_flinger:
49 const sp<IAudioFlinger>& AudioSystem::get_audio_flinger()
50 {
51     Mutex::Autolock _l(gLock);
52     if (gAudioFlinger == 0) {
53         sp<IServiceManager> sm = defaultServiceManager();
54         sp<IBinder> binder;                                                                                                      
55         do {
56             binder = sm->getService(String16("media.audio_flinger"));
57             if (binder != 0)
58                 break;
59             ALOGW("AudioFlinger not published, waiting...");
60             usleep(500000); // 0.5 s
61         } while (true);
62         if (gAudioFlingerClient == NULL) {
63             gAudioFlingerClient = new AudioFlingerClient();
64         } else {
65             if (gAudioErrorCallback) {
66                 gAudioErrorCallback(NO_ERROR);
67             }
68         }
69         binder->linkToDeath(gAudioFlingerClient);
70         gAudioFlinger = interface_cast<IAudioFlinger>(binder);
71         gAudioFlinger->registerClient(gAudioFlingerClient);
72     }
73     ALOGE_IF(gAudioFlinger==0, "no AudioFlinger!?");
74 
75     return gAudioFlinger;
76 }
分析完前面的binder通讯,再看这个函数的代码,太简单了!70行最终得到一个BpAudioFlinger代理,以便和BnAudioFlinger通讯,他们在IAudioFlinger.cpp中:
255     virtual status_t setStreamVolume(audio_stream_type_t stream, float value,                            
256             audio_io_handle_t output)
257     {
258         Parcel data, reply;
259         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
260         data.writeInt32((int32_t) stream);
261         data.writeFloat(value);
262         data.writeInt32((int32_t) output);
263         remote()->transact(SET_STREAM_VOLUME, data, &reply);
264         return reply.readInt32();
265     }
263行,,类型为SET_STREAM_VOLUME,由于AudioFlinger继承BnAudioFlinger,调用AudioFlinger的onTransact,但该函数还是回调BnAudioFlinger的onTransact,进入
BnAudioFlinger::onTransact函数:
780         case SET_STREAM_VOLUME: {                                                                                 
781             CHECK_INTERFACE(IAudioFlinger, data, reply);
782             int stream = data.readInt32();
783             float volume = data.readFloat();
784             audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
785             reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
786             return NO_ERROR;
785行,进入AudioFlinger.cpp:
761 status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
762         audio_io_handle_t output)
763 {
764     // check calling permissions
765     if (!settingsAllowed()) {
766         return PERMISSION_DENIED;
767     }
769     if (uint32_t(stream) >= AUDIO_STREAM_CNT) {//定义在system/core/include/system/audio.h                        
771         return BAD_VALUE;
772     }
774     AutoMutex lock(mLock);
775     PlaybackThread *thread = NULL;
776     if (output) {
777         thread = checkPlaybackThread_l(output);
778         if (thread == NULL) {
779             return BAD_VALUE;
780         }
781     }
783     mStreamTypes[stream].volume = value;
785     if (thread == NULL) {
786         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
787             mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
788         }
789     } else {
790         thread->setStreamVolume(stream, value);
791     }
793     return NO_ERROR;
794 }
















35. camera打开device/infotm/imapx800/etc/media_profiles.xml配置的位置:
apps/Camera/src/com/android/camera/VideoCamera.java中mMediaRecorder.setProfile(mProfile); //mMediaRecorder为打开录像的录音功能
其中mProfile为 mProfile = CamcorderProfile.get(mCameraId, quality);它是通过调用JNI -> HAL层来解析media_profiles.xml文件的










36. infotmic factroy reset流程:
1. packages/apps/Settings/src/com/android/settings/MasterClearConfirm.java------>
getActivity().sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
2. frameworks/base/core/res/AndroidManifest.xml------>
1748         <receiverandroid:name="com.android.server.MasterClearReceiver"//这里的名字即为activity的路径       
1749             android:permission="android.permission.MASTER_CLEAR"
1750             android:priority="100" >
3. frameworks/base/services/java/com/android/server/MasterClearReceiver.java------->
RecoverySystem.rebootWipeUserData(context);
4. frameworks/base/core/java/android/os/RecoverySystem.java------->
bootCommand(context, "--wipe_data");
378     public  static void bootCommand(Context context, String arg) throws IOException {
379         RECOVERY_DIR.mkdirs();  // In case we need it
380         COMMAND_FILE.delete();  // In case it's not writable
381         LOG_FILE.delete();
382 
383         FileWriter command = new FileWriter(COMMAND_FILE);                                                                 
384         try {
385             command.write(arg);
386             command.write("\n");
387         } finally {
388             command.close();
389         }
390 
391         // Having written the command file, go ahead and reboot
392         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
393         pm.reboot("recovery");
394 
395         throw new IOException("Reboot failed (no permissions?)");
396     }
  其中383行COMMAND_FILE定义:
71     private static File RECOVERY_DIR = new File("/cache/recovery");
72     private static File COMMAND_FILE = new File(RECOVERY_DIR, "command"); 
385行将字符串--wipe_data写到/chache/recovery分区,接着看393行。
5. frameworks/base/services/java/com/android/server/PowerManagerService.java------->
ShutdownThread.reboot(mContext, finalReason, false);
6. frameworks/base/services/java/com/android/server/pm/ShutdownThread.java------->
reboot() -> shutdownInner() -> beginShutdownSequence() ->  sInstance.start() -> run() -> rebootOrShutdown() -> 
PowerManagerService.lowLevelShutdown() -> 到PowerManagerService.java中 -> nativeShutdown()


7. JNI frameworks/base/services/jni/com_android_server_PowerManagerService.cpp ------>
android_reboot(ANDROID_RB_POWEROFF, 0, 0);
8. system/core/libcutils/android_reboot.c  //adb等命令也是通过该函数来reboot的
__reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,LINUX_REBOOT_CMD_RESTART2, arg);//系统调用,进入kernel
9.  kernel/kernel/sys.c -------->
case LINUX_REBOOT_CMD_RESTART2:
  if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
  ret = -EFAULT;
  break;
  }
  buffer[sizeof(buffer) - 1] = '\0';
  //kernel_restart(buffer);
  imap_reset(!strncmp(buffer, "recover", 7)); 
10. arch/arm/mach-imapx800/cpu.c ------->
void imap_reset(int type)                                                                                                           
{
   imapfb_shutdown();


   writel(type, IO_ADDRESS(SYSMGR_RTC_BASE + 0x3c));
   printk(KERN_EMERG "sysreboot: %s\n", (type == 2)? 
   "charger": ((type == 1)? "recovery":
       "normal")); //这里肯定是recovery了


   writel(0x1, IO_ADDRESS(SYSMGR_RTC_BASE + 0x2c));
   writel(0x1, IO_ADDRESS(SYSMGR_RTC_BASE + 0x44));
   
   imap_set_retry_param_default();
   
   writel(0x3, IO_ADDRESS(SYSMGR_RTC_BASE));
   while(1);
}






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值