isd客户端发现响应内容类型为 text html,Android 监听应用卸载:弹出反馈界面并上传客户端数据...

/* 头文件begin */

#include "UninstalledObserver.h"

/* 头文件end */

#ifdef __cplusplus

extern

"C"

{

#endif

/* 内全局变量begin */

static

char TAG

[]

=

"UninstalledObserver"

;

static jboolean isCopy

= JNI_TRUE

;

static

const

char ObserverProcessName

[]

=

"com.baidu.video:observer"

;

static

const

char APP_DIR

[]

=

"/data/data/com.baidu.video/lib"

;

static

const

char APP_FILES_DIR

[]

=

"/data/data/com.baidu.video/files"

;

static

char

* APP_OBSERVED_FILE

=

"/data/data/com.baidu.video/files/observedFile"

;

//static  char* APP_OBSERVED_FILE = "/data/data/com.baidu.video/databases/bdplayer_database";

static

char

* APP_FEEDBACK_URL

=

"http://www.baidu.com"

;

static

const

char APP_LOCK_FILE

[]

=

"/data/data/com.baidu.video/files/lockFile"

;

int  watchDescriptor

;

int  fileDescriptor

;

pid_t observer

=-

1

;

/* 内全局变量 */

/*

* Class:     com_baidu_video_UninstalledObserver

* Method:    init

* Signature: ()V

* return: 子进程pid

*/

JNIEXPORT

int JNICALL

Java_com_baidu_video_UninstalledObserver_init

(JNIEnv

*env

, jobject obj

, jstring userSerial

,

jstring path

,jstring url

,jstring uploadData

)

{

int isObserverAlive

=

-

1

;

isObserverAlive

=

isObserverProcessAlive

(APP_OBSERVED_FILE

);

if

(isObserverAlive

==

0

){

//判断到监听进程还在

return observer

;

}

if

(path

!= NULL

){

APP_OBSERVED_FILE

=(*env

)->

GetStringUTFChars

(env

,path

,

0

);

}

// fork子进程,以执行轮询任务

pid_t pid

=

fork

();

if

(pid

<

0

)

{

//fork failed !!!

exit

(

1

);

}

else

if

(pid

==

0

)

{

//保存监听进程id

writePidFile

(APP_OBSERVED_FILE

);

// 分配空间,以便读取event

void

*p_buf

=

malloc

(

sizeof

(

struct inotify_event

));

if

(p_buf

== NULL

)

{

//malloc failed !!!

exit

(

1

);

}

// 分配空间,以便打印mask

int maskStrLength

=

7

+

10

+

1

;

// mask=0x占7字节,32位整形数最大为10位,转换为字符串占10字节,'\0'占1字节

char

*p_maskStr

=

malloc

(maskStrLength

);

if

(p_maskStr

== NULL

)

{

free

(p_buf

);

exit

(

1

);

}

// 开始监听

startObserver

(env

,p_buf

,p_maskStr

);

while

(

1

)

{

// 开始循环监听

size_t readBytes

=

read

(fileDescriptor

, p_buf

,

sizeof

(

struct inotify_event

));

// 若文件被删除,可能是已卸载,还需进一步判断app文件夹是否存在

if

(IN_DELETE_SELF

==

((

struct inotify_event

*) p_buf

)->mask

)

{

FILE

*p_appDir

=

fopen

(APP_DIR

,

"r"

);

if

(p_appDir

!= NULL

){

//应用主目录还在(可能还没有来得及清除),sleep(2)等等再看看

sleep

(

2

);

p_appDir

=

fopen

(APP_DIR

,

"r"

);

}

// 确认已卸载

if

(p_appDir

== NULL

)

{

inotify_rm_watch

(fileDescriptor

, watchDescriptor

);

break

;

}

// 未卸载,可能用户执行了"清除数据"

else

{

fclose

(p_appDir

);

//应用没有卸载,重新监听

startObserver

(env

,p_buf

,p_maskStr

);

}

}

}

remove

(APP_OBSERVED_FILE

);

remove

(APP_LOCK_FILE

);

// 释放资源

free

(p_buf

);

free

(p_maskStr

);

// 停止监听

char

*szWebAddr

=

(*env

)->

GetStringUTFChars

(env

,url

,

0

);

char

*szRequest

=(*env

)->

GetStringUTFChars

(env

,uploadData

,

0

);

if

(szWebAddr

&& szRequest

){

//APP_FEEDBACK_URL= (*env)->GetStringUTFChars(env,url, 0);

uploadStatData

(szWebAddr

, szRequest

);

}

else

{

//LOG_DEBUG("UninstalledObserver","url == NULL,不能进行打点。。。。");

}

free

(szWebAddr

);

free

(szRequest

);

if

(userSerial

== NULL

)

{

// 执行命令am start -a android.intent.action.VIEW -d $(url)

execlp

(

"am"

,

"am"

,

"start"

,

"-a"

,

"android.intent.action.VIEW"

,

"-d"

, APP_FEEDBACK_URL

,

(

char

*)NULL

);

}

else

{

// 执行命令am start --user userSerial -a android.intent.action.VIEW -d $(url)

execlp

(

"am"

,

"am"

,

"start"

,

"--user"

,   (*env)->GetStringUTFChars(env, userSerial, &isCopy), "-a", "android.intent.action.VIEW", "-d", APP_FEEDBACK_URL, (char *)NULL);

}

exit

(

0

);

}

else

{

// 父进程直接退出,使子进程被init进程领养,以避免子进程僵死,同时返回子进程pid

return pid

;

}

}

void

startObserver

(JNIEnv

*env

,

void

*p_buf

,

char

*p_maskStr

){

jstring tag

=

(*env

)->

NewStringUTF

(env

, TAG

);

// 若监听文件所在文件夹不存在,退出监听

FILE

*p_filesDir

=

fopen

(APP_FILES_DIR

,

"r"

);

if

(p_filesDir

== NULL

)

{

exit

(

1

);

}

// 若被监听文件不存在,退出监听

FILE

*p_observedFile

=

fopen

(APP_OBSERVED_FILE

,

"r"

);

if

(p_observedFile

== NULL

)

{

exit

(

1

);

}

fclose

(p_observedFile

);

// 通过检测加锁状态来保证只有一个卸载监听进程

int lockFileDescriptor

=

open

(APP_LOCK_FILE

, O_RDONLY

);

if

(lockFileDescriptor

==

-

1

)

{

exit

(

1

);

}

int lockRet

=

flock

(lockFileDescriptor

, LOCK_EX | LOCK_NB

);

if

(lockRet

==

-

1

)

{

exit

(

0

);

}

// 初始化

fileDescriptor

=

inotify_init

();

if

(fileDescriptor

<

0

)

{

free

(p_buf

);

free

(p_maskStr

);

exit

(

1

);

}

watchDescriptor

=

inotify_add_watch

(fileDescriptor

, APP_OBSERVED_FILE

, IN_ALL_EVENTS

);

if

(watchDescriptor

<

0

)

{

free

(p_buf

);

free

(p_maskStr

);

exit

(

1

);

}

}

/*** 检测到卸载应用时候向服务器上传打点数据

szWebAddr: 页面地址(包含host+addr)

szRequest: 请求内容

**/

int

uploadStatData

(

char

*szWebAddr

,

char

*szRequest

)

{

int sockfd

, ret

, responseDataLength

, selectResult

;

struct sockaddr_in servaddr

;

char sockData

[BUFSIZEBIG

],  buf

[BUFSIZEBIG

],

*szRequestLength

;

socklen_t len

;

fd_set   t_set1

;

struct timeval  tv

;

struct hostent

*pHostent

= NULL

;

//        int i,j;

//        char webAddr[128];

//        char szRequestData[BUFSIZEBIG];

//LOG_DEBUG("UninstalledObserver","开始打点");

if

((sockfd

=

socket

(AF_INET

, SOCK_STREAM

,

0

))

<

0

)

{

//LOG_DEBUG("UninstalledObserver","创建网络连接失败,本线程即将终止---socket error!\n");

exit

(

0

);

};

if

(!szWebAddr

){

//LOG_DEBUG("UninstalledObserver","if(!szWebAddr)  return 0;");

return

0

;

}

//        for(i=0;i

//            webAddr[i]=szWebAddr[i];

//        }

//        //LOG_DEBUG("UninstalledObserver","上传地址:");

//        //LOG_DEBUG("UninstalledObserver",webAddr);

bzero

(&servaddr

,

sizeof

(servaddr

));

servaddr

.sin_family

= AF_INET

;

servaddr

.sin_port

=

htons

(PORT

);

//获取hostent

pHostent

=

gethostbyname

(szWebAddr

);

if

(!pHostent

)

{

//LOG_DEBUG("UninstalledObserver","if(!pHostent) return 0;");

//            if (inet_pton(AF_INET, IPSTR, &servaddr.sin_addr) <= 0 ){

//                //LOG_DEBUG("UninstalledObserver","创建网络连接失败,本线程即将终止 exit(0);");

//                exit(0);

//            };

return

0

;

}

else

{

servaddr

.sin_addr

.s_addr

=

((

struct in_addr

*)(pHostent

->h_addr

))->s_addr

;

}

if

(

connect

(sockfd

,

(

struct sockaddr

*)&servaddr

,

sizeof

(servaddr

))

<

0

){

//LOG_DEBUG("UninstalledObserver","连接到服务器失败,connect error!");

exit

(

0

);

}

//LOG_DEBUG("UninstalledObserver","与远端建立了连接!");

//发送数据

szRequestLength

=(

char

*)

malloc

(

128

);

len

=

strlen

(szRequest

);

sprintf

(szRequestLength

,

"%d"

, len

);

memset

(sockData

,

0

, BUFSIZEBIG

);

strcat

(sockData

,

"POST /postlog/?app=androidphone HTTP/1.1\n"

);

strcat

(sockData

,

"Host: app.video.baidu.com\n"

);

//strcat(sockData, "Host: cq01-video-rdtest01.vm.baidu.com\n");

strcat

(sockData

,

"Content-Type: application/x-www-form-urlencoded\n"

);

strcat

(sockData

,

"Content-Length: "

);

strcat

(sockData

, szRequestLength

);

strcat

(sockData

,

"\n\n"

);

strcat

(sockData

, szRequest

);

strcat

(sockData

,

"\r\n\r\n"

);

//        for(j=0;j

//            szRequestData[j]=szRequest[j];

//        }

//        //LOG_DEBUG("UninstalledObserver","上传数据:");

//        //LOG_DEBUG("UninstalledObserver",szRequestData);

ret

=

write

(sockfd

,sockData

,

strlen

(sockData

));

if

(ret

<

0

)

{

//LOG_DEBUG("UninstalledObserver","打点失败!");

exit

(

0

);

}

else

{

//LOG_DEBUG("UninstalledObserver","打点成功!");

}

FD_ZERO

(&t_set1

);

FD_SET

(sockfd

,

&t_set1

);

while

(

1

){

sleep

(

1

);

tv

.tv_sec

=

0

;

tv

.tv_usec

=

0

;

selectResult

=

0

;

selectResult

=

select

(sockfd

+

1

,

&t_set1

, NULL

, NULL

,

&tv

);

if

(selectResult

<

0

)

{

close

(sockfd

);

//LOG_DEBUG("UninstalledObserver","在读取数据报文时SELECT检测到异常,该异常导致线程终止!return -1;");

return

-

1

;

};

if

(selectResult

>

0

){

memset

(buf

,

0

, BUFSIZEBIG

);

responseDataLength

=

read

(sockfd

, buf

, BUFSIZEBIG

-

1

);

if

(responseDataLength

==

0

){

close

(sockfd

);

//LOG_DEBUG("UninstalledObserver","读取数据报文时发现远端关闭,该线程终止!");

return

-

1

;

}

//LOG_DEBUG("UninstalledObserver","服务器响应数据: ");

//LOG_DEBUG("UninstalledObserver",buf);

}

}

close

(sockfd

);

return

0

;

}

/**

* @Brief  write the pid into the szPidFile

*

* @Param szPidFile name of pid file

*/

void

writePidFile

(

const

char

*szPidFile

)

{

/*open the file*/

char str

[

32

];

int pidFile

=

open

(szPidFile

, O_WRONLY|O_TRUNC

);

if

(pidFile

<

0

)

{

exit

(

1

);

}

/*F_LOCK(block&lock) F_TLOCK(try&lock) F_ULOCK(unlock) F_TEST(will not lock)*/

if

(

flock

(pidFile

, LOCK_EX | LOCK_NB

)

<

0

)

{

//if (lockf(pidFile, F_TLOCK, 0) < 0) {

fprintf

(stderr

,

"Can't lockf Pid File: %s"

, szPidFile

);

//LOG_DEBUG("UninstalledObserver","writePidFile: Can't lockf Pid File");

exit

(

1

);

}

/*get the pid,and write it to the pid file.*/

sprintf

(str

,

"%d\n"

,

getpid

());

ssize_t len

=

strlen

(str

);

ssize_t ret

=

write

(pidFile

, str

, len

);

//fprintf (pFile, " %d ",getpid());

//LOG_DEBUG("UninstalledObserver","writePidFile: 监听进程pid如下");

//LOG_DEBUG("UninstalledObserver",str);

if

(ret

!= len

)

{

fprintf

(stderr

,

"Can't Write Pid File: %s"

, szPidFile

);

//LOG_DEBUG("UninstalledObserver","writePidFile: Can't Write Pid File");

exit

(

1

);

}

close

(pidFile

);

//LOG_DEBUG("UninstalledObserver","writePidFile: 成功保存了监听进程pid");

}

int

isObserverProcessAlive

(

const

char

*szPidFile

){

FILE

*pidFile

;

int i

;

char observerPID

[

32

];

if

((pidFile

=

fopen

(szPidFile

,

"rb"

))==NULL

){

//LOG_DEBUG("UninstalledObserver","isObserverProcessAlive: Can't Open Pid File");

return

1

;

}

//fread(&observerPID,sizeof(observerPID),1,pidFile);

fscanf

(pidFile

,

"%d"

,

&observer

);

fclose

(pidFile

);

if

(observer

>

1

){

sprintf

(observerPID

,

"%d\n"

, observer

);

//LOG_DEBUG("UninstalledObserver","isObserverProcessAlive: 读取到上次存入的pid");

//LOG_DEBUG("UninstalledObserver",observerPID);

if

(

kill

(observer

,

0

)

==

0

){

//LOG_DEBUG("UninstalledObserver","isObserverProcessAlive: 判断到监听进程还在。");

return

0

;

}

//LOG_DEBUG("UninstalledObserver","isObserverProcessAlive: 判断到监听进程已不存在。");

}

else

{

//LOG_DEBUG("UninstalledObserver","isObserverProcessAlive: 没有读取到上次存入的pid,无法判断监听进程是否还在。");

return

1

;

}

}

#ifdef __cplusplus

}

#endif

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值