diff --git a/tools/droiddoc/templates-pdk/assets/android-developer-resource-browser.js b/tools/droiddoc/templates-pdk/assets/android-developer-resource-browser.js
new file mode 100644
index 0000000..dc65aa2
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/assets/android-developer-resource-browser.js
@@ -0,0 +1,235 @@
+(function() { // anonymize
+
+var allTags = {};
+var loadedResults = [];
+
+/**
+ * Initialization code run upon the DOM being ready.
+ */
+$(document).ready(function() {
+  // Parse page query parameters.
+  var params = parseParams(document.location.search);
+  params.tag = params.tag ? makeArray(params.tag) : null;
+
+  // Load tag and resource dataset.
+  loadTags();
+  loadResources();
+
+  showResults(params);
+
+  // Watch for keypresses in the keyword filter textbox, and update
+  // search results to reflect the keyword filter.
+  $('#resource-browser-keyword-filter').keyup(function() {
+    // Filter results on screen by keyword.
+    var keywords = $(this).val().split(/\s+/g);
+    for (var i = 0; i < loadedResults.length; i++) {
+      var hide = false;
+      for (var j = 0; j < keywords.length; j++) {
+        if (!resultMatchesKeyword(loadedResults[i].result, keywords[j])) {
+          hide = true;
+          break;
+        }
+      }
+
+      loadedResults[i].node[hide ? 'hide' : 'show']();
+    }
+  });
+});
+
+/**
+ * Returns whether or not the given search result contains the given keyword.
+ */
+function resultMatchesKeyword(result, keyword) {
+  keyword = keyword.toLowerCase();
+  if (result.title &&
+      result.title.en.toLowerCase().indexOf(keyword) >= 0)
+    return true;
+  else if (result.description &&
+           result.description.en.toLowerCase().indexOf(keyword) >= 0)
+    return true;
+  else if (result.topicsHtml &&
+           result.topicsHtml.replace(/\<.*?\>/g,'').toLowerCase().indexOf(keyword) >= 0)
+    return true;
+  return false;
+}
+
+/**
+ * Populates the allTags array with tag data from the ANDROID_TAGS
+ * variable in the resource data JS file.
+ */
+function loadTags() {
+  for (var tagClass in ANDROID_TAGS) {
+    for (var tag in ANDROID_TAGS[tagClass]) {
+      allTags[tag] = {
+        displayTag: ANDROID_TAGS[tagClass][tag],
+        tagClass: tagClass
+      };
+    }
+  }
+}
+
+/**
+ * Massage the ANDROID_RESOURCES resource list in the resource data JS file.
+ */
+function loadResources() {
+  for (var i = 0; i < ANDROID_RESOURCES.length; i++) {
+    var resource = ANDROID_RESOURCES[i];
+
+    // Convert the tags array to a tags hash for easier querying.
+    resource.tagsHash = {};
+    for (var j = 0; j < resource.tags.length; j++)
+      resource.tagsHash[resource.tags[j]] = true;
+
+    // Determine the type and topics of the resource by inspecting its tags.
+    resource.topics = [];
+    for (tag in resource.tagsHash)
+      if (tag in allTags) {
+        if (allTags[tag].tagClass == 'type') {
+          resource.type = tag;
+        } else if (allTags[tag].tagClass == 'topic') {
+          resource.topics.push(tag);
+        }
+      }
+
+    // Add a humanized topics list string.
+    resource.topicsHtml = humanizeList(resource.topics, function(item) {
+      return '<strong>' + allTags[item].displayTag + '</strong>';
+    });
+  }
+}
+
+/**
+ * Loads resources for the given query parameters.
+ */
+function showResults(params) {
+  loadedResults = [];
+  $('#resource-browser-search-params').empty();
+  $('#resource-browser-results').empty();
+
+  var i, j;
+  var searchTags = [];
+  if (params.tag) {
+    for (i = 0; i < params.tag.length; i++) {
+      var tag = params.tag[i];
+      if (tag.toLowerCase() in allTags) {
+        searchTags.push(tag.toLowerCase());
+      }
+    }
+  }
+
+  if (searchTags.length) {
+    // Show query params.
+    var taggedWithHtml = ['Showing technical resources tagged with '];
+    taggedWithHtml.push(humanizeList(searchTags, function(item) {
+      return '<strong>' + allTags[item].displayTag + '</strong>';
+    }));
+    $('#resource-browser-search-params').html(taggedWithHtml.join('') + ':');
+  } else {
+    $('#resource-browser-search-params').html('Showing all technical resources:');
+  }
+
+  var results = [];
+
+  // Create the list of resources to show.
+  for (i = 0; i < ANDROID_RESOURCES.length; i++) {
+    var resource = ANDROID_RESOURCES[i];
+    var skip = false;
+
+    if (searchTags.length) {
+      for (j = 0; j < searchTags.length; j++)
+        if (!(searchTags[j] in resource.tagsHash)) {
+          skip = true;
+          break;
+        }
+
+      if (skip)
+        continue;
+
+      results.push(resource);
+      continue;
+    }
+
+    results.push(resource);
+  }
+
+  // Format and show the list of resource results.
+  if (results.length) {
+    $('#resource-browser-results .no-results').hide();
+    for (i = 0; i < results.length; i++) {
+      var result = results[i];
+      var resultJqNode = $(tmpl('tmpl_resource_browser_result', result));
+      for (tag in result.tagsHash)
+        resultJqNode.addClass('tagged-' + tag);
+      $('#resource-browser-results').append(resultJqNode);
+
+      loadedResults.push({ node: resultJqNode, result: result });
+    }
+  } else {
+    $('#resource-browser-results .no-results').show();
+  }
+}
+
+/**
+ * Formats the given array into a human readable, English string, ala
+ * 'a, b and c', with an optional item formatter/wrapper function.
+ */
+function humanizeList(arr, itemFormatter) {
+  itemFormatter = itemFormatter || function(o){ return o; };
+  arr = arr || [];
+
+  var out = [];
+  for (var i = 0; i < arr.length; i++) {
+    out.push(itemFormatter(arr[i]) +
+        ((i < arr.length - 2) ? ', ' : '') +
+        ((i == arr.length - 2) ? ' and ' : ''));
+  }
+
+  return out.join('');
+}
+
+/**
+ * Parses a parameter string, i.e. foo=1&bar=2 into
+ * a dictionary object.
+ */
+function parseParams(paramStr) {
+  var params = {};
+  paramStr = paramStr.replace(/^[?#]/, '');
+
+  var pairs = paramStr.split('&');
+  for (var i = 0; i < pairs.length; i++) {
+    var p = pairs[i].split('=');
+    var key = p[0] ? decodeURIComponent(p[0]) : p[0];
+    var val = p[1] ? decodeURIComponent(p[1]) : p[1];
+    if (val === '0')
+      val = 0;
+    if (val === '1')
+      val = 1;
+
+    if (key in params) {
+      // Handle array values.
+      params[key] = makeArray(params[key]);
+      params[key].push(val);
+    } else {
+      params[key] = val;
+    }
+  }
+
+  return params;
+}
+
+/**
+ * Returns the argument as a single-element array, or the argument itself
+ * if it's already an array.
+ */
+function makeArray(o) {
+  if (!o)
+    return [];
+
+  if (typeof o === 'object' && 'splice' in o) {
+    return o;
+  } else {
+    return [o];
+  }
+}
+
+})();
