New icon to dump heap information and share it.

Alternatively,
  $ adb shell am start -n <pkg>/com.android.launcher3.MemoryDumpActivity

Change-Id: I8c615ec3abffaf6ad693c93bdf569550d8f97298
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fa9938f..baf6990 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -110,6 +110,21 @@
                 android:resource="@xml/wallpaper_picker_preview" />
         </activity>
 
+        <!-- Debugging tools -->
+        <activity
+            android:name="com.android.launcher3.MemoryDumpActivity"
+            android:theme="@android:style/Theme.NoDisplay"
+            android:label="@string/debug_memory_activity"
+            android:enabled="@bool/debug_memory_enabled"
+            android:icon="@null"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
         <!-- Intent received used to prepopulate the default workspace. -->
         <receiver
             android:name="com.android.launcher3.PreloadReceiver"
diff --git a/proguard.flags b/proguard.flags
index ada6226..7397088 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -62,3 +62,7 @@
 -keep class com.android.launcher3.ClippedImageView {
   *;
 }
+
+-keep class com.android.launcher3.MemoryDumpActivity {
+  *;
+}
diff --git a/res/values/config.xml b/res/values/config.xml
index d4f8185..e65818f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -90,4 +90,7 @@
     <integer name="hotseat_all_apps_index">2</integer>
     <!-- must be between 0 and 100 -->
     <integer name="hotseat_item_scale_percentage">100</integer>
+
+    <!-- Memory debugging, including a memory dump icon -->
+    <bool name="debug_memory_enabled">true</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f6abf68..b57ae74 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -277,4 +277,7 @@
     <!-- Dummy string [CHAR_LIMIT=60] -->
     <string name="custom_workspace_cling_description_2"></string>
 
+    <!-- Debug-only activity name. [DO NOT TRANSLATE] -->
+    <string name="debug_memory_activity">* HPROF</string>
+
 </resources>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7f3c482..0253103 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1041,7 +1041,7 @@
             mSearchDropTargetBar.setup(this, dragController);
         }
 
-        if (DEBUG_MEMORY) {
+        if (getResources().getBoolean(R.bool.debug_memory_enabled)) {
             Log.v(TAG, "adding WeightWatcher");
             ((FrameLayout) mLauncherView).addView(new WeightWatcher(this),
                     new FrameLayout.LayoutParams(
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index fa1670c..e7aa3d8 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -23,9 +23,15 @@
 import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Debug;
+import android.os.Environment;
 import android.os.Handler;
 
+import java.io.File;
+import java.io.IOException;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 
 public class LauncherAppState {
     private Context mContext;
@@ -61,6 +67,10 @@
 
         mStarttime = System.currentTimeMillis();
 
+        if (context.getResources().getBoolean(R.bool.debug_memory_enabled)) {
+            WeightWatcher.sUpdateThread.start();
+        }
+
         // set sIsScreenXLarge and sScreenDensity *before* creating icon cache
         sIsScreenLarge = context.getResources().getBoolean(R.bool.is_large_screen);
         sScreenDensity = context.getResources().getDisplayMetrics().density;
diff --git a/src/com/android/launcher3/MemoryDumpActivity.java b/src/com/android/launcher3/MemoryDumpActivity.java
new file mode 100644
index 0000000..19b1c4e
--- /dev/null
+++ b/src/com/android/launcher3/MemoryDumpActivity.java
@@ -0,0 +1,66 @@
+package com.android.launcher3;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class MemoryDumpActivity extends Activity {
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    public static void dumpHprofAndShare(final Context context) {
+        try {
+            final String path = String.format("%s/launcher-memory-%d.ahprof",
+                    Environment.getExternalStorageDirectory(),
+                    System.currentTimeMillis());
+            Log.v(Launcher.TAG, "Dumping memory info to " + path);
+
+            android.os.Debug.dumpHprofData(path); // will block
+
+            Intent shareIntent = new Intent(Intent.ACTION_SEND);
+            shareIntent.setType("application/vnd.android.bugreport");
+
+            final long pss = Debug.getPss();
+            final PackageManager pm = context.getPackageManager();
+            shareIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("Launcher memory dump (PSS=%d)", pss));
+            String appVersion;
+            try {
+                appVersion = pm.getPackageInfo(context.getPackageName(), 0).versionName;
+            } catch (PackageManager.NameNotFoundException e) {
+                appVersion = "?";
+            }
+            shareIntent.putExtra(Intent.EXTRA_TEXT, String.format("App version: %s\nBuild: %s",
+                    appVersion, Build.DISPLAY));
+            shareIntent.setType("application/vnd.android.hprof");
+
+            //shareIntent.putExtra(Intent.EXTRA_TEXT, android.os.SystemProperties.get("ro.build.description"));
+
+            final File pathFile = new File(path);
+            final Uri pathUri = Uri.fromFile(pathFile);
+
+            shareIntent.putExtra(Intent.EXTRA_STREAM, pathUri);
+            context.startActivity(shareIntent);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        dumpHprofAndShare(this);
+        finish();
+    }
+}
\ No newline at end of file