diff --git a/Android.bp b/Android.bp
index 328cf7a985a6f0c615a86d2a8d2c2a2ad9135422..c4f158d3ad8f2505ef88c2bb9e989281d1bcd5c1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -27,6 +27,7 @@ python_binary_host {
     name: "external_updater_notifier",
     main: "notifier.py",
     srcs: [
+        "git_utils.py",
         "notifier.py",
     ],
 }
diff --git a/archive_utils.py b/archive_utils.py
index 91007a751bdfd4965ba28667081cad1ebbe47d9a..f0198c5a408471fbeb76b80683a9c8a37f77d66a 100644
--- a/archive_utils.py
+++ b/archive_utils.py
@@ -26,8 +26,8 @@ class ZipFileWithPermission(zipfile.ZipFile):
     See https://bugs.python.org/issue15795
     """
 
-    def extract(self, member, path=None, pwd=None):
-        ret_val = super().extract(member, path, pwd)
+    def _extract_member(self, member, targetpath, pwd):
+        ret_val = super()._extract_member(member, targetpath, pwd)
 
         if not isinstance(member, zipfile.ZipInfo):
             member = self.getinfo(member)
diff --git a/external_updater.py b/external_updater.py
index 65a89644ff8ccd083739043d120a4c8dcd02c8ad..5e2e944c0778b50fb917604d896e7bf102b17499 100644
--- a/external_updater.py
+++ b/external_updater.py
@@ -129,20 +129,22 @@ def _process_update_result(path):
 def _check_some(paths, delay):
     results = {}
     for path in paths:
-        results[path] = _process_update_result(path)
+        relative_path = fileutils.get_relative_project_path(path)
+        results[relative_path] = _process_update_result(path)
         time.sleep(delay)
     return results
 
 
 def _check_all(delay):
     results = {}
-    for path, dirs, files in os.walk(args.path):
+    for path, dirs, files in os.walk(fileutils.EXTERNAL_PATH):
         dirs.sort(key=lambda d: d.lower())
         if fileutils.METADATA_FILENAME in files:
             # Skip sub directories.
             dirs[:] = []
-            results[path] = _process_update_result(path)
-        time.sleep(delay)
+            relative_path = fileutils.get_relative_project_path(path)
+            results[relative_path] = _process_update_result(path)
+            time.sleep(delay)
     return results
 
 
@@ -204,7 +206,7 @@ def _do_update(args):
         git_utils.push(full_path, args.remote_name)
 
     if args.branch_and_commit:
-        git_utils.checkout(full_path, 'aosp/master')
+        git_utils.checkout(full_path, args.remote_name + '/master')
 
 
 def parse_args():
@@ -226,7 +228,7 @@ def parse_args():
         '--json_output',
         help='Path of a json file to write result to.')
     check_parser.add_argument(
-        '--all',
+        '--all', action='store_true',
         help='If set, check updates for all supported projects.')
     check_parser.add_argument(
         '--delay', default=0, type=int,
diff --git a/notifier.py b/notifier.py
index 982354cf8b896604bd2f81855f7b39a75e006e14..455a5b99f095a3dd8c0909ba864c26dc6e8a663a 100644
--- a/notifier.py
+++ b/notifier.py
@@ -21,6 +21,7 @@ external_updater_notifier \
     googletest
 """
 
+from datetime import timedelta, datetime
 import argparse
 import json
 import os
@@ -28,6 +29,7 @@ import re
 import subprocess
 import time
 
+import git_utils
 
 def parse_args():
     """Parses commandline arguments."""
@@ -48,6 +50,9 @@ def parse_args():
     parser.add_argument(
         'paths', nargs='*',
         help='Paths of the project.')
+    parser.add_argument(
+        '--all', action='store_true',
+        help='Checks all projects.')
 
     return parser.parse_args()
 
@@ -73,6 +78,22 @@ def _send_email(proj, latest_ver, recipient, upgrade_log):
                    input=msg, encoding='ascii')
 
 
+NOTIFIED_TIME_KEY_NAME = 'latest_notified_time'
+
+
+def _should_notify(latest_ver, proj_history):
+    if latest_ver in proj_history:
+        # Processed this version before.
+        return False
+
+    timestamp = proj_history.get(NOTIFIED_TIME_KEY_NAME, 0)
+    time_diff = datetime.today() - datetime.fromtimestamp(timestamp)
+    if git_utils.is_commit(latest_ver) and time_diff <= timedelta(days=30):
+        return False
+
+    return True
+
+
 def _process_results(args, history, results):
     for proj, res in results.items():
         if 'latest' not in res:
@@ -82,11 +103,12 @@ def _process_results(args, history, results):
         if latest_ver == current_ver:
             continue
         proj_history = history.setdefault(proj, {})
-        if latest_ver not in proj_history:
+        if _should_notify(latest_ver, proj_history):
             upgrade_log = _upgrade(proj) if args.generate_change else ""
             try:
                 _send_email(proj, latest_ver, args.recipients, upgrade_log)
                 proj_history[latest_ver] = int(time.time())
+                proj_history[NOTIFIED_TIME_KEY_NAME] = int(time.time())
             except subprocess.CalledProcessError as err:
                 msg = """Failed to send email for {} ({}).
 stdout: {}
@@ -112,7 +134,7 @@ def send_notification(args):
     _process_results(args, history, results)
 
     with open(args.history, 'w') as f:
-        json.dump(history, f, sort_keys=True)
+        json.dump(history, f, sort_keys=True, indent=4)
 
 
 def _upgrade(proj):
@@ -136,11 +158,15 @@ def _upgrade(proj):
 
 
 def _check_updates(args):
-    subprocess.run(['out/soong/host/linux-x86/bin/external_updater',
-                    'check',
-                    '--json_output', RESULT_FILE_PATH,
-                    '--delay', '0'] + args.paths,
-                   cwd=os.environ['ANDROID_BUILD_TOP'])
+    params = ['out/soong/host/linux-x86/bin/external_updater',
+              'check', '--json_output', RESULT_FILE_PATH,
+              '--delay', '30']
+    if args.all:
+        params.append('--all')
+    else:
+        params += args.paths
+
+    subprocess.run(params, cwd=os.environ['ANDROID_BUILD_TOP'])
 
 
 def main():
diff --git a/updater_utils.py b/updater_utils.py
index 9daa2da726e2368a36593b168f9c33ef54ab9b86..54ddf98a9bbdd6493f5d6237ad247638b0fc7fb6 100644
--- a/updater_utils.py
+++ b/updater_utils.py
@@ -80,10 +80,9 @@ def _match_and_get_version(prefix, suffix, version):
     except ValueError:
         return []
 
-    if version_prefix != prefix or version_suffix != suffix:
-        return []
+    right_format = (version_prefix == prefix and version_suffix == suffix)
 
-    return [int(v) for v in version.split('.')]
+    return [right_format] + [int(v) for v in version.split('.')]
 
 
 def get_latest_version(current_version, version_list):