手机虚拟定位 可以在家里钉钉打卡

       手机虚拟定位 可以在家里钉钉打卡 现在很多的应用都是基于位置服务的,而且把位置服务作为重要的参考标准,其实这是很不安全的,位置信息的数据未经过任何加密,而且是从我们的手机中发送出去的,所以是可以修改的。这一期我们来探讨一下如何修改手机中的定位信息。太基础的原理我就不多说了,可以参考前几期文章。
        先整理一下思路,Android在开发者模式下有一个"允许模拟位置选项",它是location service加载 MOCK location provider 实现的,通过这种线程注入的方式修改GPS信息是hacker们最喜欢的方式,但现在很多应用已经可以检测到这种注入方式而被屏蔽掉,也就是说如果我们只在APP层面上想解决方法总是有被检测出来的可能。那我们就得把问题往深了想,通过修改最底层的GPS数据来欺骗APP,在Framework层面上没有任何修改迹象,这样基于APP层面的检测机制就拿我们没有任何办法。
        思路确定后我们来探讨实践路线,首先我们要建立一个管道,让我们想要定位的GPS数据提交到Android操作系统的最底层,也就是Linux Kernel层面;然后我们要修改 GPS的 location report 机制,让它从内核中提取到我们的数据,然后逐层上报到APP层。有点明修栈道暗度陈仓的感觉。


        总体来说分成两部实现:1.建立到系统内核的数据管道;2.修改GPS上报机制。
        这次实验使用的是闲置的神乐三代手机,编译源码采用CyanogenMod-13
        因为Android系统从内核态到APP层要经过很多的层次,所以对于建立数据管道的步骤比较繁琐,我这里分成了5个步骤,对应5个层面来实现,每一步分别对应Android的 Kernel driver,HAL,JNI,Framework,Application。
下面描述一下实践步骤:
=============分割线1==============
第一步,修改Kernel driver
进入 kernel/xiaomi/cancro/drivers 目录下,新建vp.h文件

  1.  
    #ifndef _VP_ANDROID_H_
  2.  
    #define _VP_ANDROID_H_
  3.  
     
  4.  
    #include <linux/cdev.h>
  5.  
    #include <linux/semaphore.h>
  6.  
     
  7.  
    #define VP_DEVICE_NODE_NAME "vp"
  8.  
    #define VP_DEVICE_FILE_NAME "vp"
  9.  
    #define VP_DEVICE_PROC_NAME "vp"
  10.  
    #define VP_DEVICE_CLASS_NAME "vp"
  11.  
     
  12.  
    typedef struct {
  13.  
    int toggle;
  14.  
    double virtual_latitude;
  15.  
    double virtual_longitude;
  16.  
    } VirtualPosition;
  17.  
     
  18.  
     
  19.  
     
  20.  
     
  21.  
    struct vp_android_dev {
  22.  
    int lamp;
  23.  
    VirtualPosition val;
  24.  
    struct semaphore sem;
  25.  
    struct cdev dev;
  26.  
    };
  27.  
    #endif

新建vp.c文件

  1.  
    /*******************************************
  2.  
    *include file and define functions
  3.  
    *******************************************/
  4.  
    #include <linux/init.h>
  5.  
    #include <linux/module.h>
  6.  
    #include <linux/types.h>
  7.  
    #include <linux/fs.h>
  8.  
    #include <linux/proc_fs.h>
  9.  
    #include <linux/device.h>
  10.  
    #include <asm/uaccess.h>
  11.  
     
  12.  
    #include "vp.h"
  13.  
     
  14.  
    /*主设备和从设备号变量*/
  15.  
    static int vp_major = 0;
  16.  
    static int vp_minor = 0;
  17.  
     
  18.  
    /*设备类别和设备变量*/
  19.  
    static struct class* vp_class = NULL;
  20.  
    static struct vp_android_dev* vp_dev = NULL;
  21.  
     
  22.  
    /*传统的设备文件操作方法*/
  23.  
    static int vp_open(struct inode* inode, struct file* filp);
  24.  
    static int vp_release(struct inode* inode, struct file* filp);
  25.  
    static ssize_t vp_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);
  26.  
    static ssize_t vp_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);
  27.  
     
  28.  
    /*设备文件操作方法表*/
  29.  
    static struct file_operations vp_fops = {
  30.  
    .owner = THIS_MODULE,
  31.  
    .open = vp_open,
  32.  
    .release = vp_release,
  33.  
    .read = vp_read,
  34.  
    .write = vp_write,
  35.  
    };
  36.  
     
  37.  
    /*访问设置属性方法*/
  38.  
    static ssize_t vp_lamp_show(struct device* dev, struct device_attribute* attr, char* buf);
  39.  
    static ssize_t vp_lamp_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);
  40.  
     
  41.  
    /*定义设备属性*/
  42.  
    static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, vp_lamp_show, vp_lamp_store);
  43.  
     
  44.  
     
  45.  
    /*******************************************
  46.  
    *define traditional file access
  47.  
    *******************************************/
  48.  
    /*打开设备方法*/
  49.  
    static int vp_open(struct inode* inode, struct file* filp) {
  50.  
    struct vp_android_dev* dev;
  51.  
     
  52.  
    /*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/
  53.  
    dev = container_of(inode->i_cdev, struct vp_android_dev, dev);
  54.  
    filp->private_data = dev;
  55.  
     
  56.  
    return 0;
  57.  
    }
  58.  
     
  59.  
    /*设备文件释放时调用,空实现*/
  60.  
    static int vp_release(struct inode* inode, struct file* filp) {
  61.  
    return 0;
  62.  
    }
  63.  
     
  64.  
    /*读取设备的寄存器val的值*/
  65.  
    static ssize_t vp_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) {
  66.  
    ssize_t err = 0;
  67.  
    struct vp_android_dev* dev = filp->private_data;
  68.  
     
  69.  
    /*同步访问*/
  70.  
    if(down_interruptible(&(dev->sem))) {
  71.  
    return -ERESTARTSYS;
  72.  
    }
  73.  
     
  74.  
    if(count < sizeof(dev->val)) {
  75.  
    goto out;
  76.  
    }
  77.  
     
  78.  
    /*将寄存器val的值拷贝到用户提供的缓冲区*/
  79.  
    if(copy_to_user(buf, &(dev->val), sizeof(dev->val))) {
  80.  
    err = -EFAULT;
  81.  
    goto out;
  82.  
    }
  83.  
     
  84.  
    err = sizeof(dev->val);
  85.  
     
  86.  
    out:
  87.  
    up(&(dev->sem));
  88.  
    return err;
  89.  
    }
  90.  
     
  91.  
    /*写设备的寄存器值val*/
  92.  
    static ssize_t vp_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {
  93.  
    struct vp_android_dev* dev = filp->private_data;
  94.  
    ssize_t err = 0;
  95.  
     
  96.  
    /*同步访问*/
  97.  
    if(down_interruptible(&(dev->sem))) {
  98.  
    return -ERESTARTSYS;
  99.  
    }
  100.  
     
  101.  
    if(count != sizeof(dev->val)) {
  102.  
    goto out;
  103.  
    }
  104.  
     
  105.  
    /*将用户提供的缓冲区的值写到设备寄存器去*/
  106.  
    if(copy_from_user(&(dev->val), buf, count)) {
  107.  
    err = -EFAULT;
  108.  
    goto out;
  109.  
    }
  110.  
     
  111.  
    err = sizeof(dev->val);
  112.  
     
  113.  
    out:
  114.  
    up(&(dev->sem));
  115.  
    return err;
  116.  
    }
  117.  
     
  118.  
     
  119.  
    /*******************************************
  120.  
    *define devfs access
  121.  
    *******************************************/
  122.  
    /*读取寄存器lamp的值到缓冲区buf中,内部使用*/
  123.  
    static ssize_t __vp_get_lamp(struct vp_android_dev* dev, char* buf) {
  124.  
    int lamp = 0;
  125.  
     
  126.  
    /*同步访问*/
  127.  
    if(down_interruptible(&(dev->sem))) {
  128.  
    return -ERESTARTSYS;
  129.  
    }
  130.  
     
  131.  
    lamp = dev->lamp;
  132.  
    up(&(dev->sem));
  133.  
     
  134.  
    return snprintf(buf, PAGE_SIZE, "%d\n", lamp);
  135.  
    }
  136.  
     
  137.  
    /*把缓冲区buf的值写到设备寄存器lamp中去,内部使用*/
  138.  
    static ssize_t __vp_set_lamp(struct vp_android_dev* dev, const char* buf, size_t count) {
  139.  
    int lamp = 0;
  140.  
     
  141.  
    /*将字符串转换成数字*/
  142.  
    lamp = simple_strtol(buf, NULL, 10);
  143.  
     
  144.  
    /*同步访问*/
  145.  
    if(down_interruptible(&(dev->sem))) {
  146.  
    return -ERESTARTSYS;
  147.  
    }
  148.  
     
  149.  
    dev->lamp = lamp;
  150.  
    up(&(dev->sem));
  151.  
     
  152.  
    return count;
  153.  
    }
  154.  
     
  155.  
    /*读取设备属性lamp*/
  156.  
    static ssize_t vp_lamp_show(struct device* dev, struct device_attribute* attr, char* buf) {
  157.  
    struct vp_android_dev* hdev = (struct vp_android_dev*)dev_get_drvdata(dev);
  158.  
     
  159.  
    return __vp_get_lamp(hdev, buf);
  160.  
    }
  161.  
     
  162.  
    /*写设备属性lamp*/
  163.  
    static ssize_t vp_lamp_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) {
  164.  
    struct vp_android_dev* hdev = (struct vp_android_dev*)dev_get_drvdata(dev);
  165.  
     
  166.  
    return __vp_set_lamp(hdev, buf, count);
  167.  
    }
  168.  
     
  169.  
     
  170.  
    /*******************************************
  171.  
    *define proc access
  172.  
    *******************************************/
  173.  
    /*读取设备寄存器lamp的值,保存在page缓冲区中*/
  174.  
    static ssize_t vp_proc_read(char* page, char** start, off_t off, int count, int* eof, void* data) {
  175.  
    if(off > 0) {
  176.  
    *eof = 1;
  177.  
    return 0;
  178.  
    }
  179.  
     
  180.  
    return __vp_get_lamp(vp_dev, page);
  181.  
    }
  182.  
     
  183.  
    /*把缓冲区的值buff保存到设备寄存器lamp中去*/
  184.  
    static ssize_t vp_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data) {
  185.  
    int err = 0;
  186.  
    char* page = NULL;
  187.  
     
  188.  
    if(len > PAGE_SIZE) {
  189.  
    printk(KERN_ALERT "The buff is too large: %lu.\n", len);
  190.  
    return -EFAULT;
  191.  
    }
  192.  
     
  193.  
    page = ( char*)__get_free_page(GFP_KERNEL);
  194.  
    if(!page) {
  195.  
    printk(KERN_ALERT "Failed to alloc page.\n");
  196.  
    return -ENOMEM;
  197.  
    }
  198.  
     
  199.  
    /*先把用户提供的缓冲区值拷贝到内核缓冲区中去*/
  200.  
    if(copy_from_user(page, buff, len)) {
  201.  
    printk(KERN_ALERT "Failed to copy buff from user.\n");
  202.  
    err = -EFAULT;
  203.  
    goto out;
  204.  
    }
  205.  
     
  206.  
    err = __vp_set_lamp(vp_dev, page, len);
  207.  
     
  208.  
    out:
  209.  
    free_page(( unsigned long)page);
  210.  
    return err;
  211.  
    }
  212.  
     
  213.  
    /*创建/proc/vp文件*/
  214.  
    static void vp_create_proc(void) {
  215.  
    struct proc_dir_entry *entry;
  216.  
    entry = create_proc_entry(VP_DEVICE_PROC_NAME, 0, NULL);
  217.  
    if(entry)
  218.  
    {
  219.  
    entry->read_proc = vp_proc_read;
  220.  
    entry->write_proc = vp_proc_write;
  221.  
    }
  222.  
    }
  223.  
     
  224.  
    /*删除/proc/vp文件*/
  225.  
    static void vp_remove_proc(void) {
  226.  
    remove_proc_entry(VP_DEVICE_PROC_NAME, NULL);
  227.  
    }
  228.  
     
  229.  
     
  230.  
    /*******************************************
  231.  
    *define load and remove function
  232.  
    *******************************************/
  233.  
    /*初始化设备*/
  234.  
    static int __vp_setup_dev(struct vp_android_dev* dev) {
  235.  
    int err;
  236.  
    dev_t devno = MKDEV(vp_major, vp_minor);
  237.  
     
  238.  
    memset(dev, 0, sizeof(struct vp_android_dev));
  239.  
     
  240.  
    cdev_init(&(dev->dev), &vp_fops);
  241.  
    dev->dev.owner = THIS_MODULE;
  242.  
    dev->dev.ops = &vp_fops;
  243.  
     
  244.  
    /*注册字符设备*/
  245.  
    err = cdev_add(&(dev->dev),devno, 1);
  246.  
    if(err) {
  247.  
    return err;
  248.  
    }
  249.  
     
  250.  
    /*初始化信号量和寄存器lamp, val的值*/
  251.  
    sema_init(&(dev->sem), 1);
  252.  
    dev->lamp = 7777;
  253.  
    dev->val.toggle = 1;
  254.  
    dev->val.virtual_latitude = 45.104108;
  255.  
    dev->val.virtual_longitude = 130.816878;
  256.  
     
  257.  
    return 0;
  258.  
    }
  259.  
     
  260.  
    /*模块加载方法*/
  261.  
    static int __init vp_init(void){
  262.  
    int err = -1;
  263.  
    dev_t dev = 0;
  264.  
    struct device* temp = NULL;
  265.  
     
  266.  
    printk(KERN_ALERT "Initializing vp device.\n");
  267.  
     
  268.  
    /*动态分配主设备和从设备号*/
  269.  
    err = alloc_chrdev_region(&dev, 0, 1, VP_DEVICE_NODE_NAME);
  270.  
    if(err < 0) {
  271.  
    printk(KERN_ALERT "Failed to alloc char dev region.\n");
  272.  
    goto fail;
  273.  
    }
  274.  
     
  275.  
    vp_major = MAJOR(dev);
  276.  
    vp_minor = MINOR(dev);
  277.  
     
  278.  
    /*分配helo设备结构体变量*/
  279.  
    vp_dev = kmalloc( sizeof(struct vp_android_dev), GFP_KERNEL);
  280.  
    if(!vp_dev) {
  281.  
    err = -ENOMEM;
  282.  
    printk(KERN_ALERT "Failed to alloc vp_dev.\n");
  283.  
    goto unregister;
  284.  
    }
  285.  
     
  286.  
    /*初始化设备*/
  287.  
    err = __vp_setup_dev(vp_dev);
  288.  
    if(err) {
  289.  
    printk(KERN_ALERT "Failed to setup dev: %d.\n", err);
  290.  
    goto cleanup;
  291.  
    }
  292.  
     
  293.  
    /*在/sys/class/目录下创建设备类别目录vp*/
  294.  
    vp_class = class_create(THIS_MODULE, VP_DEVICE_CLASS_NAME);
  295.  
    if(IS_ERR(vp_class)) {
  296.  
    err = PTR_ERR(vp_class);
  297.  
    printk(KERN_ALERT "Failed to create vp class.\n");
  298.  
    goto destroy_cdev;
  299.  
    }
  300.  
     
  301.  
    /*在/dev/目录和/sys/class/vp目录下分别创建设备文件vp*/
  302.  
    temp = device_create(vp_class, NULL, dev, "%s", VP_DEVICE_FILE_NAME);
  303.  
    if(IS_ERR(temp)) {
  304.  
    err = PTR_ERR(temp);
  305.  
    printk(KERN_ALERT "Failed to create vp device.");
  306.  
    goto destroy_class;
  307.  
    }
  308.  
     
  309.  
    /*在/sys/class/vp/vp目录下创建属性文件val*/
  310.  
    err = device_create_file(temp, &dev_attr_val);
  311.  
    if(err < 0) {
  312.  
    printk(KERN_ALERT "Failed to create attribute val.");
  313.  
    goto destroy_device;
  314.  
    }
  315.  
     
  316.  
    dev_set_drvdata(temp, vp_dev);
  317.  
     
  318.  
    /*创建/proc/vp文件*/
  319.  
    vp_create_proc();
  320.  
     
  321.  
    printk(KERN_ALERT "Succedded to initialize vp device.\n");
  322.  
    return 0;
  323.  
     
  324.  
    destroy_device:
  325.  
    device_destroy(vp_class, dev);
  326.  
     
  327.  
    destroy_class:
  328.  
    class_destroy(vp_class);
  329.  
     
  330.  
    destroy_cdev:
  331.  
    cdev_del(&(vp_dev->dev));
  332.  
     
  333.  
    cleanup:
  334.  
    kfree(vp_dev);
  335.  
     
  336.  
    unregister:
  337.  
    unregister_chrdev_region(MKDEV(vp_major, vp_minor), 1);
  338.  
     
  339.  
    fail:
  340.  
    return err;
  341.  
    }
  342.  
     
  343.  
    /*模块卸载方法*/
  344.  
    static void __exit vp_exit(void) {
  345.  
    dev_t devno = MKDEV(vp_major, vp_minor);
  346.  
     
  347.  
    printk(KERN_ALERT "Destroy vp device.\n");
  348.  
     
  349.  
    /*删除/proc/vp文件*/
  350.  
    vp_remove_proc();
  351.  
     
  352.  
    /*销毁设备类别和设备*/
  353.  
    if(vp_class) {
  354.  
    device_destroy(vp_class, MKDEV(vp_major, vp_minor));
  355.  
    class_destroy(vp_class);
  356.  
    }
  357.  
     
  358.  
    /*删除字符设备和释放设备内存*/
  359.  
    if(vp_dev) {
  360.  
    cdev_del(&(vp_dev->dev));
  361.  
    kfree(vp_dev);
  362.  
    }
  363.  
     
  364.  
    /*释放设备号*/
  365.  
    unregister_chrdev_region(devno, 1);
  366.  
    }
  367.  
     
  368.  
    MODULE_LICENSE( "GPL");
  369.  
    MODULE_DESCRIPTION( "Virtualposition Driver");
  370.  
     
  371.  
    module_init(vp_init);
  372.  
    module_exit(vp_exit);

添加 Kconfig 文件

  1.  
    config VP
  2.  
    tristate "Virtual Position Driver"
  3.  
    default n
  4.  
    help
  5.  
    This is the virtual position driver.

添加 Makefile 文件

obj-$(CONFIG_VP) += vp.o

修改 drivers/Kconfig 文件 在menu "Device Drivers"和endmenu之间添加一行:

source "drivers/vp/Kconfig"  

修改drivers/Makefile文件,添加一行:

obj-$(CONFIG_HELLO) += vp/  

修改 arch/arm/configs目录下的cyanogen_cancro_defconfig 文件,在文件末尾加入

  1.  
    # CONFIG_VP
  2.  
    CONFIG_VP=y


=============分割线2==============
第二步,修改HAL
进入 ./hardware/libhardware/include/hardware 目录,新建 vp.h 文件

  1.  
    #ifndef ANDROID_VP_INTERFACE_H
  2.  
    #define ANDROID_VP_INTERFACE_H
  3.  
    #include <hardware/hardware.h>
  4.  
    __BEGIN_DECLS
  5.  
     
  6.  
    /*定义模块ID*/
  7.  
    #define VP_HARDWARE_MODULE_ID "vp"
  8.  
     
  9.  
     
  10.  
    //typedef enum{false, true} bool;
  11.  
     
  12.  
     
  13.  
    /*define virtual position structrue*/
  14.  
    typedef struct {
  15.  
    int toggle;
  16.  
    double virtual_latitude;
  17.  
    double virtual_longitude;
  18.  
    } VirtualPosition;
  19.  
     
  20.  
     
  21.  
    /*硬件模块结构体*/
  22.  
    struct vp_module_t {
  23.  
    struct hw_module_t common;
  24.  
    };
  25.  
     
  26.  
    /*硬件接口结构体*/
  27.  
    struct vp_device_t {
  28.  
    struct hw_device_t common;
  29.  
    int fd;
  30.  
    int (*set_val)(struct vp_device_t* dev, VirtualPosition val);
  31.  
    int (*get_val)(struct vp_device_t* dev, VirtualPosition* val);
  32.  
    };
  33.  
     
  34.  
    __END_DECLS
  35.  
     
  36.  
    #endif

进入到 hardware/libhardware/modules 目录,新建vp目录,并添加vp.c文件

  1.  
    #define LOG_TAG "VpStub"
  2.  
     
  3.  
    #include <hardware/hardware.h>
  4.  
    #include <hardware/vp.h>
  5.  
    #include <fcntl.h>
  6.  
    #include <errno.h>
  7.  
    #include <cutils/log.h>
  8.  
    #include <cutils/atomic.h>
  9.  
     
  10.  
    #define DEVICE_NAME "/dev/vp"
  11.  
    #define MODULE_NAME "Vp"
  12.  
    #define MODULE_AUTHOR "[email protected]"
  13.  
     
  14.  
    /*设备打开和关闭接口*/
  15.  
    static int vp_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);
  16.  
    static int vp_device_close(struct hw_device_t* device);
  17.  
     
  18.  
    /*设备访问接口*/
  19.  
    static int vp_set_val(struct vp_device_t* dev, VirtualPosition val);
  20.  
    static int vp_get_val(struct vp_device_t* dev, VirtualPosition* val);
  21.  
     
  22.  
    /*模块方法表*/
  23.  
    static struct hw_module_methods_t vp_module_methods = {
  24.  
    open: vp_device_open
  25.  
    };
  26.  
     
  27.  
    /*模块实例变量*/
  28.  
    struct vp_module_t HAL_MODULE_INFO_SYM = {
  29.  
    common: {
  30.  
    tag: HARDWARE_MODULE_TAG,
  31.  
    version_major: 1,
  32.  
    version_minor: 0,
  33.  
    id: VP_HARDWARE_MODULE_ID,
  34.  
    name: MODULE_NAME,
  35.  
    author: MODULE_AUTHOR,
  36.  
    methods: &vp_module_methods,
  37.  
    }
  38.  
    };
  39.  
     
  40.  
     
  41.  
     
  42.  
     
  43.  
    static int vp_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {
  44.  
    struct vp_device_t* dev;dev = (struct vp_device_t*)malloc(sizeof(struct vp_device_t));
  45.  
     
  46.  
    if(!dev) {
  47.  
    ALOGE( "Vp Stub: failed to alloc space");
  48.  
    return -EFAULT;
  49.  
    }
  50.  
     
  51.  
    memset(dev, 0, sizeof(struct vp_device_t));
  52.  
    dev->common.tag = HARDWARE_DEVICE_TAG;
  53.  
    dev->common.version = 0;
  54.  
    dev->common. module = (hw_module_t*)module;
  55.  
    dev->common.close = vp_device_close;
  56.  
    dev->set_val = vp_set_val;dev->get_val = vp_get_val;
  57.  
     
  58.  
    if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
  59.  
    ALOGE( "Vp Stub: failed to open /dev/vp -- %s.", strerror(errno));free(dev);
  60.  
    return -EFAULT;
  61.  
    }
  62.  
     
  63.  
    *device = &(dev->common);
  64.  
    ALOGI( "Vp Stub: open /dev/vp successfully.");
  65.  
     
  66.  
    return 0;
  67.  
    }
  68.  
     
  69.  
     
  70.  
    static int vp_device_close(struct hw_device_t* device) {
  71.  
    struct vp_device_t* vp_device = (struct vp_device_t*)device;
  72.  
     
  73.  
    if(vp_device) {
  74.  
    close(vp_device->fd);
  75.  
    free(vp_device);
  76.  
    }
  77.  
     
  78.  
    return 0;
  79.  
    }
  80.  
     
  81.  
    static int vp_set_val(struct vp_device_t* dev, VirtualPosition val) {
  82.  
    ALOGI( "Vp Stub: set value %d to device.", val);
  83.  
     
  84.  
    write(dev->fd, &val, sizeof(val));
  85.  
     
  86.  
    return 0;
  87.  
    }
  88.  
     
  89.  
    static int vp_get_val(struct vp_device_t* dev, VirtualPosition* val) {
  90.  
    if(!val) {
  91.  
    ALOGE( "Vp Stub: error val pointer");
  92.  
    return -EFAULT;
  93.  
    }
  94.  
     
  95.  
    read(dev->fd, val, sizeof(*val));
  96.  
     
  97.  
    ALOGI( "Vp Stub: get value %d from device", *val);
  98.  
     
  99.  
    return 0;
  100.  
    }

继续在vp目录下新建Android.mk文件:

  1.  
    LOCAL_PATH := $(call my-dir)
  2.  
    include $(CLEAR_VARS)
  3.  
    LOCAL_MODULE_TAGS := optional
  4.  
    LOCAL_PRELINK_MODULE := false
  5.  
    LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
  6.  
    LOCAL_SHARED_LIBRARIES := liblog
  7.  
    LOCAL_SRC_FILES := vp.c
  8.  
    LOCAL_MODULE := vp. default
  9.  
    include $(BUILD_SHARED_LIBRARY)


=============分割线3==============
第三步,修改JNI
进入 frameworks/base/services/core/jni 目录,新建com_android_server_VirtualPositionService.cpp文件

  1.  
    #define LOG_TAG "VirtualPositionService"
  2.  
    #include "jni.h"
  3.  
    #include "JNIHelp.h"
  4.  
    #include "android_runtime/AndroidRuntime.h"
  5.  
    #include <utils/misc.h>
  6.  
    #include <utils/Log.h>
  7.  
    #include <hardware/hardware.h>
  8.  
    #include <hardware/vp.h>
  9.  
    #include <stdio.h>
  10.  
     
  11.  
     
  12.  
    namespace android
  13.  
    {
  14.  
     
  15.  
    VirtualPosition virtual_position = { 1, 0.0, 0.0};
  16.  
    /*在硬件抽象层中定义的硬件访问结构体,参考<hardware/vp.h>*/
  17.  
    struct vp_device_t* vp_device = NULL;
  18.  
    /*通过硬件抽象层定义的硬件访问接口设置硬件寄存器val的值*/
  19.  
    static void vp_setVal() {
  20.  
    ALOGI( "VirtualPosition JNI: set value to device.");
  21.  
    if(!vp_device) {
  22.  
    ALOGI( "VirtualPosition JNI: device is not open.");
  23.  
    return;
  24.  
    }
  25.  
     
  26.  
    vp_device->set_val(vp_device, virtual_position);
  27.  
    }
  28.  
    /*通过硬件抽象层定义的硬件访问接口读取硬件寄存器val的值*/
  29.  
    static void vp_getVal() {
  30.  
    if(!vp_device) {
  31.  
    ALOGI( "VirtualPosition JNI: device is not open.");
  32.  
    }
  33.  
    vp_device->get_val(vp_device, &virtual_position);
  34.  
     
  35.  
    ALOGI( "VirtualPosition JNI: get value from device.");
  36.  
    }
  37.  
    /*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/
  38.  
    static inline int vp_device_open(const hw_module_t* module, struct vp_device_t** device) {
  39.  
    return module->methods->open(module, VP_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
  40.  
    }
  41.  
    /*通过硬件模块ID来加载指定的硬件抽象层模块并打开硬件*/
  42.  
    static jboolean vp_init(JNIEnv* env, jclass clazz) {
  43.  
    vp_module_t* module;
  44.  
     
  45.  
    ALOGI( "VirtualPosition JNI: initializing......");
  46.  
    if(hw_get_module(VP_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
  47.  
    ALOGI( "VirtualPosition JNI: vp Stub found.");
  48.  
    if(vp_device_open(&(module->common), &vp_device) == 0) {
  49.  
    ALOGI( "VirtualPosition JNI: vp device is open.");
  50.  
    return 0;
  51.  
    }
  52.  
    ALOGE( "VirtualPosition JNI: failed to open vp device.");
  53.  
    return -1;
  54.  
    }
  55.  
    ALOGE( "VirtualPosition JNI: failed to get vp stub module.");
  56.  
    return -1;
  57.  
    }
  58.  
     
  59.  
    static void android_server_VirtualPositionService_set_virtual_toggle(JNIEnv* env, jclass clazz, jint tog)
  60.  
    {
  61.  
    virtual_position.toggle = tog;
  62.  
    vp_setVal();
  63.  
    }
  64.  
     
  65.  
     
  66.  
    static jint android_server_VirtualPositionService_get_virtual_toggle(JNIEnv* env, jclass clazz)
  67.  
    {
  68.  
    vp_getVal();
  69.  
    return virtual_position.toggle;
  70.  
    }
  71.  
     
  72.  
     
  73.  
    static void android_server_VirtualPositionService_set_virtual_latitude(JNIEnv* env, jclass clazz, jdouble vlat)
  74.  
    {
  75.  
    virtual_position.virtual_latitude = vlat;
  76.  
    vp_setVal();
  77.  
    }
  78.  
     
  79.  
     
  80.  
    static jdouble android_server_VirtualPositionService_get_virtual_latitude(JNIEnv* env, jclass clazz)
  81.  
    {
  82.  
    vp_getVal();
  83.  
    return virtual_position.virtual_latitude;
  84.  
    }
  85.  
     
  86.  
     
  87.  
    static void android_server_VirtualPositionService_set_virtual_longitude(JNIEnv* env, jclass clazz, jdouble vlon)
  88.  
    {
  89.  
    virtual_position.virtual_longitude = vlon;
  90.  
    vp_setVal();
  91.  
    }
  92.  
     
  93.  
     
  94.  
    static jdouble android_server_VirtualPositionService_get_virtual_longitude(JNIEnv* env, jclass clazz)
  95.  
    {
  96.  
    vp_getVal();
  97.  
    return virtual_position.virtual_longitude;
  98.  
    }
  99.  
     
  100.  
     
  101.  
     
  102.  
     
  103.  
     
  104.  
     
  105.  
    /*JNI方法表*/
  106.  
    static const JNINativeMethod method_table[] = {
  107.  
    { "init_native",
  108.  
    "()Z",
  109.  
    ( void*)vp_init},
  110.  
    { "native_set_virtual_toggle",
  111.  
    "(I)V",
  112.  
    ( void*)android_server_VirtualPositionService_set_virtual_toggle},
  113.  
    { "native_get_virtual_toggle",
  114.  
    "()I",
  115.  
    ( void*)android_server_VirtualPositionService_get_virtual_toggle},
  116.  
    { "native_set_virtual_latitude",
  117.  
    "(D)V",
  118.  
    ( void*)android_server_VirtualPositionService_set_virtual_latitude},
  119.  
    { "native_get_virtual_latitude",
  120.  
    "()D",
  121.  
    ( void*)android_server_VirtualPositionService_get_virtual_latitude},
  122.  
    { "native_set_virtual_longitude",
  123.  
    "(D)V",
  124.  
    ( void*)android_server_VirtualPositionService_set_virtual_longitude},
  125.  
    { "native_get_virtual_longitude",
  126.  
    "()D",
  127.  
    ( void*)android_server_VirtualPositionService_get_virtual_longitude},
  128.  
     
  129.  
     
  130.  
    };
  131.  
    /*注册JNI方法*/
  132.  
    int register_android_server_VirtualPositionService(JNIEnv *env) {
  133.  
    return jniRegisterNativeMethods(env, "com/android/server/VirtualPositionService", method_table, NELEM(method_table));
  134.  
    }
  135.  
    };

修改同目录下的onload.cpp文件,首先在namespace android增加com_android_server_VirtualPositionService函数声明:

  1.  
    namespace android {
  2.  
     
  3.  
    ..............................................................................................
  4.  
     
  5.  
    int register_android_server_VirtualPositionService(JNIEnv *env);
  6.  
     
  7.  
    };
  8.  
    在JNI_onLoad增加register_android_server_VirtualPositionService函数调用:
  9.  
    extern "C" jint JNI_onLoad(JavaVM* vm, void* reserved)
  10.  
    {
  11.  
    .................................................................................................
  12.  
    register_android_server_VirtualPositionService(env);
  13.  
    .................................................................................................
  14.  
    }

修改同目录下的Android.mk文件,在LOCAL_SRC_FILES变量中增加一行:

  1.  
    LOCAL_SRC_FILES:= \
  2.  
    com_android_server_AlarmManagerService.cpp \
  3.  
    com_android_server_BatteryService.cpp \
  4.  
    com_android_server_InputManager.cpp \
  5.  
    com_android_server_LightsService.cpp \
  6.  
    com_android_server_PowerManagerService.cpp \
  7.  
    com_android_server_SystemServer.cpp \
  8.  
    com_android_server_UsbService.cpp \
  9.  
    com_android_server_VibratorService.cpp \
  10.  
    com_android_server_location_GpsLocationProvider.cpp \
  11.  
    com_android_server_VirtualPositionService.cpp \
  12.  
    onload.cpp


=============分割线4==============
第四步,修改Framework
进入到frameworks/base/core/java/android/os目录,新增VirtualPositionService.aidl接口定义文件

  1.  
    package android.os;
  2.  
     
  3.  
     
  4.  
    interface IVirtualPositionService {
  5.  
    void setVirtualToggle(int tog);
  6.  
    int getVirtualToggle();
  7.  
    void setVirtualLatitude(double vlat);
  8.  
    double getVirtualLatitude();
  9.  
    void setVirtualLongitude(double vlon);
  10.  
    double getVirtualLongitude();
  11.  
    }

然后进入 frameworks/base目录,打开Android.mk文件,修改LOCAL_SRC_FILES变量的值,增加IVirtualPosition.aidl源文件:

  1.  
    LOCAL_SRC_FILES += /
  2.  
    ....................................................................
  3.  
    core/java/android/os/IVibratorService.aidl /
  4.  
    core/java/android/os/IVirtualPosition.aidl /
  5.  
    core/java/android/service/urlrenderer/IUrlRendererService.aidl /
  6.  
    .....................................................................

进入到frameworks/base/services/java/com/android/server目录,新增VirtualPositionService.java文件

  1.  
    package com.android.server;
  2.  
    import android.content.Context;
  3.  
    import android.os.IVirtualPositionService;
  4.  
    import android.util.Slog;
  5.  
     
  6.  
     
  7.  
    public class VirtualPositionService extends IVirtualPositionService.Stub {
  8.  
    private static final String TAG = "VirtualPositionService";
  9.  
    VirtualPositionService() {
  10.  
    init_native();
  11.  
    }
  12.  
    public void setVirtualToggle(int tog) {
  13.  
    native_set_virtual_toggle(tog);
  14.  
    }
  15.  
     
  16.  
     
  17.  
    public int getVirtualToggle(){
  18.  
    return native_get_virtual_toggle();
  19.  
    }
  20.  
     
  21.  
     
  22.  
    public void setVirtualLatitude(double vlat) {
  23.  
    native_set_virtual_latitude(vlat);
  24.  
    }
  25.  
     
  26.  
     
  27.  
    public double getVirtualLatitude(){
  28.  
    return native_get_virtual_latitude();
  29.  
    }
  30.  
     
  31.  
     
  32.  
    public void setVirtualLongitude(double vlon) {
  33.  
    native_set_virtual_longitude(vlon);
  34.  
    }
  35.  
     
  36.  
     
  37.  
    public double getVirtualLongitude() {
  38.  
    return native_get_virtual_longitude();
  39.  
    }
  40.  
     
  41.  
    private static native boolean init_native();
  42.  
    private static native void native_set_virtual_toggle(int tog);
  43.  
    private static native int native_get_virtual_toggle();
  44.  
    private static native void native_set_virtual_latitude(double vlat);
  45.  
    private static native double native_get_virtual_latitude();
  46.  
    private static native void native_set_virtual_longitude(double vlon);
  47.  
    private static native double native_get_virtual_longitude();
  48.  
     
  49.  
     
  50.  
    };

修改同目录的SystemServer.java文件,在ServerThread::run函数中增加加载VirtualPositionService的代码:


  1.  
    @Override
  2.  
    public void run() {
  3.  
    ....................................................................................
  4.  
    try {
  5.  
    Slog.i(TAG, "DiskStats Service");
  6.  
    ServiceManager.addService( "diskstats", new DiskStatsService(context));
  7.  
    } catch (Throwable e) {
  8.  
    Slog.e(TAG, "Failure starting DiskStats Service", e);
  9.  
    }
  10.  
    try {
  11.  
    Slog.i(TAG, "VirtualPosition Service");
  12.  
    ServiceManager.addService( "virtualposition", new VirtualPositionService());
  13.  
    } catch (Throwable e) {
  14.  
    Slog.e(TAG, "Failure starting VirtualPosition Service", e);
  15.  
    }
  16.  
    ......................................................................................
  17.  
    }

然后需要修改sepolicy文件,具体的文件在github上,请下载使用。


=============分割线5==============
第五步,修改application

  1.  
    package com.example.phdemo.myapplication;
  2.  
     
  3.  
     
  4.  
    import android.os.RemoteException;
  5.  
    import android.app.Activity;
  6.  
    import android.os.ServiceManager;
  7.  
    import android.os.Bundle;
  8.  
    import android.widget.CompoundButton;
  9.  
    import android.os.IVirtualPositionService;
  10.  
    import android.os.RemoteException;
  11.  
    import android.util.Log;
  12.  
    import android.view.View;
  13.  
    import android.view.View.OnClickListener;
  14.  
    import android.widget.Button;
  15.  
    import android.widget.EditText;
  16.  
    import android.widget.ToggleButton;
  17.  
    import android.widget.CompoundButton.OnCheckedChangeListener;
  18.  
     
  19.  
     
  20.  
    public class MainActivity extends Activity implements View.OnClickListener {
  21.  
     
  22.  
     
  23.  
    private final static String LOG_TAG = "com.example.phdemo.virtualposition";
  24.  
     
  25.  
     
  26.  
    private IVirtualPositionService virtualpositionService = null;
  27.  
    private ToggleButton toggleButton = null;
  28.  
    private EditText altitudeValueText = null;
  29.  
    private EditText longitudeValueText = null;
  30.  
    private Button getButton = null;
  31.  
    private Button setButton = null;
  32.  
    private Button clearButton = null;
  33.  
     
  34.  
     
  35.  
    /** Called when the activity is first created. */
  36.  
    @Override
  37.  
    public void onCreate(Bundle savedInstanceState) {
  38.  
    super.onCreate(savedInstanceState);
  39.  
    setContentView(R.layout.activity_main);
  40.  
     
  41.  
     
  42.  
    virtualpositionService = IVirtualPositionService.Stub.asInterface(
  43.  
    ServiceManager.getService( "virtualposition"));
  44.  
     
  45.  
     
  46.  
    toggleButton=(ToggleButton)findViewById(R.id.toggleButton);
  47.  
    altitudeValueText = (EditText)findViewById(R.id.altitude_value);
  48.  
    longitudeValueText = (EditText)findViewById(R.id.longitude_value);
  49.  
    getButton = (Button)findViewById(R.id.button_get);
  50.  
    setButton = (Button)findViewById(R.id.button_set);
  51.  
    clearButton = (Button)findViewById(R.id.button_clear);
  52.  
     
  53.  
    getButton.setOnClickListener( this);
  54.  
    setButton.setOnClickListener( this);
  55.  
    clearButton.setOnClickListener( this);
  56.  
     
  57.  
    try{
  58.  
    int val_tog = virtualpositionService.getVirtualToggle();
  59.  
    if(val_tog == 1){
  60.  
    toggleButton.setChecked( true);
  61.  
    } else{
  62.  
    toggleButton.setChecked( false);
  63.  
    }
  64.  
    } catch (Exception e) {}
  65.  
     
  66.  
     
  67.  
    toggleButton.setOnCheckedChangeListener( new OnCheckedChangeListener(){
  68.  
    public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
  69.  
    toggleButton.setChecked(isChecked);
  70.  
    try{
  71.  
    virtualpositionService.setVirtualToggle(isChecked? 1:0);
  72.  
    } catch(Exception e){}
  73.  
    }
  74.  
    });
  75.  
    Log.i(LOG_TAG, "VirtualPosition Activity Created");
  76.  
    }
  77.  
     
  78.  
     
  79.  
    @Override
  80.  
    public void onClick(View v) {
  81.  
    if(v.equals(getButton)) {
  82.  
    try {
  83.  
    double val_altitude = virtualpositionService.getVirtualLatitude();
  84.  
    String text_altitude = String.valueOf(val_altitude);
  85.  
    altitudeValueText.setText(text_altitude);
  86.  
    double val_longitude = virtualpositionService.getVirtualLongitude();
  87.  
    String text_longitude = String.valueOf(val_longitude);
  88.  
    longitudeValueText.setText(text_longitude);
  89.  
    int val_tog = virtualpositionService.getVirtualToggle();
  90.  
    if(val_tog == 1){
  91.  
    toggleButton.setChecked( true);
  92.  
    } else{
  93.  
    toggleButton.setChecked( false);
  94.  
    }
  95.  
    } catch (Exception e) {
  96.  
    Log.e(LOG_TAG, "Remote Exception while reading value from GpsLocationProvider.");
  97.  
    }
  98.  
    }
  99.  
    else if(v.equals(setButton)) {
  100.  
    try {
  101.  
    String text_altitude = altitudeValueText.getText().toString();
  102.  
    String text_longitude = longitudeValueText.getText().toString();
  103.  
    double val_altitude = Double.parseDouble(text_altitude);
  104.  
    double val_longitude = Double.parseDouble(text_longitude);
  105.  
    virtualpositionService.setVirtualLatitude(val_altitude);
  106.  
    virtualpositionService.setVirtualLongitude(val_longitude);
  107.  
    } catch (Exception e) {
  108.  
    Log.e(LOG_TAG, "Remote Exception while writing value to GpsLocationProvider.");
  109.  
    }
  110.  
    }
  111.  
    else if(v.equals(clearButton)) {
  112.  
    String text = "";
  113.  
    altitudeValueText.setText(text);
  114.  
    longitudeValueText.setText(text);
  115.  
    }
  116.  
    }
  117.  
    }


=============分割线6==============
最后一步,在JNI层面修改location report 机制。
进入 frameworks/base/services/core/jni 目录,修改com_android_server_location_GpsLocationProvider.cpp文件:
在全局变量部分加入

  1.  
    // add by aggresss
  2.  
    static int vp_fd = open("/dev/vp", O_RDWR);
  3.  
    static VirtualPosition vp_val;

修改location_callback函数:

  1.  
    static void location_callback(GpsLocation* location)
  2.  
    {
  3.  
    JNIEnv* env = AndroidRuntime::getJNIEnv();
  4.  
    //add by aggresss
  5.  
    read(vp_fd, &vp_val, sizeof(VirtualPosition));
  6.  
    if(vp_val.toggle == 1){
  7.  
    env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
  8.  
    (jdouble)vp_val.virtual_latitude, (jdouble)vp_val.virtual_longitude,
  9.  
    (jdouble)location->altitude,
  10.  
    (jfloat)location->speed, (jfloat)location->bearing,
  11.  
    (jfloat)location->accuracy, (jlong)location->timestamp);
  12.  
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
  13.  
    }
  14.  
    else{
  15.  
    env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
  16.  
    (jdouble)location->latitude, (jdouble)location->longitude,
  17.  
    (jdouble)location->altitude,
  18.  
    (jfloat)location->speed, (jfloat)location->bearing,
  19.  
    (jfloat)location->accuracy, (jlong)location->timestamp);
  20.  
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
  21.  
    }
  22.  
    }


=============我是完成的分割线==============
完成后,重新编译固件,开机后启动VirtualPosition的APP,设置你想要的坐标,想在哪就在哪了。

猜你喜欢

转载自www.cnblogs.com/shenlekeji/p/9381611.html