Merge "Adjust autocomplete"
diff --git a/acts/framework/acts/controllers/android_device.py b/acts/framework/acts/controllers/android_device.py
index 6439267..1bdb9d0 100755
--- a/acts/framework/acts/controllers/android_device.py
+++ b/acts/framework/acts/controllers/android_device.py
@@ -395,6 +395,7 @@
         self.crash_report = None
         self.data_accounting = collections.defaultdict(int)
         self._sl4a_manager = sl4a_manager.Sl4aManager(self.adb)
+        self.last_logcat_timestamp = None
 
     def clean_up(self):
         """Cleans up the AndroidDevice object and releases any resources it
@@ -749,10 +750,13 @@
             extra_params = self.adb_logcat_param
         else:
             extra_params = "-b all"
-
+        if self.last_logcat_timestamp:
+            begin_at = '-T "%s"' % self.last_logcat_timestamp
+        else:
+            begin_at = '-T 1'
         # TODO(markdr): Pull 'adb -s %SERIAL' from the AdbProxy object.
-        cmd = "adb -s {} logcat -T 1 -v year {} >> {}".format(
-            self.serial, extra_params, logcat_file_path)
+        cmd = "adb -s {} logcat {} -v year {} >> {}".format(
+            self.serial, begin_at, extra_params, logcat_file_path)
         self.adb_logcat_process = utils.start_standing_subprocess(cmd)
         self.adb_logcat_file_path = logcat_file_path
 
@@ -763,6 +767,13 @@
             raise AndroidDeviceError(
                 "Android device %s does not have an ongoing adb logcat collection."
                 % self.serial)
+        # Set the last timestamp to the current timestamp. This may cause
+        # a race condition that allows the same line to be logged twice,
+        # but it does not pose a problem for our logging purposes.
+        logcat_output = self.adb.logcat('-t 1 -v year')
+        next_line = logcat_output.find('\n')
+        self.last_logcat_timestamp = logcat_output[next_line + 1:
+                                                   next_line + 24]
         utils.stop_standing_subprocess(self.adb_logcat_process)
         self.adb_logcat_process = None
 
@@ -1344,12 +1355,12 @@
         self.adb.shell(
             "am start -n com.google.android.setupwizard/.SetupWizardExitActivity"
         )
-        #Wait up to 5 seconds for user_setup_complete to be updated
+        # Wait up to 5 seconds for user_setup_complete to be updated
         for _ in range(5):
             if self.is_user_setup_complete():
                 return
             time.sleep(1)
-        #If fail to exit setup wizard, set local.prop and reboot
+        # If fail to exit setup wizard, set local.prop and reboot
         if not self.is_user_setup_complete():
             self.adb.shell("echo ro.test_harness=1 > /data/local.prop")
             self.adb.shell("chmod 644 /data/local.prop")
diff --git a/acts/framework/acts/libs/ota/ota_updater.py b/acts/framework/acts/libs/ota/ota_updater.py
index ed300aa..a43c9ce 100644
--- a/acts/framework/acts/libs/ota/ota_updater.py
+++ b/acts/framework/acts/libs/ota/ota_updater.py
@@ -14,6 +14,7 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 
+from acts import utils
 from acts.libs.ota.ota_runners import ota_runner_factory
 
 # Maps AndroidDevices to OtaRunners
@@ -54,10 +55,13 @@
     _check_initialization(android_device)
     try:
         ota_runners[android_device].update()
-    except:
+    except Exception as e:
         if ignore_update_errors:
             return
-        raise
+        android_device.log.error(e)
+        android_device.take_bug_report('ota_update',
+                                       utils.get_current_epoch_time())
+        raise e
 
 
 def can_update(android_device):
diff --git a/acts/framework/acts/test_utils/tel/TelephonyBaseTest.py b/acts/framework/acts/test_utils/tel/TelephonyBaseTest.py
index b300492..83d7a36 100644
--- a/acts/framework/acts/test_utils/tel/TelephonyBaseTest.py
+++ b/acts/framework/acts/test_utils/tel/TelephonyBaseTest.py
@@ -334,8 +334,9 @@
                          test_name, e)
             result = False
 
-        log_begin_time = getattr(ad, "test_log_begin_time", None)\
-                         or acts_logger.epoch_to_log_line_timestamp(begin_time - 1000 * 60)
+        log_begin_time = getattr(
+            ad, "test_log_begin_time", None
+        ) or acts_logger.epoch_to_log_line_timestamp(begin_time - 1000 * 60)
         log_path = os.path.join(self.log_path, test_name,
                                 "%s_%s.logcat" % (ad.serial, begin_time))
         try:
diff --git a/acts/framework/acts/test_utils/tel/tel_test_utils.py b/acts/framework/acts/test_utils/tel/tel_test_utils.py
index 3eecf14..b2f0b2d 100644
--- a/acts/framework/acts/test_utils/tel/tel_test_utils.py
+++ b/acts/framework/acts/test_utils/tel/tel_test_utils.py
@@ -1937,7 +1937,7 @@
         return False
 
 
-def active_file_download_task(log, ad, file_name="5MB"):
+def check_curl_availability(ad):
     if not hasattr(ad, "curl_capable"):
         try:
             out = ad.adb.shell("/data/curl --version")
@@ -1949,7 +1949,10 @@
         except Exception:
             setattr(ad, "curl_capable", False)
             ad.log.info("curl is unavailable, use chrome to download file")
+    return ad.curl_capable
 
+
+def active_file_download_task(log, ad, file_name="5MB", method="chrome"):
     # files available for download on the same website:
     # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
     # download file by adb command, as phone call will use sl4a
@@ -1969,13 +1972,23 @@
     timeout = min(max(file_size / 100000, 600), 3600)
     output_path = "/sdcard/Download/" + file_name + ".zip"
     url = "http://ipv4.download.thinkbroadband.com/" + file_name + ".zip"
-    #url = "http://146.148.91.8/download/" + file_name + ".zip"
-    return (http_file_download_by_sl4a, (ad, url, output_path, file_size, True,
-                                         timeout))
+    if method == "sl4a":
+        return (http_file_download_by_sl4a, (ad, url, output_path, file_size,
+                                             True, timeout))
+    if method == "curl" and check_curl_availability(ad):
+        url = "http://146.148.91.8/download/" + file_name + ".zip"
+        return (http_file_download_by_curl, (ad, url, output_path, file_size,
+                                             True, timeout))
+    elif method == "sl4a":
+        return (http_file_download_by_sl4a, (ad, url, output_path, file_size,
+                                             True, timeout))
+    else:
+        return (http_file_download_by_chrome, (ad, url, file_size, True,
+                                               timeout))
 
 
-def active_file_download_test(log, ad, file_name="5MB"):
-    task = active_file_download_task(log, ad, file_name)
+def active_file_download_test(log, ad, file_name="5MB", method="chrome"):
+    task = active_file_download_task(log, ad, file_name, method=method)
     return task[0](*task[1])
 
 
@@ -2091,17 +2104,14 @@
     curl_cmd += " --url %s > %s" % (url, file_path)
     accounting_apk = "com.android.server.telecom"  #"com.quicinc.cne.CNEService"
     result = True
-    begin_time = int(time.time() * 1000 - 2 * 60 * 60 * 1000)
-    end_time = int(time.time() * 1000 + 2 * 60 * 60 * 1000)
     try:
         data_accounting = {
             "mobile_rx_bytes":
             ad.droid.getMobileRxBytes(),
             "subscriber_mobile_data_usage":
-            get_mobile_data_usage(ad, None, None, begin_time, end_time),
+            get_mobile_data_usage(ad, None, None),
             "curl_mobile_data_usage":
-            get_mobile_data_usage(ad, None, accounting_apk, begin_time,
-                                  end_time)
+            get_mobile_data_usage(ad, None, accounting_apk)
         }
         ad.log.info("Before downloading: %s", data_accounting)
         ad.log.info("Download %s to %s by adb shell command %s", url,
@@ -2113,10 +2123,9 @@
                 "mobile_rx_bytes":
                 ad.droid.getMobileRxBytes(),
                 "subscriber_mobile_data_usage":
-                get_mobile_data_usage(ad, None, None, begin_time, end_time),
+                get_mobile_data_usage(ad, None, None),
                 "curl_mobile_data_usage":
-                get_mobile_data_usage(ad, None, accounting_apk, begin_time,
-                                      end_time)
+                get_mobile_data_usage(ad, None, accounting_apk)
             }
             ad.log.info("After downloading: %s", new_data_accounting)
             accounting_diff = {
@@ -2181,17 +2190,12 @@
     ad.adb.shell("rm -f %s" % file_to_be_delete)
     ad.adb.shell("rm -rf /sdcard/Download/.*")
     ad.adb.shell("rm -f /sdcard/Download/.*")
-    begin_time = int(time.time() * 1000 - 2 * 60 * 60 * 1000)
-    end_time = int(time.time() * 1000 + 2 * 60 * 60 * 1000)
     data_accounting = {
-        "total_rx_bytes":
-        ad.droid.getTotalRxBytes(),
-        "mobile_rx_bytes":
-        ad.droid.getMobileRxBytes(),
-        "subscriber_mobile_data_usage":
-        get_mobile_data_usage(ad, None, None, begin_time, end_time),
-        "chrome_mobile_data_usage":
-        get_mobile_data_usage(ad, None, chrome_apk, begin_time, end_time)
+        "total_rx_bytes": ad.droid.getTotalRxBytes(),
+        "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
+        "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
+        "chrome_mobile_data_usage": get_mobile_data_usage(
+            ad, None, chrome_apk)
     }
     ad.log.info("Before downloading: %s", data_accounting)
     ad.ensure_screen_on()
@@ -2213,10 +2217,9 @@
                 "mobile_rx_bytes":
                 ad.droid.getMobileRxBytes(),
                 "subscriber_mobile_data_usage":
-                get_mobile_data_usage(ad, None, None, begin_time, end_time),
+                get_mobile_data_usage(ad, None, None),
                 "chrome_mobile_data_usage":
-                get_mobile_data_usage(ad, None, chrome_apk, begin_time,
-                                      end_time)
+                get_mobile_data_usage(ad, None, chrome_apk)
             }
             ad.log.info("After downloading: %s", new_data_accounting)
             accounting_diff = {
@@ -2279,8 +2282,6 @@
     ad.adb.shell("rm -f %s" % file_path)
     accounting_apk = SL4A_APK_NAME
     result = True
-    begin_time = int(time.time() * 1000 - 2 * 60 * 60 * 1000)
-    end_time = int(time.time() * 1000 + 2 * 60 * 60 * 1000)
     try:
         if not getattr(ad, "downloading_droid", None):
             ad.downloading_droid, ad.downloading_ed = ad.get_droid()
@@ -2298,10 +2299,9 @@
             "mobile_rx_bytes":
             ad.droid.getMobileRxBytes(),
             "subscriber_mobile_data_usage":
-            get_mobile_data_usage(ad, None, None, begin_time, end_time),
+            get_mobile_data_usage(ad, None, None),
             "sl4a_mobile_data_usage":
-            get_mobile_data_usage(ad, None, accounting_apk, begin_time,
-                                  end_time)
+            get_mobile_data_usage(ad, None, accounting_apk)
         }
         ad.log.info("Before downloading: %s", data_accounting)
         ad.log.info("Download file from %s to %s by sl4a RPC call", url,
@@ -2318,10 +2318,9 @@
                 "mobile_rx_bytes":
                 ad.droid.getMobileRxBytes(),
                 "subscriber_mobile_data_usage":
-                get_mobile_data_usage(ad, None, None, begin_time, end_time),
+                get_mobile_data_usage(ad, None, None),
                 "sl4a_mobile_data_usage":
-                get_mobile_data_usage(ad, None, accounting_apk, begin_time,
-                                      end_time)
+                get_mobile_data_usage(ad, None, accounting_apk)
             }
             ad.log.info("After downloading: %s", new_data_accounting)
             accounting_diff = {
@@ -2354,17 +2353,18 @@
             ad.adb.shell("rm %s" % file_path, ignore_status=True)
 
 
-def get_mobile_data_usage(ad,
-                          subscriber_id=None,
-                          apk=None,
-                          begin_time=None,
-                          end_time=None):
+def get_mobile_data_usage(ad, subscriber_id=None, apk=None):
     if not subscriber_id:
         subscriber_id = ad.droid.telephonyGetSubscriberId()
-    if begin_time is None:
-        begin_time = 0
-    if end_time is None:
-        end_time = int(time.time() * 1000 + 2 * 60 * 60 * 1000)
+    if not getattr(ad, "data_metering_begin_time", None) or not getattr(
+            ad, "data_metering_end_time", None):
+        current_time = int(time.time() * 1000)
+        setattr(ad, "data_metering_begin_time",
+                current_time - 24 * 60 * 60 * 1000)
+        setattr(ad, "data_metering_end_time",
+                current_time + 30 * 24 * 60 * 60 * 1000)
+    begin_time = ad.data_metering_begin_time
+    end_time = ad.data_metering_end_time
     if apk:
         uid = ad.get_apk_uid(apk)
         try:
@@ -3620,9 +3620,9 @@
             ad_rx.messaging_ed.clear_events(EventSmsReceived)
             ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
             ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
-            time.sleep(0.1)  #sleep 100ms after starting event tracking
+            time.sleep(1)  #sleep 100ms after starting event tracking
             ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
-                                                     True)
+                                                     False)
             try:
                 ad_tx.messaging_ed.pop_event(EventSmsSentSuccess,
                                              max_wait_time)
@@ -3679,7 +3679,8 @@
     log_results = ad.search_logcat(
         "%s Message sent successfully" % type, begin_time=begin_time)
     if log_results:
-        ad.log.info("Found SL4A %s sent succeessful log message" % type)
+        ad.log.info("Found %s sent succeessful log message: %s", type,
+                    log_results[-1]["log_message"])
         return True
     else:
         log_results = ad.search_logcat(
@@ -3689,8 +3690,8 @@
             for log_result in log_results:
                 if "status is SUCCEEDED" in log_result["log_message"]:
                     ad.log.info(
-                        "Found BugleDataModel %s send succeed log message" %
-                        type)
+                        "Found BugleDataModel %s send succeed log message: %s",
+                        type, log_result["log_message"])
                     return True
     return False
 
@@ -3701,13 +3702,15 @@
         "New %s Received" % type, begin_time=begin_time) or \
         ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
     if log_results:
-        ad.log.info("Found SL4A %s received log message" % type)
+        ad.log.info("Found SL4A %s received log message: %s", type,
+                    log_results[-1]["log_message"])
         return True
     else:
         log_results = ad.search_logcat(
             "Received %s message" % type, begin_time=begin_time)
         if log_results:
-            ad.log.info("Found %s received log message" % type)
+            ad.log.info("Found %s received log message: %s", type,
+                        log_results[-1]["log_message"])
             return True
     return False
 
diff --git a/acts/framework/tests/libs/ota/ota_updater_test.py b/acts/framework/tests/libs/ota/ota_updater_test.py
index fff4136..466ea69 100644
--- a/acts/framework/tests/libs/ota/ota_updater_test.py
+++ b/acts/framework/tests/libs/ota/ota_updater_test.py
@@ -23,6 +23,8 @@
 class MockAndroidDevice(object):
     def __init__(self, serial):
         self.serial = serial
+        self.log = mock.Mock()
+        self.take_bug_report = mock.MagicMock()
 
 
 class MockOtaRunner(object):
diff --git a/acts/tests/google/tel/live/TelLiveStressTest.py b/acts/tests/google/tel/live/TelLiveStressTest.py
index 6456cd8..7161e39 100644
--- a/acts/tests/google/tel/live/TelLiveStressTest.py
+++ b/acts/tests/google/tel/live/TelLiveStressTest.py
@@ -193,16 +193,12 @@
             the_number, message_type, length, ads[0].serial, ads[1].serial)
         self.log.info(log_msg)
         for ad in self.android_devices:
-            for i in range(3):
+            for session in ad._sl4a_manager.sessions.values():
                 try:
-                    ad.droid.logI(log_msg)
+                    session.rpc_client.logI(log_msg)
                     break
                 except Exception as e:
-                    if i == 2:
-                        ad.log.info("SL4A error: %s", e)
-                        raise
-                    else:
-                        time.sleep(5)
+                    ad.log.warning(e)
         text = "%s: " % log_msg
         text_length = len(text)
         if length < text_length:
@@ -265,7 +261,10 @@
                 the_number, ads[0].serial, ads[1].serial, duration)
         self.log.info(log_msg)
         for ad in ads:
-            ad.droid.logI(log_msg)
+            try:
+                ad.droid.logI(log_msg)
+            except Exception as e:
+                ad.log.warning(e)
         begin_time = get_current_epoch_time()
         start_qxdm_loggers(self.log, self.android_devices, begin_time)
         if self.single_phone_test: