* commit 'e3cceef7ececdac1c6df65d3f7a1557ac3ce5e3c': Minor cleanup of UsageStatsService
This commit is contained in:
@@ -75,42 +75,44 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
private static final boolean localLOGV = false;
|
private static final boolean localLOGV = false;
|
||||||
private static final boolean REPORT_UNEXPECTED = false;
|
private static final boolean REPORT_UNEXPECTED = false;
|
||||||
private static final String TAG = "UsageStats";
|
private static final String TAG = "UsageStats";
|
||||||
|
|
||||||
// Current on-disk Parcel version
|
// Current on-disk Parcel version
|
||||||
private static final int VERSION = 1008;
|
private static final int VERSION = 1008;
|
||||||
|
|
||||||
private static final int CHECKIN_VERSION = 4;
|
private static final int CHECKIN_VERSION = 4;
|
||||||
|
|
||||||
private static final String FILE_PREFIX = "usage-";
|
private static final String FILE_PREFIX = "usage-";
|
||||||
|
|
||||||
private static final String FILE_HISTORY = FILE_PREFIX + "history.xml";
|
private static final String FILE_HISTORY = FILE_PREFIX + "history.xml";
|
||||||
|
|
||||||
private static final int FILE_WRITE_INTERVAL = 30*60*1000; //ms
|
private static final int FILE_WRITE_INTERVAL = (localLOGV) ? 0 : 30*60*1000; // 30m in ms
|
||||||
|
|
||||||
private static final int MAX_NUM_FILES = 5;
|
private static final int MAX_NUM_FILES = 5;
|
||||||
|
|
||||||
private static final int NUM_LAUNCH_TIME_BINS = 10;
|
private static final int NUM_LAUNCH_TIME_BINS = 10;
|
||||||
private static final int[] LAUNCH_TIME_BINS = {
|
private static final int[] LAUNCH_TIME_BINS = {
|
||||||
250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000
|
250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000
|
||||||
};
|
};
|
||||||
|
|
||||||
static IUsageStats sService;
|
static IUsageStats sService;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
// structure used to maintain statistics since the last checkin.
|
// structure used to maintain statistics since the last checkin.
|
||||||
final private ArrayMap<String, PkgUsageStatsExtended> mStats;
|
final private ArrayMap<String, PkgUsageStatsExtended> mStats
|
||||||
|
= new ArrayMap<String, PkgUsageStatsExtended>();
|
||||||
|
|
||||||
// Maintains the last time any component was resumed, for all time.
|
// Maintains the last time any component was resumed, for all time.
|
||||||
final private ArrayMap<String, ArrayMap<String, Long>> mLastResumeTimes;
|
final private ArrayMap<String, ArrayMap<String, Long>> mLastResumeTimes
|
||||||
|
= new ArrayMap<String, ArrayMap<String, Long>>();
|
||||||
|
|
||||||
// To remove last-resume time stats when a pacakge is removed.
|
// To remove last-resume time stats when a pacakge is removed.
|
||||||
private PackageMonitor mPackageMonitor;
|
private PackageMonitor mPackageMonitor;
|
||||||
|
|
||||||
// Lock to update package stats. Methods suffixed by SLOCK should invoked with
|
// Lock to update package stats. Methods suffixed by SLOCK should invoked with
|
||||||
// this lock held
|
// this lock held
|
||||||
final Object mStatsLock;
|
final Object mStatsLock = new Object();
|
||||||
// Lock to write to file. Methods suffixed by FLOCK should invoked with
|
// Lock to write to file. Methods suffixed by FLOCK should invoked with
|
||||||
// this lock held.
|
// this lock held.
|
||||||
final Object mFileLock;
|
final Object mFileLock = new Object();
|
||||||
// Order of locks is mFileLock followed by mStatsLock to avoid deadlocks
|
// Order of locks is mFileLock followed by mStatsLock to avoid deadlocks
|
||||||
private String mLastResumedPkg;
|
private String mLastResumedPkg;
|
||||||
private String mLastResumedComp;
|
private String mLastResumedComp;
|
||||||
@@ -120,52 +122,53 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
private String mFileLeaf;
|
private String mFileLeaf;
|
||||||
private File mDir;
|
private File mDir;
|
||||||
|
|
||||||
private Calendar mCal; // guarded by itself
|
private final Calendar mCal // guarded by itself
|
||||||
|
= Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
|
||||||
|
|
||||||
private final AtomicInteger mLastWriteDay = new AtomicInteger(-1);
|
private final AtomicInteger mLastWriteDay = new AtomicInteger(-1);
|
||||||
private final AtomicLong mLastWriteElapsedTime = new AtomicLong(0);
|
private final AtomicLong mLastWriteElapsedTime = new AtomicLong(0);
|
||||||
private final AtomicBoolean mUnforcedDiskWriteRunning = new AtomicBoolean(false);
|
private final AtomicBoolean mUnforcedDiskWriteRunning = new AtomicBoolean(false);
|
||||||
|
|
||||||
static class TimeStats {
|
static class TimeStats {
|
||||||
int count;
|
int mCount;
|
||||||
int[] times = new int[NUM_LAUNCH_TIME_BINS];
|
final int[] mTimes = new int[NUM_LAUNCH_TIME_BINS];
|
||||||
|
|
||||||
TimeStats() {
|
TimeStats() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void incCount() {
|
void incCount() {
|
||||||
count++;
|
mCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(int val) {
|
void add(int val) {
|
||||||
final int[] bins = LAUNCH_TIME_BINS;
|
final int[] bins = LAUNCH_TIME_BINS;
|
||||||
for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) {
|
for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) {
|
||||||
if (val < bins[i]) {
|
if (val < bins[i]) {
|
||||||
times[i]++;
|
mTimes[i]++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
times[NUM_LAUNCH_TIME_BINS-1]++;
|
mTimes[NUM_LAUNCH_TIME_BINS-1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeStats(Parcel in) {
|
TimeStats(Parcel in) {
|
||||||
count = in.readInt();
|
mCount = in.readInt();
|
||||||
final int[] localTimes = times;
|
final int[] localTimes = mTimes;
|
||||||
for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
|
for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
|
||||||
localTimes[i] = in.readInt();
|
localTimes[i] = in.readInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToParcel(Parcel out) {
|
void writeToParcel(Parcel out) {
|
||||||
out.writeInt(count);
|
out.writeInt(mCount);
|
||||||
final int[] localTimes = times;
|
final int[] localTimes = mTimes;
|
||||||
for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
|
for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
|
||||||
out.writeInt(localTimes[i]);
|
out.writeInt(localTimes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PkgUsageStatsExtended {
|
static class PkgUsageStatsExtended {
|
||||||
final ArrayMap<String, TimeStats> mLaunchTimes
|
final ArrayMap<String, TimeStats> mLaunchTimes
|
||||||
= new ArrayMap<String, TimeStats>();
|
= new ArrayMap<String, TimeStats>();
|
||||||
final ArrayMap<String, TimeStats> mFullyDrawnTimes
|
final ArrayMap<String, TimeStats> mFullyDrawnTimes
|
||||||
@@ -174,18 +177,18 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
long mUsageTime;
|
long mUsageTime;
|
||||||
long mPausedTime;
|
long mPausedTime;
|
||||||
long mResumedTime;
|
long mResumedTime;
|
||||||
|
|
||||||
PkgUsageStatsExtended() {
|
PkgUsageStatsExtended() {
|
||||||
mLaunchCount = 0;
|
mLaunchCount = 0;
|
||||||
mUsageTime = 0;
|
mUsageTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PkgUsageStatsExtended(Parcel in) {
|
PkgUsageStatsExtended(Parcel in) {
|
||||||
mLaunchCount = in.readInt();
|
mLaunchCount = in.readInt();
|
||||||
mUsageTime = in.readLong();
|
mUsageTime = in.readLong();
|
||||||
if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount
|
if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount
|
||||||
+ ", Usage time:" + mUsageTime);
|
+ ", Usage time:" + mUsageTime);
|
||||||
|
|
||||||
final int numLaunchTimeStats = in.readInt();
|
final int numLaunchTimeStats = in.readInt();
|
||||||
if (localLOGV) Slog.v(TAG, "Reading launch times: " + numLaunchTimeStats);
|
if (localLOGV) Slog.v(TAG, "Reading launch times: " + numLaunchTimeStats);
|
||||||
mLaunchTimes.ensureCapacity(numLaunchTimeStats);
|
mLaunchTimes.ensureCapacity(numLaunchTimeStats);
|
||||||
@@ -209,16 +212,16 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
|
|
||||||
void updateResume(String comp, boolean launched) {
|
void updateResume(String comp, boolean launched) {
|
||||||
if (launched) {
|
if (launched) {
|
||||||
mLaunchCount ++;
|
mLaunchCount++;
|
||||||
}
|
}
|
||||||
mResumedTime = SystemClock.elapsedRealtime();
|
mResumedTime = SystemClock.elapsedRealtime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePause() {
|
void updatePause() {
|
||||||
mPausedTime = SystemClock.elapsedRealtime();
|
mPausedTime = SystemClock.elapsedRealtime();
|
||||||
mUsageTime += (mPausedTime - mResumedTime);
|
mUsageTime += (mPausedTime - mResumedTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLaunchCount(String comp) {
|
void addLaunchCount(String comp) {
|
||||||
TimeStats times = mLaunchTimes.get(comp);
|
TimeStats times = mLaunchTimes.get(comp);
|
||||||
if (times == null) {
|
if (times == null) {
|
||||||
@@ -227,7 +230,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
times.incCount();
|
times.incCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLaunchTime(String comp, int millis) {
|
void addLaunchTime(String comp, int millis) {
|
||||||
TimeStats times = mLaunchTimes.get(comp);
|
TimeStats times = mLaunchTimes.get(comp);
|
||||||
if (times == null) {
|
if (times == null) {
|
||||||
@@ -262,7 +265,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
mFullyDrawnTimes.valueAt(i).writeToParcel(out);
|
mFullyDrawnTimes.valueAt(i).writeToParcel(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
mLaunchTimes.clear();
|
mLaunchTimes.clear();
|
||||||
mFullyDrawnTimes.clear();
|
mFullyDrawnTimes.clear();
|
||||||
@@ -270,32 +273,25 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
mUsageTime = 0;
|
mUsageTime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UsageStatsService(String dir) {
|
UsageStatsService(String dir) {
|
||||||
mStats = new ArrayMap<String, PkgUsageStatsExtended>();
|
if (localLOGV) Slog.v(TAG, "UsageStatsService: " + dir);
|
||||||
mLastResumeTimes = new ArrayMap<String, ArrayMap<String, Long>>();
|
|
||||||
mStatsLock = new Object();
|
|
||||||
mFileLock = new Object();
|
|
||||||
mDir = new File(dir);
|
mDir = new File(dir);
|
||||||
mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
|
|
||||||
|
|
||||||
mDir.mkdir();
|
mDir.mkdir();
|
||||||
|
|
||||||
// Remove any old usage files from previous versions.
|
// Remove any old /data/system/usagestats.* files from previous versions.
|
||||||
File parentDir = mDir.getParentFile();
|
File parentDir = mDir.getParentFile();
|
||||||
String fList[] = parentDir.list();
|
String files[] = parentDir.list();
|
||||||
if (fList != null) {
|
if (files != null) {
|
||||||
String prefix = mDir.getName() + ".";
|
String prefix = mDir.getName() + ".";
|
||||||
int i = fList.length;
|
for (String file : files) {
|
||||||
while (i > 0) {
|
if (file.startsWith(prefix)) {
|
||||||
i--;
|
Slog.i(TAG, "Deleting old usage file: " + file);
|
||||||
if (fList[i].startsWith(prefix)) {
|
(new File(parentDir, file)).delete();
|
||||||
Slog.i(TAG, "Deleting old usage file: " + fList[i]);
|
|
||||||
(new File(parentDir, fList[i])).delete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current stats which are binned by date
|
// Update current stats which are binned by date
|
||||||
mFileLeaf = getCurrentDateStr(FILE_PREFIX);
|
mFileLeaf = getCurrentDateStr(FILE_PREFIX);
|
||||||
mFile = new File(mDir, mFileLeaf);
|
mFile = new File(mDir, mFileLeaf);
|
||||||
@@ -312,11 +308,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
*/
|
*/
|
||||||
private String getCurrentDateStr(String prefix) {
|
private String getCurrentDateStr(String prefix) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (prefix != null) {
|
||||||
|
sb.append(prefix);
|
||||||
|
}
|
||||||
synchronized (mCal) {
|
synchronized (mCal) {
|
||||||
mCal.setTimeInMillis(System.currentTimeMillis());
|
mCal.setTimeInMillis(System.currentTimeMillis());
|
||||||
if (prefix != null) {
|
|
||||||
sb.append(prefix);
|
|
||||||
}
|
|
||||||
sb.append(mCal.get(Calendar.YEAR));
|
sb.append(mCal.get(Calendar.YEAR));
|
||||||
int mm = mCal.get(Calendar.MONTH) - Calendar.JANUARY +1;
|
int mm = mCal.get(Calendar.MONTH) - Calendar.JANUARY +1;
|
||||||
if (mm < 10) {
|
if (mm < 10) {
|
||||||
@@ -331,17 +327,20 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Parcel getParcelForFile(File file) throws IOException {
|
private Parcel getParcelForFile(File file) throws IOException {
|
||||||
FileInputStream stream = new FileInputStream(file);
|
FileInputStream stream = new FileInputStream(file);
|
||||||
byte[] raw = readFully(stream);
|
try {
|
||||||
Parcel in = Parcel.obtain();
|
byte[] raw = readFully(stream);
|
||||||
in.unmarshall(raw, 0, raw.length);
|
Parcel in = Parcel.obtain();
|
||||||
in.setDataPosition(0);
|
in.unmarshall(raw, 0, raw.length);
|
||||||
stream.close();
|
in.setDataPosition(0);
|
||||||
return in;
|
return in;
|
||||||
|
} finally {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readStatsFromFile() {
|
private void readStatsFromFile() {
|
||||||
File newFile = mFile;
|
File newFile = mFile;
|
||||||
synchronized (mFileLock) {
|
synchronized (mFileLock) {
|
||||||
@@ -358,12 +357,13 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readStatsFLOCK(File file) throws IOException {
|
private void readStatsFLOCK(File file) throws IOException {
|
||||||
Parcel in = getParcelForFile(file);
|
Parcel in = getParcelForFile(file);
|
||||||
int vers = in.readInt();
|
int vers = in.readInt();
|
||||||
if (vers != VERSION) {
|
if (vers != VERSION) { // vers will be 0 if the parcel file was empty
|
||||||
Slog.w(TAG, "Usage stats version changed; dropping");
|
Slog.w(TAG, "Usage stats version of " + file + " changed from " + vers + " to "
|
||||||
|
+ VERSION + "; dropping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int N = in.readInt();
|
int N = in.readInt();
|
||||||
@@ -384,12 +384,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
private void readHistoryStatsFromFile() {
|
private void readHistoryStatsFromFile() {
|
||||||
synchronized (mFileLock) {
|
synchronized (mFileLock) {
|
||||||
if (mHistoryFile.getBaseFile().exists()) {
|
if (mHistoryFile.getBaseFile().exists()) {
|
||||||
readHistoryStatsFLOCK(mHistoryFile);
|
readHistoryStatsFLOCK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readHistoryStatsFLOCK(AtomicFile file) {
|
private void readHistoryStatsFLOCK() {
|
||||||
FileInputStream fis = null;
|
FileInputStream fis = null;
|
||||||
try {
|
try {
|
||||||
fis = mHistoryFile.openRead();
|
fis = mHistoryFile.openRead();
|
||||||
@@ -472,12 +472,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
return fileList;
|
return fileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFileLimitFLOCK() {
|
private void checkFileLimitFLOCK() {
|
||||||
// Get all usage stats output files
|
// Get all usage stats output files
|
||||||
ArrayList<String> fileList = getUsageStatsFileListFLOCK();
|
ArrayList<String> fileList = getUsageStatsFileListFLOCK();
|
||||||
if (fileList == null) {
|
if (fileList == null) {
|
||||||
// Strange but we dont have to delete any thing
|
// Empty /data/system/usagestats/ so we don't have anything to delete
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int count = fileList.size();
|
int count = fileList.size();
|
||||||
@@ -577,8 +577,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dayChanged || forceWriteHistoryStats) {
|
if (dayChanged || forceWriteHistoryStats) {
|
||||||
// Write history stats daily, or when forced (due to shutdown).
|
// Write history stats daily or when forced (due to shutdown) or when debugging.
|
||||||
writeHistoryStatsFLOCK(mHistoryFile);
|
writeHistoryStatsFLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the backup file
|
// Delete the backup file
|
||||||
@@ -640,10 +640,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeHistoryStatsFLOCK(AtomicFile historyFile) {
|
private void writeHistoryStatsFLOCK() {
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
try {
|
try {
|
||||||
fos = historyFile.startWrite();
|
fos = mHistoryFile.startWrite();
|
||||||
XmlSerializer out = new FastXmlSerializer();
|
XmlSerializer out = new FastXmlSerializer();
|
||||||
out.setOutput(fos, "utf-8");
|
out.setOutput(fos, "utf-8");
|
||||||
out.startDocument(null, true);
|
out.startDocument(null, true);
|
||||||
@@ -666,11 +666,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
out.endTag(null, "usage-history");
|
out.endTag(null, "usage-history");
|
||||||
out.endDocument();
|
out.endDocument();
|
||||||
|
|
||||||
historyFile.finishWrite(fos);
|
mHistoryFile.finishWrite(fos);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.w(TAG,"Error writing history stats" + e);
|
Slog.w(TAG,"Error writing history stats" + e);
|
||||||
if (fos != null) {
|
if (fos != null) {
|
||||||
historyFile.failWrite(fos);
|
mHistoryFile.failWrite(fos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -713,7 +713,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
sService = asInterface(b);
|
sService = asInterface(b);
|
||||||
return sService;
|
return sService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void noteResumeComponent(ComponentName componentName) {
|
public void noteResumeComponent(ComponentName componentName) {
|
||||||
enforceCallingPermission();
|
enforceCallingPermission();
|
||||||
String pkgName;
|
String pkgName;
|
||||||
@@ -722,7 +723,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
((pkgName = componentName.getPackageName()) == null)) {
|
((pkgName = componentName.getPackageName()) == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean samePackage = pkgName.equals(mLastResumedPkg);
|
final boolean samePackage = pkgName.equals(mLastResumedPkg);
|
||||||
if (mIsResumed) {
|
if (mIsResumed) {
|
||||||
if (mLastResumedPkg != null) {
|
if (mLastResumedPkg != null) {
|
||||||
@@ -736,14 +737,14 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean sameComp = samePackage
|
final boolean sameComp = samePackage
|
||||||
&& componentName.getClassName().equals(mLastResumedComp);
|
&& componentName.getClassName().equals(mLastResumedComp);
|
||||||
|
|
||||||
mIsResumed = true;
|
mIsResumed = true;
|
||||||
mLastResumedPkg = pkgName;
|
mLastResumedPkg = pkgName;
|
||||||
mLastResumedComp = componentName.getClassName();
|
mLastResumedComp = componentName.getClassName();
|
||||||
|
|
||||||
if (localLOGV) Slog.i(TAG, "started component:" + pkgName);
|
if (localLOGV) Slog.i(TAG, "started component:" + pkgName);
|
||||||
PkgUsageStatsExtended pus = mStats.get(pkgName);
|
PkgUsageStatsExtended pus = mStats.get(pkgName);
|
||||||
if (pus == null) {
|
if (pus == null) {
|
||||||
@@ -764,9 +765,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void notePauseComponent(ComponentName componentName) {
|
public void notePauseComponent(ComponentName componentName) {
|
||||||
enforceCallingPermission();
|
enforceCallingPermission();
|
||||||
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
String pkgName;
|
String pkgName;
|
||||||
if ((componentName == null) ||
|
if ((componentName == null) ||
|
||||||
@@ -779,9 +781,9 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mIsResumed = false;
|
mIsResumed = false;
|
||||||
|
|
||||||
if (localLOGV) Slog.i(TAG, "paused component:"+pkgName);
|
if (localLOGV) Slog.i(TAG, "paused component:"+pkgName);
|
||||||
|
|
||||||
PkgUsageStatsExtended pus = mStats.get(pkgName);
|
PkgUsageStatsExtended pus = mStats.get(pkgName);
|
||||||
if (pus == null) {
|
if (pus == null) {
|
||||||
// Weird some error here
|
// Weird some error here
|
||||||
@@ -790,11 +792,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
pus.updatePause();
|
pus.updatePause();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Persist current data to file if needed.
|
// Persist current data to file if needed.
|
||||||
writeStatsToFile(false, false);
|
writeStatsToFile(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void noteLaunchTime(ComponentName componentName, int millis) {
|
public void noteLaunchTime(ComponentName componentName, int millis) {
|
||||||
enforceCallingPermission();
|
enforceCallingPermission();
|
||||||
String pkgName;
|
String pkgName;
|
||||||
@@ -802,10 +805,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
((pkgName = componentName.getPackageName()) == null)) {
|
((pkgName = componentName.getPackageName()) == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Persist current data to file if needed.
|
// Persist current data to file if needed.
|
||||||
writeStatsToFile(false, false);
|
writeStatsToFile(false, false);
|
||||||
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
PkgUsageStatsExtended pus = mStats.get(pkgName);
|
PkgUsageStatsExtended pus = mStats.get(pkgName);
|
||||||
if (pus != null) {
|
if (pus != null) {
|
||||||
@@ -813,7 +816,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void noteFullyDrawnTime(ComponentName componentName, int millis) {
|
public void noteFullyDrawnTime(ComponentName componentName, int millis) {
|
||||||
enforceCallingPermission();
|
enforceCallingPermission();
|
||||||
String pkgName;
|
String pkgName;
|
||||||
@@ -840,7 +843,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
|
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
|
||||||
Binder.getCallingPid(), Binder.getCallingUid(), null);
|
Binder.getCallingPid(), Binder.getCallingUid(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public PkgUsageStats getPkgUsageStats(ComponentName componentName) {
|
public PkgUsageStats getPkgUsageStats(ComponentName componentName) {
|
||||||
mContext.enforceCallingOrSelfPermission(
|
mContext.enforceCallingOrSelfPermission(
|
||||||
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
|
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
|
||||||
@@ -860,7 +864,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
return new PkgUsageStats(pkgName, launchCount, usageTime, lastResumeTimes);
|
return new PkgUsageStats(pkgName, launchCount, usageTime, lastResumeTimes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public PkgUsageStats[] getAllPkgUsageStats() {
|
public PkgUsageStats[] getAllPkgUsageStats() {
|
||||||
mContext.enforceCallingOrSelfPermission(
|
mContext.enforceCallingOrSelfPermission(
|
||||||
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
|
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
|
||||||
@@ -886,8 +891,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
return retArr;
|
return retArr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] readFully(FileInputStream stream) throws java.io.IOException {
|
static byte[] readFully(FileInputStream stream) throws IOException {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int avail = stream.available();
|
int avail = stream.available();
|
||||||
byte[] data = new byte[avail];
|
byte[] data = new byte[avail];
|
||||||
@@ -905,7 +910,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectDumpInfoFLOCK(PrintWriter pw, boolean isCompactOutput,
|
private void collectDumpInfoFLOCK(PrintWriter pw, boolean isCompactOutput,
|
||||||
boolean deleteAfterPrint, HashSet<String> packages) {
|
boolean deleteAfterPrint, HashSet<String> packages) {
|
||||||
List<String> fileList = getUsageStatsFileListFLOCK();
|
List<String> fileList = getUsageStatsFileListFLOCK();
|
||||||
@@ -934,15 +939,12 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
// Delete old file after collecting info only for checkin requests
|
// Delete old file after collecting info only for checkin requests
|
||||||
dFile.delete();
|
dFile.delete();
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : " + file);
|
|
||||||
return;
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : "+file);
|
Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : "+file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectDumpInfoFromParcelFLOCK(Parcel in, PrintWriter pw,
|
private void collectDumpInfoFromParcelFLOCK(Parcel in, PrintWriter pw,
|
||||||
String date, boolean isCompactOutput, HashSet<String> packages) {
|
String date, boolean isCompactOutput, HashSet<String> packages) {
|
||||||
StringBuilder sb = new StringBuilder(512);
|
StringBuilder sb = new StringBuilder(512);
|
||||||
@@ -953,19 +955,19 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
} else {
|
} else {
|
||||||
sb.append("Date: ");
|
sb.append("Date: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(date);
|
sb.append(date);
|
||||||
|
|
||||||
int vers = in.readInt();
|
int vers = in.readInt();
|
||||||
if (vers != VERSION) {
|
if (vers != VERSION) {
|
||||||
sb.append(" (old data version)");
|
sb.append(" (old data version)");
|
||||||
pw.println(sb.toString());
|
pw.println(sb.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.println(sb.toString());
|
pw.println(sb.toString());
|
||||||
int N = in.readInt();
|
int N = in.readInt();
|
||||||
|
|
||||||
while (N > 0) {
|
while (N > 0) {
|
||||||
N--;
|
N--;
|
||||||
String pkgName = in.readString();
|
String pkgName = in.readString();
|
||||||
@@ -992,10 +994,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
sb.append(activity);
|
sb.append(activity);
|
||||||
TimeStats times = pus.mLaunchTimes.valueAt(i);
|
TimeStats times = pus.mLaunchTimes.valueAt(i);
|
||||||
sb.append(',');
|
sb.append(',');
|
||||||
sb.append(times.count);
|
sb.append(times.mCount);
|
||||||
for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
|
for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
sb.append(times.times[j]);
|
sb.append(times.mTimes[j]);
|
||||||
}
|
}
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
}
|
}
|
||||||
@@ -1007,7 +1009,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
TimeStats times = pus.mFullyDrawnTimes.valueAt(i);
|
TimeStats times = pus.mFullyDrawnTimes.valueAt(i);
|
||||||
for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
|
for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
sb.append(times.times[j]);
|
sb.append(times.mTimes[j]);
|
||||||
}
|
}
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
}
|
}
|
||||||
@@ -1027,26 +1029,26 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
sb.append(pus.mLaunchTimes.keyAt(i));
|
sb.append(pus.mLaunchTimes.keyAt(i));
|
||||||
TimeStats times = pus.mLaunchTimes.valueAt(i);
|
TimeStats times = pus.mLaunchTimes.valueAt(i);
|
||||||
sb.append(": ");
|
sb.append(": ");
|
||||||
sb.append(times.count);
|
sb.append(times.mCount);
|
||||||
sb.append(" starts");
|
sb.append(" starts");
|
||||||
int lastBin = 0;
|
int lastBin = 0;
|
||||||
for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
|
for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
|
||||||
if (times.times[j] != 0) {
|
if (times.mTimes[j] != 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
sb.append(lastBin);
|
sb.append(lastBin);
|
||||||
sb.append('-');
|
sb.append('-');
|
||||||
sb.append(LAUNCH_TIME_BINS[j]);
|
sb.append(LAUNCH_TIME_BINS[j]);
|
||||||
sb.append("ms=");
|
sb.append("ms=");
|
||||||
sb.append(times.times[j]);
|
sb.append(times.mTimes[j]);
|
||||||
}
|
}
|
||||||
lastBin = LAUNCH_TIME_BINS[j];
|
lastBin = LAUNCH_TIME_BINS[j];
|
||||||
}
|
}
|
||||||
if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
|
if (times.mTimes[NUM_LAUNCH_TIME_BINS-1] != 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
sb.append(">=");
|
sb.append(">=");
|
||||||
sb.append(lastBin);
|
sb.append(lastBin);
|
||||||
sb.append("ms=");
|
sb.append("ms=");
|
||||||
sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
|
sb.append(times.mTimes[NUM_LAUNCH_TIME_BINS-1]);
|
||||||
}
|
}
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
}
|
}
|
||||||
@@ -1059,7 +1061,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
boolean needComma = false;
|
boolean needComma = false;
|
||||||
int lastBin = 0;
|
int lastBin = 0;
|
||||||
for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
|
for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
|
||||||
if (times.times[j] != 0) {
|
if (times.mTimes[j] != 0) {
|
||||||
if (needComma) {
|
if (needComma) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
} else {
|
} else {
|
||||||
@@ -1069,27 +1071,27 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
sb.append('-');
|
sb.append('-');
|
||||||
sb.append(LAUNCH_TIME_BINS[j]);
|
sb.append(LAUNCH_TIME_BINS[j]);
|
||||||
sb.append("ms=");
|
sb.append("ms=");
|
||||||
sb.append(times.times[j]);
|
sb.append(times.mTimes[j]);
|
||||||
}
|
}
|
||||||
lastBin = LAUNCH_TIME_BINS[j];
|
lastBin = LAUNCH_TIME_BINS[j];
|
||||||
}
|
}
|
||||||
if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
|
if (times.mTimes[NUM_LAUNCH_TIME_BINS-1] != 0) {
|
||||||
if (needComma) {
|
if (needComma) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
sb.append(">=");
|
sb.append(">=");
|
||||||
sb.append(lastBin);
|
sb.append(lastBin);
|
||||||
sb.append("ms=");
|
sb.append("ms=");
|
||||||
sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
|
sb.append(times.mTimes[NUM_LAUNCH_TIME_BINS-1]);
|
||||||
}
|
}
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.write(sb.toString());
|
pw.write(sb.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches array of arguments for the specified string
|
* Searches array of arguments for the specified string
|
||||||
* @param args array of argument strings
|
* @param args array of argument strings
|
||||||
@@ -1106,7 +1108,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches array of arguments for the specified string's data
|
* Searches array of arguments for the specified string's data
|
||||||
* @param args array of argument strings
|
* @param args array of argument strings
|
||||||
@@ -1125,11 +1127,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
/*
|
/*
|
||||||
* The data persisted to file is parsed and the stats are computed.
|
* The data persisted to file is parsed and the stats are computed.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
if (mContext.checkCallingPermission(android.Manifest.permission.DUMP)
|
if (mContext.checkCallingPermission(android.Manifest.permission.DUMP)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
@@ -1143,23 +1145,23 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c");
|
final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c");
|
||||||
final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d");
|
final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d");
|
||||||
final String rawPackages = scanArgsData(args, "--packages");
|
final String rawPackages = scanArgsData(args, "--packages");
|
||||||
|
|
||||||
// Make sure the current stats are written to the file. This
|
// Make sure the current stats are written to the file. This
|
||||||
// doesn't need to be done if we are deleting files after printing,
|
// doesn't need to be done if we are deleting files after printing,
|
||||||
// since it that case we won't print the current stats.
|
// since in that case we won't print the current stats.
|
||||||
if (!deleteAfterPrint) {
|
if (!deleteAfterPrint) {
|
||||||
writeStatsToFile(true, false);
|
writeStatsToFile(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<String> packages = null;
|
HashSet<String> packages = null;
|
||||||
if (rawPackages != null) {
|
if (rawPackages != null) {
|
||||||
if (!"*".equals(rawPackages)) {
|
if (!"*".equals(rawPackages)) {
|
||||||
// A * is a wildcard to show all packages.
|
// A * is a wildcard to show all packages.
|
||||||
String[] names = rawPackages.split(",");
|
String[] names = rawPackages.split(",");
|
||||||
|
if (names.length != 0) {
|
||||||
|
packages = new HashSet<String>();
|
||||||
|
}
|
||||||
for (String n : names) {
|
for (String n : names) {
|
||||||
if (packages == null) {
|
|
||||||
packages = new HashSet<String>();
|
|
||||||
}
|
|
||||||
packages.add(n);
|
packages.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1169,7 +1171,7 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
|||||||
Slog.w(TAG, "Checkin without packages");
|
Slog.w(TAG, "Checkin without packages");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mFileLock) {
|
synchronized (mFileLock) {
|
||||||
collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint, packages);
|
collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint, packages);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user