19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006-2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server.am; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.app.IUsageStats; 2055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.os.PkgUsageStats; 268bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn 278bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackbornimport android.os.FileUtils; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 328a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 449fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackbornimport java.util.HashSet; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 486447ca30b8e41c22c7214f201120327057e356dcDianne Hackbornimport java.util.TimeZone; 49389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrickimport java.util.concurrent.atomic.AtomicBoolean; 50389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrickimport java.util.concurrent.atomic.AtomicInteger; 51389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrickimport java.util.concurrent.atomic.AtomicLong; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This service collects the statistics associated with usage 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of various components, like when a particular package is launched or 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * paused and aggregates events like number of time a component is launched 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * total duration of a component launch. 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class UsageStatsService extends IUsageStats.Stub { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SERVICE_NAME = "usagestats"; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean localLOGV = false; 62cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn private static final boolean REPORT_UNEXPECTED = false; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "UsageStats"; 646447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 656447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // Current on-disk Parcel version 66760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn private static final int VERSION = 1005; 676447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 68760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn private static final int CHECKIN_VERSION = 4; 696447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 706447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private static final String FILE_PREFIX = "usage-"; 716447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 726447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private static final int FILE_WRITE_INTERVAL = 30*60*1000; //ms 736447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 746447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private static final int MAX_NUM_FILES = 5; 756447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 76f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn private static final int NUM_LAUNCH_TIME_BINS = 10; 77f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn private static final int[] LAUNCH_TIME_BINS = { 78f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000 79f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn }; 806447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static IUsageStats sService; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // structure used to maintain statistics since the last checkin. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private Map<String, PkgUsageStatsExtended> mStats; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Lock to update package stats. Methods suffixed by SLOCK should invoked with 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this lock held 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mStatsLock; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Lock to write to file. Methods suffixed by FLOCK should invoked with 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this lock held. 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mFileLock; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Order of locks is mFileLock followed by mStatsLock to avoid deadlocks 92760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn private String mLastResumedPkg; 93760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn private String mLastResumedComp; 94760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn private boolean mIsResumed; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private File mFile; 966447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private String mFileLeaf; 976447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private File mDir; 98389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick 99389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick private Calendar mCal; // guarded by itself 100389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick 101389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick private final AtomicInteger mLastWriteDay = new AtomicInteger(-1); 102389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick private final AtomicLong mLastWriteElapsedTime = new AtomicLong(0); 103389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick private final AtomicBoolean mUnforcedDiskWriteRunning = new AtomicBoolean(false); 1046447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 1056447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn static class TimeStats { 106760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn int count; 107f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn int[] times = new int[NUM_LAUNCH_TIME_BINS]; 1086447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 109f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn TimeStats() { 110f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn } 1116447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 112760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn void incCount() { 113760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn count++; 114760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 115760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 1166447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn void add(int val) { 117f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn final int[] bins = LAUNCH_TIME_BINS; 118f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) { 119f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn if (val < bins[i]) { 120f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn times[i]++; 121f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn return; 1226447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1236447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 124f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn times[NUM_LAUNCH_TIME_BINS-1]++; 1256447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1266447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 127f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn TimeStats(Parcel in) { 128760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn count = in.readInt(); 129f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn final int[] localTimes = times; 130f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) { 131f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn localTimes[i] = in.readInt(); 1326447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 133f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn } 134f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn 135f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn void writeToParcel(Parcel out) { 136760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn out.writeInt(count); 137f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn final int[] localTimes = times; 138f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) { 139f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn out.writeInt(localTimes[i]); 1406447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1416447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1426447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class PkgUsageStatsExtended { 1456447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final HashMap<String, TimeStats> mLaunchTimes 1466447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn = new HashMap<String, TimeStats>(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLaunchCount; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mUsageTime; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mPausedTime; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mResumedTime; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStatsExtended() { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLaunchCount = 0; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsageTime = 0; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1566447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 1576447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn PkgUsageStatsExtended(Parcel in) { 1586447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mLaunchCount = in.readInt(); 1596447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mUsageTime = in.readLong(); 1608a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount 1616447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn + ", Usage time:" + mUsageTime); 1626447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 1636447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final int N = in.readInt(); 1648a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Reading comps: " + N); 1656447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn for (int i=0; i<N; i++) { 1666447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn String comp = in.readString(); 1678a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Component: " + comp); 168f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn TimeStats times = new TimeStats(in); 169f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn mLaunchTimes.put(comp, times); 1706447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1716447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 1726447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 173760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn void updateResume(boolean launched) { 174760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (launched) { 175760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn mLaunchCount ++; 176760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResumedTime = SystemClock.elapsedRealtime(); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1796447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void updatePause() { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPausedTime = SystemClock.elapsedRealtime(); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsageTime += (mPausedTime - mResumedTime); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1846447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 185760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn void addLaunchCount(String comp) { 186760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn TimeStats times = mLaunchTimes.get(comp); 187760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (times == null) { 188760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn times = new TimeStats(); 189760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn mLaunchTimes.put(comp, times); 190760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 191760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn times.incCount(); 192760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 193760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 1946447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn void addLaunchTime(String comp, int millis) { 1956447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn TimeStats times = mLaunchTimes.get(comp); 1966447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (times == null) { 1976447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn times = new TimeStats(); 1986447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mLaunchTimes.put(comp, times); 1996447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2006447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn times.add(millis); 2016447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2026447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 203f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn void writeToParcel(Parcel out) { 2046447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.writeInt(mLaunchCount); 2056447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.writeLong(mUsageTime); 2066447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final int N = mLaunchTimes.size(); 2076447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.writeInt(N); 2086447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (N > 0) { 2096447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn for (Map.Entry<String, TimeStats> ent : mLaunchTimes.entrySet()) { 2106447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.writeString(ent.getKey()); 2116447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn TimeStats times = ent.getValue(); 212f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn times.writeToParcel(out); 2136447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2146447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2156447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2166447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void clear() { 2186447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mLaunchTimes.clear(); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLaunchCount = 0; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUsageTime = 0; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2246447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn UsageStatsService(String dir) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStats = new HashMap<String, PkgUsageStatsExtended>(); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatsLock = new Object(); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLock = new Object(); 2286447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mDir = new File(dir); 2296447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0")); 2306447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 2316447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mDir.mkdir(); 2326447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 2336447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // Remove any old usage files from previous versions. 2346447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn File parentDir = mDir.getParentFile(); 2356447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn String fList[] = parentDir.list(); 2366447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (fList != null) { 2376447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn String prefix = mDir.getName() + "."; 2386447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn int i = fList.length; 2396447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn while (i > 0) { 2406447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn i--; 2416447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (fList[i].startsWith(prefix)) { 2428a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Deleting old usage file: " + fList[i]); 2436447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn (new File(parentDir, fList[i])).delete(); 2446447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2456447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2466447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 2476447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Update current stats which are binned by date 2496447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mFileLeaf = getCurrentDateStr(FILE_PREFIX); 2506447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mFile = new File(mDir, mFileLeaf); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project readStatsFromFile(); 252389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick mLastWriteElapsedTime.set(SystemClock.elapsedRealtime()); 2536447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // mCal was set by getCurrentDateStr(), want to use that same time. 254389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick mLastWriteDay.set(mCal.get(Calendar.DAY_OF_YEAR)); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Utility method to convert date into string. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String getCurrentDateStr(String prefix) { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder sb = new StringBuilder(); 262389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick synchronized (mCal) { 263389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick mCal.setTimeInMillis(System.currentTimeMillis()); 264389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick if (prefix != null) { 265389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick sb.append(prefix); 266389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 267389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick sb.append(mCal.get(Calendar.YEAR)); 268389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick int mm = mCal.get(Calendar.MONTH) - Calendar.JANUARY +1; 269389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick if (mm < 10) { 270389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick sb.append("0"); 271389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 272389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick sb.append(mm); 273389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick int dd = mCal.get(Calendar.DAY_OF_MONTH); 274389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick if (dd < 10) { 275389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick sb.append("0"); 276389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 277389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick sb.append(dd); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sb.toString(); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Parcel getParcelForFile(File file) throws IOException { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] raw = readFully(stream); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel in = Parcel.obtain(); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.unmarshall(raw, 0, raw.length); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.setDataPosition(0); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return in; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void readStatsFromFile() { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File newFile = mFile; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mFileLock) { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFile.exists()) { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project readStatsFLOCK(newFile); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check for file limit before creating a new file 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFileLimitFLOCK(); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newFile.createNewFile(); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3048a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG,"Error : " + e + " reading data from file:" + newFile); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void readStatsFLOCK(File file) throws IOException { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel in = getParcelForFile(file); 3116447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn int vers = in.readInt(); 3126447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (vers != VERSION) { 3138a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Usage stats version changed; dropping"); 3146447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn return; 3156447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 3166447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn int N = in.readInt(); 3176447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn while (N > 0) { 3186447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn N--; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkgName = in.readString(); 3206447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (pkgName == null) { 3216447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn break; 3226447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 3238a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Reading package #" + N + ": " + pkgName); 3246447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn PkgUsageStatsExtended pus = new PkgUsageStatsExtended(in); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStatsLock) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStats.put(pkgName, pus); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<String> getUsageStatsFileListFLOCK() { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if there are too many files in the system and delete older files 3336447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn String fList[] = mDir.list(); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fList == null) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<String> fileList = new ArrayList<String>(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String file : fList) { 3396447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (!file.startsWith(FILE_PREFIX)) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (file.endsWith(".bak")) { 3436447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn (new File(mDir, file)).delete(); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fileList.add(file); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fileList; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkFileLimitFLOCK() { 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get all usage stats output files 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<String> fileList = getUsageStatsFileListFLOCK(); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileList == null) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Strange but we dont have to delete any thing 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = fileList.size(); 3596447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (count <= MAX_NUM_FILES) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sort files 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(fileList); 3646447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn count -= MAX_NUM_FILES; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Delete older files 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String fileName = fileList.get(i); 3686447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn File file = new File(mDir, fileName); 3698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Deleting usage file : " + fileName); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project file.delete(); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 373389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick 374389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick /** 375389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * Conditionally start up a disk write if it's been awhile, or the 376389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * day has rolled over. 377389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * 378389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * This is called indirectly from user-facing actions (when 379389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * 'force' is false) so it tries to be quick, without writing to 380389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * disk directly or acquiring heavy locks. 381389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * 382389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * @params force do an unconditional, synchronous stats flush 383389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick * to disk on the current thread. 384389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick */ 385389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick private void writeStatsToFile(final boolean force) { 386389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick int curDay; 387389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick synchronized (mCal) { 3886447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mCal.setTimeInMillis(System.currentTimeMillis()); 389389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick curDay = mCal.get(Calendar.DAY_OF_YEAR); 390389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 391389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick final boolean dayChanged = curDay != mLastWriteDay.get(); 392389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick 393389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick // Determine if the day changed... note that this will be wrong 394389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick // if the year has changed but we are in the same day of year... 395389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick // we can probably live with this. 396389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick final long currElapsedTime = SystemClock.elapsedRealtime(); 397389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick 398389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick // Fast common path, without taking the often-contentious 399389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick // mFileLock. 400389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick if (!force) { 401389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick if (!dayChanged && 402389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick (currElapsedTime - mLastWriteElapsedTime.get()) < FILE_WRITE_INTERVAL) { 403389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick // wait till the next update 404389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick return; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 406389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick if (mUnforcedDiskWriteRunning.compareAndSet(false, true)) { 407389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick new Thread("UsageStatsService_DiskWriter") { 408389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick public void run() { 409389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick try { 410cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (localLOGV) Slog.d(TAG, "Disk writer thread starting."); 411389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick writeStatsToFile(true); 412389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } finally { 413389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick mUnforcedDiskWriteRunning.set(false); 414cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (localLOGV) Slog.d(TAG, "Disk writer thread ending."); 415389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 416389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 417389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick }.start(); 418389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 419389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick return; 420389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick } 421389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick 422389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick synchronized (mFileLock) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the most recent file 4246447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mFileLeaf = getCurrentDateStr(FILE_PREFIX); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Copy current file to back up 426be1c422a73cf70e1478a13463de5ab929991c619Suchi Amalapurapu File backupFile = null; 427be1c422a73cf70e1478a13463de5ab929991c619Suchi Amalapurapu if (mFile != null && mFile.exists()) { 428be1c422a73cf70e1478a13463de5ab929991c619Suchi Amalapurapu backupFile = new File(mFile.getPath() + ".bak"); 4291afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn if (!backupFile.exists()) { 4301afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn if (!mFile.renameTo(backupFile)) { 4311afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn Slog.w(TAG, "Failed to persist new stats"); 4321afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn return; 4331afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn } 4341afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn } else { 4351afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn mFile.delete(); 436be1c422a73cf70e1478a13463de5ab929991c619Suchi Amalapurapu } 4378550f255232eb4e4852466c5297fdc125887f5afSuchi Amalapurapu } 438be1c422a73cf70e1478a13463de5ab929991c619Suchi Amalapurapu 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Write mStats to file 441389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick writeStatsFLOCK(mFile); 442389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick mLastWriteElapsedTime.set(currElapsedTime); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dayChanged) { 444389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick mLastWriteDay.set(curDay); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // clear stats 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStats) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStats.clear(); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4496447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mFile = new File(mDir, mFileLeaf); 4506447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn checkFileLimitFLOCK(); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Delete the backup file 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (backupFile != null) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project backupFile.delete(); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4578a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed writing stats to file:" + mFile); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (backupFile != null) { 4596447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn mFile.delete(); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project backupFile.renameTo(mFile); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 464cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (localLOGV) Slog.d(TAG, "Dumped usage stats."); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 467389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick private void writeStatsFLOCK(File file) throws IOException { 468389a916769aaf4b329839285d2f975fc23aadfb4Brad Fitzpatrick FileOutputStream stream = new FileOutputStream(file); 4696447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn try { 4706447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn Parcel out = Parcel.obtain(); 471f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn writeStatsToParcelFLOCK(out); 4726447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn stream.write(out.marshall()); 4736447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.recycle(); 4746447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn stream.flush(); 4756447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } finally { 4768bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn FileUtils.sync(stream); 4776447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn stream.close(); 4786447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 481f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn private void writeStatsToParcelFLOCK(Parcel out) { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStatsLock) { 4836447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.writeInt(VERSION); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Set<String> keys = mStats.keySet(); 4856447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn out.writeInt(keys.size()); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : keys) { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStatsExtended pus = mStats.get(key); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.writeString(key); 489f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn pus.writeToParcel(out); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void publish(Context context) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.addService(SERVICE_NAME, asBinder()); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn public void shutdown() { 500cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Slog.i(TAG, "Writing usage stats before shutdown..."); 50155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn writeStatsToFile(true); 50255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 50355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static IUsageStats getService() { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sService != null) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sService; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder b = ServiceManager.getService(SERVICE_NAME); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sService = asInterface(b); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sService; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void noteResumeComponent(ComponentName componentName) { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceCallingPermission(); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkgName; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStatsLock) { 517760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if ((componentName == null) || 518760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn ((pkgName = componentName.getPackageName()) == null)) { 519760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn return; 520760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 521760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 522760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn final boolean samePackage = pkgName.equals(mLastResumedPkg); 523760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (mIsResumed) { 524760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (mLastResumedPkg != null) { 525760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn // We last resumed some other package... just pause it now 526760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn // to recover. 527cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (REPORT_UNEXPECTED) Slog.i(TAG, "Unexpected resume of " + pkgName 528760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn + " while already resumed in " + mLastResumedPkg); 529760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn PkgUsageStatsExtended pus = mStats.get(mLastResumedPkg); 530760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (pus != null) { 531760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn pus.updatePause(); 532760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 533760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 534760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 535760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 536760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn final boolean sameComp = samePackage 537760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn && componentName.getClassName().equals(mLastResumedComp); 538760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 539760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn mIsResumed = true; 540760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn mLastResumedPkg = pkgName; 541760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn mLastResumedComp = componentName.getClassName(); 542760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 5438a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.i(TAG, "started component:" + pkgName); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStatsExtended pus = mStats.get(pkgName); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pus == null) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pus = new PkgUsageStatsExtended(); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStats.put(pkgName, pus); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 549760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn pus.updateResume(!samePackage); 550760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (!sameComp) { 551760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn pus.addLaunchCount(mLastResumedComp); 552760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notePauseComponent(ComponentName componentName) { 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceCallingPermission(); 5586447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStatsLock) { 560760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn String pkgName; 561760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if ((componentName == null) || 562760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn ((pkgName = componentName.getPackageName()) == null)) { 563760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn return; 564760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 565760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn if (!mIsResumed) { 566cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (REPORT_UNEXPECTED) Slog.i(TAG, "Something wrong here, didn't expect " 567760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn + pkgName + " to be paused"); 568760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn return; 569760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn } 570760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn mIsResumed = false; 571760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 5728a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.i(TAG, "paused component:"+pkgName); 573760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStatsExtended pus = mStats.get(pkgName); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pus == null) { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Weird some error here 5778a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "No package stats for pkg:"+pkgName); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pus.updatePause(); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 582760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn 583760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn // Persist current data to file if needed. 584760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn writeStatsToFile(false); 5856447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 5866447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 5876447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn public void noteLaunchTime(ComponentName componentName, int millis) { 5886447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn enforceCallingPermission(); 5896447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn String pkgName; 5906447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if ((componentName == null) || 5916447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn ((pkgName = componentName.getPackageName()) == null)) { 5926447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn return; 5936447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 5946447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 5956447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // Persist current data to file if needed. 5966447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn writeStatsToFile(false); 5976447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 5986447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn synchronized (mStatsLock) { 5996447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn PkgUsageStatsExtended pus = mStats.get(pkgName); 6006447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (pus != null) { 6016447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn pus.addLaunchTime(componentName.getClassName(), millis); 6026447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 6036447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enforceCallingPermission() { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Binder.getCallingPid() == Process.myPid()) { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS, 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.getCallingPid(), Binder.getCallingUid(), null); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PkgUsageStats getPkgUsageStats(ComponentName componentName) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.PACKAGE_USAGE_STATS, null); 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkgName; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((componentName == null) || 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((pkgName = componentName.getPackageName()) == null)) { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStatsLock) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStatsExtended pus = mStats.get(pkgName); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pus == null) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new PkgUsageStats(pkgName, pus.mLaunchCount, pus.mUsageTime); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PkgUsageStats[] getAllPkgUsageStats() { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.PACKAGE_USAGE_STATS, null); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mStatsLock) { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Set<String> keys = mStats.keySet(); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = keys.size(); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size <= 0) { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStats retArr[] = new PkgUsageStats[size]; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key: keys) { 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PkgUsageStatsExtended pus = mStats.get(key); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retArr[i] = new PkgUsageStats(key, pus.mLaunchCount, pus.mUsageTime); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retArr; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static byte[] readFully(FileInputStream stream) throws java.io.IOException { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos = 0; 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int avail = stream.available(); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = new byte[avail]; 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int amt = stream.read(data, pos, data.length-pos); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (amt <= 0) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return data; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos += amt; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project avail = stream.available(); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (avail > data.length-pos) { 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] newData = new byte[pos+avail]; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(data, 0, newData, 0, pos); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = newData; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6706447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private void collectDumpInfoFLOCK(PrintWriter pw, boolean isCompactOutput, 6719fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn boolean deleteAfterPrint, HashSet<String> packages) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> fileList = getUsageStatsFileListFLOCK(); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileList == null) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(fileList); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String file : fileList) { 6786447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (deleteAfterPrint && file.equalsIgnoreCase(mFileLeaf)) { 6796447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // In this mode we don't print the current day's stats, since 6806447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // they are incomplete. 6816447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn continue; 6826447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 6836447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn File dFile = new File(mDir, file); 6846447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn String dateStr = file.substring(FILE_PREFIX.length()); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel in = getParcelForFile(dFile); 6879fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCompactOutput, 6889fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn packages); 6896447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (deleteAfterPrint) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Delete old file after collecting info only for checkin requests 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dFile.delete(); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (FileNotFoundException e) { 6948a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : " + file); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 6978a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed with "+e+" when collecting dump info from file : "+file); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void collectDumpInfoFromParcelFLOCK(Parcel in, PrintWriter pw, 7039fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn String date, boolean isCompactOutput, HashSet<String> packages) { 7046447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn StringBuilder sb = new StringBuilder(512); 7056447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (isCompactOutput) { 7066447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append("D:"); 7076447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(CHECKIN_VERSION); 7086447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(','); 7096447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } else { 7106447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append("Date: "); 7116447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 7126447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(date); 7146447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 7156447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn int vers = in.readInt(); 7166447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (vers != VERSION) { 7176447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(" (old data version)"); 7186447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn pw.println(sb.toString()); 7196447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn return; 7206447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 7216447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 7226447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn pw.println(sb.toString()); 7236447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn int N = in.readInt(); 7246447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 7256447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn while (N > 0) { 7266447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn N--; 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkgName = in.readString(); 7286447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (pkgName == null) { 7296447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn break; 7306447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 7316447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.setLength(0); 7326447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn PkgUsageStatsExtended pus = new PkgUsageStatsExtended(in); 7339fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn if (packages != null && !packages.contains(pkgName)) { 7349fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn // This package has not been requested -- don't print 7359fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn // anything for it. 7369fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } else if (isCompactOutput) { 7376447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append("P:"); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(pkgName); 739760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(','); 7406447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(pus.mLaunchCount); 741760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(','); 7426447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(pus.mUsageTime); 7436447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append('\n'); 7446447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final int NC = pus.mLaunchTimes.size(); 7456447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (NC > 0) { 7466447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn for (Map.Entry<String, TimeStats> ent : pus.mLaunchTimes.entrySet()) { 7476447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append("A:"); 7486639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag String activity = ent.getKey(); 7496639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag if (activity.startsWith(pkgName)) { 7506639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag sb.append('*'); 7516639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag sb.append(activity.substring( 7526639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag pkgName.length(), activity.length())); 7536639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag } else { 7546639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag sb.append(activity); 7556639bb65c5ebb9493afba6d701a22223ac45ba04Christian Sonntag } 7566447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn TimeStats times = ent.getValue(); 757760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(','); 758760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(times.count); 759f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) { 760f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(","); 761f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(times.times[i]); 762f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn } 7636447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append('\n'); 7646447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7666447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 7676447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } else { 7686447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(" "); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(pkgName); 7706447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(": "); 7716447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(pus.mLaunchCount); 7726447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(" times, "); 7736447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(pus.mUsageTime); 7746447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(" ms"); 7756447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append('\n'); 7766447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final int NC = pus.mLaunchTimes.size(); 7776447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (NC > 0) { 7786447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn for (Map.Entry<String, TimeStats> ent : pus.mLaunchTimes.entrySet()) { 7796447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(" "); 7806447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append(ent.getKey()); 7816447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn TimeStats times = ent.getValue(); 782760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(": "); 783760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(times.count); 784760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(" starts"); 785f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn int lastBin = 0; 786f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) { 787f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn if (times.times[i] != 0) { 788760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(", "); 789f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(lastBin); 790f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append('-'); 791f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(LAUNCH_TIME_BINS[i]); 792760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append("ms="); 793f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(times.times[i]); 794f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn } 795f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn lastBin = LAUNCH_TIME_BINS[i]; 796f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn } 797f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) { 798760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append(", "); 799f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(">="); 800f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(lastBin); 801760ec4a095567457707abe764cf4dfda0ed84032Dianne Hackborn sb.append("ms="); 802f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]); 803f210d6b75e2c0fe60b90c074ff9f615c1137f23eDianne Hackborn } 8046447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn sb.append('\n'); 8056447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 8066447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8086447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 8096447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn pw.write(sb.toString()); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Searches array of arguments for the specified string 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param args array of argument strings 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param value value to search for 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the value is contained in the array 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean scanArgs(String[] args, String value) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (args != null) { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String arg : args) { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.equals(arg)) { 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn /** 8319fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn * Searches array of arguments for the specified string's data 8329fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn * @param args array of argument strings 8339fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn * @param value value to search for 8349fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn * @return the string of data after the arg, or null if there is none 8359fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn */ 8369fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn private static String scanArgsData(String[] args, String value) { 8379fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn if (args != null) { 8389fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn final int N = args.length; 8399fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn for (int i=0; i<N; i++) { 8409fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn if (value.equals(args[i])) { 8419fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn i++; 8429fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn return i < N ? args[i] : null; 8439fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8449fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8459fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8469fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn return null; 8479fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8489fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The data persisted to file is parsed and the stats are computed. 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8546447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final boolean isCheckinRequest = scanArgs(args, "--checkin"); 8556447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c"); 8566447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d"); 8579fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn final String rawPackages = scanArgsData(args, "--packages"); 8586447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 8596447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // Make sure the current stats are written to the file. This 8606447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // doesn't need to be done if we are deleting files after printing, 8616447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn // since it that case we won't print the current stats. 8626447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn if (!deleteAfterPrint) { 8636447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn writeStatsToFile(true); 8646447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn } 8656447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn 8669fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn HashSet<String> packages = null; 8679fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn if (rawPackages != null) { 8689fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn if (!"*".equals(rawPackages)) { 8699fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn // A * is a wildcard to show all packages. 8709fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn String[] names = rawPackages.split(","); 8719fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn for (String n : names) { 8729fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn if (packages == null) { 8739fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn packages = new HashSet<String>(); 8749fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8759fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn packages.add(n); 8769fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8779fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8789fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } else if (isCheckinRequest) { 8799fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn // If checkin doesn't specify any packages, then we simply won't 8809fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn // show anything. 8818a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Checkin without packages"); 8829fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn return; 8839fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn } 8849fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mFileLock) { 8869fdbf6ae465f90b50ca5feb320215b98018c9937Dianne Hackborn collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint, packages); 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 891