Don't duplicate the menu in the help page for ahat.

Future changes to the menu will need to be made in only a single
location.

Change-Id: I24ffcf17d5564b98bd3552d4ba9284eb6924d52b
diff --git a/tools/ahat/README.txt b/tools/ahat/README.txt
index adc4d03..a3ecf86 100644
--- a/tools/ahat/README.txt
+++ b/tools/ahat/README.txt
@@ -23,8 +23,6 @@
    - Make sortable by clicking on headers.
  * For HeapTable with single heap shown, the heap name isn't centered?
  * Consistently document functions.
- * Should help be part of an AhatHandler, that automatically gets the menu and
-   stylesheet link rather than duplicating that?
  * Show version number with --version.
  * Show somewhere where to send bugs.
  * Include a link to /objects in the overview and menu?
@@ -79,6 +77,12 @@
  * Instance.isRoot and Instance.getRootTypes.
 
 Release History:
+ 0.3 Dec 15, 2015
+   Fix page loading performance by showing a limited number of entries by default.
+   Fix mismatch between overview and "roots" totals.
+   Annotate root objects and show their types.
+   Annotate references with their referents.
+
  0.2 Oct 20, 2015
    Take into account 'count' and 'offset' when displaying strings.
 
diff --git a/tools/ahat/src/AhatHttpHandler.java b/tools/ahat/src/AhatHttpHandler.java
index 178747c..1d05a66 100644
--- a/tools/ahat/src/AhatHttpHandler.java
+++ b/tools/ahat/src/AhatHttpHandler.java
@@ -41,15 +41,7 @@
     PrintStream ps = new PrintStream(exchange.getResponseBody());
     try {
       HtmlDoc doc = new HtmlDoc(ps, DocString.text("ahat"), DocString.uri("style.css"));
-      DocString menu = new DocString();
-      menu.appendLink(DocString.uri("/"), DocString.text("overview"));
-      menu.append(" - ");
-      menu.appendLink(DocString.uri("rooted"), DocString.text("rooted"));
-      menu.append(" - ");
-      menu.appendLink(DocString.uri("sites"), DocString.text("allocations"));
-      menu.append(" - ");
-      menu.appendLink(DocString.uri("help"), DocString.text("help"));
-      doc.menu(menu);
+      doc.menu(Menu.getMenu());
       mAhatHandler.handle(doc, new Query(exchange.getRequestURI()));
       doc.close();
     } catch (RuntimeException e) {
diff --git a/tools/ahat/src/HelpHandler.java b/tools/ahat/src/HelpHandler.java
new file mode 100644
index 0000000..8de3c85
--- /dev/null
+++ b/tools/ahat/src/HelpHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 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.ahat;
+
+import com.google.common.io.ByteStreams;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+
+/**
+ * HelpHandler.
+ *
+ * HttpHandler to show the help page.
+ */
+class HelpHandler implements HttpHandler {
+
+  @Override
+  public void handle(HttpExchange exchange) throws IOException {
+    ClassLoader loader = HelpHandler.class.getClassLoader();
+    exchange.getResponseHeaders().add("Content-Type", "text/html;charset=utf-8");
+    exchange.sendResponseHeaders(200, 0);
+    PrintStream ps = new PrintStream(exchange.getResponseBody());
+    HtmlDoc doc = new HtmlDoc(ps, DocString.text("ahat"), DocString.uri("style.css"));
+    doc.menu(Menu.getMenu());
+
+    InputStream is = loader.getResourceAsStream("help.html");
+    if (is == null) {
+      ps.println("No help available.");
+    } else {
+      ByteStreams.copy(is, ps);
+    }
+
+    doc.close();
+    ps.close();
+  }
+}
diff --git a/tools/ahat/src/Main.java b/tools/ahat/src/Main.java
index ebd49d7..091820f 100644
--- a/tools/ahat/src/Main.java
+++ b/tools/ahat/src/Main.java
@@ -79,7 +79,7 @@
     server.createContext("/objects", new AhatHttpHandler(new ObjectsHandler(ahat)));
     server.createContext("/site", new AhatHttpHandler(new SiteHandler(ahat)));
     server.createContext("/bitmap", new BitmapHandler(ahat));
-    server.createContext("/help", new StaticHandler("help.html", "text/html"));
+    server.createContext("/help", new HelpHandler());
     server.createContext("/style.css", new StaticHandler("style.css", "text/css"));
     server.setExecutor(Executors.newFixedThreadPool(1));
     System.out.println("Server started on localhost:" + port);
diff --git a/tools/ahat/src/Menu.java b/tools/ahat/src/Menu.java
new file mode 100644
index 0000000..018e019
--- /dev/null
+++ b/tools/ahat/src/Menu.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 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.ahat;
+
+/**
+ * A menu showed in the UI that can be used to jump to common pages.
+ */
+class Menu {
+  private static DocString mMenu =
+    DocString.link(DocString.uri("/"), DocString.text("overview"))
+      .append(" - ")
+      .appendLink(DocString.uri("rooted"), DocString.text("rooted"))
+      .append(" - ")
+      .appendLink(DocString.uri("sites"), DocString.text("allocations"))
+      .append(" - ")
+      .appendLink(DocString.uri("help"), DocString.text("help"));
+
+  /**
+   * Returns the menu as a DocString.
+   */
+  public static DocString getMenu() {
+    return mMenu;
+  }
+}
diff --git a/tools/ahat/src/OverviewHandler.java b/tools/ahat/src/OverviewHandler.java
index 0fe4fba..720fcb4 100644
--- a/tools/ahat/src/OverviewHandler.java
+++ b/tools/ahat/src/OverviewHandler.java
@@ -48,14 +48,7 @@
 
     doc.section("Heap Sizes");
     printHeapSizes(doc, query);
-
-    DocString menu = new DocString();
-    menu.appendLink(DocString.uri("rooted"), DocString.text("Rooted"));
-    menu.append(" - ");
-    menu.appendLink(DocString.uri("site"), DocString.text("Allocations"));
-    menu.append(" - ");
-    menu.appendLink(DocString.uri("help"), DocString.text("Help"));
-    doc.big(menu);
+    doc.big(Menu.getMenu());
   }
 
   private void printHeapSizes(Doc doc, Query query) {
diff --git a/tools/ahat/src/help.html b/tools/ahat/src/help.html
index 92ec37d..ff04ad2 100644
--- a/tools/ahat/src/help.html
+++ b/tools/ahat/src/help.html
@@ -14,17 +14,6 @@
 limitations under the License.
 -->
 
-<head>
-<link rel="stylesheet" type="text/css" href="style.css">
-</head>
-
-<div class="menu">
-  <a href="/">overview</a> -
-  <a href="rooted">rooted</a> -
-  <a href="sites">allocations</a> -
-  <a href="help">help</a>
-</div>
-
 <h1>Help</h1>
 <h2>Information shown by ahat:</h2>
 <ul>
diff --git a/tools/ahat/src/manifest.txt b/tools/ahat/src/manifest.txt
index 421de17..368b744 100644
--- a/tools/ahat/src/manifest.txt
+++ b/tools/ahat/src/manifest.txt
@@ -1,4 +1,4 @@
 Name: ahat/
 Implementation-Title: ahat
-Implementation-Version: 0.3
+Implementation-Version: 0.4
 Main-Class: com.android.ahat.Main