summaryrefslogtreecommitdiffstats
path: root/tools/memory_inspector
diff options
context:
space:
mode:
authorpetrcermak <petrcermak@chromium.org>2015-01-22 07:57:27 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-22 15:58:29 +0000
commit9cb6cf956d779c3374a9684a54a98d638d8ccd1a (patch)
treebd4b99bbb57c2bd07868db65b9d60b2f193274a8 /tools/memory_inspector
parent8dbe088dee9122e5db470ff10ca2fbbb73bfca15 (diff)
downloadchromium_src-9cb6cf956d779c3374a9684a54a98d638d8ccd1a.zip
chromium_src-9cb6cf956d779c3374a9684a54a98d638d8ccd1a.tar.gz
chromium_src-9cb6cf956d779c3374a9684a54a98d638d8ccd1a.tar.bz2
Make a Memory Inspector Chrome App
This patch adds a Memory Inspector Chrome App which wraps the Memory Inspector tool in a PNaCl executable. Note that this patch is not ready for submission yet as it requires several modifications to the Memory Inspector tool first (see the bug below). Any suggestions and/or feedback are more than welcome. BUG=448399 NOTRY=true Review URL: https://codereview.chromium.org/857553003 Cr-Commit-Position: refs/heads/master@{#312627}
Diffstat (limited to 'tools/memory_inspector')
-rw-r--r--tools/memory_inspector/chrome_app/.gitignore1
-rw-r--r--tools/memory_inspector/chrome_app/README.chromium28
-rw-r--r--tools/memory_inspector/chrome_app/assets/body.svg272
-rw-r--r--tools/memory_inspector/chrome_app/assets/cog1.svg71
-rw-r--r--tools/memory_inspector/chrome_app/assets/cog2.svg71
-rwxr-xr-xtools/memory_inspector/chrome_app/assets/generate_bitmaps.sh25
-rw-r--r--tools/memory_inspector/chrome_app/assets/icon.svg304
-rwxr-xr-xtools/memory_inspector/chrome_app/build.sh72
-rw-r--r--tools/memory_inspector/chrome_app/template/background.js86
-rw-r--r--tools/memory_inspector/chrome_app/template/config.js30
-rw-r--r--tools/memory_inspector/chrome_app/template/images/body.pngbin0 -> 23639 bytes
-rw-r--r--tools/memory_inspector/chrome_app/template/images/cog1.pngbin0 -> 1202 bytes
-rw-r--r--tools/memory_inspector/chrome_app/template/images/cog2.pngbin0 -> 720 bytes
-rw-r--r--tools/memory_inspector/chrome_app/template/images/icon_128.pngbin0 -> 8405 bytes
-rw-r--r--tools/memory_inspector/chrome_app/template/images/icon_16.pngbin0 -> 601 bytes
-rw-r--r--tools/memory_inspector/chrome_app/template/images/icon_48.pngbin0 -> 2272 bytes
-rw-r--r--tools/memory_inspector/chrome_app/template/main_window.css247
-rw-r--r--tools/memory_inspector/chrome_app/template/main_window.html38
-rw-r--r--tools/memory_inspector/chrome_app/template/main_window.js393
-rw-r--r--tools/memory_inspector/chrome_app/template/manifest.json35
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_server.py3
-rwxr-xr-xtools/memory_inspector/start_web_ui2
22 files changed, 1676 insertions, 2 deletions
diff --git a/tools/memory_inspector/chrome_app/.gitignore b/tools/memory_inspector/chrome_app/.gitignore
new file mode 100644
index 0000000..89f9ac0
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/.gitignore
@@ -0,0 +1 @@
+out/
diff --git a/tools/memory_inspector/chrome_app/README.chromium b/tools/memory_inspector/chrome_app/README.chromium
new file mode 100644
index 0000000..8278303
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/README.chromium
@@ -0,0 +1,28 @@
+This directory contains the source code of the Memory Inspector Chrome App. The
+app runs the Memory Inspector inside PNaCl and can therefore be easily
+distributed without the Chromium tree. It uses several files from the naclports
+python package. Note that it requires the ADB daemon to be running on the host
+machine (run 'adb start-server').
+
+The app is built as follows (see build.sh for more details):
+
+ 1. The output directory out/ is cleaned.
+ 2. The contents of the template/ directory are copied/linked to
+ out/memory_inspector_app/.
+ 3. Prebuilt files for running Python inside PNaCl are downloaded from
+ https://gsdview.appspot.com/naclports/ to out/memory_inspector_app/ and
+ out/memory_inspector_app/sandbox/.
+ 4. The out/memory_inspector_app/sandbox/pydata_pnacl.tar file is augmented
+ with Memory Inspector dependencies (e.g. ../memory_inspector/).
+ 5. The app can now be added to Chrome by loading the out/memory_inspector_app
+ folder as unpacked extension in chrome://extensions. A zip file
+ out/memory_inspector_app.zip is also generated for easy distribution.
+
+The app is currently (January 2015) in a very early stage of development. If you
+encounter any issues, please report them on https://crbug.com and use the Memory
+Inspector directly by running ../start_web_ui instead.
+
+For more information see:
+ - Meta-bug: https://crbug.com/448399
+ - naclports: https://code.google.com/p/naclports/
+
diff --git a/tools/memory_inspector/chrome_app/assets/body.svg b/tools/memory_inspector/chrome_app/assets/body.svg
new file mode 100644
index 0000000..07635d2
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/assets/body.svg
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ viewBox="0 0 48 48"
+ id="svg3070"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="android_icon.svg">
+ <metadata
+ id="metadata3080">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3078">
+ <filter
+ inkscape:collect="always"
+ id="filter3987">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.0204955"
+ id="feGaussianBlur3989" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1855"
+ inkscape:window-height="1176"
+ id="namedview3076"
+ showgrid="false"
+ inkscape:zoom="16"
+ inkscape:cx="23.403239"
+ inkscape:cy="23.493959"
+ inkscape:window-x="1985"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3070"
+ inkscape:snap-global="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4407" />
+ </sodipodi:namedview>
+ <rect
+ style="fill:#323232;fill-opacity:1;stroke:none"
+ id="rect4405"
+ width="37.970795"
+ height="37.985714"
+ x="4.9828935"
+ y="4.9963875"
+ ry="2.8708735" />
+ <path
+ sodipodi:nodetypes="sscsssccssscssccssssssssssssssscssccscssscccczzzzzzzzzz"
+ style="fill:#6afff9;fill-opacity:1;stroke:none;filter:url(#filter3987)"
+ inkscape:connector-curvature="0"
+ id="path3903"
+ d="m 12.867638,35.132271 c 0,1.020467 0.834928,1.855394 1.855394,1.855394 l 1.855394,0 0,6.493877 c 0,1.539977 1.243113,2.783091 2.78309,2.783091 1.539977,0 2.78309,-1.243114 2.78309,-2.783091 l 0,-6.493877 3.710788,0 0,6.493877 c 0,1.539977 1.243113,2.783091 2.78309,2.783091 1.539977,0 2.78309,-1.243114 2.78309,-2.783091 l 0,-6.493877 1.855394,0 c 1.020466,0 1.855394,-0.834927 1.855394,-1.855394 l 0,-18.553936 -22.264724,0 z M 8.229155,16.578335 c -1.539977,0 -2.783091,1.243114 -2.783091,2.783091 l 0,12.987755 c 0,1.539976 1.243114,2.78309 2.783091,2.78309 1.539976,0 2.78309,-1.243114 2.78309,-2.78309 l 0,-12.987755 c 0,-1.539977 -1.243114,-2.783091 -2.78309,-2.783091 z m 31.54169,0 c -1.539976,0 -2.78309,1.243114 -2.78309,2.783091 l 0,12.987755 c 0,1.539976 1.243114,2.78309 2.78309,2.78309 1.539977,0 2.783091,-1.243114 2.783091,-2.78309 l 0,-12.987755 c 0,-1.539977 -1.243114,-2.783091 -2.783091,-2.783091 z M 30.549539,5.742837 32.970828,3.321548 c 0.361802,-0.361802 0.361802,-0.946251 0,-1.308052 -0.361802,-0.361802 -0.946251,-0.361802 -1.308052,0 L 28.916793,4.750201 C 27.432478,4.017321 25.771901,3.59058 24,3.59058 c -1.781178,0 -3.451032,0.426741 -4.944624,1.168898 L 16.300117,2.004219 c -0.361802,-0.361802 -0.946251,-0.361802 -1.308053,0 -0.361802,0.361801 -0.361802,0.94625 0,1.308052 l 2.430566,2.430566 c -2.75526,2.031656 -4.554992,5.297148 -4.554992,8.980105 l 22.264724,0 c 0,-3.692234 -1.809009,-6.957726 -4.582823,-8.980105 z M 19.3615,11.012155 c -0.542479,0 -0.927681,-0.418069 -0.927681,-0.928155 0,-0.510086 0.369591,-0.927239 0.927681,-0.927239 0.55809,0 0.927713,0.426961 0.927713,0.928239 0,0.501278 -0.385234,0.927155 -0.927713,0.927155 z m 9.277,0 c -0.600761,0.02226 -0.927713,-0.465564 -0.927713,-0.927655 0,-0.462091 0.396814,-0.927739 0.927713,-0.927739 0.530899,0 0.927681,0.443102 0.927681,0.927739 0,0.484637 -0.32692,0.905397 -0.927681,0.927655 z"
+ transform="matrix(0.72047804,0,0,0.7213519,6.7318483,6.6891355)" />
+ <path
+ sodipodi:nodetypes="sscsssccssscssccssssssssssssssscssccscssscccczzzzzzzzzz"
+ style="opacity:0.6;fill:#6bc1c1;fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0"
+ id="path3949"
+ d="m 16.002699,32.031866 c 0,0.736116 0.601547,1.338392 1.33677,1.338392 l 1.336771,0 0,4.68437 c 0,1.110866 0.895635,2.007588 2.005156,2.007588 1.109519,0 2.005154,-0.896722 2.005154,-2.007588 l 0,-4.68437 2.673542,0 0,4.68437 c 0,1.110866 0.895635,2.007588 2.005155,2.007588 1.10952,0 2.005155,-0.896722 2.005155,-2.007588 l 0,-4.68437 1.336771,0 c 0.735223,0 1.33677,-0.602276 1.33677,-1.338392 l 0,-13.383917 -16.041244,0 z M 12.660774,18.647949 c -1.10952,0 -2.005156,0.896722 -2.005156,2.007588 l 0,9.368741 c 0,1.110865 0.895636,2.007588 2.005156,2.007588 1.109518,0 2.005155,-0.896723 2.005155,-2.007588 l 0,-9.368741 c 0,-1.110866 -0.895637,-2.007588 -2.005155,-2.007588 z m 22.725095,0 c -1.10952,0 -2.005156,0.896722 -2.005156,2.007588 l 0,9.368741 c 0,1.110865 0.895636,2.007588 2.005156,2.007588 1.109519,0 2.005155,-0.896723 2.005155,-2.007588 l 0,-9.368741 c 0,-1.110866 -0.895636,-2.007588 -2.005155,-2.007588 z M 28.74212,10.831741 30.486605,9.0851405 c 0.260671,-0.2609863 0.260671,-0.6825797 0,-0.9435662 -0.26067,-0.2609863 -0.681752,-0.2609863 -0.942422,0 l -1.97842,1.9741277 C 26.496346,9.5870374 25.299937,9.2792073 24.023321,9.2792073 c -1.283299,0 -2.486392,0.3078301 -3.562493,0.8431867 L 18.475724,8.1348825 c -0.26067,-0.2609865 -0.681753,-0.2609865 -0.942423,0 -0.26067,0.2609863 -0.26067,0.6825797 0,0.9435661 l 1.75117,1.7532924 c -1.985105,1.465539 -3.281772,3.821109 -3.281772,6.477816 l 16.041244,0 c 0,-2.663399 -1.30335,-5.018969 -3.301823,-6.477816 z m -8.060736,3.801033 c -0.390844,0 -0.668374,-0.301575 -0.668374,-0.669526 0,-0.367952 0.266282,-0.668865 0.668374,-0.668865 0.402091,0 0.668396,0.307989 0.668396,0.669587 0,0.361597 -0.277552,0.668804 -0.668396,0.668804 z m 6.683874,0 c -0.432835,0.01606 -0.668397,-0.335835 -0.668397,-0.669166 0,-0.33333 0.285897,-0.669225 0.668397,-0.669225 0.382502,0 0.668374,0.319632 0.668374,0.669225 0,0.349594 -0.235538,0.653111 -0.668374,0.669166 z" />
+ <path
+ style="fill:none"
+ inkscape:connector-curvature="0"
+ d="M 6.7318483,6.6891355 H 41.314795 V 41.314027 H 6.7318483 z"
+ id="path3072" />
+ <path
+ style="fill:#ffffff;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path3852"
+ d="m 12.660774,20.069261 c -0.44708,0 -0.564246,0.175612 -0.564246,1.286478 l 0,7.968241 c 0,1.110865 0.108254,1.28604 0.564246,1.28604 0.470843,0 0.564023,-0.175175 0.564023,-1.28604 l 0,-7.968241 c 0,-1.110866 -0.07833,-1.286478 -0.564023,-1.286478 z m 22.725206,0.361 c -0.504569,0 -0.564134,0.175612 -0.564134,1.286478 l 0,7.247241 c 0,1.110864 0.08466,1.28604 0.564023,1.28604 0.512973,0 0.564246,-0.175176 0.564246,-1.28604 l 0,-7.247241 c 0,-1.110866 -0.08477,-1.286478 -0.564135,-1.286478 z m -7.795932,-9.093817 2.663977,-2.5949285 c 0.108383,-0.1055735 0.06434,-0.2683976 -0.02073,-0.3542934 -0.08506,-0.085896 -0.320377,-0.059828 -0.417329,0.05926 l -2.609941,2.6064709 c -1.069417,-0.528665 -1.906096,-0.763551 -3.182712,-0.763551 -1.283299,0 -2.126425,0.235047 -3.202525,0.770404 L 18.204001,8.4397766 c -0.0889,-0.089013 -0.262937,-0.1579431 -0.382555,-0.016511 -0.119618,0.1414319 -0.08552,0.2835905 0.01655,0.382958 l 2.599503,2.5305814 c -1.242042,0.890276 -2.646962,2.360299 -2.805595,3.994013 -0.02916,0.300308 -0.03567,0.64879 0.05676,0.771869 0.09241,0.123078 0.24306,0.143031 0.24306,0.143031 l 12.023156,0 c 0,0 0.243151,-0.04207 0.301958,-0.151443 0.05881,-0.109377 0.112324,-0.354684 0.07727,-0.680595 -0.16722,-1.55458 -1.478226,-3.153195 -2.74406,-4.077236 z m -6.908664,3.584758 c -0.526962,0 -0.956435,-0.253004 -0.956435,-0.957595 0,-0.70459 0.528127,-1.029729 0.956435,-1.029729 0.428307,0 0.956434,0.305212 0.956434,1.029729 0,0.724518 -0.429472,0.957595 -0.956434,0.957595 z m 6.683874,0.07213 c -0.587253,0 -1.028482,-0.415879 -1.028482,-1.030091 0,-0.614211 0.406962,-1.029369 1.028843,-1.029369 0.62188,0 1.028122,0.423363 1.028122,1.029729 0,0.606367 -0.441229,1.029731 -1.028483,1.029731 z"
+ sodipodi:nodetypes="sssssssssssssscszccscszscszcczsczzzzzzzzzz" />
+ <rect
+ style="fill:#ffffff;fill-opacity:0.97716896;stroke:none"
+ id="rect3856"
+ width="1.2769656"
+ height="4.8565254"
+ x="20.039185"
+ y="33.769924"
+ ry="0.46252623" />
+ <rect
+ ry="0.46252623"
+ y="33.769924"
+ x="26.743933"
+ height="4.8565254"
+ width="1.2769656"
+ id="rect3858"
+ style="fill:#ffffff;fill-opacity:0.97716896;stroke:none" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4044"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,7.5486703,9.778199)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,8.7460832,9.790094)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4048"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4056"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,7.5486703,19.369198)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,8.7460832,19.381094)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4058"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4060"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,30.29884,9.7781986)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,31.496253,9.790094)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4062"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,30.29884,19.369198)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4064"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4066"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,31.496253,19.381094)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,15.574004,23.349403)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4068"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4070"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,16.771416,23.361299)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4072"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,22.274856,23.349403)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,23.472269,23.361299)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4074"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4076"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,15.574004,27.382394)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,16.771416,27.39429)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4078"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,22.274856,27.382394)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4080"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4082"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,23.472269,27.39429)" />
+</svg>
diff --git a/tools/memory_inspector/chrome_app/assets/cog1.svg b/tools/memory_inspector/chrome_app/assets/cog1.svg
new file mode 100644
index 0000000..f80535f
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/assets/cog1.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="9.6800003"
+ height="9.6800003"
+ viewBox="0 0 9.6800003 9.6800003"
+ id="svg3070"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="cog1.svg">
+ <defs
+ id="defs7" />
+ <metadata
+ id="metadata3080">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1855"
+ inkscape:window-height="1176"
+ id="namedview3076"
+ showgrid="false"
+ inkscape:zoom="45.254834"
+ inkscape:cx="0.5260293"
+ inkscape:cy="8.811166"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3070"
+ inkscape:snap-global="false"
+ fit-margin-top="0.1"
+ fit-margin-left="0.1"
+ fit-margin-right="0.1"
+ fit-margin-bottom="0.1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4407"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ originx="-17.146881px"
+ originy="-17.758715px" />
+ </sodipodi:namedview>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ d="M 4.0993739,0.10000031 3.955047,1.529977 C 3.6606418,1.6084493 3.3817812,1.7244042 3.1242193,1.8737023 L 2.0113836,0.9640616 0.96406137,2.0113834 1.8737015,3.125168 C 1.7244073,3.3828134 1.6084118,3.661503 1.5299762,3.9559988 L 0.1,4.0993751 l 0,1.4812504 1.4299762,0.144327 c 0.078437,0.2942422 0.1945471,0.5724334 0.3437253,0.8298801 L 0.96406137,7.6686182 2.0113836,8.715938 3.1251682,7.8062983 c 0.257443,0.1491762 0.5356366,0.2652919 0.8298788,0.3437263 l 0.1443269,1.4299757 1.4812501,0 0.1433782,-1.4299757 C 6.0184983,8.0715822 6.2971869,7.9555934 6.5548308,7.8062983 L 7.6686174,8.715938 8.7159366,7.6686182 7.8062965,6.5557823 C 7.9555957,6.2982177 8.0715462,6.0193584 8.1500238,5.7249525 L 9.58,5.5806255 9.58,4.0993751 8.1500238,3.9559988 C 8.0715462,3.6613382 7.9557117,3.3819836 7.8062965,3.1242193 L 8.7159366,2.0113834 7.6686174,0.9640616 6.5557807,1.8737023 C 6.2980168,1.7242884 6.0186622,1.6084563 5.7240022,1.529977 L 5.580624,0.10000031 z M 4.84,3.469844 c 0.7567674,0 1.3705197,0.6133893 1.3705197,1.3701568 0,0.7567685 -0.6137523,1.3701558 -1.3705197,1.3701558 -0.7567684,0 -1.3697928,-0.6133873 -1.3697928,-1.3701558 0,-0.7567675 0.6130244,-1.3701568 1.3697928,-1.3701568 z"
+ id="path3055"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccsssss" />
+</svg>
diff --git a/tools/memory_inspector/chrome_app/assets/cog2.svg b/tools/memory_inspector/chrome_app/assets/cog2.svg
new file mode 100644
index 0000000..4f5094e
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/assets/cog2.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="5.3200002"
+ height="5.3200002"
+ viewBox="0 0 5.3200001 5.3200001"
+ id="svg3070"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="cog2.svg">
+ <defs
+ id="defs7" />
+ <metadata
+ id="metadata3080">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1855"
+ inkscape:window-height="1176"
+ id="namedview3076"
+ showgrid="false"
+ inkscape:zoom="90.509668"
+ inkscape:cx="1.9628626"
+ inkscape:cy="2.935888"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3070"
+ inkscape:snap-global="false"
+ fit-margin-top="0.1"
+ fit-margin-bottom="0.1"
+ fit-margin-right="0.1"
+ fit-margin-left="0.1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4407"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ originx="-25.839217px"
+ originy="-16.914482px" />
+ </sodipodi:namedview>
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsssc"
+ inkscape:connector-curvature="0"
+ id="path3053"
+ d="M 2.5313438,0.10000017 2.3745594,0.85150325 C 2.2137389,0.87678122 2.0595108,0.9231857 1.914314,0.988141 L 1.3730812,0.44254207 0.75876058,0.9406976 1.1795007,1.5830834 C 1.0857868,1.7116618 1.0084841,1.8532134 0.950365,2.0053293 L 0.18296036,2.0014373 0.1,2.7889981 0.85160297,2.9455629 C 0.87686447,3.106301 0.92299857,3.2606303 0.9878984,3.4057636 L 0.44271562,3.9466193 0.9404913,4.5614876 1.5834533,4.1401878 C 1.7119259,4.2338351 1.853205,4.3107607 2.0051804,4.3688651 L 2.0019604,5.13745 2.7891415,5.2200001 2.9454423,4.467546 C 3.1063097,4.4423079 3.2604494,4.3968116 3.4056887,4.3318583 L 3.9469237,4.8774572 4.5622302,4.3793016 4.140502,3.7369169 C 4.234216,3.6083825 4.3115021,3.4667371 4.3696378,3.3146711 L 5.1380315,3.3174653 5.2200035,2.5308525 4.468397,2.3742888 C 4.4431251,2.2134169 4.3970949,2.0585457 4.332088,1.9132289 L 4.8772718,1.3733222 4.3794951,0.75750674 3.7375211,1.1788046 C 3.6088561,1.0850775 3.4669644,1.0083395 3.3147716,0.9501871 l 0.00364,-0.76763486 z M 2.6619661,1.9275214 c 0.024741,8.89e-5 0.04993,0.0012 0.075067,0.00389 0.4021284,0.042243 0.6931053,0.4024955 0.6508628,0.8046407 C 3.3456619,3.1382013 2.9860754,3.4301733 2.583948,3.3879283 2.1818185,3.3456852 1.8898546,2.9854338 1.9320961,2.5832866 1.9716991,2.2062736 2.2909014,1.9263319 2.6619715,1.9276182 z"
+ style="fill:#ffffff;fill-opacity:1;stroke:none" />
+</svg>
diff --git a/tools/memory_inspector/chrome_app/assets/generate_bitmaps.sh b/tools/memory_inspector/chrome_app/assets/generate_bitmaps.sh
new file mode 100755
index 0000000..70f6d15
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/assets/generate_bitmaps.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+ASSETS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+CHROME_APP_DIR="$(cd "${ASSETS_DIR}/.." && pwd)"
+IMAGES_DIR="$(cd "${CHROME_APP_DIR}/template/images" && pwd)"
+
+SRC_FILES=("icon.svg" "icon.svg" "icon.svg" "body.svg" "cog1.svg" "cog2.svg")
+DST_FILES=( \
+ "icon_16.png" "icon_48.png" "icon_128.png" "body.png" "cog1.png" "cog2.png")
+DST_SIZES=(16 48 128 300 60 30)
+
+# Generate bitmap images.
+for i in "${!SRC_FILES[@]}"; do
+ src_file="${ASSETS_DIR}/${SRC_FILES[$i]}"
+ dst_file="${IMAGES_DIR}/${DST_FILES[$i]}"
+ size="${DST_SIZES[$i]}"
+ echo "Generating ${dst_file}"
+ inkscape -z -e "${dst_file}" -w "${size}" -h "${size}" "${src_file}" > \
+ /dev/null
+done
+
diff --git a/tools/memory_inspector/chrome_app/assets/icon.svg b/tools/memory_inspector/chrome_app/assets/icon.svg
new file mode 100644
index 0000000..b295f8c
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/assets/icon.svg
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ viewBox="0 0 48 48"
+ id="svg3070"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="android_icon.svg">
+ <metadata
+ id="metadata3080">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3078">
+ <filter
+ inkscape:collect="always"
+ id="filter3987">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.0204955"
+ id="feGaussianBlur3989" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1855"
+ inkscape:window-height="1176"
+ id="namedview3076"
+ showgrid="false"
+ inkscape:zoom="16"
+ inkscape:cx="3.271104"
+ inkscape:cy="18.864582"
+ inkscape:window-x="1985"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3070"
+ inkscape:snap-global="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4407" />
+ </sodipodi:namedview>
+ <rect
+ style="fill:#323232;fill-opacity:1;stroke:none"
+ id="rect4405"
+ width="37.970795"
+ height="37.985714"
+ x="4.9828935"
+ y="4.9963875"
+ ry="2.8708735" />
+ <path
+ sodipodi:nodetypes="sscsssccssscssccssssssssssssssscssccscssscccczzzzzzzzzz"
+ style="fill:#6afff9;fill-opacity:1;stroke:none;filter:url(#filter3987)"
+ inkscape:connector-curvature="0"
+ id="path3903"
+ d="m 12.867638,35.132271 c 0,1.020467 0.834928,1.855394 1.855394,1.855394 l 1.855394,0 0,6.493877 c 0,1.539977 1.243113,2.783091 2.78309,2.783091 1.539977,0 2.78309,-1.243114 2.78309,-2.783091 l 0,-6.493877 3.710788,0 0,6.493877 c 0,1.539977 1.243113,2.783091 2.78309,2.783091 1.539977,0 2.78309,-1.243114 2.78309,-2.783091 l 0,-6.493877 1.855394,0 c 1.020466,0 1.855394,-0.834927 1.855394,-1.855394 l 0,-18.553936 -22.264724,0 z M 8.229155,16.578335 c -1.539977,0 -2.783091,1.243114 -2.783091,2.783091 l 0,12.987755 c 0,1.539976 1.243114,2.78309 2.783091,2.78309 1.539976,0 2.78309,-1.243114 2.78309,-2.78309 l 0,-12.987755 c 0,-1.539977 -1.243114,-2.783091 -2.78309,-2.783091 z m 31.54169,0 c -1.539976,0 -2.78309,1.243114 -2.78309,2.783091 l 0,12.987755 c 0,1.539976 1.243114,2.78309 2.78309,2.78309 1.539977,0 2.783091,-1.243114 2.783091,-2.78309 l 0,-12.987755 c 0,-1.539977 -1.243114,-2.783091 -2.783091,-2.783091 z M 30.549539,5.742837 32.970828,3.321548 c 0.361802,-0.361802 0.361802,-0.946251 0,-1.308052 -0.361802,-0.361802 -0.946251,-0.361802 -1.308052,0 L 28.916793,4.750201 C 27.432478,4.017321 25.771901,3.59058 24,3.59058 c -1.781178,0 -3.451032,0.426741 -4.944624,1.168898 L 16.300117,2.004219 c -0.361802,-0.361802 -0.946251,-0.361802 -1.308053,0 -0.361802,0.361801 -0.361802,0.94625 0,1.308052 l 2.430566,2.430566 c -2.75526,2.031656 -4.554992,5.297148 -4.554992,8.980105 l 22.264724,0 c 0,-3.692234 -1.809009,-6.957726 -4.582823,-8.980105 z M 19.3615,11.012155 c -0.542479,0 -0.927681,-0.418069 -0.927681,-0.928155 0,-0.510086 0.369591,-0.927239 0.927681,-0.927239 0.55809,0 0.927713,0.426961 0.927713,0.928239 0,0.501278 -0.385234,0.927155 -0.927713,0.927155 z m 9.277,0 c -0.600761,0.02226 -0.927713,-0.465564 -0.927713,-0.927655 0,-0.462091 0.396814,-0.927739 0.927713,-0.927739 0.530899,0 0.927681,0.443102 0.927681,0.927739 0,0.484637 -0.32692,0.905397 -0.927681,0.927655 z"
+ transform="matrix(0.72047804,0,0,0.7213519,6.7318483,6.6891355)" />
+ <path
+ sodipodi:nodetypes="sscsssccssscssccssssssssssssssscssccscssscccczzzzzzzzzz"
+ style="opacity:0.6;fill:#6bc1c1;fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0"
+ id="path3949"
+ d="m 16.002699,32.031866 c 0,0.736116 0.601547,1.338392 1.33677,1.338392 l 1.336771,0 0,4.68437 c 0,1.110866 0.895635,2.007588 2.005156,2.007588 1.109519,0 2.005154,-0.896722 2.005154,-2.007588 l 0,-4.68437 2.673542,0 0,4.68437 c 0,1.110866 0.895635,2.007588 2.005155,2.007588 1.10952,0 2.005155,-0.896722 2.005155,-2.007588 l 0,-4.68437 1.336771,0 c 0.735223,0 1.33677,-0.602276 1.33677,-1.338392 l 0,-13.383917 -16.041244,0 z M 12.660774,18.647949 c -1.10952,0 -2.005156,0.896722 -2.005156,2.007588 l 0,9.368741 c 0,1.110865 0.895636,2.007588 2.005156,2.007588 1.109518,0 2.005155,-0.896723 2.005155,-2.007588 l 0,-9.368741 c 0,-1.110866 -0.895637,-2.007588 -2.005155,-2.007588 z m 22.725095,0 c -1.10952,0 -2.005156,0.896722 -2.005156,2.007588 l 0,9.368741 c 0,1.110865 0.895636,2.007588 2.005156,2.007588 1.109519,0 2.005155,-0.896723 2.005155,-2.007588 l 0,-9.368741 c 0,-1.110866 -0.895636,-2.007588 -2.005155,-2.007588 z M 28.74212,10.831741 30.486605,9.0851405 c 0.260671,-0.2609863 0.260671,-0.6825797 0,-0.9435662 -0.26067,-0.2609863 -0.681752,-0.2609863 -0.942422,0 l -1.97842,1.9741277 C 26.496346,9.5870374 25.299937,9.2792073 24.023321,9.2792073 c -1.283299,0 -2.486392,0.3078301 -3.562493,0.8431867 L 18.475724,8.1348825 c -0.26067,-0.2609865 -0.681753,-0.2609865 -0.942423,0 -0.26067,0.2609863 -0.26067,0.6825797 0,0.9435661 l 1.75117,1.7532924 c -1.985105,1.465539 -3.281772,3.821109 -3.281772,6.477816 l 16.041244,0 c 0,-2.663399 -1.30335,-5.018969 -3.301823,-6.477816 z m -8.060736,3.801033 c -0.390844,0 -0.668374,-0.301575 -0.668374,-0.669526 0,-0.367952 0.266282,-0.668865 0.668374,-0.668865 0.402091,0 0.668396,0.307989 0.668396,0.669587 0,0.361597 -0.277552,0.668804 -0.668396,0.668804 z m 6.683874,0 c -0.432835,0.01606 -0.668397,-0.335835 -0.668397,-0.669166 0,-0.33333 0.285897,-0.669225 0.668397,-0.669225 0.382502,0 0.668374,0.319632 0.668374,0.669225 0,0.349594 -0.235538,0.653111 -0.668374,0.669166 z" />
+ <path
+ style="fill:none"
+ inkscape:connector-curvature="0"
+ d="M 6.7318483,6.6891355 H 41.314795 V 41.314027 H 6.7318483 z"
+ id="path3072" />
+ <path
+ style="fill:#ffffff;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path3852"
+ d="m 12.660774,20.069261 c -0.44708,0 -0.564246,0.175612 -0.564246,1.286478 l 0,7.968241 c 0,1.110865 0.108254,1.28604 0.564246,1.28604 0.470843,0 0.564023,-0.175175 0.564023,-1.28604 l 0,-7.968241 c 0,-1.110866 -0.07833,-1.286478 -0.564023,-1.286478 z m 22.725206,0.361 c -0.504569,0 -0.564134,0.175612 -0.564134,1.286478 l 0,7.247241 c 0,1.110864 0.08466,1.28604 0.564023,1.28604 0.512973,0 0.564246,-0.175176 0.564246,-1.28604 l 0,-7.247241 c 0,-1.110866 -0.08477,-1.286478 -0.564135,-1.286478 z m -7.795932,-9.093817 2.663977,-2.5949285 c 0.108383,-0.1055735 0.06434,-0.2683976 -0.02073,-0.3542934 -0.08506,-0.085896 -0.320377,-0.059828 -0.417329,0.05926 l -2.609941,2.6064709 c -1.069417,-0.528665 -1.906096,-0.763551 -3.182712,-0.763551 -1.283299,0 -2.126425,0.235047 -3.202525,0.770404 L 18.204001,8.4397766 c -0.0889,-0.089013 -0.262937,-0.1579431 -0.382555,-0.016511 -0.119618,0.1414319 -0.08552,0.2835905 0.01655,0.382958 l 2.599503,2.5305814 c -1.242042,0.890276 -2.646962,2.360299 -2.805595,3.994013 -0.02916,0.300308 -0.03567,0.64879 0.05676,0.771869 0.09241,0.123078 0.24306,0.143031 0.24306,0.143031 l 12.023156,0 c 0,0 0.243151,-0.04207 0.301958,-0.151443 0.05881,-0.109377 0.112324,-0.354684 0.07727,-0.680595 -0.16722,-1.55458 -1.478226,-3.153195 -2.74406,-4.077236 z m -6.908664,3.584758 c -0.526962,0 -0.956435,-0.253004 -0.956435,-0.957595 0,-0.70459 0.528127,-1.029729 0.956435,-1.029729 0.428307,0 0.956434,0.305212 0.956434,1.029729 0,0.724518 -0.429472,0.957595 -0.956434,0.957595 z m 6.683874,0.07213 c -0.587253,0 -1.028482,-0.415879 -1.028482,-1.030091 0,-0.614211 0.406962,-1.029369 1.028843,-1.029369 0.62188,0 1.028122,0.423363 1.028122,1.029729 0,0.606367 -0.441229,1.029731 -1.028483,1.029731 z"
+ sodipodi:nodetypes="sssssssssssssscszccscszscszcczsczzzzzzzzzz" />
+ <rect
+ style="fill:#ffffff;fill-opacity:0.97716896;stroke:none"
+ id="rect3856"
+ width="1.2769656"
+ height="4.8565254"
+ x="20.039185"
+ y="33.769924"
+ ry="0.46252623" />
+ <rect
+ ry="0.46252623"
+ y="33.769924"
+ x="26.743933"
+ height="4.8565254"
+ width="1.2769656"
+ id="rect3858"
+ style="fill:#ffffff;fill-opacity:0.97716896;stroke:none" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ d="m 21.496892,20.085776 -0.14435,1.431939 c -0.294452,0.07858 -0.573357,0.194694 -0.83096,0.344197 l -1.113013,-0.910889 -1.047489,1.048759 0.909785,1.115313 c -0.149318,0.257999 -0.265332,0.537071 -0.34378,0.831971 l -1.430204,0.143573 0,1.483283 1.430204,0.144525 c 0.07845,0.294646 0.194578,0.573219 0.34378,0.831019 l -0.909785,1.115314 1.047489,1.048757 1.113962,-0.910888 c 0.257484,0.149381 0.535722,0.265656 0.830011,0.344198 l 0.14435,1.431938 1.481486,0 0.143401,-1.431938 c 0.294543,-0.07855 0.573276,-0.194698 0.830961,-0.344198 l 1.113964,0.910888 1.047486,-1.048757 -0.909785,-1.114363 c 0.149323,-0.257918 0.265292,-0.53716 0.343782,-0.83197 l 1.430204,-0.144525 0,-1.483283 -1.430204,-0.143573 c -0.07849,-0.295065 -0.194343,-0.574803 -0.343782,-0.832921 l 0.909785,-1.114363 -1.047486,-1.048759 -1.113014,0.910889 c -0.257805,-0.149619 -0.537204,-0.26561 -0.831911,-0.344197 l -0.143401,-1.431939 z m 0.740744,3.374468 c 0.756888,0 1.370738,0.614231 1.370738,1.372037 0,0.757807 -0.61385,1.372036 -1.370738,1.372036 -0.756889,0 -1.370011,-0.614229 -1.370011,-1.372036 0,-0.757806 0.613122,-1.372037 1.370011,-1.372037 z"
+ id="path3055"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccsssss">
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="rotate"
+ from="0 21.988 25.395"
+ to="360 21.988 25.395"
+ dur="2s"
+ repeatDur="indefinite"
+ id="animateTransform3000" />
+ </path>
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4044"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,7.5486703,9.778199)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,8.7460832,9.790094)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4048"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4056"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,7.5486703,19.369198)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,8.7460832,19.381094)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4058"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4060"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,30.29884,9.7781986)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,31.496253,9.790094)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4062"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,30.29884,19.369198)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4064"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4066"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,31.496253,19.381094)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,15.574004,23.349403)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4068"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4070"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,16.771416,23.361299)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4072"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,22.274856,23.349403)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,23.472269,23.361299)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4074"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4076"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,15.574004,27.382394)" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,16.771416,27.39429)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4078"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.55879234,0,0,0.57941537,22.274856,27.382394)"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ sodipodi:ry="1.3526119"
+ sodipodi:rx="1.3526119"
+ sodipodi:cy="18.569031"
+ sodipodi:cx="8.0457087"
+ id="path4080"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path4082"
+ sodipodi:cx="8.0457087"
+ sodipodi:cy="18.569031"
+ sodipodi:rx="1.3526119"
+ sodipodi:ry="1.3526119"
+ d="m 9.3983206,18.569031 a 1.3526119,1.3526119 0 1 1 -2.7052238,0 1.3526119,1.3526119 0 1 1 2.7052238,0 z"
+ transform="matrix(0.55879234,0,0,0.57941537,23.472269,27.39429)" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsssc"
+ inkscape:connector-curvature="0"
+ id="path3053"
+ d="m 27.928862,26.697346 -0.213013,0.73786 c -0.15621,0.01235 -0.307867,0.04632 -0.452421,0.09955 l -0.473026,-0.588207 -0.630257,0.448196 0.349485,0.675196 c -0.100539,0.120881 -0.186436,0.256034 -0.254833,0.403273 l -0.734999,-0.06541 -0.145288,0.779784 0.707103,0.216593 c 0.01078,0.162534 0.04209,0.320341 0.09215,0.470469 l -0.567577,0.496377 0.425598,0.653894 0.651281,-0.369154 c 0.115278,0.103812 0.244224,0.191954 0.384992,0.262158 l -0.0673,0.767227 0.747377,0.145537 0.21263,-0.738848 c 0.156251,-0.0123 0.307747,-0.04538 0.452342,-0.0986 l 0.473028,0.588207 0.631201,-0.448117 -0.350431,-0.675274 c 0.100535,-0.120838 0.186424,-0.256085 0.254833,-0.403273 l 0.736039,0.06439 0.144262,-0.778916 -0.707103,-0.216593 C 29.584161,28.961 29.552994,28.80266 29.502844,28.652339 l 0.567499,-0.495429 -0.42552,-0.654839 -0.650334,0.369231 c -0.115456,-0.103908 -0.245005,-0.191911 -0.385977,-0.262181 l 0.06762,-0.766245 z m -0.02752,1.835379 c 0.0237,0.0021 0.04774,0.0052 0.0716,0.0099 0.381789,0.07442 0.630505,0.457483 0.556431,0.855667 -0.07407,0.398186 -0.443012,0.660914 -0.824799,0.586493 -0.38179,-0.07442 -0.631452,-0.457562 -0.557379,-0.855747 0.06944,-0.373299 0.39869,-0.627252 0.75414,-0.59622 z"
+ style="fill:#ffffff;fill-opacity:1;stroke:none">
+ <!--<animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="rotate"
+ from="360 28.401 28.42"
+ to="0 28.401 28.42"
+ dur="1.5s"
+ repeatDur="indefinite"
+ id="animateTransform3001" />-->
+ </path>
+</svg>
diff --git a/tools/memory_inspector/chrome_app/build.sh b/tools/memory_inspector/chrome_app/build.sh
new file mode 100755
index 0000000..7d3e9dd
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/build.sh
@@ -0,0 +1,72 @@
+#!/bin/bash -e
+
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+CHROME_APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+MEMORY_INSPECTOR_DIR="$(cd "${CHROME_APP_DIR}/.." && pwd)"
+TEMPLATE_DIR="${CHROME_APP_DIR}/template"
+
+OUT_DIR="${1:-${CHROME_APP_DIR}/out}"
+APP_FOLDER_NAME="memory_inspector_app"
+APP_DIR="${OUT_DIR}/${APP_FOLDER_NAME}"
+SANDBOX_DIR="${APP_DIR}/sandbox"
+ZIP_FILE="${APP_DIR}.zip"
+
+# NaCl Python prebuilts URL.
+NACL_PREBUILTS_BASE_URL="https://gsdview.appspot.com/naclports/builds/pepper_40/trunk-154-geacd680/publish/python/pnacl"
+
+# Memory Inspector prebuilts bucket and destination folder.
+MEMORY_INSPECTOR_PREBUILTS_BUCKET="chromium-telemetry"
+MEMORY_INSPECTOR_PREBUILTS_DIR="${MEMORY_INSPECTOR_DIR}/prebuilts"
+
+# Memory Inspector dependencies and destination folder in the sandbox
+# filesystem.
+MEMORY_INSPECTOR_DEPS=( \
+ "memory_inspector/" "classification_rules/" "prebuilts/" "start_web_ui")
+MEMORY_INSPECTOR_DEPS_FOLDER="memory_inspector"
+
+
+# Delete existing app folder and zip file.
+rm "${APP_DIR}" -rf
+rm "${ZIP_FILE}" -f
+
+# Create a new app folder.
+mkdir -p "${APP_DIR}"
+
+# Link all files from the template/ folder.
+ln -s -t "${APP_DIR}" "${TEMPLATE_DIR}"/*
+
+# Download NaCl Python prebuilt files.
+wget "${NACL_PREBUILTS_BASE_URL}/naclprocess.js" -P "${APP_DIR}" --no-verbose
+wget "${NACL_PREBUILTS_BASE_URL}/python.nmf" -P "${SANDBOX_DIR}" --no-verbose
+wget "${NACL_PREBUILTS_BASE_URL}/python.pexe" -P "${SANDBOX_DIR}" --no-verbose
+wget "${NACL_PREBUILTS_BASE_URL}/pydata_pnacl.tar" -P "${SANDBOX_DIR}" \
+ --no-verbose
+
+# Download Memory Inspector prebuilt files.
+download_from_google_storage --directory "${MEMORY_INSPECTOR_PREBUILTS_DIR}" \
+ --bucket "${MEMORY_INSPECTOR_PREBUILTS_BUCKET}"
+
+# Add Memory Inspector dependencies to pydata_pnacl.tar.
+tmp_dir="$(mktemp -d)"
+(
+ cd "${tmp_dir}"
+ ln -s "${MEMORY_INSPECTOR_DIR}" "${MEMORY_INSPECTOR_DEPS_FOLDER}"
+ for dependency in "${MEMORY_INSPECTOR_DEPS[@]}"; do
+ tar --owner="memory-inspector:1002" --group="memory-inspector:1002" \
+ --append --dereference --file "${SANDBOX_DIR}/pydata_pnacl.tar" \
+ "${MEMORY_INSPECTOR_DEPS_FOLDER}/${dependency}"
+ done
+)
+rm "${tmp_dir}" -rf
+echo "Chrome app directory: ${APP_DIR}"
+
+# Zip the app.
+(
+ cd "${OUT_DIR}"
+ zip "${ZIP_FILE}" "${APP_FOLDER_NAME}" -r -q
+)
+echo "Chrome app zip file: ${ZIP_FILE}"
+
diff --git a/tools/memory_inspector/chrome_app/template/background.js b/tools/memory_inspector/chrome_app/template/background.js
new file mode 100644
index 0000000..7128ff1
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/background.js
@@ -0,0 +1,86 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+/**
+ * Singleton object representing the Memory Inspector Chrome App.
+ * @constructor
+ */
+var MemoryInspectorApp = function() {
+ this.window_ = undefined;
+};
+
+/** Main window parameters. */
+MemoryInspectorApp.WINDOW_URL = 'main_window.html';
+MemoryInspectorApp.WINDOW_ID = 'main';
+MemoryInspectorApp.WINDOW_WIDTH = Math.min(screen.width, 1200);
+MemoryInspectorApp.WINDOW_HEIGHT = Math.min(screen.height, 800);
+
+/**
+ * Launch the Memory Inspector. If it is already running, focus the main window.
+ */
+MemoryInspectorApp.prototype.launch = function() {
+ if (this.window_ === undefined) {
+ this.start_();
+ } else {
+ this.focus_();
+ }
+};
+
+/**
+ * Start the Memory Inspector by creating the main window.
+ * @private
+ */
+MemoryInspectorApp.prototype.start_ = function() {
+ var options = {
+ 'id': MemoryInspectorApp.WINDOW_ID,
+ 'bounds': {
+ 'width': MemoryInspectorApp.WINDOW_WIDTH,
+ 'height': MemoryInspectorApp.WINDOW_HEIGHT
+ },
+ 'hidden': true // The main window shows itself after it retrieves settings.
+ };
+ chrome.app.window.create(MemoryInspectorApp.WINDOW_URL, options,
+ this.onWindowCreated_.bind(this));
+};
+
+/**
+ * Listener called when the main window is created.
+ * @private
+ * @param {AppWindow} createdWindow The created window.
+ */
+MemoryInspectorApp.prototype.onWindowCreated_ = function(createdWindow) {
+ this.window_ = createdWindow;
+ this.window_.onClosed.addListener(this.onWindowClosed_.bind(this));
+};
+
+/**
+ * Listener called when the main window is closed.
+ * @private
+ */
+MemoryInspectorApp.prototype.onWindowClosed_ = function() {
+ this.window_ = undefined;
+};
+
+/**
+ * Focus the main window.
+ * @private
+ */
+MemoryInspectorApp.prototype.focus_ = function() {
+ if (this.window_ !== undefined) {
+ this.window_.focus();
+ }
+};
+
+window.addEventListener('load', function() {
+ // Create the singleton MemoryInspectorApp instance and hook it up with the
+ // app launcher.
+ var app = new MemoryInspectorApp();
+ chrome.app.runtime.onLaunched.addListener(app.launch.bind(app));
+
+ // Make the instance global for debugging purposes.
+ window.app = app;
+});
+
diff --git a/tools/memory_inspector/chrome_app/template/config.js b/tools/memory_inspector/chrome_app/template/config.js
new file mode 100644
index 0000000..ebf4e53
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/config.js
@@ -0,0 +1,30 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+/**
+ * Configuration for the Memory Inspector Chrome App.
+ */
+var MemoryInspectorConfig = {};
+
+/** The port on which the Python server process will listen. */
+MemoryInspectorConfig.PORT = 8089;
+
+/** The path to the Python NMF file. */
+MemoryInspectorConfig.NMF = '/sandbox/python.nmf';
+
+/** The command-line arguments for the Python server process. */
+MemoryInspectorConfig.ARGV = [
+ 'python.nmf',
+ '/memory_inspector/start_web_ui',
+ '--port', MemoryInspectorConfig.PORT,
+ '--no-browser'];
+
+/** The environment variables for the Python server process. */
+MemoryInspectorConfig.ENV = ['NACL_DATA_URL=/sandbox/'];
+
+/** The current working directory of the Python server process. */
+MemoryInspectorConfig.CWD = '/'; // Relative to the virtual filesystem.
+
diff --git a/tools/memory_inspector/chrome_app/template/images/body.png b/tools/memory_inspector/chrome_app/template/images/body.png
new file mode 100644
index 0000000..7d86626
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/images/body.png
Binary files differ
diff --git a/tools/memory_inspector/chrome_app/template/images/cog1.png b/tools/memory_inspector/chrome_app/template/images/cog1.png
new file mode 100644
index 0000000..9521e67
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/images/cog1.png
Binary files differ
diff --git a/tools/memory_inspector/chrome_app/template/images/cog2.png b/tools/memory_inspector/chrome_app/template/images/cog2.png
new file mode 100644
index 0000000..d5989b9
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/images/cog2.png
Binary files differ
diff --git a/tools/memory_inspector/chrome_app/template/images/icon_128.png b/tools/memory_inspector/chrome_app/template/images/icon_128.png
new file mode 100644
index 0000000..d437789
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/images/icon_128.png
Binary files differ
diff --git a/tools/memory_inspector/chrome_app/template/images/icon_16.png b/tools/memory_inspector/chrome_app/template/images/icon_16.png
new file mode 100644
index 0000000..85c1589
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/images/icon_16.png
Binary files differ
diff --git a/tools/memory_inspector/chrome_app/template/images/icon_48.png b/tools/memory_inspector/chrome_app/template/images/icon_48.png
new file mode 100644
index 0000000..aaa597c
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/images/icon_48.png
Binary files differ
diff --git a/tools/memory_inspector/chrome_app/template/main_window.css b/tools/memory_inspector/chrome_app/template/main_window.css
new file mode 100644
index 0000000..d0db251
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/main_window.css
@@ -0,0 +1,247 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+body {
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ height: 100%;
+ width: 100%;
+ overflow: hidden;
+}
+
+/******************************************************************************
+ * Terminal
+ ******************************************************************************/
+
+#terminal {
+ display: block;
+ position: absolute;
+ margin: 0;
+ padding: 3px;
+ width: calc(100% - 6px);
+ height: calc(25% - 6px);
+ overflow-x: hidden;
+ overflow-y: auto;
+ top: -25%;
+ left: 0;
+ z-index: 20;
+
+ background: #000000;
+
+ font-size: 12px;
+ font-family: 'DejaVu Sans Mono', 'Everson Mono', FreeMono, Menlo, Terminal,
+ monospace;
+ color: #FFFFFF;
+
+ -webkit-user-select: text;
+ user-select: text;
+
+ /* Animation for toggling the terminal. */
+ transition: top 0.2s ease-in-out;
+}
+
+body.terminal_visible #terminal {
+ top: 0;
+}
+
+.terminal_message_output {
+ /* Use default style. */
+}
+
+.terminal_message_info {
+ color: #06989A;
+}
+
+.terminal_message_error {
+ color: #FF0000;
+}
+
+#terminal_button {
+ display: block;
+ position: absolute;
+ padding: 5px 10px 10px 10px;
+ border-radius: 0 0 10px 10px;
+ width: 15px;
+ top: 0;
+ right: 50px;
+ z-index: 30;
+
+ background: #333333;
+ opacity: 0.5;
+
+ text-align: center;
+ font-size: 12px;
+ font-family: 'DejaVu Sans Mono', 'Everson Mono', FreeMono, Menlo, Terminal,
+ monospace;
+ font-weight: bold;
+ color: #AAAAAA;
+}
+
+#terminal_button:hover {
+ background: #555555;
+ color: #FFFFFF;
+ opacity: 0.7;
+}
+
+#terminal_button:active {
+ background: #777777;
+ color: #FFFFFF;
+ opacity: 0.7;
+}
+
+/******************************************************************************
+ * Contents
+ ******************************************************************************/
+
+#contents {
+ display: block;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ margin: 0;
+ padding: 0;
+
+ /* Animation for toggling the terminal. */
+ transition: height 0.2s ease-in-out, top 0.2s ease-in-out;
+}
+
+body.terminal_visible #contents {
+ top: 25%;
+ height: 75%;
+}
+
+#inspector_view {
+ display: block;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+ z-index: 0;
+ visibility: none;
+}
+
+body.inspector_view_visible #inspector_view {
+ visibility: visible;
+}
+
+#load_overlay {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+ z-index: 10;
+ background: #DDDDDD;
+
+ /* Fade out animation. */
+ transition: visibility 0s linear 0.2s, opacity 0.2s linear;
+}
+
+body.inspector_view_visible #load_overlay {
+ visibility: none;
+ pointer-events: none;
+ opacity: 0;
+}
+
+/******************************************************************************
+ * Load message
+ ******************************************************************************/
+
+#load_message {
+ display: block;
+ position: absolute;
+
+ /* Center the loading screen. */
+ top: 50%;
+ left: 50%;
+ transform: translateY(-50%) translateX(-50%);
+
+ font-family: Helvetica, Arial, sans-serif;
+ text-align: center;
+}
+
+#load_message_title {
+ margin-top: -12px;
+ margin-bottom: 12px;
+ color: #0073EA;
+ font-weight: bold;
+ font-size: 20px;
+}
+
+#load_dots,
+#phantom_load_dots {
+ display: inline-block;
+ width: 3em;
+ text-align: left;
+}
+
+#load_message_subtitle {
+ color: gray;
+ font-style: italic;
+ font-size: 12px;
+}
+
+/******************************************************************************
+ * Load animation
+ ******************************************************************************/
+
+#load_animation {
+ display: inline-block;
+ position: relative;
+ padding: 0;
+ width: 300px;
+ height: 300px;
+ overflow: hidden;
+}
+
+#load_animation_body {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+#load_animation_cog1 {
+ position: absolute;
+ top: 125px;
+ left: 109px;
+
+ -webkit-animation: clockwise_spin 2s linear infinite;
+ animation: clockwise_spin 2s linear infinite;
+}
+
+#load_animation_cog2 {
+ position: absolute;
+ top: 168px;
+ left: 159px;
+
+ -webkit-animation: counterclockwise_spin 1s linear infinite;
+ animation: counterclockwise_spin 1s linear infinite;
+}
+
+@-webkit-keyframes clockwise_spin {
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+@keyframes clockwise_spin {
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+@-webkit-keyframes counterclockwise_spin {
+ 100% {
+ transform: rotate(-360deg);
+ }
+}
+@keyframes counterclockwise_spin {
+ 100% {
+ transform: rotate(-360deg);
+ }
+}
+
diff --git a/tools/memory_inspector/chrome_app/template/main_window.html b/tools/memory_inspector/chrome_app/template/main_window.html
new file mode 100644
index 0000000..a876e03
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/main_window.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!--
+Copyright 2015 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<html>
+ <head>
+ <title>Memory Inspector</title>
+ <script type="text/javascript" src="naclprocess.js"></script>
+ <script type="text/javascript" src="config.js"></script>
+ <script type="text/javascript" src="main_window.js"></script>
+ <link rel="stylesheet" type="text/css" href="main_window.css">
+ </head>
+ <body>
+ <a id="terminal_button">&gt;_</a>
+ <div id="terminal">
+ </div>
+ <div id="contents">
+ <div id="load_overlay">
+ <div id="load_message">
+ <div id="load_animation">
+ <img id="load_animation_body" src="images/body.png" alt=""></img>
+ <img id="load_animation_cog1" src="images/cog1.png" alt=""></img>
+ <img id="load_animation_cog2" src="images/cog2.png" alt=""></img>
+ </div>
+ <div id="load_message_title">
+ <span id="phantom_load_dots"></span>Loading<span id="load_dots"></span>
+ </div>
+ <div id="load_message_subtitle">
+ This usually takes around 5 seconds but may take up to a minute after a fresh installation or an update
+ </div>
+ </div>
+ </div>
+ <webview id="inspector_view"></webview>
+ </div>
+ </body>
+</html>
diff --git a/tools/memory_inspector/chrome_app/template/main_window.js b/tools/memory_inspector/chrome_app/template/main_window.js
new file mode 100644
index 0000000..fc9e124
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/main_window.js
@@ -0,0 +1,393 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+/**
+ * Singleton object representing the main window of the Memory Inspector Chrome
+ * App.
+ * @constructor
+ */
+var MemoryInspectorWindow = function() {
+ // HTML elements in the window.
+ this.terminalElement_ = undefined;
+ this.terminalButtonElement_ = undefined;
+ this.contentsElement_ = undefined;
+ this.inspectorViewElement_ = undefined;
+ this.loadOverlayElement_ = undefined;
+ this.loadMessageElement_ = undefined;
+ this.loadDotsElement_ = undefined;
+ this.phantomLoadDots_ = undefined;
+
+ // Dots animation.
+ this.loadDotsAnimationIntervalId_ = undefined;
+
+ // Process manager.
+ this.processManager_ = undefined;
+
+ // Terminal.
+ this.terminalVisible_ = false;
+};
+
+/** The threshold for terminal auto-scroll. */
+MemoryInspectorWindow.AUTOSCROLL_THRESHOLD = 10;
+
+/** The interval between steps of the loading dots animation (milliseconds). */
+MemoryInspectorWindow.LOAD_DOTS_ANIMATION_INTERVAL = 500;
+
+/** The maximum number of dots in the loading dots animation. */
+MemoryInspectorWindow.MAX_LOAD_DOTS_COUNT = 3;
+
+/** The interval between polls to the backend server (milliseconds). */
+MemoryInspectorWindow.POLL_INTERVALL = 500;
+
+/**
+ * Initialize the main window. It will be shown once settings are retrieved
+ * (asynchronous request).
+ * @private
+ */
+MemoryInspectorWindow.prototype.initialize = function() {
+ this.setUpGui_();
+ this.startServerProcess_();
+ this.retrieveSettings_();
+ this.pollServer_();
+};
+
+/**
+ * Set up the main window. This method retrieves relevant HTML elements, adds
+ * corresponding event handlers, and starts animations.
+ * @private
+ */
+MemoryInspectorWindow.prototype.setUpGui_ = function() {
+ // Retrieve HTML elements in the window.
+ this.terminalElement_ = document.getElementById('terminal');
+ this.terminalButtonElement_ = document.getElementById('terminal_button');
+ this.contentsElement_ = document.getElementById('contents');
+ this.inspectorViewElement_ = document.getElementById('inspector_view');
+ this.loadOverlayElement_ = document.getElementById('load_overlay');
+ this.loadMessageElement_ = document.getElementById('load_message');
+ this.loadDotsElement_ = document.getElementById('load_dots');
+ this.phantomLoadDotsElement_ = document.getElementById('phantom_load_dots');
+
+ // Hook up the terminal toggle button.
+ this.terminalButtonElement_.addEventListener('click',
+ this.toggleTerminal_.bind(this));
+
+ // Print app name and version in the terminal.
+ var manifest = chrome.runtime.getManifest();
+ this.printInfo_(manifest.name + ' (version ' + manifest.version + ')\n');
+
+ // Start the loading dots animation.
+ this.loadDotsAnimationIntervalId_ = window.setInterval(
+ this.animateLoadDots_.bind(this),
+ MemoryInspectorWindow.LOAD_DOTS_ANIMATION_INTERVAL);
+};
+
+/**
+ * Toggle the terminal.
+ * @private
+ */
+MemoryInspectorWindow.prototype.toggleTerminal_ = function() {
+ if (this.terminalVisible_) {
+ this.hideTerminal_();
+ } else {
+ this.showTerminal_();
+ }
+ this.storeSettings_();
+};
+
+/**
+ * Show the terminal.
+ * @private
+ */
+MemoryInspectorWindow.prototype.showTerminal_ = function() {
+ // Scroll to the bottom.
+ this.terminalElement_.scrollTop = terminal.scrollHeight;
+ document.body.classList.add('terminal_visible');
+ this.terminalVisible_ = true;
+};
+
+/**
+ * Hide the terminal.
+ * @private
+ */
+MemoryInspectorWindow.prototype.hideTerminal_ = function() {
+ document.body.classList.remove('terminal_visible');
+ this.terminalVisible_ = false;
+};
+
+/**
+ * Stop the loading dots animation.
+ * @private
+ */
+MemoryInspectorWindow.prototype.stopLoadDotsAnimation_ = function() {
+ window.clearInterval(this.loadDotsAnimationIntervalId_);
+ this.loadDotsAnimationIntervalId_ = undefined;
+};
+
+/**
+ * Animate the loading dots.
+ * @private
+ */
+MemoryInspectorWindow.prototype.animateLoadDots_ = function() {
+ if (this.loadDotsElement_.innerText.length >=
+ MemoryInspectorWindow.MAX_LOAD_DOTS_COUNT) {
+ this.loadDotsElement_.innerText = '.';
+ } else {
+ this.loadDotsElement_.innerText += '.';
+ }
+};
+
+/**
+ * Start the server process inside PNaCl.
+ * @private
+ */
+MemoryInspectorWindow.prototype.startServerProcess_ = function() {
+ // Create and hook up a NaCl process manager.
+ var mgr = this.processManager = new NaClProcessManager();
+ mgr.setStdoutListener(this.onServerStdout_.bind(this));
+ mgr.setErrorListener(this.onServerError_.bind(this));
+ mgr.setRootProgressListener(this.onServerProgress_.bind(this));
+ mgr.setRootLoadListener(this.onServerLoad_.bind(this));
+
+ // Set dummy terminal size.
+ // (see https://code.google.com/p/naclports/issues/detail?id=186)
+ mgr.onTerminalResize(200, 200);
+
+ // Spawn the server process.
+ this.printInfo_('Spawning ' + MemoryInspectorConfig.ARGV.join(' ') + '\n');
+ mgr.spawn(
+ MemoryInspectorConfig.NMF,
+ MemoryInspectorConfig.ARGV,
+ MemoryInspectorConfig.ENV,
+ MemoryInspectorConfig.CWD,
+ 'pnacl',
+ null /* parent */,
+ this.onServerProcessSpawned_.bind(this));
+};
+
+/**
+ * Listener called when the server process is spawned.
+ * @private
+ * @param {number} pid The PID of the spawned server process or error code if
+ * negative.
+ */
+MemoryInspectorWindow.prototype.onServerProcessSpawned_ = function(pid) {
+ this.processManager.waitpid(pid, 0, this.onServerProcessExit_.bind(this));
+};
+
+/**
+ * Listener called when the server process exits.
+ * @private
+ * @param {number} pid The PID of the server process or an error code on error.
+ * @param {number} status The exit code of the server process.
+ */
+MemoryInspectorWindow.prototype.onServerProcessExit_ = function(pid, status) {
+ this.printInfo_('NaCl module exited with status ' + status + '\n');
+};
+
+/**
+ * Listener called when an stdout event is received from the server process.
+ * @private
+ * @param {string} msg The string sent to stdout.
+ */
+MemoryInspectorWindow.prototype.onServerStdout_ = function(msg) {
+ this.printOutput_(msg);
+};
+
+/**
+ * Listener called when an error event is received from the server process.
+ * @private
+ * @param {string} cmd The name of the process with the error.
+ * @param {string} err The error message.
+ */
+MemoryInspectorWindow.prototype.onServerError_ = function(cmd, err) {
+ this.printError_(cmd + ': ' + err + '\n');
+};
+
+/**
+ * Listener called when a part of the server NaCl module has been loaded.
+ * @private
+ * @param {string} url The URL that is being loaded.
+ * @param {boolean} lengthComputable Is our progress quantitatively measurable?
+ * @param {number} loaded The number of bytes that have been loaded.
+ * @param {number} total The total number of bytes to be loaded.
+ */
+MemoryInspectorWindow.prototype.onServerProgress_ = function(url,
+ lengthComputable, loaded, total) {
+ if (url === undefined) {
+ return;
+ }
+
+ var message = 'Loading ' + url.substring(url.lastIndexOf('/') + 1);
+ if (lengthComputable && total > 0) {
+ var percentLoaded = Math.round(loaded / total * 100);
+ var kbLoaded = Math.round(loaded / 1024);
+ var kbTotal = Math.round(total / 1024);
+ message += ' [' + kbLoaded + '/' + kbTotal + ' KiB ' + percentLoaded + '%]';
+ }
+ this.printInfo_(message + '\n');
+};
+
+/**
+ * Listener called when the server NaCl module has been successfully loaded.
+ * @private
+ */
+MemoryInspectorWindow.prototype.onServerLoad_ = function() {
+ this.printInfo_('NaCl module loaded\n');
+};
+
+/**
+ * Print an output message in the terminal.
+ * @private
+ * @param {string} msg The text of the message.
+ */
+MemoryInspectorWindow.prototype.printOutput_ = function(msg) {
+ this.printMessage_(msg, 'terminal_message_output');
+};
+
+/**
+ * Print an info message in the terminal.
+ * @private
+ * @param {string} msg The text of the message.
+ */
+MemoryInspectorWindow.prototype.printInfo_ = function(msg) {
+ this.printMessage_(msg, 'terminal_message_info');
+};
+
+/**
+ * Print an error message in the terminal.
+ * @private
+ * @param {string} msg The text of the message.
+ */
+MemoryInspectorWindow.prototype.printError_ = function(msg) {
+ this.printMessage_(msg, 'terminal_message_error');
+};
+
+/**
+ * Print a message of a given type in the terminal.
+ * @private
+ * @param {string} msg The text of the message.
+ * @param {string} cls The CSS class of the message.
+ */
+MemoryInspectorWindow.prototype.printMessage_ = function(msg, cls) {
+ // Determine whether we are at the bottom of the terminal.
+ var scrollBottom = this.terminalElement_.scrollTop +
+ this.terminalElement_.clientHeight;
+ var autoscrollBottomMin = this.terminalElement_.scrollHeight -
+ MemoryInspectorWindow.AUTOSCROLL_THRESHOLD;
+ var shouldScroll = scrollBottom >= autoscrollBottomMin;
+
+ // Append the message to the terminal.
+ var messageElement = document.createElement('span');
+ messageElement.innerText = msg;
+ messageElement.classList.add(cls);
+ this.terminalElement_.appendChild(messageElement);
+
+ // If we were at the bottom of the terminal, scroll to the bottom again.
+ if (shouldScroll) {
+ this.terminalElement_.scrollTop = this.terminalElement_.scrollHeight;
+ }
+};
+
+/**
+ * Asynchronously retrieve main window settings from local storage.
+ * @private
+ */
+MemoryInspectorWindow.prototype.retrieveSettings_ = function() {
+ chrome.storage.local.get('terminal_visible',
+ this.onSettingsRetrieved_.bind(this));
+};
+
+/**
+ * Asynchronously store main window settings in local storage.
+ * @private
+ */
+MemoryInspectorWindow.prototype.storeSettings_ = function() {
+ var settings = {};
+ settings['terminal_visible'] = this.terminalVisible_;
+ chrome.storage.local.set(settings);
+};
+
+/**
+ * Listener called when main window settings were retrieved from local storage.
+ * It saves them and finally shows the app window.
+ * @private
+ * @param {Object.<string, *>} settings The retrieved settings.
+ */
+MemoryInspectorWindow.prototype.onSettingsRetrieved_ = function(settings) {
+ if (chrome.runtime.lastError === undefined && settings['terminal_visible']) {
+ // Skip CSS animations by temporarily hiding everything.
+ document.body.style.display = 'none';
+ this.showTerminal_();
+ document.body.style.display = 'block';
+ }
+
+ // We are finally ready to show the window.
+ chrome.app.window.current().show();
+};
+
+/**
+ * Keep polling the backend server until it is reachable. The requests are
+ * asynchronous.
+ * @private
+ */
+MemoryInspectorWindow.prototype.pollServer_ = function() {
+ var requestUrl = 'http://127.0.0.1:' + MemoryInspectorConfig.PORT +
+ '?timestamp=' + new Date().getTime();
+ var request = new XMLHttpRequest();
+ request.addEventListener('readystatechange',
+ this.onPollRequestStateChange_.bind(this, request));
+ request.open('GET', requestUrl);
+ request.send();
+};
+
+/**
+ * Listener called when the state of the server request changes. If the request
+ * is complete and successful, the inspector view is navigated to the server.
+ * If unsuccessful, the request is repeated. Incomplete requests are ignored.
+ * @private
+ * @param {XMLHttpRequest} request The request.
+ */
+MemoryInspectorWindow.prototype.onPollRequestStateChange_ = function(request) {
+ // We wait until the request is complete.
+ if (request.readyState !== XMLHttpRequest.DONE) {
+ return;
+ }
+
+ // If the request was not successful, try again.
+ if (request.status !== 200) {
+ console.log('Inspector server unreachable. Trying again...');
+ setTimeout(this.pollServer_.bind(this),
+ MemoryInspectorWindow.POLL_INTERVALL);
+ return;
+ }
+
+ // Stop the animation, load the inspector, and display it.
+ console.log('Inspector server ready. Loading the inspector view...');
+ this.inspectorViewElement_.addEventListener('loadstop',
+ this.onInspectorLoaded_.bind(this));
+ this.inspectorViewElement_.src = 'http://127.0.0.1:' +
+ MemoryInspectorConfig.PORT;
+};
+
+/**
+ * Listener called when the inspector is loaded. It stops the loading dots
+ * animation, shows the inspector view, and fades out the loading overlay.
+ * @private
+ */
+MemoryInspectorWindow.prototype.onInspectorLoaded_ = function() {
+ this.stopLoadDotsAnimation_();
+ document.body.classList.add('inspector_view_visible');
+};
+
+window.addEventListener('load', function() {
+ // Create the singleton MemoryInspectorWindow instance and initialize it.
+ var mainWindow = new MemoryInspectorWindow();
+ mainWindow.initialize();
+
+ // Make the instance global for debugging purposes.
+ window.mainWindow = mainWindow;
+});
+
diff --git a/tools/memory_inspector/chrome_app/template/manifest.json b/tools/memory_inspector/chrome_app/template/manifest.json
new file mode 100644
index 0000000..a88b39f
--- /dev/null
+++ b/tools/memory_inspector/chrome_app/template/manifest.json
@@ -0,0 +1,35 @@
+{
+ "name": "Memory Inspector",
+ "description": "Memory inspector tool for Android",
+ "version": "0.1.0",
+ "manifest_version": 2,
+ "icons": {
+ "16": "images/icon_16.png",
+ "48": "images/icon_48.png",
+ "128": "images/icon_128.png"
+ },
+ "app": {
+ "background": {
+ "scripts": [
+ "background.js"
+ ]
+ }
+ },
+ "permissions": [
+ "storage",
+ "system.storage",
+ "unlimitedStorage",
+ "fileSystem",
+ "webview",
+ {
+ "socket": [
+ "tcp-listen:*:*",
+ "tcp-connect",
+ "resolve-host",
+ "udp-bind:*:*",
+ "udp-send-to:*:*"
+ ]
+ },
+ "http://127.0.0.1:*/*"
+ ]
+}
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_server.py b/tools/memory_inspector/memory_inspector/frontends/www_server.py
index f8368fb..9e7e604 100644
--- a/tools/memory_inspector/memory_inspector/frontends/www_server.py
+++ b/tools/memory_inspector/memory_inspector/frontends/www_server.py
@@ -753,7 +753,8 @@ def Start(http_port):
for k, v in _persistent_storage.LoadSettings(backend.name).iteritems():
backend.settings[k] = v
- httpd = wsgiref.simple_server.make_server('', http_port, _HttpRequestHandler)
+ httpd = wsgiref.simple_server.make_server(
+ '127.0.0.1', http_port, _HttpRequestHandler)
try:
httpd.serve_forever()
except KeyboardInterrupt:
diff --git a/tools/memory_inspector/start_web_ui b/tools/memory_inspector/start_web_ui
index 2c16b64..3d0f8d8 100755
--- a/tools/memory_inspector/start_web_ui
+++ b/tools/memory_inspector/start_web_ui
@@ -34,5 +34,5 @@ if __name__ == '__main__':
print 'Serving on port %d' % options.port
if not options.no_browser:
import webbrowser
- webbrowser.open('http://localhost:%d' % options.port)
+ webbrowser.open('http://127.0.0.1:%d' % options.port)
www_server.Start(options.port)