工作笔记-杂文

http://source.android.com/source/initializing.html
sync code:

repo sync -j4

设置ccache来减少编译时间:

添加环境变量:

 1.$ export USE_CCACHE=1

 #建立缓存目录 

 2.$ export CCACHE_DIR=~/.ccache

设置缓存大小:

3.$cd android/

4.$prebuilt/linux-x86/ccache/ccache -M 50G

有可能在./prebuilts/misc/linux-x86/ccache/ccache

You can watch ccache being used by doing the following:

$ watch -n1 -d prebuilt/misc/linux-x86/ccache/ccache -s


ubuntu 12.10配置adb:

以前adb连接都没有问题的,但是用来连接RK3188的机子,死活连不上,摸索很久,发现要如下配置:

/etc/udev/rules.d/51-android.rules中加入pid, vid:

SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0010", MODE="0666", OWNER="lsc"

重启udev:

sudo service udev restart

/home/lsc/.android/adb_usb.ini中加入vid:

0x2207

重启adb即可:

 adb kill-server

adb shell即可连上去了




全志编译complier:
lunch --> 19
make -j4 -l8
pack -d;-d参数表示有串口输出,否则输出到sdcard.具体看 device/softwinner/xxx/package.sh脚本,他会执行vendor/softwinner/tools/pack/pack脚本

Infotmic编译:
. ./build/envstup.sh


choosecombo
选择,然后make -j8 -l8即可
project :
/device/softwinner/xxx


kernel and uboot:
/vendor/softwinner/

编译kernel,uboot:
 make -j4 bootimage



烧写ramdisk和kernel:
进入out/target/product/crane-byd7目录下:
sudo fastboot flash boot boot.img
uboot:
fastboot flash bootloader bootloader.fex




git恢复修改或则新增的文件:
进入所在的目录如frameworks/base,然后git status . 可以察看修改和新增的文件,git checkout ./ 即可回复修改的,新增的要手动删除






framework中boot.img文件的生成脚本:
在linux-3.0/scripts/build_sun4i.sh中有:
 79     mkbootimg --kernel output/bImage \
 80             --ramdisk output/sun4i_rootfs.cpio.gz \
 81             --board 'sun4i' \
 82             --base 0x40000000 \
 83             -o output/boot.img
作用就是把kernel和ramdisk打包成boot.img,内容格式为:bootimage_head + pagesize(default 2K) + kernel + pagesize + ramdisk + pagesize

boot.img的生成:
build/core/Makefile中,主要是调用out/host/linux-x86/bin/mkbootimg工具生成的,如
    --kernel     out/target/product/tcc8800/kernel
    --ramdisk   out/target/product/tcc8800/ramdisk.img
    --cmdline   console=ttyTCC,115200n8
    --base 0x40000000  --pagesize 8192
可见boot.img是由kernel,ramdisk并且传入命令行参数组成的,mkbootimg工具的代码在system/core/mkbootimg/中

我们的工程中,没有用到在linux-3.0/scripts/build_sun4i.sh中的(已经删除了该语句),而是用build/core/Makefile中的

全志A10平台制作boot.img和ramdisk.img、system.img方法:

boot.img:

out/host/linux-x86/bin/mkbootimg  --kernel out/target/product/crane-rearview/kernel --ramdisk out/target/product/crane-rearview/ramdisk.img --cmdline "console=ttyS0,115200 rw init=/init loglevel=8" --base 0x40000000 --output out/target/product/crane-rearview/boot.img

ramdisk:

out/host/linux-x86/bin/mkbootfs out/target/product/crane-rearview/root | out/host/linux-x86/bin/minigzip > out/target/product/crane-rearview/ramdisk.img

system.img:

make_ext4fs -s -l 536870912 -a system out/target/product/crane-rearview/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/crane-rearview/system


ubuntu12.04下make menuconfig 时候出错的问题:
sudo  apt-get install  libncurses5-dev就可以啦
回复回去则:
sudo apt-get install  libncurses5-dev:i386

查找一个项目中的指定文件并删除他们的命令:
find . -iname .git |xargs rm -rf




git的一些命令:
git branch             查看当前分支
git branch -r          查看所有分支
git pull origin xxx  更新当前分支
git checkout xxx   切换分支

git创建一个新分支并提交:
git commit -a -m "..."
git branch xxx
git checkout xxx
git push origin HEAD:xxx
git删除本地分支:
git branch -d 分支名字

git commit后,没有提交,不小心git checkout回到了以前的分支,这时候要恢复先前提交的,用:

git reflog查看所有提交记录,然后git cherry-pick commitID即可

如果不知道repo init路径,进入其他项目的.repo/manifests目录下,git branch -a查看名称,然后切换如git checkout  -b rockchip remotes/origin/rockchip,就可以切到rockchip分支看到xml文件了

repo init老是无法连接google服务器,可以拷贝一份其他项目.repo/repo的文件,然后加上--no-repo-verify参数,如:

repo init  -u --no-repo-verify  ssh://venus/home/git/android/kitkat/platform/manifest -b mediatek -m kk_mt8127_default.xml

最新可用方法:

万恶的墙下,我们可以用其他的url来下载代码。

屏蔽掉repo里面的

#REPO_URL = 'https://gerrit.googlesource.com/git-repo'

在你的下载连接后添加  --repo-url=git://codeaurora.org/tools/repo.git --repo-branch=caf-stable

意外发现:

添加/etc/hosts

203.208.46.200 android.googlesource.com



boot.img的生成:
build/core/Makefile中,主要是调用out/host/linux-x86/bin/mkbootimg工具生成的,如
    --kernel     out/target/product/tcc8800/kernel
    --ramdisk   out/target/product/tcc8800/ramdisk.img
    --cmdline   console=ttyTCC,115200n8
    --base 0x40000000  --pagesize 8192
可见boot.img是由kernel,ramdisk并且传入命令行参数组成的,mkbootimg工具的代码在system/core/mkbootimg/中



git提交的步骤:
git add 修改过的文件名
git commit -m "........"
git push
删除了一个文件如base/core/java/com/broadcom/bt/service/framework/PowerManagementService.java,重新更新则用
git checkout -- base/core/java/com/broadcom/bt/service/framework/PowerManagementService.java


察看文件夹内容大小的命令:
du -h --max-depth=1



制作system.img的方法,进入out/target/product/crane-jbs/目录下运行:
make_ext4fs -s -l 512M -a system system.img system 即可
解压make_ext4fs打的包:
simg2img system.img ZNKG5.img
mkdir ZNKG5
sudo mount -o loop ZNKG5.img ZNKG5
打包就按照上面的方法,或则运行mkuserimg.sh -s ZNKG5 ZNKG5-new.img ext4  512M

android的开机动画代码在frameworks/base/cmds/bootanimation/BootAnimation.cpp中,
看了里面的路径定义USER_BOOTANIMATION_FILE就知道BootAnimation.zip包应该放在那个位置了



Android.mk中LOCAL_CFLAGS的用法:
如在device/softwinner/crane-jbs7/BoardConfig.mk 中有:SW_BOARD_USR_WIFI := usibm01a
这样在hardware/libhardware_legacy/wifi/Android.mk中:
ifeq ($(SW_BOARD_USR_WIFI), usibm01a)
LOCAL_CFLAGS += -DUSI_BM01A_SDIO_WIFI_USED
endif
这样就相当于定义了USI_BM01A_SDIO_WIFI_USED这个宏,在wifi.c中就可以用了:
#elif defined USI_BM01A_SDIO_WIFI_USED
  93
  94     #ifndef WIFI_DRIVER_MODULE_PATH
  95     #define WIFI_DRIVER_MODULE_PATH         "/system/vendor/modules/usi4329_dhd.ko"
  96     #endif
  97     #ifndef WIFI_DRIVER_MODULE_NAME
  98     #define WIFI_DRIVER_MODULE_NAME         "dhd"
  99     #endif
 100     #ifndef WIFI_DRIVER_MODULE_ARG
 101     #define WIFI_DRIVER_MODULE_ARG         "firmware_path=/system/vendor/modules/usi4329_fw.bin nvram_path=/system/vendor/modules/usi4329_nvram.txt"
 102     #endif





gps移植过程:
在scripts/build_sun4i_crane.sh中有cp modules/gps/gps.ko_ $LICHEE_MOD_DIR/gps.ko
在framework中替换device/softwinner/common/hardware/libhardware/gps/haiweixun/gps.exDroid.so,
gps模拟器路径development/tools/emulator/system/gps/Android.mk,会生成gps.goldfish.so库

jbs-server:
repo init -u ssh://jbs-server/home/git/android/platform/manifests.git
初始化repo的新地址:
curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
chmod a+x ~/bin/repo
如果提示:
Initializing project platform/InfotmDocs ...
fatal: '/home/git/android/shark/platform/InfotmDocs.git' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
那么是因为curl的地址不对,、换一个即可
有时候这句运行提示远程错误,就要把~/bin/repo中的 REPO_URL='https://code.google.com/p/git-repo/'更改为 REPO_URL='http://code.google.com/p/git-repo/'
RK3066: repo init -u ssh://venus/home/git/android/sawfish/platform/manifests.git -m ics-rk3066.xml
设置java环境:
    121 export PATH=/opt/jdk1.6.0_27/bin:/opt/bin:/usr/local/arm/arm-2010q1/bin:/home/lsc/bin:$PATH
    122
    123 CLASSPATH="/opt/jdk1.6.0_27/lib"
    124
    125 JAVA_HOME="/opt/jdk1.6.0_27"
    126                                                                                                                   
    127 export CLASSPATH=.:$JAVA_HOME/lib:$CLASSPATH


repo sync
///////////////////
cd .repo/
 rm manifest.xml
ln -s manifests/ics-cwhl.xml manifest.xml
修改或者提交文件只能在各自的git目录下进行,
修改文件,察看当前分支, git branch,如果不是xxx
git checkout -b xxx
git commit -a -m "..........."
git push origin xxx:xxx
然后进入:
 cd .repo/manifests
 vi manifest.xml ,比如如果修改了/system/bluetooth,则增加 remote="origin" revision="xxx"
cd manifests;git commit -a -m ".............";git push

如果git commit之后,想回复该commit 之前,则:
git rebase origin/jb-infotm-x15
后来发现用这种才可以啊:
git reset --hard cd1baec9426648ce644cc247e4c70abed9238cd8 //想要恢复的版本ID

将工程全部切换到某个分支下:
repo start --all xxx

在一个分支 xxx提交后,git checkout aaa切换分支,也想提交到该分支上,则
git cherry-pick 0b995f883e485f973cb77636bd97a9fd258d13d3(log为xxx分支下提交的LOG)
git push orgin HEAD:aaa
///////////////////



ctags -R
drivers/misc/inv_mpu$



GPIO配置脚本的使用:
Port:端口+组内序号<功能分配><内部电阻状态><驱动能力><输出电平状态>
1.函数原型: int Script_parser_fetch(char *main_name, char *sub_name, int value[], int count);
                       主键名称,    子键名称    存放用户获取的数据   传进的数据空间的最大word个数
成功返回0,失败返回-1
这个函数可以获取配置里面的一个值或者一组GPIO或者一组字符窜的配置。
获取一个值:
如有配置
[fm_para]
fm_pattern = 0
则:
    {
        int  fm_pattern;
        int  ret;

        ret = script_parser_fetch(“fm_para”, “fm_pattern”, &fm_pattern, 1);
    if(ret >= 0)
        return fm_pattern;
    else
        return ret;
    }
获取一组GPIO配置:
如有配置
[twi_para]
twi_scl   = port:PH12<1><default><default><default>
则:
    {
        user_gpio_set_t  gpio_info[1];
        int  ret;

        ret = script_parser_fetch(“twi_para”, “twi_scl”, gpio_info, sizeof(user_gpio_set_t)/sizeof(int));
        if(ret < 0)
        printf(“fetch script gpio infomation fail\n”);
    else
        printf(“fetch script gpio infomation ok \n”);

    return ret;
    }
获取字符窜:
如有配置
[string_test]
string_demo = string:abcdefghijklmn
则:
    {
        char  string_info[128];
        int  ret;

        memset(string_info, 0, 128);
        ret = script_parser_fetch(“string_test”, “string_demo”, string_info, 128/sizeof(int));
        if(ret < 0)
        printf(“fetch script string infomation fail\n”);
    else
        printf(“fetch script string infomation ok \n”);

    return ret;
    }

2.更改某个GPIO的输出电平:
如有配置
[audio_para]
audio_earphone_ctrl   = port:PH12<1><default><default><default>
则:
int gpio_earphone_switch = gpio_request_ex("audio_para", "audio_earphone_ctrl"); //用这一句可以直接取得控制句柄
gpio_write_one_pin_value(gpio_earphone_switch, 0, "audio_earphone_ctrl");//设置输出低电平

3.读取某个GPIO的输入电平:
int gpio_earphone_switch = gpio_request_ex("audio_para", "audio_earphone_ctrl"); //取得控制句柄
Int Gpio_read_one_pin_value (__hdle devpin, const char *gpio_name);
返回值:  高电平返回1
          低电平返回0
      非输入状态返回-1

4.设置句柄下单个GPIO配置:


函数原型:__hdle  Gpio_request (user_gpio_set_t *gpio_list,      
unsigned group_count_max);
参数:gpio_list          数据地址,保存GPIO属性,来自于配置脚本或者是用户自定义
      group_count_max   用户保存GPIO数据的结构体的最大个数
      返回值:   成功返回非空指针
                 失败返回空指针



5.解析AXP209中GPIO的配置:
    [lcd0_para]
    lcd_bl_en     = port:power1<1><0><default><1>
    这是表示用到AXP中GPIO1作为输出,默认输出为高电平,它的解析写法如下:
    user_gpio_set_t  gpio_info;
     ret = OSAL_Script_FetchParser_Data("lcd0_para","lcd_bl_en", (int *)&gpio_info, sizeof(user_gpio_set_t)/sizeof(int));
    if(ret < 0)
    {
        DE_INF("%s.lcd_pwm not exist\n", primary_key);
    }
    然后设置输入输出,等,如:
    gpio_info.data = 1;设置输出高电平
    然后用下面语句即可设置为所要的输出状态:
    hdl = OSAL_GPIO_Request(gpio_info, 1);
    //if_release_to_default_status:
    //如果是0或者1,表示释放后的GPIO处于输入状态,输入状状态不会导致外部电平的错误。
    //如果是2,表示释放后的GPIO状态不变,即释放的时候不管理当前GPIO的硬件寄存器。
    OSAL_GPIO_Release(hdl, 2);//设置完成后,释放句柄
    而OSAL_GPIO_Request最终是调用
    axp_gpio_set_io(gpio_list->port_num, gpio_list->mul_sel);
    axp_gpio_set_value(gpio_list->port_num, gpio_list->data);
    等去操作AXP的。
    //最后调用:
    //OSAL_GPIO_DevWRITE_ONEPIN_DATA(gdisp.screen[sel].gpio_hdl[io_index], data, gpio_name);//写GPIO的输出是0还是1
    具体操作函数在vendor/softwinner/linux-3.0/drivers/video/sun5i/disp/OSAL中

camera所在的路径:
drivers/media/video/sun4i_csi/device

FM发射芯片radio-qn8027:
drivers/media/radio/radio-qn8027.c


马达驱动路径:
drivers/misc/sun4i-vibrator.c


cat /proc/kmsg


ctrl+shift+"+"三个键 可以放大终端字体

*#06#


repo sync
进入修改目录:
git commit -a -m "............."
git fetch origin
git rebase origin/xxx
git remote show origin
git push
git push origin HEAD:xxx(以后用这个保险一点)

git checkout -b  xxx;git push origin HEAD:xxx
GIT恢复到指定版本:
git reset --hard d756f627fe568f4d8bcf1852ba60557eeab477a5 (版本号)

git revert HEAD --no-edit                  撤销前一次 commit
git revert HEAD^ --no-edit              撤销前前一次 commit
git push

修改服务器端口号:
sudo vi /etc/ssh/sshd_config
修改port 22 为 port 端口号
sudo /etc/init.d/ssh restart
重启ssh
附 ssh连接方法
ssh IP -p 端口号

代码中新增加一个代码目录,并加入到git中的方法:
ssh xxx;
su git;密码是git
cd;
比如xxx项目,进入/home/git/android/shark/platform中,要在代码根目录中增加InfotmDocs文件夹,运行new_project.sh InfotmDocs.git
回到本地机器,在xxx目录运行git clone ssh://jbs@venus/home/git/android/shark/platform/InfotmDocs.git
然后将要增加的代码拷贝到InfotmDocs,git add .;git commit -m "......";git push origin HEAD:xxx;这样就可以啦

MU509 AT命令用法:
    1:请查看模块的版本。方法为 进入ADB
                                         1:stop ril-daemon
                                         2:cat /dev/ttyUSB2
                                         3:在另外shell 打开。
                                         4:执行   echo -e "ati\r\n" > /dev/ttyUSB2
                                         这时cat 后台将会打印命令返回信息. 若是11.813.01.04.00请升级为11.813.01.05.00,11.813.01.05.00开机会快点。
        升级文件见“android下MU509(版本11.813.01.05.00)一键升级工具及说明 ”









base/services/camera/libcameraservice/CameraService.cpp






vim保存上次访问的位置,在.vimrc中输入
au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endif

但还要修改文件 ~/.viminfo 的权限,否则要sudo vim 才能起作用,修改后的权限如下:

-rwx-wx--x 1 lsc lsc 5240  4月 19 15:49 .viminfo






adb shell时候提示权限不足,要用sudo adb shell(fastboot也一样)的问题,是由于/etc/udev/rules.d/51-android.rules的权限问题引起的,修改该文件如下的即可:SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d010", MODE="0666", OWNER="lsc",主要是OWNER,MODE两项




删除触控屏驱动sudo modprobe -r psmouse


adb shell logcat -b radio -v time

Ubuntu 12.04 开机自动设置亮度的方法:
打开软件中心,安装laptop-mode包;
打开文件:/etc/laptop-mode/laptop-mode.conf
将以下标志修改为1:
ENABLE_LAPTOP_MODE_ON_AC=1
保存文件;
打开文件:/etc/laptop-mode/conf.d/lcd-brightness.conf
修改如下行:  www.2cto.com  
CONTROL_BRIGHTNESS=1
 
BATT_BRIGHTNESS_COMMAND="echo 3"
LM_AC_BRIGHTNESS_COMMAND="echo 3"
NOLM_AC_BRIGHTNESS_COMMAND="echo 3"
#BRIGHTNESS_OUTPUT="/proc/acpi/video/VID/LCD/brightness"
BRIGHTNESS_OUTPUT="/sys/class/backlight/acpi_video0/brightness"
保存文件;
执行命令  sudo update-grub;
重启机器即可。


sudo 查找命令:
sudo apt-cache search mkimage



android APK签名方法:
./host/linux-x86/framework/signapk.jar
build/target/product/security
 java -jar signapk.jar platform.x509.pem platform.pk8






ubuntu更换短密码:
sudo passwd username







ubuntu12.04下安装eclipse打开有错误的解决方法:
cp /usr/lib/jni/libswt-* ~/.swt/lib/linux/x86_64

ctrl + ]提示找到1个或多个是,输入 :tselect




ubuntu下安装内核源代码
apt-cache search linux-source
apt-get install linux-source-3.0.0(这个要修改对应的内核版本)
具体看http://blog.csdn.net/haokaihaohe110/article/details/7426447


apk安装位置的设定:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   android:installLocation="auto" ></mainfest>
此行是配置让Android系统自行决定应用的安装位置。
adb shell中还有如下命令:
pm set-install-location: changes the default install location.
  NOTE: this is only intended for debugging; using this can cause
  applications to break and other undersireable behavior.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media




android中添加一个新device方法:
1.新建/device/softwinner/crane-lsc目录
2.新建vendorsetup.sh文件,我们运行lunch时候会出现的选项,内容如下
     add_lunch_combo crane_lsc-eng
     add_lunch_combo crane_lsc-userdebug
     add_lunch_combo crane_lsc-user
3.新建crane_lsc.mk、BoardConfig.mk文件,新建AndroidProducts.mk,这是必须要有的,否则出错,它就是调用crane_pla.mk,内容如下:
    PRODUCT_MAKEFILES := $(LOCAL_DIR)/crane_pla.mk
4.新建AndroidBoard.mk,这是必须要有的,否则出错,它就是调用编译kernel和uboot等,内容如下:
    LOCAL_PATH := $(call my-dir)                           
    include vendor/softwinner/build/kernel.mk

5.所以我们看看vendor/softwinner/build/kernel.mk,有40多行,看重点的两句就行了:
     32 $(BUILT_KERNEL_TARGET): FORCE
     33     cd $(TOP)/vendor/softwinner/buildroot/scripts && cp -rf top_build.sh  ../../build.sh
     34     cd $(TOP)/vendor/softwinner/ && ./build.sh -p sun4i_crane -k 3.0
进入vendor/softwinner/build.sh只有一句:
    buildroot/scripts/common.sh,所以进入common.sh看看,有200多行:
    这个文件的主要工作就是查找解压设置编译工具的位置,环境变量等,然后复制kernel的模块到out目录下
    还有编译uboot等
如重要的两句:
    225     cd ${KERN_DIR} && ./build.sh -p ${PLATFORM}
    对应就是编译内核 ./build.sh -p sun4i_crane
    还有编译u-boot: cd ${U_BOOT_DIR} && ./build.sh -p sun4i

6.而最后的打包命令pack是如何生成的呢?
在device/softwinner/common/vendorsetup.sh中有一函数:
     12 function pack()
     13 {
     14     T=$(gettop)
     15     export CRANE_IMAGE_OUT=$OUT
     16     export PACKAGE=$T/vendor/softwinner/tools/pack
     17     sh $T/device/softwinner/$(get_build_var TARGET_DEVICE)/package.sh $1
     18 }
这就是我们运行pack时候执行的函数,所以会进入自己的TARGET_DEVICE中执行package.sh脚本,内容如下:
    1 cd $PACKAGE                                                                                                                                  
    2 if [ "$1" = "-d" ]; then
    3     echo "--------debug version, have uart printf-------------"
    4     ./pack -c sun4i -p crane -b game -d card0
    5 else
    6     echo "--------release version, donnot have uart printf-------------"
    7     ./pack -c sun4i -p crane -b game -d uart0
    8 fi
    9 cd -
所以就进入vendor/softwinner/tools/pack执行pack脚本了,他有400多行:
    最终就是调用里面的121 do_pack_crane()函数,

如果是A20,则编译uboot和kernel为:cd ./vendor/softwinner/ && ./build.sh -p sun7i_android


vim 增加鼠标复制功能
set mouse=v








C++运行时候多态(动态联翩)的理解:
    比如定义了一个形状的基类:
    class Shape//形状********************************************
    {
    public:
        virtual void DrawSelf()//绘制自己
        {
           cout << "我是一个什么也绘不出的图形" << endl;
        }
    };
    多边形和圆分别继承它并覆盖父类的方法:
    class Polygo:public Shape//多边形****************************
    {
    public:
        void DrawSelf()   //绘制自己
        {
           cout << "连接各顶点" << endl;
        }
    };

    class Circ:public Shape//圆*********************************
    {
    public:
        void DrawSelf()   //绘制自己
        {
           cout << "以圆心和半径为依据画弧" << endl;
        }
    };
    并且有一个调用方法:
    void OutputShape( Shape arg)//专门负责调用形状的绘制自己的函数******************
    {
        arg.DrawSelf();
    }
    那么我们调用:
        Polygon shape1;
        Circ shape2;
        OutputShape(shape1);
        OutputShape(shape2);
    发现输出的是父类的方法,而不是各自的子类方法,但如果把调用方法改为如下,则可实现调用的是各自的子类方法:
    void OutputShape( Shape& arg)//专门负责调用形状的绘制自己的函数*****************
    {
        arg.DrawSelf();
    }
    原因是:C++编译器在编译的时候会悄悄地在含有虚函数的基类前面加一个指针vptr和创建一个VTable(表在别的位置),用这个指针来指向该表,这个表格会包含每一个
        虚函数的索引,子类会继承这张表,而且表的索引顺序和基类一样(当然,如果覆盖了虚函数的方法,那么对应的索引将是子类的新方法地址了),当用基类的指针调用对象的
        方法时,通过调用对象本身的vptr找到表,表中有很多方法,到底该使用那个呢?原来编译器在创建VTable时,已经为每个virtual函数安排好了座次,而且悄悄的将函数的名字
    用索引号来替换,用这个索引来找出相应的虚函,这时候,我们通过这个索引号就可以在VTable中得到一个函数地址,此外,如果是纯虚函数,由于它没有函数体,表中相应位置
    放的就不是该函数的地址,而是一个出错处理的函数入口地址
    对于上面的例子,C++会悄悄的做三个表,Shape一个,Polygon一个,Circ一个,分别记录DrawSelf函数的入口地址,然后根据传进来的的对象地址,查表找到
    对应的DrawSelf函数的入口地址,当然这些功能都是C++编译的时候自己额外增加来实现,但是这个查找过程,其实也就是这些额外代码的运行过程是在运行时候完成的,就调用
    函数OutputShape本身而言,它是不知道那个对象调用了它的,所以才被叫运行时的多态。如下例子说明:
    程序中通过基类指针或引用对虚函数的调用语句都会被编译器改写成如下的形式:(即:利用基类的指针指向派生类对象,调用派生类对象的函数--->实现多态性。)
        (*(p -> _vptr[slotNum]))(p, arg-list);
        其中:p是基类型指针,_vptr是p指向的对象的隐含指针,而slotNum就是你调用的虚函数在vtable中的编号,这个数组元素的索引号在编译时就确定了下来。



C++中静态成员和非静态成员的理解:
    1. 非静态数据成员被放在每一个对象体内作为对象专有的数据成员
    2. 静态数据成员被提取出来放在程序的静态数据区内为该类所有对象共享,一次仅存一份
    3. 静态和非静态成员函数最终都被提取出来放在程序的代码段中并为该类的所有对象共享,因此每一个成员函数也只存在一份代码实体
       因此,构成对象本身的只有数据,任何成员函数都不隶属于任何一个对象,非静态成员函数与对象的关系就是绑定,绑定的中介就是this指针
    4. 类的静态数据成员可以在class的定义中直接初始化,但这只是声明并给它提供一个初值而已,还必须在某一个源文件中把它定义一次(即分配内存)
    5. this指针是存在与类的成员函数中,指向被调用函数所在的类实例的地址,如下例子说明:
       某一类Point中有构造函数:Point(int a, int b) { x=a; y=b;}和成员函数:Void MovePoint( int a, int b){ x+=a; y+=b;}
       但C++编译器处理后成员函数的原型变成 void MovePoint( Point *this, int a, int b),默认加入了this指针
    


C++虚函数和纯虚函数用法:
    1. 虚函数和纯虚函数可以定义在同一个类,含有纯虚函数的类被称为抽象类,而只含有虚函数的类不能被称为抽象类
    2. 虚函数可以被直接使用,也可以被子类重载以后以多态的形式调用,而纯虚函数必须在子类中实现该函数才可以使用,因为纯虚函数在基类只有声明而没
    有定义
    3. 虚函数和纯虚函数都可以在子类中被重载,以多态的形式被调用
    4. 虚函数的定义形式:virtual {method body} ;纯虚函数的定义形式:virtual { } = 0; 在虚函数和纯虚函数的定义中不能有static标识符,原因很简
    单,被static修饰
       的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样
    5. 如果一个类中含有纯虚函数,那么任何试图对该类进行实例化的语句都将导致错误的产生,因为抽象基类是不能被直接调用的。必须被子类继承重载以
    后,根据要求
       调用其子类的方法
    6. 带纯虚函数的类叫虚基类,这种基类不能直接生成对象,而只有被继承,并重写其虚函数后,才能使用。这样的类也叫抽象类



析构函数不会被继承,构造函数也不能是虚函数,要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时
候,必然会由于试图调用构造函数、析构函数而导致编译错误


strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?
    答:为了实现链式表达式。 // 2分
    例如int length = strlen( strcpy( strDest, "hello world") );


深入分析Linux内核源码: http://oss.org.cn/kernel-book/





class ClassName
{
public:
   int Fun() const;
  .....
};
有了const,这样,在调用函数Fun时就不能修改类里面的数据


android防止反编译
让proguard.cfg起作用的做法很简单,就是在eclipse自动生成的default.properties文件中加上一句“proguard.config=proguard.cfg”就可以了








判断手机当前上网用的是sim卡还是wifi
private boolean checkWifi() {  
    boolean isWifiConnect = true;  
    ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] networkInfos = cm.getAllNetworkInfo();  

    for (int i = 0; i<networkInfos.length; i++) {  
        if (networkInfos[i].getState() == NetworkInfo.State.CONNECTED) {  
           if(networkInfos[i].getType() == cm.TYPE_MOBILE) {  
           isWifiConnect = false;  
           }  
           if(networkInfos[i].getType() == cm.TYPE_WIFI) {  
           isWifiConnect = true;  
           }  
        }  
    }

        return isWifiConnect;
}  


判断当前的手机屏幕是否开启了旋转屏幕这个选项
 systemGravity = Settings.System.getInt(this  
.getContentResolver(),  
Settings.System.ACCELEROMETER_ROTATION);//1 is open;0 is close;


launcher布局:
可以实现把自己的apk放到主屏幕上哦,不过是烧写玩后第一次开机的时候就解析xml文件了,所以以后的lanucher更改必须要烧写或者恢复出厂设置才生效的
http://blog.csdn.net/wdaming1986/article/details/6978814




android的notificaiton的声音sound也是申请的AudioManager机制来播放声音的。恢复出厂设置后,手机刚启动,接受短信没有声音,如果恢复出厂设置后,等一会
儿,过个2分钟再接受短信,就有铃声了。下面我把我分析代码的方法写下来,给自己和读者一些启发
framework/base/services/java/com/android/server/NotificationManagerService.java类中
在871行有这句代码:uri = notification.sound;在886行有这句代码:mSound.play(mContext, uri, looping, audioStreamType)
在467行有这段代码:
if (0 == Settings.Secure.getInt(mContext.getContentResolver(),  
                 Settings.Secure.DEVICE_PROVISIONED, 0)) {  
         mDisabledNotifications = StatusBarManager.DISABLE_NOTIFICATION_ALERTS;  
     }  
研究以上的注释,发现原来google故意这么设置的,至于google为什么要这么设置,我没有深究,暂时没有想明白,但是这个这个初始化的时候必须要tsetup
wizard (设置向导)运行一次,所以导致了值不对,所以这个notification就不响了。




Android.mk常用的一些语法:
include $(call first-makefiles-under,$(LOCAL_PATH))
include $(call all-makefiles-under,$(LOCAL_PATH))




如何降低GCC版本
查看/usr/bin/下所有的GCC版本,找到你想要的
sudo ln -sf /usr/bin/gcc-4.4 /usr/bin/gcc




如何解决面板显示不了网络状态的问题
sudo apt-get install nm-applet
sudo apt-get install network-manager-gnome
nm-applet
sudo vim /etc/NetworkManager/NetworkManager.conf
更改为如下,然后重启即可:
  8 [ifupdown]
  9 managed=true
声音图标则在面板 -> 指示器小程序

gnome 无法使用alt+tab切换窗口解决方法:
安装cpmpiz配置管理程序:sudo apt-get install compizconfig-settings-manager
gnome右键终端:
sudo apt-get install nautilus-open-terminal    



imapx15制作ramdisk:
out/host/linux-x86/bin/mkimage -A arm -O linux -T ramdisk -C none -a 0x41000000 -n "hRamdisk" -d  ramdisk.img.ori ramdisk.img





开机自动挂载分区命令:
查看UUID:
sudo blkid

vim /etc/fstab,增加如下:
/dev/disk/by-uuid/6b90dc40-85bf-40d1-b80c-68d9adce3d38 /home/lsc/disk auto nosuid,nodev,nofail 0 0








virtualbox打开提示错误的办法:
http://sfchipan.me/ubuntu-12-1-use-virtualbox-to-install-win7/
今天来上班 我的虚拟机 就提示这样的错误。 我检测了下系统日志,原来是系统升级了。没更新 kernel-headers 的问题。

打开终端: 执行下面的步骤

sudo apt-get update
然后
sudo apt-get upgrade
这将确保你有最新的所有文件。
然后做
sudo apt-get install linux-headers-$(uname -r)
然后做
VBoxManage startvm ubuntu
如果你自己执行了 sudo /etc/init.d/vboxdrv setup
请执行下 sudo /etc/init.d/vboxdrv setup 然后在执行VBoxManage命令!




编译kernel时候提示找不到gcc编译工具,有可能是SVN版本的问题,卸载即可:
sudo apt-get install subversion,原因是由于用git管理代码但又下载了svnversion引起的,



platform_driver_probe与platform_driver_register的区别:
唯一的区别是platform_driver_probe;不能被以后其他的device probe了,也就是说这个driver只能和一个device绑定
所有的设备通过bus_id挂在总线上,多个device可以共用一个driver,但是一个device不可以对应多个driver,因为driver会申请device中的资源,如果之前有别的driver已经申请了这些资源,后来的driver当然也就不会注册成功了





创建一个loop device的步骤:
1. dd if=/dev/zero of=FS_on_file bs=1k count=10000 //注意这里不能是/dev/null哦,否则创建不成功
2. 使用losetup命令创建一个loop device:losetup /dev/loop0 FS_on_file
3. 创建一个文件系统:mkfs -t ext3 /dev/loop0
4. 挂载这个文件系统: mount /dev/loop0 /mnt/FS_file0
最后:如果要删除刚才创建的这些对象,依次执行如下步骤:
$ umount /dev/loop0
$ losetup -d /dev/loop0
$ rm FS_on_file



eclipse运行出错的Can't load library: /home/lsc/.swt/lib/linux/x86_64/libswt-gtk-3740.so
Can't load library: /home/lsc/.swt/lib/linux/x86_64/libswt-gtk.so     解决方法:
cp /usr/lib/jni/libswt-* ~/.swt/lib/linux/x86_64








git diff 没有颜色的解决方法:
$ git config --global color.status auto    
$ git config --global color.diff auto    
$ git config --global color.branch auto    
$ git config --global color.interactive auto  


如何编译模块的时候提示类似如下信息:
ERROR: "imapx_pad_get_indat" [drivers/input/touchscreen/gslX680.ko] undefined!
ERROR: "imapx_pad_irq_clear" [drivers/input/touchscreen/gslX680.ko] undefined!
ERROR: "imapx_pad_irq_pending" [drivers/input/touchscreen/gslX680.ko] undefined!
ERROR: "imapx_pad_irq_number" [drivers/input/touchscreen/gslX680.ko] undefined!
则是因为这些函数没有EXPORT_SYMBOL的原因,export出来即可


无法安装sun-java6-jdk的解决方法:
sudo gedit /etc/apt/sources.list添加这个源:
deb http://us.archive.ubuntu.com/ubuntu/ hardy multiverse
sudo apt-get update
sudo apt-get install sun-java6-jdk
然后更改JAVA配置:
sudo update-alternatives --config javac
sudo update-alternatives --config java



修改android默认语言在device的mk文件中 persist.sys.language=zh \ persist.sys.country=CN \
参考build/target/product/languages_full.mk中的缩写即可。
各国语言缩写-各国语言简称
en 英文
en_US 英文 (美国)
ar 阿拉伯文
ar_AE 阿拉伯文 (阿拉伯联合酋长国)
ar_BH 阿拉伯文 (巴林)
ar_DZ 阿拉伯文 (阿尔及利亚)
ar_EG 阿拉伯文 (埃及)
ar_IQ 阿拉伯文 (伊拉克)
ar_JO 阿拉伯文 (约旦)
ar_KW 阿拉伯文 (科威特)
ar_LB 阿拉伯文 (黎巴嫩)
ar_LY 阿拉伯文 (利比亚)
ar_MA 阿拉伯文 (摩洛哥)
ar_OM 阿拉伯文 (阿曼)
ar_QA 阿拉伯文 (卡塔尔)
ar_SA 阿拉伯文 (沙特阿拉伯)
ar_SD 阿拉伯文 (苏丹)
ar_SY 阿拉伯文 (叙利亚)
ar_TN 阿拉伯文 (突尼斯)
ar_YE 阿拉伯文 (也门)
be 白俄罗斯文
be_BY 白俄罗斯文 (白俄罗斯)
bg 保加利亚文
bg_BG 保加利亚文 (保加利亚)
ca 加泰罗尼亚文
ca_ES 加泰罗尼亚文 (西班牙)
ca_ES_EURO 加泰罗尼亚文 (西班牙,Euro)
cs 捷克文
cs_CZ 捷克文 (捷克共和国)
da 丹麦文
da_DK 丹麦文 (丹麦)
de 德文
de_AT 德文 (奥地利)
de_AT_EURO 德文 (奥地利,Euro)
de_CH 德文 (瑞士)
de_DE 德文 (德国)
de_DE_EURO 德文 (德国,Euro)
de_LU 德文 (卢森堡)
de_LU_EURO 德文 (卢森堡,Euro)
el 希腊文
el_GR 希腊文 (希腊)
en_AU 英文 (澳大利亚)
en_CA 英文 (加拿大)
en_GB 英文 (英国)
en_IE 英文 (爱尔兰)
en_IE_EURO 英文 (爱尔兰,Euro)
en_NZ 英文 (新西兰)
en_ZA 英文 (南非)
es 西班牙文
es_BO 西班牙文 (玻利维亚)
es_AR 西班牙文 (阿根廷)
es_CL 西班牙文 (智利)
es_CO 西班牙文 (哥伦比亚)
es_CR 西班牙文 (哥斯达黎加)
es_DO 西班牙文 (多米尼加共和国)
es_EC 西班牙文 (厄瓜多尔)
es_ES 西班牙文 (西班牙)
es_ES_EURO 西班牙文 (西班牙,Euro)
es_GT 西班牙文 (危地马拉)
es_HN 西班牙文 (洪都拉斯)
es_MX 西班牙文 (墨西哥)
es_NI 西班牙文 (尼加拉瓜)
et 爱沙尼亚文
es_PA 西班牙文 (巴拿马)
es_PE 西班牙文 (秘鲁)
es_PR 西班牙文 (波多黎哥)
es_PY 西班牙文 (巴拉圭)
es_SV 西班牙文 (萨尔瓦多)
es_UY 西班牙文 (乌拉圭)
es_VE 西班牙文 (委内瑞拉)
et_EE 爱沙尼亚文 (爱沙尼亚)
fi 芬兰文
fi_FI 芬兰文 (芬兰)
fi_FI_EURO 芬兰文 (芬兰,Euro)
fr 法文
fr_BE 法文 (比利时)
fr_BE_EURO 法文 (比利时,Euro)
fr_CA 法文 (加拿大)
fr_CH 法文 (瑞士)
fr_FR 法文 (法国)
fr_FR_EURO 法文 (法国,Euro)
fr_LU 法文 (卢森堡)
fr_LU_EURO 法文 (卢森堡,Euro)
hr 克罗地亚文
hr_HR 克罗地亚文 (克罗地亚)
hu 匈牙利文
hu_HU 匈牙利文 (匈牙利)
is 冰岛文
is_IS 冰岛文 (冰岛)
it 意大利文
it_CH 意大利文 (瑞士)
it_IT 意大利文 (意大利)
it_IT_EURO 意大利文 (意大利,Euro)
iw 希伯来文
iw_IL 希伯来文 (以色列)
ja 日文
ja_JP 日文 (日本)
ko 朝鲜文
ko_KR 朝鲜文 (南朝鲜)
lt 立陶宛文
lt_LT 立陶宛文 (立陶宛)
lv 拉托维亚文(列托)
lv_LV 拉托维亚文(列托) (拉脱维亚)
mk 马其顿文
mk_MK 马其顿文 (马其顿王国)
nl 荷兰文
nl_BE 荷兰文 (比利时)
nl_BE_EURO 荷兰文 (比利时,Euro)
nl_NL 荷兰文 (荷兰)
nl_NL_EURO 荷兰文 (荷兰,Euro)
no 挪威文
no_NO 挪威文 (挪威)
no_NO_NY 挪威文 (挪威,Nynorsk)
pl 波兰文
pl_PL 波兰文 (波兰)
pt 葡萄牙文
pt_BR 葡萄牙文 (巴西)
pt_PT 葡萄牙文 (葡萄牙)
pt_PT_EURO 葡萄牙文 (葡萄牙,Euro)
ro 罗马尼亚文
ro_RO 罗马尼亚文 (罗马尼亚)
ru 俄文
ru_RU 俄文 (俄罗斯)
sh 塞波尼斯-克罗地亚文
sh_YU 塞波尼斯-克罗地亚文 (南斯拉夫)
sk 斯洛伐克文
sk_SK 斯洛伐克文 (斯洛伐克)
sl 斯洛文尼亚文
sl_SI 斯洛文尼亚文 (斯洛文尼亚)
sq 阿尔巴尼亚文
sq_AL 阿尔巴尼亚文 (阿尔巴尼亚)
sr 塞尔维亚文
sr_YU 塞尔维亚文 (南斯拉夫)
sv 瑞典文
sv_SE 瑞典文 (瑞典)
th 泰文
th_TH 泰文 (泰国)
tr 土耳其文
tr_TR 土耳其文 (土耳其)
uk 乌克兰文
uk_UA 乌克兰文 (乌克兰)
zh 中文
zh_CN 中文 (中国)
zh_HK 中文 (香港)
zh_TW 中文 (台湾)

 

补充:

fa 波斯文

fa_IR 波斯文(伊朗)

fa_AF 波斯文(阿富汗)

he 希伯来文

he_IL 希伯来文 (以色列)





android各个文件夹的权限配置:
system/core/include/private/android_filesystem_config.h



Activity 以 Dialog 形式存在:
只要在AndroidManifest.xml中设置该Activity属性为:
android:theme="@android:style/Theme.Dialog"  
?android:theme="@android:style/Theme.Dialog"   将一个Activity显示为对话框模式
?android:theme="@android:style/Theme.NoTitleBar"  不显示应用程序标题栏
?android:theme="@android:style/Theme.NoTitleBar.Fullscreen"  不显示应用程序标题栏,并全屏
?android:theme="Theme.Light"  背景为白色
?android:theme="Theme.Light.NoTitleBar"  白色背景并无标题栏
?android:theme="Theme.Light.NoTitleBar.Fullscreen"  白色背景,无标题栏,全屏
?android:theme="Theme.Black"  背景黑色
?android:theme="Theme.Black.NoTitleBar"  黑色背景并无标题栏
?android:theme="Theme.Black.NoTitleBar.Fullscreen"    黑色背景,无标题栏,全屏
?android:theme="Theme.Wallpaper"  用系统桌面为应用程序背景
?android:theme="Theme.Wallpaper.NoTitleBar"  用系统桌面为应用程序背景,且无标题栏
?android:theme="Theme.Wallpaper.NoTitleBar.Fullscreen"  用系统桌面为应用程序背景,无标题栏,全屏
?android:theme="Translucent"
?android:theme="Theme.Translucent.NoTitleBar"
?android:theme="Theme.Translucent.NoTitleBar.Fullscreen"
?android:theme="Theme.Panel"
?android:theme="Theme.Light.Panel"


串口中remount system:
mount -o remount rw /system


android定制默认输入法,比如拼音输入法:
在frameworks/base/packages/SettingsProvider/res/values/defaults.xml增加一个配置:
<string name="config_default_input_method" translatable="false">com.android.inputmethod.pinyin/.PinyinIME</string>
方法一:
在frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java中增加:
loadStringSetting(stmt, Settings.Secure.ENABLED_INPUT_METHODS, R.string.config_default_input_method);
方法二:
在frameworks/base/services/java/com/android/server/InputMethodManagerService.java的buildInputMethodListLocked()方法中增加:
    String defaultIme = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
    if ( defaultIme == null )
    {
        final Resources res = mContext.getResources();
        try
        {
        String myIME = res.getString( com.android.internal.R.string.config_default_input_method );
        if ( myIME != null && myIME.length() > 0 )
        {
            Settings.Secure.putString( mContext.getContentResolver(),
                    Settings.Secure.DEFAULT_INPUT_METHOD,
                    myIME );
        }
        }
        catch ( Exception e )
        {
        }
    }






CWHL关于关机播放音乐的问题,ND6如有需要复制该代码即可:
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java中对powerkey进行处理:
case KeyEvent.KEYCODE_POWER: -> interceptPowerKeyDown(在PhoneWindowManager.java中):
     713     private void interceptPowerKeyDown(boolean handled) {                     
     714         mPowerKeyHandled = handled;
     715         if (!handled) {
     716             mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
     717         }
     718     }

frameworks/base/core/java/com/android/internal/app/ShutdownThread.java中有
180         MediaPlayer mediaplayer =new MediaPlayer();
181         try
182         {
183             mediaplayer.setDataSource("/system/media/shutdown.mp3");
184             mediaplayer.prepare();
185             mediaplayer.start();
186         }catch (IOException e)
187         {
188
189         }




java延时函数:
try {
        Thread.sleep(5000);//括号里面的5000代表5000毫秒,也就是5秒,可以该成你需要的时间
} catch (InterruptedException e) {
        e.printStackTrace();
}



android时区设置可以查看external/icu4c/data/misc/timezoneTypes.txt的时区表







android新增API然后打包android.jar的方法:
1、在frameworks/base/下新建目录如av
2、在frameworks/base/Android.mk的packages_to_document后面增加如android/av
3、在build/core/pathmap.mk的FRAMEWORKS_BASE_SUBDIRS增加tv
4、执行make clean;make update-api;make -j4 -l8;make sdk即可生成android.jar

禁止视频音频播放的方法:
在MediaPlayerService.cpp中static sp<MediaPlayerBase> createPlayer()函数中把相应的类型去掉即可,注意要保留CEDARX_PLAYER:类型,否则无法打开摄像机








imapx15制作ramdisk:
out/host/linux-x86/bin/mkbootfs out/target/product/nd6/root | out/host/linux-x86/bin/minigzip > out/target/product/nd6/ramdisk.img
mv out/target/product/nd6/ramdisk.img ramdisk.img.ori
out/host/linux-x86/bin/mkimage -A arm -O linux -T ramdisk -C none -a 0x41000000 -n "hRamdisk" -d  ramdisk.img.ori ramdisk.img
infotmic压缩system.img的方法:
./build/tools/mktarball.sh out/host/linux-x86/bin/fs_get_stats out/target/product/m75y2l system out/target/product/m75y2l/system.tar out/target/product/m75y2l/system.img
(system.img是先修改里面各个文件的权限,然后tar cvf system.tar system,然后gzip -c system.tar > system.img得到的)
解压的方法:
tar xvf system.img





virtualbox安装的过程:
WARNING: The character device /dev/vboxdrv does not exist.
     Please install the virtualbox-ose-dkms package and the appropriate
     headers, most likely linux-headers-generic
运行:
sudo dpkg-reconfigure virtualbox-dkms
接着提示:
 * No suitable module for running kernel found
                                                                                                                                                        [fail]
invoke-rc.d: initscript virtualbox, action "restart" failed.
运行:
 sudo apt-get install 3.5.0-17-generic

再运行上一条命令就可以啦

还有记得加上usb权限,

sudo gpasswd -a xxx vboxusers //xxx为自己的用户名字
如果共享文件不成功,再安装一次增强包然后重启就可以了


android截屏的方法:
执行文件在system/bin/中,有screencap   screenshot,它们的源代码在 frameworks/base/cmds目录下面,用法:
screencap -p /sdcard1/screenshot.png
screenshot -s /system/media/audio/Cesium.ogg -i /sdcard1/screenshot.png



apktool的使用:
从http://code.google.com/p/android-apktool/下载apktool1.5.2.tar.bz2和apktool-install-linux-r05-ibot.tar.bz2,然后解压放到usr/local/bin/目录下,
运行apktool的时候记得加上sudo,否则打包时候报错:
Exception in thread "main" brut.androlib.AndrolibException: brut.common.BrutException: could not exec command: [aapt, p, --min-sdk-version, 3, --target-sdk-version, 15, -F, /home/lsc/disk/jbs-cwhl/device/softwinner/crane-jbs7/preinstall/co.apk, -0, arsc, /home/lsc/disk/jbs-cwhl/device/softwinner/crane-jbs7/preinstall/compa/build/apk]
Caused by: brut.common.BrutException: could not exec command: [aapt, p, --min-sdk-version, 3, --target-sdk-version, 15, -F, /home/lsc/disk/jbs-cwhl/device/softwinner/crane-jbs7/preinstall/co.apk, -0, arsc, /home/lsc/disk/jbs-cwhl/device/softwinner/crane-jbs7/preinstall/compa/build/apk]
    ... 5 more
Caused by: java.io.IOException: Cannot run program "aapt": java.io.IOException: error=13, Permission denied
    ... 6 more
Caused by: java.io.IOException: java.io.IOException: error=13, Permission denied
    ... 9 more
用法
解包:sudo apktool d xxx.apk
打包:sudo apktool b xxx xxx.apk



vim里面有一个特性,如果你在一行注释后新加一行,vim会自动在下一行的开始位置添加注释符号,但是,我经常从其它地方复制一些代码,如果代码中有一行注释,
就会导致后面的所有代码全部自动被注释掉,相当不方便,去掉自动注释的办法,在.vimrc中增加如下内容即可
autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o 


wifi密码保存的路径为/data/misc/wifi/wpa_supplicant.conf,如我的机子上adb shell;cat /data/misc/wifi/wpa_supplicant.conf得到的信息:
network={
    ssid="Test"
    psk="0013076247"
    key_mgmt=WPA-PSK
    priority=2
}
psk就是密码啦


infotmic LCD:
linux-3.0.8/drivers/InfotmMedia/lcd_api/source中为所有lcd的配置文件,其中结构体类型LCD_Priv_conf配置了上电的时序,时序的解析文件在同目录下的lcd_api.c中
而CLK的频率计算方法则如下:
    h_total = cfg->width + cfg->HSPW + cfg->HBPD + cfg->HFPD;
    v_total = cfg->height + cfg->VSPW + cfg->VBPD + cfg->VFPD;
    pixTotal = h_total * v_total;
    clkfreq = pixTotal / 1000 * cfg->fpsx1000;
我们配置中填写的是fpsx1000,想要得到合适的频率,可以根据这个公式计算合适的fpsx1000  



android启动过程在init中启动不了主要的进程,就会reboot并进入recovery模式,代码位置:
system/core/init/signal_handler.c
 93     if (svc->flags & SVC_CRITICAL) {
 94         if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {
 95             if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {
 96                 ERROR("critical process '%s' exited %d times in %d minutes; "
 97                       "rebooting into recovery mode\n", svc->name,
 98                       CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60);
 99                 android_reboot(ANDROID_RB_RESTART2, 0, "recovery");                                                                                        
100                 return 0;
101             }

 




今天用A20的代码编译kernel,自己增加了几个驱动的C文件,和打开了SPI配置的功能,晕死,编译时候老是出错,要不是提示找不到SPI函数,要不是提示要手动选择YES/NO

来配置选项,明明把arch/arm/configs/sun7ismp_android_defconfig复制到.config,make menuconfig后发现根本不是sun7ismp_android_defconfig;把配置直接写到arch/arm/configs/sun7ismp_android_defconfig中也不行,make之后发现新加的配置不生效,以前A10是没有这些问题的,了搞了半天发现真的有点不同于A10,正确的配置如下:

make ARCH=arm sun7ismp_android_defconfig //要加上ARCH,否则用X86下面的配置

make ARCH=arm sun7ismp_android_defconfig menuconfig //不能直接make menuconfig,否则前面一步生成的.config还是不起作用

这样进入图形界面选择SPI功能,和自己新增的配置,保存退出,然后把.config 复制到sun7ismp_android_defconfig就可以了

如果自己网上下载的内核,要编译一个平台如s3c6400_defconfig,正确做法是:

make ARCH=arm s3c6400_defconfig;

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- zImage modules; //记得加modules啊,否则不编译ko的




adb中启动一个acitvity的命令:

am start -n com.example.tabhost/com.example.tabhost.MainActivy



android.intent.action.MAIN             决定点击apk时候启动那个activity

android.intent.category.LAUNCHER  决定时候把图标显示在桌面上

android.intent.category.HOME           决定开机启动那个应用程序,即设置为launcher



power上报机制:

drivers/power/power_supply_core.c power_supply_register函数中

    dev->class = power_supply_class;
    dev->type = &power_supply_dev_type;                                                                                                                        
    dev->parent = parent;
    dev->release = power_supply_dev_release;
    dev_set_drvdata(dev, psy);
    psy->dev = dev;

主要是为 dev->type和psy->dev赋值,并且power_supply_class_init函数中:

power_supply_class->dev_uevent = power_supply_uevent;

使得后续kobject_uevent上报时候,power_supply_uevent的内容,位于 drivers/power/power_supply_sysfs.c中;

在上层cat时候显示的则为power_supply_sysfs.c中

#define POWER_SUPPLY_ATTR(_name)                    \
{                                   \
    .attr = { .name = #_name },                 \
    .show = power_supply_show_property,             \
    .store = power_supply_store_property,               \
}

所定义的内容。


一直不知道android是如何判断一个输入设备是何种类型的吗?比如注册了一个键盘驱动,生成一个节点input5, android如何就知道这个input5是一个键盘设备呢,这是在驱动中set_bit(EV_KEY, input->evbit)来设置的,EV_KEY就是键盘类型啊。

而android又是如何为这个设备查找对应的kl键盘布局的呢,也是在驱动中,比如input->name = "uartkeyboard-input", 那么android就查找看有没有uartkeyboard-input.kl文件,如果没有就用默认的

如果要上层在插入物理键盘时候隐藏软件盘,那么底层驱动的键值表必须包括KEY_Q这个键值,这是为什么呢?看frameworks/base/services/input/EventHub.cpp的一段代码就知道了:

        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
        if (hasKeycodeLocked(device, AKEYCODE_Q)) {
            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
        }    
简单判断是否包含Q键值,有的话才会认为是INPUT_DEVICE_CLASS_ALPHAKEY类型,这样才能自动隐藏软件盘




android中指定读取硬件时钟芯片的实时时间用命令: busybox hwclock

设置系统时间:busybox date -s "2007-08-03 14:15:00"

将系统时间写入时钟芯片:busybox hwclock -w

查看系统时间:busybox  date

原因:

hwclock工具调用的是linux标准的接口/dev/rtc0设备节点,文件在drivers/rtc/rtc-dev.c

android自己实现了一个rtc驱动,读取的是/dev/alarm, 位置在drivers/staging/android/alarm-dev.c, JNI层在frameworks/base/core/jni/android_os_SystemClock.cpp
而且android必须要实现alarm功能才能设置时间,即时间struct rtc_class_ops结构体的.read_alarm, .set_alarm方法,并且device_may_wakeup为true, 否则只能用/dev/rtc0节点才能读取,设置硬件芯片时间

kenel中rtc不能编译成ko加载,否则每次启动时间不对



A20 spi驱动 spi-sun7i.c:

/* spi device on or off control */
static void sun7i_spi_cs_control(struct spi_device *spi, bool on)
{
    struct sun7i_spi *aw_spi = spi_master_get_devdata(spi->master);
    unsigned int cs = 0; 
    if (aw_spi->cs_control) {
        if (on) {
            /* set active */
            cs = (spi->mode & SPI_CS_HIGH) ? 1 : 0;  //on为1表示使能cs引脚,SPI_CS_HIGH为1,表示高电平使能,所以如果高点平使能,则cs为1                                                                                                
        } else {
            /* set inactive */
            cs = (spi->mode & SPI_CS_HIGH) ? 0 : 1; 
        }    
        spi_ss_level(aw_spi->base_addr, cs); 
    }    
}


master->mode_bits       = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; //这是4个spi适配器通用的配置,如果某个spi设备比较特殊,则在这里根据判断名字不同,更改成自己想要的配置


在sun7i_spi_work函数中:

        struct spi_message *msg = NULL;
        struct spi_device  *spi = NULL;
        struct spi_transfer *t  = NULL;
        unsigned int cs_change = 0;
。。。。。。 
           /* first active the cs */
            if (cs_change)
                aw_spi->cs_control(spi, 1);
            /* update the new cs value */
            cs_change = t->cs_change;

            /* full duplex mode */
            if (t->rx_buf && t->tx_buf)
                spi_clear_dhb(aw_spi->base_addr);

            /*
             * do transfer
             * > 64 : dma ;  <= 64 : cpu
             * wait for done completion in this function, wakup in the irq hanlder
             */
            status = sun7i_spi_xfer(spi, t);
            if (status)
                break; /* fail quit, zero means succeed */

            /* accmulate the value in the message */
            msg->actual_length += t->len;
            /* may be need to delay */
            if (t->delay_usecs)
                udelay(t->delay_usecs);

            /* if zero, keep active, otherwise deactived. */
            if (cs_change)
                aw_spi->cs_control(spi, 0);
        }


其中spi_transfer结构体定义:

struct spi_transfer {                                                                                                                                          
    /* it's ok if tx_buf == rx_buf (right?)
     * for MicroWire, one buffer must be null
     * buffers must work with dma_*map_single() calls, unless
     *   spi_message.is_dma_mapped reports a pre-existing mapping
     */
    const void  *tx_buf;
    void        *rx_buf;
    unsigned    len;

    dma_addr_t  tx_dma;
    dma_addr_t  rx_dma;

    unsigned    cs_change:1;
    u8      bits_per_word;
    u16     delay_usecs;
    u32     speed_hz;

    struct list_head transfer_list;
};

它是具体的驱动创建的,比如 fm24cl64b_read函数的 struct spi_transfer st[2],其中cs_change位默认为1,意思是假设cs线低电平有效的话,如果传输完成数据后如果要让cs线拉高,则该位为1,如果要cs线拉低,则该位为0;我们默认情况下传输完成后是要拉高的,所以按照默认即可。




android 的launcher只有一个桌面时候,默认壁纸是不居中的,而是靠最左边,修改居中的办法:

diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f6416c8..e432c45 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1143,8 +1143,14 @@ public class Workspace extends SmoothPagedView
                 mWaitingForUpdate = false;
                 if (computeScrollOffset() && mWindowToken != null) {
                     try {
-                        mWallpaperManager.setWallpaperOffsets(mWindowToken,
-                                mWallpaperOffset.getCurrX(), 0.5f);
+
+                        Log.e(TAG, "sclu mWallpaperOffset.getCurrX() =  " + mWallpaperOffset.getCurrX() + "child = " + getChildCount());
+                         if (((mWallpaperOffset.getCurrX() == 0) && (getChildCount() == 0)) || ((mWallpaperOffset.getCurrX() == 0) && (getChildCount() == 1)))
+                            mWallpaperManager.setWallpaperOffsets(mWindowToken,
+                                    0.5f, 0.5f);
+                        else
+                            mWallpaperManager.setWallpaperOffsets(mWindowToken,
+                                    mWallpaperOffset.getCurrX(), 0.5f);
                         setWallpaperOffsetSteps();
                     } catch (IllegalArgumentException e) {
                         Log.e(TAG, "Error updating wallpaper offset: " + e);


RK3168 android 4.4.2 代码,设置中不选24小时格式,但是状态栏和锁屏界面日期栏没有出现PM或者AM格式,修正如下:

--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -59,7 +59,7 @@ public class Clock extends TextView {
     private static final int AM_PM_STYLE_SMALL   = 1;
     private static final int AM_PM_STYLE_GONE    = 2;
 
-    private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
+    private static final int AM_PM_STYLE = AM_PM_STYLE_NORMAL;
 
     public Clock(Context context) {
         this(context, null);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java b/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java
index 6c701c7..ac8489e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java
@@ -95,7 +95,7 @@ public class ClockView extends RelativeLayout {
 
         AmPm(View parent, Typeface tf) {
             // No longer used, uncomment if we decide to use AM/PM indicator again
-            // mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
+             //mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
             if (mAmPmTextView != null && tf != null) {
                 mAmPmTextView.setTypeface(tf);
             }
@@ -213,6 +213,18 @@ public class ClockView extends RelativeLayout {
         mCalendar.setTimeInMillis(System.currentTimeMillis());
 
         CharSequence newTime = DateFormat.format(mFormat, mCalendar);
+        Context context = getContext();
+        String ampmValues;
+        if(DateFormat.is24HourFormat(context)){
+            ampmValues = "";
+        }else{
+            if(mCalendar.get(Calendar.AM_PM) == 0){
+                ampmValues = " AM";
+            }else{
+                ampmValues = " PM";
+            }
+        }
+        newTime = newTime + ampmValues;
         mTimeView.setText(newTime);
         mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
     }


Your version is: java version "1.6.0_27".
The correct version is: Java SE 1.6.

解决方法:

</pre><pre name="code" class="cpp">



android 资源文件string.xml中的product属性有default, nosdcard和tablet,比如:

<string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"正在卸载 USB 存储设备..."</string>
<string name="progress_unmounting" product="default" msgid="1327894998409537190">"正在卸载 SD 卡..."</string>
在device.mk中有PRODUCT_CHARACTERISTICS := tablet可以设置,如果没有制定,就用default指定的


android自带浏览器搜索功能无法使用,比如在音乐中长按一首歌,会弹出选择浏览器搜索歌名的界面,但是点击无响应,是因为没有安装google自带的Velvet.apk。


android init.rc的service有一个属性 class main, 表示将该服务归入为main类,就是多个服务可以归为一类,有点像分组;这样后续如果要启动该类服务可以用 class_start main

即可



低级错误导致android ProgressDialog不能更新:

错误方法:

    在线程中handler message通知handler处理后,用m_pDialog.setMessage("升级完成");来更新标题,接着Thread.sleep延时2秒再关闭。导致dialog无法更新

正确方法:

 handler中不能延时,应该在thread中,发送更新message,延时2秒,再发一个message通知关闭;handler中用switch (msg,what) 来区分两次的消息



ubuntu重装virtualbox后,提示:

The character device /dev/vboxdrv does not exist.
     Please install the virtualbox-ose-dkms package and the appropriate
     headers, most likely linux-headers-generic.

     You will not be able to start VMs until this problem is fixed.
网上搜索,方法很多,各有各的说法,解决的办法都不一样,很多都尝试过,都失败了。最后终于找到了合适我的:

gcc g++版本和先前不一样,第一次安装virtualbox时候用的是 4.7版本,后来由于编译android系统,降级为4.4;才出现了上述问题,将gcc g++版本升级回4.7再重装virtualbox即可。


官网下载libiconv-1.14

libiconv-1.14/jni/libcharset/lib/localcharset.c:51:24: error: langinfo.h: No such file or directory

按照网上的解决方法:

修改目录文件libcharset/config.h的宏定义,禁止该宏定义:

/* Define if you haveand nl_langinfo(CODESET). */

#define HAVE_LANGINFO_CODESET 0

发现不行,直接在.c代码开头#undef  HAVE_LANGINFO_CODESET即可

还有,代码用编译出来的iconv.a库老是编译不过,后来直接把代码放到iconv源代码中编译生成执行文件即可,省得麻烦。


理一下A23平台的axp代码架构,免得每次都要看半天才清楚:

代码在drivers/power/axp_power中,用的是axp223

axp22-board.c负责用platform注册芯片所有的电源,包括DC/DC和LDO

struct regulator_init_data中有一个.enabled成员,如:

    [vcc_ldo2] = {
        .constraints = {
            .name = "axp22_aldo1",
            .min_uV = 700000,
            .max_uV = 3300000,
            .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
            .initial_state = PM_SUSPEND_STANDBY,
            .state_standby = {
                //.uV = ldo2_vol * 1000,
                .enabled = 0,
            }
        },
为0表示休眠时候不供电, 它还有一个disabled成员,为1表示休眠时候关掉电源,enabled和disabled的值总是相反,否则不起作用,判断代码在drivers/regulator/core.c中:

    if (!rstate->enabled && !rstate->disabled) {
        if (can_set_state)
            rdev_warn(rdev, "No configuration\n");
        return 0;
    }    

    if (rstate->enabled && rstate->disabled) {                                                                                                         
        rdev_err(rdev, "invalid configuration\n");
        return -EINVAL;
    }    

    if (!can_set_state) {
        rdev_err(rdev, "no way to set suspend state\n");
        return -EINVAL;
    }    

    if (rstate->enabled)
        ret = rdev->desc->ops->set_suspend_enable(rdev);
    else 
        ret = rdev->desc->ops->set_suspend_disable(rdev);
    if (ret < 0) { 
        rdev_err(rdev, "failed to enabled/disable\n");
        return ret;
    }

platform_driver_register注册的proble中,调用axp-mfd.c中的axp_register_mfd->axp_mfd_add_subdevs->platform_device_add来将每个ldo或者dc/cd作为一个独立的平台资源注册,他们的名字都为axp22-regulator,但是每个id各不一样,最终注册的device名字变成

axp22-regulator + id的名字如“ axp22-regulator.2”等

这样文件drivers/power/axp_power/axp22-regu.c中platform_driver_register将会匹配上面的对应的device名字,在probe中用regulator_register注册进入了前面说的drivers/regulator/core.c中,这样axp的电源开关,休眠等就交给了regulator core来管理。

如何配置默认打开电源?

在axp22-regu.c的regulator_register中,把该路电源注册到core.c中,会调用set_machine_constraints函数:

static int set_machine_constraints(struct regulator_dev *rdev,
    const struct regulation_constraints *constraints)
{
...................
    ret = machine_constraints_voltage(rdev, rdev->constraints);
....................
    if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
        ops->enable) {
        ret = ops->enable(rdev);
        if (ret < 0) {
            rdev_err(rdev, "failed to enable\n");
            goto out;
        }
    }
}
machine_constraints_voltage就是负责设置输出电压的:

    /* do we need to apply the constraint voltage */
    if (rdev->constraints->apply_uV &&
        rdev->constraints->min_uV == rdev->constraints->max_uV) {
        ret = _regulator_do_set_voltage(rdev,
                        rdev->constraints->min_uV,
                        rdev->constraints->max_uV);
        if (ret < 0) {
            rdev_err(rdev, "failed to apply %duV constraint\n",
                 rdev->constraints->min_uV);
            return ret;
        }
    }

_regulator_do_set_voltage就是最终设置输出电压函数,可以看到只有满足if条件才会调用,所以要在axp22-board.c中把

.min_uV =  3300000,
.max_uV =  3300000,
这两个设置为相同的值,

 unsigned always_on:1;   /* regulator never off when system is on */
unsigned boot_on:1; /* bootloader/firmware enabled regulator */
unsigned apply_uV:1;    /* apply uV constraint if min == max */
apply_uV使用位域定义的,给他赋值为1即可。

这样设置了默认输出电压,接着enable就可以输出了,从前面core中的函数看要,要enable那么设置always_on为1(或则boot_on为1并且定义了enable)即可,所以还要在axp22-board.c的.constraints中设置always_on即可,(或则后面两个条件满足也可以)


驱动中申请regulator时候的名字是那个?

regulator_get  -> _regulator_get -> regulator_dev_lookup, 在该函数中会调用如下

    list_for_each_entry(r, &regulator_list, list)
        if (strcmp(rdev_get_name(r), supply) == 0)
            return r; 

static const char *rdev_get_name(struct regulator_dev *rdev)                                                                                           
{
    if (rdev->constraints && rdev->constraints->name)
        return rdev->constraints->name;
    else if (rdev->desc->name)
        return rdev->desc->name;
    else 
        return "";
}
可见,名字就是axp22-board.c中constraints结构体name的名字,如.name = "axp20_ldo4":

    [vcc_ldo4] = { 
        .constraints = { 
            /* board default is 3.3V */
            .name = "axp22_ldo4",
            .min_uV = 1250000,
            .max_uV = 3300000,
            .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
            .initial_state = PM_SUSPEND_STANDBY,
            .state_standby = { 
                //.uV = ldo4_vol * 1000,
                //.enabled = 1,
            }
        },



android mtp模式:

如果为mtp模式,/mnt/sdcard/分区的空间和userdata分区空间是一样大,而且为同一个分区,因为/mnt/sdcard/挂载的是/data/media,两者的内容是一样的。如果连接usb到电脑,那么根据MTP协议把/mnt/sdcard/分区共享到了电脑上,这有点像电脑的网络共享,android和电脑都可以同事访问该MTP分区,但是android占权限的主导地位。由此可见mtp是一种移动设给和电脑通过USB共享文件夹的协议


编译网络工具ethtool android版本,下载ethtool-2.6.37源代码,在./configure生成Makefile时候加上参数GCC=arm-none-linux-gnueabi,这样生成Makefile后,打开它,在arm-none-linux-gnueabi-gcc后面加上参数 --static,编译成静态文件ethtool即可,用法比如./ethtool -i eth0


全志平台配置插入电源直接开机,不进入充电模式:

代码在vendor/softwinner/boot/boot1/apps/Boot_Android/Board/fel_detect/fel_detect.c中

    power_start = 0;
   // 0: 不允许插火牛直接开机,必须通过判断:满足以下条件可以直接开机:长按power按键,前次是系统状态,如果电池电量过低,则不允许开机
   // 1: 任意状态下,允许插火牛直接开机,同时要求电池电量足够高
   // 2: 不允许插火牛直接开机,必须通过判断:满足以下条件可以直接开机:长按power按键,前次是系统状态,不要求电池电量
   // 3: 任意状态下,允许插火牛直接开机,不要求电池电量
    if(wBoot_script_parser_fetch("target", "power_start", &power_start, 1)) 
    {   
      power_start=0;
    } 

所以只要把sys_config.fex中的power_start配置为3即可,默认是0



私人定制adb需求:

蛋疼的客户为了产品保密,要求做一个特别的adb 工具,只能连接他的平板,那好吧,修改adb 源代码,把数据位全部反过来:

lsc@lsc:~/disk/M71GY2/system/core/adb$ git diff
diff --git a/adb/transport_local.c b/adb/transport_local.c
index 96a24ba..49c275e 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -29,15 +29,24 @@
 #define H4(x)  (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24)
 static inline void fix_endians(apacket *p)
 {
-    p->msg.command     = H4(p->msg.command);
-    p->msg.arg0        = H4(p->msg.arg0);
-    p->msg.arg1        = H4(p->msg.arg1);
-    p->msg.data_length = H4(p->msg.data_length);
-    p->msg.data_check  = H4(p->msg.data_check);
-    p->msg.magic       = H4(p->msg.magic);
+    p->msg.command     = ~H4(p->msg.command);
+    p->msg.arg0        = ~H4(p->msg.arg0);
+    p->msg.arg1        = ~H4(p->msg.arg1);
+    p->msg.data_length = ~H4(p->msg.data_length);
+    p->msg.data_check  = ~H4(p->msg.data_check);
+    p->msg.magic       = ~H4(p->msg.magic);
 }
 #else
-#define fix_endians(p) do {} while (0)
+//#define fix_endians(p) do {} while (0)
+static inline void fix_endians(apacket *p)
+{
+    p->msg.command     = ~(p->msg.command);
+    p->msg.arg0        = ~(p->msg.arg0);
+    p->msg.arg1        = ~(p->msg.arg1);
+    p->msg.data_length = ~(p->msg.data_length);
+    p->msg.data_check  = ~(p->msg.data_check);
+    p->msg.magic       = ~(p->msg.magic);
+}
 #endif
 
 #if ADB_HOST
diff --git a/adb/transport_usb.c b/adb/transport_usb.c
index ee6b637..ef92e20 100644
--- a/adb/transport_usb.c
+++ b/adb/transport_usb.c
@@ -31,19 +31,28 @@
 #define H4(x)  (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24)
 static inline void fix_endians(apacket *p)
 {
-    p->msg.command     = H4(p->msg.command);
-    p->msg.arg0        = H4(p->msg.arg0);
-    p->msg.arg1        = H4(p->msg.arg1);
-    p->msg.data_length = H4(p->msg.data_length);
-    p->msg.data_check  = H4(p->msg.data_check);
-    p->msg.magic       = H4(p->msg.magic);
+    p->msg.command     = ~H4(p->msg.command);
+    p->msg.arg0        = ~H4(p->msg.arg0);
+    p->msg.arg1        = ~H4(p->msg.arg1);
+    p->msg.data_length = ~H4(p->msg.data_length);
+    p->msg.data_check  = ~H4(p->msg.data_check);
+    p->msg.magic       = ~H4(p->msg.magic);
 }
 unsigned host_to_le32(unsigned n)
 {
     return H4(n);
 }
 #else
-#define fix_endians(p) do {} while (0)
+//#define fix_endians(p) do {} while (0)
+static inline void fix_endians(apacket *p)
+{
+    p->msg.command     = ~(p->msg.command);
+    p->msg.arg0        = ~(p->msg.arg0);
+    p->msg.arg1        = ~(p->msg.arg1);
+    p->msg.data_length = ~(p->msg.data_length);
+    p->msg.data_check  = ~(p->msg.data_check);
+    p->msg.magic       = ~(p->msg.magic);
+}
重新编译成下位机adb adbd和 linux 主机adb工具

window下adb 工具这样编译:

sudo apt-get install mingw32;

 make USE_MINGW=y adb

生成:

out/host/windows-x86/bin/AdbWinUsbApi.dll
out/host/windows-x86/bin/AdbWinApi.dll

out/host/windows-x86/bin/adb.exe

替换掉原来的即可



android编译代码,如果要拷贝很多so到out目录,那么下面这个脚本超级有用,在mk文件中加入即可,路径修改成自己的:

src_files := $(shell ls $(CUR_PATH)/airis )
PRODUCT_COPY_FILES += $(foreach file, $(src_files), \
                              $(CUR_PATH)/airis/$(file):system/lib/$(file)) 


在launcher中隐藏某个apk的icon:

--- a/src/com/android/launcher2/AllAppsList.java
+++ b/src/com/android/launcher2/AllAppsList.java
@@ -91,6 +91,11 @@ class AllAppsList {
 
         if (matches.size() > 0) {
             for (ResolveInfo info : matches) {
+                String name = info.activityInfo.name;
+                if(name.equals("com.google.android.maps.PlacesActivity")
+                        || name.equals("com.google.android.maps.driveabout.app.DestinationActivity"))
+                    continue;
+
                 add(new ApplicationInfo(context.getPackageManager(), info, mIconCache, null));
             }
         }


2. 默认铃声, 通知, 闹钟音乐
可以在system.prop 分别配置

ro.config.ringtone=Playa.ogg(默认铃声设置,文件在/system/media/audio/ringtones 把喜欢的铃声放这里,比如123.MP3放入ringtones文件夹中,这里代码改为ro.config.ringtone=123.mp3)

ro.config.notification_sound=regulus.ogg(默认提示音,文件在/system/media/audio/notifications 修改方法同上)

ro.config.alarm_alert=Alarm_Beep_03.ogg(默认闹铃,文件在/system/media/audio/alarms 修改方法同上)

3. 壁纸不跟随滑动
packages/apps/Launcher2/./src/com/android/launcher2/Workspace.java  大概 875行
private float wallpaperOffsetForCurrentScroll() 
修改 wallpaperOffsetForCurrentScroll 的返回值。改成 return  0.5f; 


全志A83T编译kernel时候报错:

./stdio.h:456:1: error: 'gets' undeclared here (not in a function)

网上搜索很久,不过最管用的还是修改stdio.in.h, 如下:

 cd ./out/sun9iw1p1/linux/common/buildroot/build/host-m4-1.4.15/lib/

sed -i -e '/gets is a security/d' ./stdio.in.h

然后重新编译即可


蛋疼的客户没有什么做不出来的,提供的apk放在内部不可卸载方式安装就报错不能运行,把so库单独拿出来也不管用;安装在外部可卸载就正常,但是又要求app不能卸载,好吧,只能把setting和launcher中的可卸载地方屏蔽掉,还有禁止用adb 来卸载,分别修改如下:

--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -38,6 +38,7 @@ import android.view.ViewGroup;
 import android.view.animation.AnimationUtils;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.LinearInterpolator;
+import android.util.Log;
 
 import com.android.launcher3.compat.UserHandleCompat;
 
@@ -180,6 +181,18 @@ public class DeleteDropTarget extends ButtonDropTarget {
         boolean isVisible = true;
         boolean useUninstallLabel = !LauncherAppState.isDisableAllApps() &&
                 isAllAppsApplication(source, info);
+        boolean flag = info instanceof AppInfo;
+        Log.e("sclu", "flag=" + flag);
+        if (flag) {
+            AppInfo appInfo = (AppInfo) info;
+            String name = appInfo.componentName + "";
+            if (name.contains("com.android.chrome")) {
+                useUninstallLabel = false;
+                isVisible = false;
+            }
+            Log.e("sclu", "className=" + appInfo.componentName);
+        }


--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -34,6 +34,7 @@ import android.view.ViewGroup;
 import android.view.animation.AnimationUtils;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.LinearInterpolator;
+import android.util.Log;
 
 import com.android.launcher.R;
 
@@ -147,11 +148,18 @@ public class DeleteDropTarget extends ButtonDropTarget {
         // delete the app (it was downloaded), and rename the string to "uninstall" in such a case
         if (isAllAppsApplication(source, info)) {
             ApplicationInfo appInfo = (ApplicationInfo) info;
+            String name = appInfo.componentName + "";
             if ((appInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) {
                 isUninstall = true;
             } else {
                 isVisible = false;
             }
+
+            if (name.contains("com.android.chrome")) {
+                isUninstall = false;
+                isVisible = false;
+            }
+            Log.e("sclu", "className=" + appInfo.componentName);

--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -368,7 +368,7 @@ public class InstalledAppDetails extends Fragment
         }
         // If this is a device admin, it can't be uninstalled or disabled.
         // We do this here so the text of the button is still set correctly.
-        if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
+        if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName) || mPackageInfo.packageName.equals("com.android.chrome")) {
             enabled = false;
         }


--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11496,6 +11497,10 @@ public class PackageManagerService extends IPackageManager.Stub {
             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
                     flags, outInfo, writeSettings);
         } else {
+            if (ps.name.equals("com.google.android.talk") || ps.name.equals("com.android.chrome")) {
+                Slog.e("sclu", "can't remove google talk or chrome");
+                return false;
+            }



android4.2以后在frameworks/base/core/res/res/values/string.xml中新增资源,还要在symbols.xml中导出;除了在当前目录要mm外,还要在frameworks/base/core目录mm,否则提示找不到资源



android 4.4编译老是提示:

out/target/common/obj/PACKAGING/public_api.txt:23888: error 12: Class android.telephony.gsm.SmsManager changed static qualifier
out/target/common/obj/PACKAGING/public_api.txt:23888: error 26: Class android.telephony.gsm.SmsManager added final qualifier but was previously uninstantiable and therefore could not be subclassed
out/target/common/obj/PACKAGING/public_api.txt:23889: error 4: Added public method android.telephony.gsm.SmsManager.divideMessage
out/target/common/obj/PACKAGING/public_api.txt:23890: error 4: Added public method android.telephony.gsm.SmsManager.getDefault
out/target/common/obj/PACKAGING/public_api.txt:23891: error 4: Added public method android.telephony.gsm.SmsManager.sendDataMessage
out/target/common/obj/PACKAGING/public_api.txt:23892: error 4: Added public method android.telephony.gsm.SmsManager.sendMultipartTextMessage
out/target/common/obj/PACKAGING/public_api.txt:23893: error 4: Added public method android.telephony.gsm.SmsManager.sendTextMessage
out/target/common/obj/PACKAGING/public_api.txt:23894: error 5: Added public field android.telephony.gsm.SmsManager.RESULT_ERROR_GENERIC_FAILURE
out/target/common/obj/PACKAGING/public_api.txt:23895: error 5: Added public field android.telephony.gsm.SmsManager.RESULT_ERROR_NO_SERVICE
out/target/common/obj/PACKAGING/public_api.txt:23896: error 5: Added public field android.telephony.gsm.SmsManager.RESULT_ERROR_NULL_PDU
out/target/common/obj/PACKAGING/public_api.txt:23897: error 5: Added public field android.telephony.gsm.SmsManager.RESULT_ERROR_RADIO_OFF
out/target/common/obj/PACKAGING/public_api.txt:23898: error 5: Added public field android.telephony.gsm.SmsManager.STATUS_ON_SIM_FREE
out/target/common/obj/PACKAGING/public_api.txt:23899: error 5: Added public field android.telephony.gsm.SmsManager.STATUS_ON_SIM_READ
out/target/common/obj/PACKAGING/public_api.txt:23900: error 5: Added public field android.telephony.gsm.SmsManager.STATUS_ON_SIM_SENT
out/target/common/obj/PACKAGING/public_api.txt:23901: error 5: Added public field android.telephony.gsm.SmsManager.STATUS_ON_SIM_UNREAD
out/target/common/obj/PACKAGING/public_api.txt:23902: error 5: Added public field android.telephony.gsm.SmsManager.STATUS_ON_SIM_UNSENT

如果你检查了java jar javac javah javap配置都是jdk1.6.0_45,都没有问题;那么删除掉framework 代码,重新checkout 即可;

我的就是把整个硬盘拿到新电脑上用导致的问题,需要更新代码日期,最好办法就是删除代码,重新checkout出来即可



RK解压resource.img:

在kernel目录有resource_tool工具,新建tempdir临时目录

./resource_tool --unpack --verbose --image=resource.img tempdir

解压dtb文件:

dtc -I dtb -O dts  firefly-rk3288.dtb  -o my.dtsi

即可生成dtsi文件


bootanimation.zip打包命令:

 zip -Z store bootanimation.zip part0/*jpg part1/*jpg desc.txt


git 新建一个工程比如android6.0:

在marshmallow/platform下新建一个repo文件夹,进入repo 运行new_project.sh manifest

回到本地计算机,运行git clone ssh://venus/home/git/android/marshmallow/platform/repo manifest.git克隆

新建default.xml文件并添加一下内容:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote name="origin"
          fetch="/home/git/android"                                                                                                                                                                          
          sync-c="true" />
    
  <default revision="a64_android6.0_dvk"
           remote="origin"
       sync-c="true"
       sync-j="8" />
  <project name="device/common"/>
  <project name="device/asus"/>
  <project name="device/generic"/>
  <project name="device/google"/>
  <project name="device/htc"/>
  <project name="device/lge"/>
  <project name="device/moto"/>
  <project name="device/sample"/>
  <project name="device/softwinner/common"/>
  <project name="device/softwinner/octopus-common"/>
  <project name="device/softwinner/octopus-f1"/>
  <project name="device/softwinner/tulip-common"/>
  <project name="device/softwinner/tulip-p1"/>
  <project name="platform/abi" path="abi"/>
  <project name="platform/art" path="art"/>
  <project name="platform/bionic" path="bionic" />
  <project name="platform/bootable" path="bootable" />
  <project name="platform/build" path="build" >
    <copyfile dest="Makefile" src="core/root.mk"/>
    <copyfile dest="编译说明.txt" src="readme.txt"/>
  </project>

</manifest> 

其中project name内容是后续要添加的,这里只是一部分而已,接着提交到服务器

这样合并好代码并提交后,以后下载代码用:

repo init -u ssh://venus/home/git/android/marshmallow/platform/repo/manifest.git -b a64_android6.0_game.xml

-b后面的xml是新增的分支,如果不用-b参数,则默认default.xml

你可能感兴趣的:(工作笔记-杂文)