Loading services/java/com/android/server/am/UsageStatsService.java +81 −40 Original line number Diff line number Diff line Loading @@ -44,6 +44,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * This service collects the statistics associated with usage Loading Loading @@ -88,11 +91,13 @@ public final class UsageStatsService extends IUsageStats.Stub { private boolean mIsResumed; private File mFile; private String mFileLeaf; //private File mBackupFile; private long mLastWriteElapsedTime; private File mDir; private Calendar mCal; private int mLastWriteDay; private Calendar mCal; // guarded by itself private final AtomicInteger mLastWriteDay = new AtomicInteger(-1); private final AtomicLong mLastWriteElapsedTime = new AtomicLong(0); private final AtomicBoolean mUnforcedDiskWriteRunning = new AtomicBoolean(false); static class TimeStats { int count; Loading Loading @@ -241,17 +246,18 @@ public final class UsageStatsService extends IUsageStats.Stub { mFileLeaf = getCurrentDateStr(FILE_PREFIX); mFile = new File(mDir, mFileLeaf); readStatsFromFile(); mLastWriteElapsedTime = SystemClock.elapsedRealtime(); mLastWriteElapsedTime.set(SystemClock.elapsedRealtime()); // mCal was set by getCurrentDateStr(), want to use that same time. mLastWriteDay = mCal.get(Calendar.DAY_OF_YEAR); mLastWriteDay.set(mCal.get(Calendar.DAY_OF_YEAR)); } /* * Utility method to convert date into string. */ private String getCurrentDateStr(String prefix) { mCal.setTimeInMillis(System.currentTimeMillis()); StringBuilder sb = new StringBuilder(); synchronized (mCal) { mCal.setTimeInMillis(System.currentTimeMillis()); if (prefix != null) { sb.append(prefix); } Loading @@ -266,6 +272,7 @@ public final class UsageStatsService extends IUsageStats.Stub { sb.append("0"); } sb.append(dd); } return sb.toString(); } Loading Loading @@ -361,22 +368,55 @@ public final class UsageStatsService extends IUsageStats.Stub { } } private void writeStatsToFile(boolean force) { synchronized (mFileLock) { /** * Conditionally start up a disk write if it's been awhile, or the * day has rolled over. * * This is called indirectly from user-facing actions (when * 'force' is false) so it tries to be quick, without writing to * disk directly or acquiring heavy locks. * * @params force do an unconditional, synchronous stats flush * to disk on the current thread. */ private void writeStatsToFile(final boolean force) { int curDay; synchronized (mCal) { mCal.setTimeInMillis(System.currentTimeMillis()); final int curDay = mCal.get(Calendar.DAY_OF_YEAR); curDay = mCal.get(Calendar.DAY_OF_YEAR); } final boolean dayChanged = curDay != mLastWriteDay.get(); // Determine if the day changed... note that this will be wrong // if the year has changed but we are in the same day of year... // we can probably live with this. final boolean dayChanged = curDay != mLastWriteDay; long currElapsedTime = SystemClock.elapsedRealtime(); final long currElapsedTime = SystemClock.elapsedRealtime(); // Fast common path, without taking the often-contentious // mFileLock. if (!force) { if (((currElapsedTime-mLastWriteElapsedTime) < FILE_WRITE_INTERVAL) && (!dayChanged)) { if (!dayChanged && (currElapsedTime - mLastWriteElapsedTime.get()) < FILE_WRITE_INTERVAL) { // wait till the next update return; } if (mUnforcedDiskWriteRunning.compareAndSet(false, true)) { new Thread("UsageStatsService_DiskWriter") { public void run() { try { Slog.d(TAG, "Disk writer thread starting."); writeStatsToFile(true); } finally { mUnforcedDiskWriteRunning.set(false); Slog.d(TAG, "Disk writer thread ending."); } } }.start(); } return; } synchronized (mFileLock) { // Get the most recent file mFileLeaf = getCurrentDateStr(FILE_PREFIX); // Copy current file to back up Loading @@ -395,10 +435,10 @@ public final class UsageStatsService extends IUsageStats.Stub { try { // Write mStats to file writeStatsFLOCK(); mLastWriteElapsedTime = currElapsedTime; writeStatsFLOCK(mFile); mLastWriteElapsedTime.set(currElapsedTime); if (dayChanged) { mLastWriteDay = curDay; mLastWriteDay.set(curDay); // clear stats synchronized (mStats) { mStats.clear(); Loading @@ -418,10 +458,11 @@ public final class UsageStatsService extends IUsageStats.Stub { } } } Slog.d(TAG, "Dumped usage stats."); } private void writeStatsFLOCK() throws IOException { FileOutputStream stream = new FileOutputStream(mFile); private void writeStatsFLOCK(File file) throws IOException { FileOutputStream stream = new FileOutputStream(file); try { Parcel out = Parcel.obtain(); writeStatsToParcelFLOCK(out); Loading Loading
services/java/com/android/server/am/UsageStatsService.java +81 −40 Original line number Diff line number Diff line Loading @@ -44,6 +44,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * This service collects the statistics associated with usage Loading Loading @@ -88,11 +91,13 @@ public final class UsageStatsService extends IUsageStats.Stub { private boolean mIsResumed; private File mFile; private String mFileLeaf; //private File mBackupFile; private long mLastWriteElapsedTime; private File mDir; private Calendar mCal; private int mLastWriteDay; private Calendar mCal; // guarded by itself private final AtomicInteger mLastWriteDay = new AtomicInteger(-1); private final AtomicLong mLastWriteElapsedTime = new AtomicLong(0); private final AtomicBoolean mUnforcedDiskWriteRunning = new AtomicBoolean(false); static class TimeStats { int count; Loading Loading @@ -241,17 +246,18 @@ public final class UsageStatsService extends IUsageStats.Stub { mFileLeaf = getCurrentDateStr(FILE_PREFIX); mFile = new File(mDir, mFileLeaf); readStatsFromFile(); mLastWriteElapsedTime = SystemClock.elapsedRealtime(); mLastWriteElapsedTime.set(SystemClock.elapsedRealtime()); // mCal was set by getCurrentDateStr(), want to use that same time. mLastWriteDay = mCal.get(Calendar.DAY_OF_YEAR); mLastWriteDay.set(mCal.get(Calendar.DAY_OF_YEAR)); } /* * Utility method to convert date into string. */ private String getCurrentDateStr(String prefix) { mCal.setTimeInMillis(System.currentTimeMillis()); StringBuilder sb = new StringBuilder(); synchronized (mCal) { mCal.setTimeInMillis(System.currentTimeMillis()); if (prefix != null) { sb.append(prefix); } Loading @@ -266,6 +272,7 @@ public final class UsageStatsService extends IUsageStats.Stub { sb.append("0"); } sb.append(dd); } return sb.toString(); } Loading Loading @@ -361,22 +368,55 @@ public final class UsageStatsService extends IUsageStats.Stub { } } private void writeStatsToFile(boolean force) { synchronized (mFileLock) { /** * Conditionally start up a disk write if it's been awhile, or the * day has rolled over. * * This is called indirectly from user-facing actions (when * 'force' is false) so it tries to be quick, without writing to * disk directly or acquiring heavy locks. * * @params force do an unconditional, synchronous stats flush * to disk on the current thread. */ private void writeStatsToFile(final boolean force) { int curDay; synchronized (mCal) { mCal.setTimeInMillis(System.currentTimeMillis()); final int curDay = mCal.get(Calendar.DAY_OF_YEAR); curDay = mCal.get(Calendar.DAY_OF_YEAR); } final boolean dayChanged = curDay != mLastWriteDay.get(); // Determine if the day changed... note that this will be wrong // if the year has changed but we are in the same day of year... // we can probably live with this. final boolean dayChanged = curDay != mLastWriteDay; long currElapsedTime = SystemClock.elapsedRealtime(); final long currElapsedTime = SystemClock.elapsedRealtime(); // Fast common path, without taking the often-contentious // mFileLock. if (!force) { if (((currElapsedTime-mLastWriteElapsedTime) < FILE_WRITE_INTERVAL) && (!dayChanged)) { if (!dayChanged && (currElapsedTime - mLastWriteElapsedTime.get()) < FILE_WRITE_INTERVAL) { // wait till the next update return; } if (mUnforcedDiskWriteRunning.compareAndSet(false, true)) { new Thread("UsageStatsService_DiskWriter") { public void run() { try { Slog.d(TAG, "Disk writer thread starting."); writeStatsToFile(true); } finally { mUnforcedDiskWriteRunning.set(false); Slog.d(TAG, "Disk writer thread ending."); } } }.start(); } return; } synchronized (mFileLock) { // Get the most recent file mFileLeaf = getCurrentDateStr(FILE_PREFIX); // Copy current file to back up Loading @@ -395,10 +435,10 @@ public final class UsageStatsService extends IUsageStats.Stub { try { // Write mStats to file writeStatsFLOCK(); mLastWriteElapsedTime = currElapsedTime; writeStatsFLOCK(mFile); mLastWriteElapsedTime.set(currElapsedTime); if (dayChanged) { mLastWriteDay = curDay; mLastWriteDay.set(curDay); // clear stats synchronized (mStats) { mStats.clear(); Loading @@ -418,10 +458,11 @@ public final class UsageStatsService extends IUsageStats.Stub { } } } Slog.d(TAG, "Dumped usage stats."); } private void writeStatsFLOCK() throws IOException { FileOutputStream stream = new FileOutputStream(mFile); private void writeStatsFLOCK(File file) throws IOException { FileOutputStream stream = new FileOutputStream(file); try { Parcel out = Parcel.obtain(); writeStatsToParcelFLOCK(out); Loading