Initial checkin of actionable memory metric.

Describes the actionable memory metric and provides an AmmTest.apk
application demonstrating use of the APIs modeled by the metric.

Java heap and dex code models are provided to start.

Bug: 69729799
Test: AmmTest.apk builds and runs on device.
Change-Id: I154ec7611ef968d68b764a9c5d4bde11ff607798
diff --git a/Android.mk b/Android.mk
index 361ceec..3267483 100644
--- a/Android.mk
+++ b/Android.mk
@@ -79,6 +79,7 @@
 include $(art_path)/oatdump/Android.mk
 include $(art_path)/tools/Android.mk
 include $(art_path)/tools/ahat/Android.mk
+include $(art_path)/tools/amm/Android.mk
 include $(art_path)/tools/dexfuzz/Android.mk
 include $(art_path)/libart_fake/Android.mk
 
diff --git a/tools/amm/AmmTest/AndroidManifest.xml b/tools/amm/AmmTest/AndroidManifest.xml
new file mode 100644
index 0000000..16529bc
--- /dev/null
+++ b/tools/amm/AmmTest/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.amm.test">
+
+  <application
+    android:label="AmmTest"
+    android:debuggable="true">
+
+    <activity android:name="com.android.amm.test.MainActivity">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/MainActivity.java b/tools/amm/AmmTest/src/com/android/amm/test/MainActivity.java
new file mode 100644
index 0000000..787f90e
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/MainActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package com.android.amm.test;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+  @Override
+  public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+  }
+}
+
diff --git a/tools/amm/Android.mk b/tools/amm/Android.mk
new file mode 100644
index 0000000..dfbb7cf
--- /dev/null
+++ b/tools/amm/Android.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# --- AmmTest.apk --------------
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := AmmTest
+LOCAL_MODULE_TAGS := samples tests
+LOCAL_SRC_FILES := $(call all-java-files-under, AmmTest/src)
+LOCAL_MANIFEST_FILE := AmmTest/AndroidManifest.xml
+include $(BUILD_PACKAGE)
+
diff --git a/tools/amm/README.md b/tools/amm/README.md
new file mode 100644
index 0000000..17f94a8
--- /dev/null
+++ b/tools/amm/README.md
@@ -0,0 +1,16 @@
+# Actionable Memory Metric
+
+The goal of the actionable memory metric (AMM) is to provide a view of an
+application's memory use that application developers can track, understand,
+and control. AMM can be thought of as a Java heap dump augmented with models
+for non-Java allocations that app developers have some control of.
+
+There are two components of the actionable memory metric:
+1. The value of the metric.
+2. An actionable breakdown of the value of the metric.
+
+The metric is made up of a collection of separate models for different
+categories of memory use. Each model contributes to the value and actionable
+breakdown of the overall metric.
+
+See models/ for a list of models proposed for the actionable memory metric.
diff --git a/tools/amm/models/DexCode.md b/tools/amm/models/DexCode.md
new file mode 100644
index 0000000..a907280
--- /dev/null
+++ b/tools/amm/models/DexCode.md
@@ -0,0 +1,17 @@
+# Dex Code Model
+
+The value of the Dex Code model is the sum of the original uncompressed file
+sizes of all loaded dex files. It is calculated using the best approximation
+of the dex file size available to us on device. On Android O, for example,
+this can be approximated as the virtual size of the corresponding memory
+mapped `.vdex` file read from `/proc/self/maps`. Different Android platform
+versions and scenarios may require different approximations.
+
+The actionable breakdown of the dex code model is a breakdown by
+`dalvik.system.DexFile` instance. Further breakdown of individual dex files
+can be achieved using tools such as dexdump.
+
+For example, for an application `AmmTest.apk` that has a single `classes.dex` file
+that is 500 KB uncompressed, the `DexFile` instance for
+`/data/app/com.android.amm.test-_uHI4CJWpeoztbjN6Tr-Nw==/base.apk` is shown as
+Taking up 500 KB (or the best available approximation thereof).
diff --git a/tools/amm/models/JavaHeap.md b/tools/amm/models/JavaHeap.md
new file mode 100644
index 0000000..c34c186
--- /dev/null
+++ b/tools/amm/models/JavaHeap.md
@@ -0,0 +1,8 @@
+# Java Heap Model
+
+The value of the Java heap model is the sum of bytes of Java objects allocated
+on the Java heap. It can be calculated using:
+
+    Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
+
+A Java heap dump is used for an actionable breakdown of the Java heap.