Merge change 8061 into donut

* changes:
  Throw a connecting exception when timed out.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0d00f21..28a77a5 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -399,7 +399,8 @@
      * @hide
      */
     public void disableCompatibilityMode() {
-        flags |= FLAG_SUPPORTS_LARGE_SCREENS;
+        flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
+                FLAG_SUPPORTS_SMALL_SCREENS);
         supportsDensities = ANY_DENSITIES_ARRAY;
     }
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index cebb696..39c27aa9 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -92,6 +92,8 @@
     private static final Object mSync = new Object();
     private static WeakReference<byte[]> mReadBuffer;
 
+    private static boolean sCompatibilityModeEnabled = true; 
+
     static class ParsePackageItemArgs {
         final Package owner;
         final String[] outError;
@@ -2629,6 +2631,11 @@
     public static ApplicationInfo generateApplicationInfo(Package p, int flags) {
         if (p == null) return null;
         if (!copyNeeded(flags, p, null)) {
+            // CompatibilityMode is global state. It's safe to modify the instance
+            // of the package.
+            if (!sCompatibilityModeEnabled) {
+                p.applicationInfo.disableCompatibilityMode();
+            }
             return p.applicationInfo;
         }
 
@@ -2643,6 +2650,9 @@
         if ((flags & PackageManager.GET_SUPPORTS_DENSITIES) != 0) {
             ai.supportsDensities = p.supportsDensities;
         }
+        if (!sCompatibilityModeEnabled) {
+            ai.disableCompatibilityMode();
+        }
         return ai;
     }
 
@@ -2827,4 +2837,11 @@
                 + " " + service.info.name + "}";
         }
     }
+
+    /**
+     * @hide
+     */
+    public static void setCompatibilityModeEnabled(boolean compatibilityModeEnabled) {
+        sCompatibilityModeEnabled = compatibilityModeEnabled;
+    }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bf6003e..b5440f2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2508,11 +2508,17 @@
         public static final String CHECKIN_EVENTS = "checkin_events";
 
         /**
-         * Event tags for list of services to upload during checkin.
+         * Comma-separated list of service names to dump and upload during checkin.
          */
         public static final String CHECKIN_DUMPSYS_LIST = "checkin_dumpsys_list";
 
         /**
+         * Comma-separated list of packages to specify for each service that is
+         * dumped (currently only meaningful for user activity).
+         */
+        public static final String CHECKIN_PACKAGE_LIST = "checkin_package_list";
+
+        /**
          * The interval (in seconds) between periodic checkin attempts.
          */
         public static final String CHECKIN_INTERVAL = "checkin_interval";
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 4e0a87c..bb6b4b0 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -921,10 +921,8 @@
                 mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
                 mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
                 mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant();
-                // the language is not set here, instead it is cached so it will be associated
-                // with all upcoming utterances. But we still need to change the language support,
-                // which is achieved by calling isLanguageAvailable()
-                result = mITts.isLanguageAvailable(
+
+                result = mITts.setLanguage(mPackageName,
                         mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1],
                         mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1],
                         mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] );
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index e9f8ea1..9053468 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -171,7 +171,8 @@
                 mCameraJObjectWeak, msgType, 0, 0, NULL);
         break;
     default:
-        LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
+        // TODO: Change to LOGV
+        LOGD("dataCallback(%d, %p)", msgType, dataPtr.get());
         copyAndPost(env, dataPtr, msgType);
         break;
     }
@@ -222,6 +223,8 @@
 // finalizer is invoked later.
 static void android_hardware_Camera_release(JNIEnv *env, jobject thiz)
 {
+    // TODO: Change to LOGV
+    LOGD("release camera");
     JNICameraContext* context = NULL;
     sp<Camera> camera;
     {
diff --git a/core/res/res/layout/search_dropdown_app_selector.xml b/core/res/res/layout/search_dropdown_app_selector.xml
deleted file mode 100644
index f86645f..0000000
--- a/core/res/res/layout/search_dropdown_app_selector.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/layout/search_dropdown_app_selector.xml
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:baselineAligned="false"
-    >
-
-    <ImageView android:id="@+id/search_app_icon1"
-        android:layout_width="32dip"
-        android:layout_height="32dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="fitCenter"
-        android:src="@android:drawable/ic_search_category_default" />
-        
-    <TextView android:id="@+id/search_app_text1"
-        style="?android:attr/dropDownItemStyle"
-        android:singleLine="true"
-        android:layout_height="wrap_content"
-        android:layout_width="0dip"
-        android:layout_weight="1"
-        android:layout_gravity="center_vertical" />
-    
-</LinearLayout>
diff --git a/core/res/res/layout/search_dropdown_item_2line.xml b/core/res/res/layout/search_dropdown_item_2line.xml
deleted file mode 100644
index 5546b6636..0000000
--- a/core/res/res/layout/search_dropdown_item_2line.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/searchResultListItemHeight"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:baselineAligned="false"
-    >
-    
-    <TwoLineListItem
-        android:paddingTop="1dip"
-        android:paddingBottom="1dip"
-        android:gravity="center_vertical"
-        android:layout_width="0dip"
-        android:layout_weight="1"
-        android:layout_height="wrap_content"
-        android:mode="twoLine" >
-    
-        <TextView
-            android:id="@android:id/text1"
-            style="?android:attr/dropDownItemStyle"
-            android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
-            android:singleLine="true"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content" />
-    
-        <TextView
-            android:id="@android:id/text2"
-            style="?android:attr/dropDownItemStyle"
-            android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
-            android:textColor="?android:attr/textColorSecondaryInverse"
-            android:singleLine="true"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/text1"
-            android:layout_alignLeft="@android:id/text1" />
-    
-    </TwoLineListItem>
-
-</LinearLayout>
diff --git a/core/res/res/layout/search_dropdown_item_icons_1line.xml b/core/res/res/layout/search_dropdown_item_icons_1line.xml
deleted file mode 100644
index 4f65d74..0000000
--- a/core/res/res/layout/search_dropdown_item_icons_1line.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-    <!-- NOTE: The appearance of the inner text element must match the appearance -->
-    <!-- of the text element in apps/common/res/layout/simple_dropdown_item_1line.xml -->
-    
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:paddingLeft="4dip"
-    android:paddingRight="2dip"
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/searchResultListItemHeight"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:baselineAligned="false"
-    >
-    
-    <ImageView android:id="@android:id/icon1"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside" />
-
-    <TextView android:id="@android:id/text1"
-        style="?android:attr/dropDownItemStyle"
-        android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
-        android:singleLine="true"
-        android:layout_height="wrap_content"
-        android:layout_width="0dip"
-        android:layout_weight="1"  />
-
-    <ImageView android:id="@android:id/icon2"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside" />
-
-</LinearLayout>
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 9a4c97d..cfefcb7 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -139,16 +139,18 @@
     private final ReentrantLock speechQueueLock = new ReentrantLock();
     private final ReentrantLock synthesizerLock = new ReentrantLock();
 
-    private SynthProxy nativeSynth;
+    private static SynthProxy sNativeSynth = null;
     @Override
     public void onCreate() {
         super.onCreate();
-        Log.i("TTS", "TTS starting");
+        Log.i("TtsService", "TtsService.onCreate()");
 
         mResolver = getContentResolver();
 
         String soLibPath = "/system/lib/libttspico.so";
-        nativeSynth = new SynthProxy(soLibPath);
+        if (sNativeSynth == null) {
+            sNativeSynth = new SynthProxy(soLibPath);
+        }
 
         mSelf = this;
         mIsSpeaking = false;
@@ -171,7 +173,7 @@
         // Don't hog the media player
         cleanUpPlayer();
 
-        nativeSynth.shutdown();
+        sNativeSynth.shutdown();
 
         // Unregister all callbacks.
         mCallbacks.kill();
@@ -239,36 +241,36 @@
 
     private int setSpeechRate(String callingApp, int rate) {
         if (isDefaultEnforced()) {
-            return nativeSynth.setSpeechRate(getDefaultRate());
+            return sNativeSynth.setSpeechRate(getDefaultRate());
         } else {
-            return nativeSynth.setSpeechRate(rate);
+            return sNativeSynth.setSpeechRate(rate);
         }
     }
 
 
     private int setPitch(String callingApp, int pitch) {
-        return nativeSynth.setPitch(pitch);
+        return sNativeSynth.setPitch(pitch);
     }
 
 
     private int isLanguageAvailable(String lang, String country, String variant) {
-        //Log.v("TTS", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
-        return nativeSynth.isLanguageAvailable(lang, country, variant);
+        //Log.v("TtsService", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
+        return sNativeSynth.isLanguageAvailable(lang, country, variant);
     }
 
 
     private String[] getLanguage() {
-        return nativeSynth.getLanguage();
+        return sNativeSynth.getLanguage();
     }
 
 
     private int setLanguage(String callingApp, String lang, String country, String variant) {
-        //Log.v("TTS", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
+        Log.v("TtsService", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
         if (isDefaultEnforced()) {
-            return nativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
+            return sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
                     getDefaultLocVariant());
         } else {
-            return nativeSynth.setLanguage(lang, country, variant);
+            return sNativeSynth.setLanguage(lang, country, variant);
         }
     }
 
@@ -340,7 +342,7 @@
      *            engines.
      */
     private int speak(String callingApp, String text, int queueMode, ArrayList<String> params) {
-        Log.i("TTS service received", text);
+        Log.v("TtsService", "TTS service received " + text);
         if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
             stop(callingApp);
         } else if (queueMode == 2) {
@@ -390,7 +392,7 @@
             // something has gone very wrong with processSpeechQueue.
             speechQueueAvailable = speechQueueLock.tryLock(1000, TimeUnit.MILLISECONDS);
             if (speechQueueAvailable) {
-                Log.i("TTS", "Stopping");
+                Log.i("TtsService", "Stopping");
                 for (int i = mSpeechQueue.size() - 1; i > -1; i--){
                     if (mSpeechQueue.get(i).mCallingApp.equals(callingApp)){
                         mSpeechQueue.remove(i);
@@ -398,7 +400,7 @@
                 }
                 if ((mCurrentSpeechItem != null) &&
                      mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
-                    result = nativeSynth.stop();
+                    result = sNativeSynth.stop();
                     mKillList.put(mCurrentSpeechItem, true);
                     if (mPlayer != null) {
                         try {
@@ -412,10 +414,10 @@
                 } else {
                     result = TextToSpeech.TTS_SUCCESS;
                 }
-                Log.i("TTS", "Stopped");
+                Log.i("TtsService", "Stopped");
             }
         } catch (InterruptedException e) {
-          Log.e("TTS stop", "tryLock interrupted");
+          Log.e("TtsService", "TTS stop: tryLock interrupted");
           e.printStackTrace();
         } finally {
             // This check is needed because finally will always run; even if the
@@ -448,7 +450,7 @@
                 if ((mCurrentSpeechItem != null) &&
                     ((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
                       mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
-                    result = nativeSynth.stop();
+                    result = sNativeSynth.stop();
                     mKillList.put(mCurrentSpeechItem, true);
                     if (mPlayer != null) {
                         try {
@@ -462,10 +464,10 @@
                 } else {
                     result = TextToSpeech.TTS_SUCCESS;
                 }
-                Log.i("TTS", "Stopped all");
+                Log.i("TtsService", "Stopped all");
             }
         } catch (InterruptedException e) {
-          Log.e("TTS stopAll", "tryLock interrupted");
+          Log.e("TtsService", "TTS stopAll: tryLock interrupted");
           e.printStackTrace();
         } finally {
             // This check is needed because finally will always run; even if the
@@ -588,10 +590,10 @@
                         if (speechRate.length() > 0){
                             setSpeechRate("", Integer.parseInt(speechRate));
                         }
-                        nativeSynth.speak(speechItem.mText, streamType);
+                        sNativeSynth.speak(speechItem.mText, streamType);
                     }
                 } catch (InterruptedException e) {
-                    Log.e("TTS speakInternalOnly", "tryLock interrupted");
+                    Log.e("TtsService", "TTS speakInternalOnly(): tryLock interrupted");
                     e.printStackTrace();
                 } finally {
                     // This check is needed because finally will always run;
@@ -617,7 +619,7 @@
             public void run() {
                 boolean synthAvailable = false;
                 String utteranceId = "";
-                Log.i("TTS", "Synthesizing to " + speechItem.mFilename);
+                Log.i("TtsService", "Synthesizing to " + speechItem.mFilename);
                 try {
                     synthAvailable = synthesizerLock.tryLock();
                     if (!synthAvailable) {
@@ -657,10 +659,10 @@
                         if (speechRate.length() > 0){
                             setSpeechRate("", Integer.parseInt(speechRate));
                         }
-                        nativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+                        sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
                     }
                 } catch (InterruptedException e) {
-                    Log.e("TTS synthToFileInternalOnly", "tryLock interrupted");
+                    Log.e("TtsService", "TTS synthToFileInternalOnly(): tryLock interrupted");
                     e.printStackTrace();
                 } finally {
                     // This check is needed because finally will always run;
@@ -705,7 +707,7 @@
         if (cb == null){
             return;
         }
-        Log.i("TTS callback", "dispatch started");
+        Log.i("TtsService", "TTS callback: dispatch started");
         // Broadcast to all clients the new value.
         final int N = mCallbacks.beginBroadcast();
         try {
@@ -715,7 +717,7 @@
             // the dead object for us.
         }
         mCallbacks.finishBroadcast();
-        Log.i("TTS callback", "dispatch completed to " + N);
+        Log.i("TtsService", "TTS callback: dispatch completed to " + N);
     }
 
     private SpeechItem splitCurrentTextIfNeeded(SpeechItem currentSpeechItem){
@@ -764,7 +766,7 @@
             SoundResource sr = getSoundResource(mCurrentSpeechItem);
             // Synth speech as needed - synthesizer should call
             // processSpeechQueue to continue running the queue
-            Log.i("TTS processing: ", mCurrentSpeechItem.mText);
+            Log.i("TtsService", "TTS processing: " + mCurrentSpeechItem.mText);
             if (sr == null) {
                 if (mCurrentSpeechItem.mType == SpeechItem.TEXT) {
                     mCurrentSpeechItem = splitCurrentTextIfNeeded(mCurrentSpeechItem);
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index d8dafb6..143c7d5 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -262,7 +262,6 @@
     final ResolveInfo mResolveInfo = new ResolveInfo();
     ComponentName mResolveComponentName;
     PackageParser.Package mPlatformPackage;
-    private boolean mCompatibilityModeEnabled = true;
 
     public static final IPackageManager main(Context context, boolean factoryTest) {
         PackageManagerService m = new PackageManagerService(context, factoryTest);
@@ -765,7 +764,7 @@
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
             if (Config.LOGV) Log.v(
-                TAG, "getApplicationInfo " + packageName
+                TAG, "getPackageInfo " + packageName
                 + ": " + p);
             if (p != null) {
                 return generatePackageInfo(p, flags);
@@ -796,7 +795,7 @@
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
             if (Config.LOGV) Log.v(
-                TAG, "getApplicationInfo " + packageName
+                TAG, "getPackageGids" + packageName
                 + ": " + p);
             if (p != null) {
                 final PackageSetting ps = (PackageSetting)p.mExtras;
@@ -894,11 +893,7 @@
                     + ": " + p);
             if (p != null) {
                 // Note: isEnabledLP() does not apply here - always return info
-                ApplicationInfo appInfo = PackageParser.generateApplicationInfo(p, flags);
-                if (!mCompatibilityModeEnabled) {
-                    appInfo.disableCompatibilityMode();
-                }
-                return appInfo;
+                return PackageParser.generateApplicationInfo(p, flags);
             }
             if ("android".equals(packageName)||"system".equals(packageName)) {
                 return mAndroidApplication;
@@ -4817,11 +4812,12 @@
         mSystemReady = true;
 
         // Read the compatibilty setting when the system is ready.
-        mCompatibilityModeEnabled = android.provider.Settings.System.getInt(
+        boolean compatibilityModeEnabled = android.provider.Settings.System.getInt(
                 mContext.getContentResolver(),
                 android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
+        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
         if (DEBUG_SETTINGS) {
-            Log.d(TAG, "compatibility mode:" + mCompatibilityModeEnabled);
+            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
         }
     }
 
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index 2d58659..d458911 100755
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -39,6 +39,7 @@
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -617,7 +618,7 @@
     }
     
     private void collectDumpInfoFLOCK(PrintWriter pw, boolean isCompactOutput,
-            boolean deleteAfterPrint) {
+            boolean deleteAfterPrint, HashSet<String> packages) {
         List<String> fileList = getUsageStatsFileListFLOCK();
         if (fileList == null) {
             return;
@@ -633,7 +634,8 @@
             String dateStr = file.substring(FILE_PREFIX.length());
             try {
                 Parcel in = getParcelForFile(dFile);
-                collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCompactOutput);
+                collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCompactOutput,
+                        packages);
                 if (deleteAfterPrint) {
                     // Delete old file after collecting info only for checkin requests
                     dFile.delete();
@@ -648,7 +650,7 @@
     }
     
     private void collectDumpInfoFromParcelFLOCK(Parcel in, PrintWriter pw,
-            String date, boolean isCompactOutput) {
+            String date, boolean isCompactOutput, HashSet<String> packages) {
         StringBuilder sb = new StringBuilder(512);
         if (isCompactOutput) {
             sb.append("D:");
@@ -678,7 +680,10 @@
             }
             sb.setLength(0);
             PkgUsageStatsExtended pus = new PkgUsageStatsExtended(in);
-            if (isCompactOutput) {
+            if (packages != null && !packages.contains(pkgName)) {
+                // This package has not been requested -- don't print
+                // anything for it.
+            } else if (isCompactOutput) {
                 sb.append("P:");
                 sb.append(pkgName);
                 sb.append(',');
@@ -765,6 +770,25 @@
         return false;
     }
     
+    /**
+     * Searches array of arguments for the specified string's data
+     * @param args array of argument strings
+     * @param value value to search for
+     * @return the string of data after the arg, or null if there is none
+     */
+    private static String scanArgsData(String[] args, String value) {
+        if (args != null) {
+            final int N = args.length;
+            for (int i=0; i<N; i++) {
+                if (value.equals(args[i])) {
+                    i++;
+                    return i < N ? args[i] : null;
+                }
+            }
+        }
+        return null;
+    }
+    
     @Override
     /*
      * The data persisted to file is parsed and the stats are computed. 
@@ -773,6 +797,7 @@
         final boolean isCheckinRequest = scanArgs(args, "--checkin");
         final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c");
         final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d");
+        final String rawPackages = scanArgsData(args, "--packages");
         
         // Make sure the current stats are written to the file.  This
         // doesn't need to be done if we are deleting files after printing,
@@ -781,8 +806,27 @@
             writeStatsToFile(true);
         }
         
+        HashSet<String> packages = null;
+        if (rawPackages != null) {
+            if (!"*".equals(rawPackages)) {
+                // A * is a wildcard to show all packages.
+                String[] names = rawPackages.split(",");
+                for (String n : names) {
+                    if (packages == null) {
+                        packages = new HashSet<String>();
+                    }
+                    packages.add(n);
+                }
+            }
+        } else if (isCheckinRequest) {
+            // If checkin doesn't specify any packages, then we simply won't
+            // show anything.
+            Log.w(TAG, "Checkin without packages");
+            return;
+        }
+        
         synchronized (mFileLock) {
-            collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint);
+            collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint, packages);
         }
     }