262 lines
6.3 KiB
C++
262 lines
6.3 KiB
C++
#ifndef __APPINSIGHT_H__
|
|
#define __APPINSIGHT_H__
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <string>
|
|
#include <cstring>
|
|
#include <array>
|
|
#include <memory>
|
|
|
|
#include <cutils/properties.h>
|
|
#include <android/log.h>
|
|
|
|
#ifndef LOG_TAG
|
|
#define LOG_TAG "AppInsight"
|
|
#endif
|
|
|
|
#define APPINSIGHT_LOGD(B, ...) if(B) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)
|
|
|
|
#define INFO_DUMP_GET_SYSTEM_PROP(TYPE, VAR, KEY, DEFAULT) \
|
|
{\
|
|
char value[PROPERTY_VALUE_MAX]; \
|
|
property_get(KEY, value, DEFAULT); \
|
|
VAR = (TYPE) atoi(value); \
|
|
}
|
|
|
|
#define KEYLIST \
|
|
keyType(SCENARIO), \
|
|
keyType(APPNAME), \
|
|
keyType(CODECTYPE), \
|
|
keyType(WIDTH), \
|
|
keyType(HEIGHT), \
|
|
keyType(PIXEL_FORMAT), \
|
|
keyType(BITRATE), \
|
|
keyType(PROFILE), \
|
|
keyType(LEVEL), \
|
|
keyType(FRAMERATE), \
|
|
keyType(GRID_WIDTH), \
|
|
keyType(GRID_HEIGHT), \
|
|
keyType(TILE_WIDTH), \
|
|
keyType(TILE_HEIGHT), \
|
|
keyType(PROGRESSIVE), \
|
|
keyType(ICC_PROFILE), \
|
|
keyType(COLOR_TYPE), \
|
|
keyType(COLOR_SPACE), \
|
|
keyType(SAMPLE_SIZE), \
|
|
keyType(REGION_DECODE), \
|
|
keyType(INFODUMPMAX)
|
|
|
|
#define TYPENONE(x) x
|
|
#define TYPESTR(x) #x
|
|
|
|
namespace AppInsight {
|
|
|
|
#define OUTPATH "/sdcard/appinsight"
|
|
|
|
#ifdef keyType
|
|
#undef keyType
|
|
#endif
|
|
#define keyType TYPENONE
|
|
enum InfoDumpKey {KEYLIST};
|
|
|
|
class InfoDump {
|
|
public:
|
|
InfoDump(bool vendor=true)
|
|
:modified(false),enabled(false),isVendor(vendor)
|
|
{
|
|
if(isVendor)
|
|
{
|
|
INFO_DUMP_GET_SYSTEM_PROP(bool, enabled, "vendor.mtk.appinsight.videoimage.enabled", "0");
|
|
}
|
|
else
|
|
{
|
|
INFO_DUMP_GET_SYSTEM_PROP(bool, enabled, "mtk.appinsight.videoimage.enabled", "0");
|
|
}
|
|
|
|
info.fill(NULL);
|
|
infoType.fill(UNINIT);
|
|
|
|
if(!enabled) return;
|
|
|
|
char temp[512];
|
|
if(isVendor)
|
|
property_get("vendor.mtk.appinsight.videoimage.scenario", temp, "");
|
|
else
|
|
property_get("mtk.appinsight.videoimage.scenario", temp, "");
|
|
|
|
if(temp[0]==0) { enabled = false; return; }
|
|
else add(SCENARIO, temp);
|
|
|
|
if(isVendor)
|
|
property_get("vendor.mtk.appinsight.videoimage.appname", temp, "");
|
|
else
|
|
property_get("mtk.appinsight.videoimage.appname", temp, "");
|
|
|
|
if(temp[0]==0) { enabled = false; return; }
|
|
else add(APPNAME, temp);
|
|
}
|
|
~InfoDump()
|
|
{
|
|
if(!enabled) return;
|
|
for (int i=0;i<INFODUMPMAX; i++)
|
|
{
|
|
if(infoType[i] == UNINIT) continue;
|
|
else if(info[i] != NULL) free(info[i]);
|
|
}
|
|
}
|
|
|
|
bool add(InfoDumpKey k, const char* v)
|
|
{
|
|
if(!enabled) return false;
|
|
if(k>=INFODUMPMAX) return false;
|
|
|
|
int len = strlen(v) + 1;
|
|
|
|
switch(infoType[k])
|
|
{
|
|
case STRING:
|
|
{
|
|
int orilen = *((int*)info[k]);
|
|
if(orilen < len)
|
|
{
|
|
free(info[k]);
|
|
info[k] = (char*)malloc(sizeof(int) + len);
|
|
*((int*)info[k]) = len;
|
|
}
|
|
break;
|
|
}
|
|
case NUMBER:
|
|
case UNINIT:
|
|
default:
|
|
if(info[k]) free(info[k]);
|
|
info[k] = (char*)malloc(sizeof(int) + len + 1);
|
|
*((int*)info[k]) = len + 1;
|
|
}
|
|
|
|
memcpy(info[k]+4, v, len);
|
|
infoType[k] = STRING;
|
|
modified = true;
|
|
return true;
|
|
}
|
|
|
|
bool add(InfoDumpKey k, int v)
|
|
{
|
|
if(!enabled) return false;
|
|
if(k>=INFODUMPMAX) return false;
|
|
|
|
switch(infoType[k])
|
|
{
|
|
case NUMBER:
|
|
if(info[k] == NULL) info[k] = (char*)malloc(sizeof(int));
|
|
if(*((int*)info[k]) == v) return false;
|
|
break;
|
|
case STRING:
|
|
case UNINIT:
|
|
default:
|
|
if(info[k]) free(info[k]);
|
|
info[k] = (char*)malloc(sizeof(int));
|
|
}
|
|
|
|
*((int*)info[k]) = v;
|
|
infoType[k] = NUMBER;
|
|
modified = true;
|
|
return true;
|
|
}
|
|
|
|
bool add(InfoDumpKey k, std::string v)
|
|
{
|
|
if(!enabled) return false;
|
|
return add(k, v.c_str());
|
|
}
|
|
|
|
void commit()
|
|
{
|
|
if(!enabled) return;
|
|
if(!modified) return;
|
|
|
|
time_t rawtime;
|
|
struct tm * timeinfo;
|
|
|
|
time(&rawtime);
|
|
timeinfo = localtime(&rawtime);
|
|
if(timeinfo == nullptr) return;
|
|
|
|
int loglen = 2048;
|
|
int offset = 0;
|
|
|
|
// auto delete sp
|
|
auto logbuffer_sp = std::shared_ptr<char>((char*)malloc(loglen), [](char* ptr) {if(ptr) free(ptr);});
|
|
if(logbuffer_sp == nullptr) return;
|
|
|
|
char* logbuffer = logbuffer_sp.get();
|
|
|
|
offset += snprintf(logbuffer, loglen-offset, "%s appinsight:", asctime(timeinfo));
|
|
for ( int i=0; i<INFODUMPMAX; i++)
|
|
{
|
|
if(infoType[i] == UNINIT)
|
|
{
|
|
offset += snprintf(logbuffer+offset, loglen-offset, "%s:null,", InfoDumpKeyname[i]);
|
|
}
|
|
else if(infoType[i] == NUMBER)
|
|
{
|
|
offset += snprintf(logbuffer+offset, loglen-offset, "%s:%d,", InfoDumpKeyname[i], *((int*) info[i]));
|
|
}
|
|
else if(infoType[i] == STRING)
|
|
{
|
|
offset += snprintf(logbuffer+offset, loglen-offset, "%s:%s,", InfoDumpKeyname[i], info[i]+4);
|
|
}
|
|
}
|
|
|
|
FILE* fout = fopen(OUTPATH, "a+");
|
|
if(fout == NULL) return;
|
|
|
|
fprintf(fout, "%s appinsight: %s\n", asctime(timeinfo), logbuffer);
|
|
fclose(fout);
|
|
|
|
printlog(logbuffer);
|
|
|
|
modified = false;
|
|
}
|
|
|
|
void printlog(char* logbuffer)
|
|
{
|
|
if(!enabled) return;
|
|
if(!modified) return;
|
|
|
|
APPINSIGHT_LOGD(enabled, "%s", logbuffer);
|
|
}
|
|
|
|
bool enable()
|
|
{
|
|
return enabled;
|
|
}
|
|
|
|
private:
|
|
|
|
#ifdef keyType
|
|
#undef keyType
|
|
#endif
|
|
#define keyType TYPESTR
|
|
const char *InfoDumpKeyname[INFODUMPMAX+1] = {KEYLIST};
|
|
|
|
enum InfoType { UNINIT, NUMBER, STRING };
|
|
|
|
std::array<char*, INFODUMPMAX> info;
|
|
std::array<InfoType, INFODUMPMAX> infoType;
|
|
/*
|
|
* memlayout:
|
|
* UNINIT: NULL
|
|
* NUMBER: char[4] <--(value int)
|
|
* STRING: char[4+LEN] <--(LEN int + value str)
|
|
*/
|
|
|
|
bool modified;
|
|
bool enabled;
|
|
bool isVendor;
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|