Methods Summary |
---|
private void | checkFileLimitFLOCK()
File dir = getUsageFilesDir();
if (dir == null) {
Log.w(TAG, "Couldnt find writable directory for usage stats file");
return;
}
// Get all usage stats output files
ArrayList<String> fileList = getUsageStatsFileListFLOCK();
if (fileList == null) {
// Strange but we dont have to delete any thing
return;
}
int count = fileList.size();
if (count <= _MAX_NUM_FILES) {
return;
}
// Sort files
Collections.sort(fileList);
count -= _MAX_NUM_FILES;
// Delete older files
for (int i = 0; i < count; i++) {
String fileName = fileList.get(i);
File file = new File(dir, fileName);
Log.i(TAG, "Deleting file : "+fileName);
file.delete();
}
|
private void | collectDumpInfoFLOCK(java.io.PrintWriter pw, java.lang.String[] args)
List<String> fileList = getUsageStatsFileListFLOCK();
if (fileList == null) {
return;
}
final boolean isCheckinRequest = scanArgs(args, "-c");
Collections.sort(fileList);
File usageFile = new File(mFilePrefix);
String dirName = usageFile.getParent();
File dir = new File(dirName);
String filePrefix = usageFile.getName();
// file name followed by dot
int prefixLen = filePrefix.length()+1;
String todayStr = getCurrentDateStr(null);
for (String file : fileList) {
File dFile = new File(dir, file);
String dateStr = file.substring(prefixLen);
try {
Parcel in = getParcelForFile(dFile);
collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCheckinRequest);
if (isCheckinRequest && !todayStr.equalsIgnoreCase(dateStr)) {
// Delete old file after collecting info only for checkin requests
dFile.delete();
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Failed with "+e+" when collecting dump info from file : " + file);
return;
} catch (IOException e) {
Log.w(TAG, "Failed with "+e+" when collecting dump info from file : "+file);
}
}
|
private void | collectDumpInfoFromParcelFLOCK(android.os.Parcel in, java.io.PrintWriter pw, java.lang.String date, boolean isCheckinRequest)
StringBuilder sb = new StringBuilder();
sb.append("Date:");
sb.append(date);
boolean first = true;
while (in.dataAvail() > 0) {
String pkgName = in.readString();
int launchCount = in.readInt();
long usageTime = in.readLong();
if (isCheckinRequest) {
if (!first) {
sb.append(",");
}
sb.append(pkgName);
sb.append(",");
sb.append(launchCount);
sb.append(",");
sb.append(usageTime);
sb.append("ms");
} else {
if (first) {
sb.append("\n");
}
sb.append("pkg=");
sb.append(pkgName);
sb.append(", launchCount=");
sb.append(launchCount);
sb.append(", usageTime=");
sb.append(usageTime);
sb.append(" ms\n");
}
first = false;
}
pw.write(sb.toString());
|
protected void | dump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)
synchronized (mFileLock) {
collectDumpInfoFLOCK(pw, args);
}
|
public void | enforceCallingPermission()
if (Binder.getCallingPid() == Process.myPid()) {
return;
}
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
|
public com.android.internal.os.PkgUsageStats[] | getAllPkgUsageStats()
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
synchronized (mStatsLock) {
Set<String> keys = mStats.keySet();
int size = keys.size();
if (size <= 0) {
return null;
}
PkgUsageStats retArr[] = new PkgUsageStats[size];
int i = 0;
for (String key: keys) {
PkgUsageStatsExtended pus = mStats.get(key);
retArr[i] = new PkgUsageStats(key, pus.mLaunchCount, pus.mUsageTime);
i++;
}
return retArr;
}
|
private java.lang.String | getCurrentDateStr(java.lang.String prefix)
mCal.setTime(new Date());
StringBuilder sb = new StringBuilder();
if (prefix != null) {
sb.append(prefix);
sb.append(".");
}
int mm = mCal.get(Calendar.MONTH) - Calendar.JANUARY +1;
if (mm < 10) {
sb.append("0");
}
sb.append(mm);
int dd = mCal.get(Calendar.DAY_OF_MONTH);
if (dd < 10) {
sb.append("0");
}
sb.append(dd);
sb.append(mCal.get(Calendar.YEAR));
return sb.toString();
|
private android.os.Parcel | getParcelForFile(java.io.File file)
FileInputStream stream = new FileInputStream(file);
byte[] raw = readFully(stream);
Parcel in = Parcel.obtain();
in.unmarshall(raw, 0, raw.length);
in.setDataPosition(0);
stream.close();
return in;
|
public com.android.internal.os.PkgUsageStats | getPkgUsageStats(android.content.ComponentName componentName)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
String pkgName;
if ((componentName == null) ||
((pkgName = componentName.getPackageName()) == null)) {
return null;
}
synchronized (mStatsLock) {
PkgUsageStatsExtended pus = mStats.get(pkgName);
if (pus == null) {
return null;
}
return new PkgUsageStats(pkgName, pus.mLaunchCount, pus.mUsageTime);
}
|
public static com.android.internal.app.IUsageStats | getService()
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService(SERVICE_NAME);
sService = asInterface(b);
return sService;
|
private java.io.File | getUsageFilesDir()
if (mFilePrefix == null) {
return null;
}
File pre = new File(mFilePrefix);
return new File(pre.getParent());
|
private java.util.ArrayList | getUsageStatsFileListFLOCK()
File dir = getUsageFilesDir();
if (dir == null) {
Log.w(TAG, "Couldnt find writable directory for usage stats file");
return null;
}
// Check if there are too many files in the system and delete older files
String fList[] = dir.list();
if (fList == null) {
return null;
}
File pre = new File(mFilePrefix);
String filePrefix = pre.getName();
// file name followed by dot
int prefixLen = filePrefix.length()+1;
ArrayList<String> fileList = new ArrayList<String>();
for (String file : fList) {
int index = file.indexOf(filePrefix);
if (index == -1) {
continue;
}
if (file.endsWith(".bak")) {
continue;
}
fileList.add(file);
}
return fileList;
|
public void | notePauseComponent(android.content.ComponentName componentName)
enforceCallingPermission();
String pkgName;
if ((componentName == null) ||
((pkgName = componentName.getPackageName()) == null)) {
return;
}
if ((mResumedPkg == null) || (!pkgName.equalsIgnoreCase(mResumedPkg))) {
Log.w(TAG, "Something wrong here, Didn't expect "+pkgName+" to be paused");
return;
}
if (localLOGV) Log.i(TAG, "paused component:"+pkgName);
synchronized (mStatsLock) {
PkgUsageStatsExtended pus = mStats.get(pkgName);
if (pus == null) {
// Weird some error here
Log.w(TAG, "No package stats for pkg:"+pkgName);
return;
}
pus.updatePause();
}
// Persist data to file
writeStatsToFile();
|
public void | noteResumeComponent(android.content.ComponentName componentName)
enforceCallingPermission();
String pkgName;
if ((componentName == null) ||
((pkgName = componentName.getPackageName()) == null)) {
return;
}
if ((mResumedPkg != null) && (mResumedPkg.equalsIgnoreCase(pkgName))) {
// Moving across activities in same package. just return
return;
}
if (localLOGV) Log.i(TAG, "started component:"+pkgName);
synchronized (mStatsLock) {
PkgUsageStatsExtended pus = mStats.get(pkgName);
if (pus == null) {
pus = new PkgUsageStatsExtended();
mStats.put(pkgName, pus);
}
pus.updateResume();
}
mResumedPkg = pkgName;
|
public void | publish(android.content.Context context)
mContext = context;
ServiceManager.addService(SERVICE_NAME, asBinder());
|
static byte[] | readFully(java.io.FileInputStream stream)
int pos = 0;
int avail = stream.available();
byte[] data = new byte[avail];
while (true) {
int amt = stream.read(data, pos, data.length-pos);
if (amt <= 0) {
return data;
}
pos += amt;
avail = stream.available();
if (avail > data.length-pos) {
byte[] newData = new byte[pos+avail];
System.arraycopy(data, 0, newData, 0, pos);
data = newData;
}
}
|
private void | readStatsFLOCK(java.io.File file)
Parcel in = getParcelForFile(file);
while (in.dataAvail() > 0) {
String pkgName = in.readString();
PkgUsageStatsExtended pus = new PkgUsageStatsExtended();
pus.mLaunchCount = in.readInt();
pus.mUsageTime = in.readLong();
synchronized (mStatsLock) {
mStats.put(pkgName, pus);
}
}
|
private void | readStatsFromFile()
File newFile = mFile;
synchronized (mFileLock) {
try {
if (newFile.exists()) {
readStatsFLOCK(newFile);
} else {
// Check for file limit before creating a new file
checkFileLimitFLOCK();
newFile.createNewFile();
}
} catch (IOException e) {
Log.w(TAG,"Error : " + e + " reading data from file:" + newFile);
}
}
|
private static boolean | scanArgs(java.lang.String[] args, java.lang.String value)Searches array of arguments for the specified string
if (args != null) {
for (String arg : args) {
if (value.equals(arg)) {
return true;
}
}
}
return false;
|
private void | writeStatsFLOCK()
FileOutputStream stream = new FileOutputStream(mFile);
Parcel out = Parcel.obtain();
writeStatsToParcelFLOCK(out);
stream.write(out.marshall());
out.recycle();
stream.flush();
stream.close();
|
private void | writeStatsToFile()
synchronized (mFileLock) {
long currTime = new Date().getTime();
boolean dayChanged = ((currTime - mLastTime) >= (24*60*60*1000));
long currRealTime = SystemClock.elapsedRealtime();
if (((currRealTime-mLastWriteRealTime) < _FILE_WRITE_INTERVAL) &&
(!dayChanged)) {
// wait till the next update
return;
}
// Get the most recent file
String todayStr = getCurrentDateStr(mFilePrefix);
// Copy current file to back up
File backupFile = new File(mFile.getPath() + ".bak");
mFile.renameTo(backupFile);
try {
checkFileLimitFLOCK();
mFile.createNewFile();
// Write mStats to file
writeStatsFLOCK();
mLastWriteRealTime = currRealTime;
mLastTime = currTime;
if (dayChanged) {
// clear stats
synchronized (mStats) {
mStats.clear();
}
mFile = new File(todayStr);
}
// Delete the backup file
if (backupFile != null) {
backupFile.delete();
}
} catch (IOException e) {
Log.w(TAG, "Failed writing stats to file:" + mFile);
if (backupFile != null) {
backupFile.renameTo(mFile);
}
}
}
|
private void | writeStatsToParcelFLOCK(android.os.Parcel out)
synchronized (mStatsLock) {
Set<String> keys = mStats.keySet();
for (String key : keys) {
PkgUsageStatsExtended pus = mStats.get(key);
out.writeString(key);
out.writeInt(pus.mLaunchCount);
out.writeLong(pus.mUsageTime);
}
}
|