Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2021 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.car.telemetry; |
| 18 | |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 19 | import static com.google.common.truth.Truth.assertThat; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 20 | import static com.google.common.truth.Truth.assertWithMessage; |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 21 | |
Rui Qiu | d5b4b0b | 2021-09-14 15:51:50 -0700 | [diff] [blame] | 22 | import static org.mockito.ArgumentMatchers.any; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 23 | import static org.mockito.ArgumentMatchers.eq; |
Rui Qiu | d5b4b0b | 2021-09-14 15:51:50 -0700 | [diff] [blame] | 24 | import static org.mockito.Mockito.never; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 25 | import static org.mockito.Mockito.verify; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 26 | import static org.mockito.Mockito.when; |
| 27 | |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 28 | import android.car.telemetry.CarTelemetryManager; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 29 | import android.car.telemetry.ICarTelemetryServiceListener; |
| 30 | import android.car.telemetry.MetricsConfigKey; |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 31 | import android.content.Context; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 32 | import android.os.Handler; |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 33 | import android.os.PersistableBundle; |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 34 | |
| 35 | import androidx.test.filters.SmallTest; |
| 36 | |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 37 | import com.android.car.CarLocalServices; |
Rui Qiu | ac8b5ba | 2021-08-25 16:04:17 -0700 | [diff] [blame] | 38 | import com.android.car.CarPropertyService; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 39 | import com.android.car.systeminterface.SystemInterface; |
Rui Qiu | 3d3806b | 2021-09-22 11:42:45 -0700 | [diff] [blame] | 40 | import com.android.car.systeminterface.SystemStateInterface; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 41 | |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 42 | import org.junit.Before; |
| 43 | import org.junit.Rule; |
| 44 | import org.junit.Test; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 45 | import org.junit.runner.RunWith; |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 46 | import org.mockito.Mock; |
| 47 | import org.mockito.junit.MockitoJUnit; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 48 | import org.mockito.junit.MockitoJUnitRunner; |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 49 | import org.mockito.junit.MockitoRule; |
| 50 | |
Rui Qiu | d5b4b0b | 2021-09-14 15:51:50 -0700 | [diff] [blame] | 51 | import java.io.ByteArrayOutputStream; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 52 | import java.io.File; |
| 53 | import java.nio.file.Files; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 54 | import java.util.concurrent.CountDownLatch; |
| 55 | import java.util.concurrent.TimeUnit; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 56 | |
| 57 | @RunWith(MockitoJUnitRunner.class) |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 58 | @SmallTest |
| 59 | public class CarTelemetryServiceTest { |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 60 | private static final long TIMEOUT_MS = 5_000L; |
| 61 | private static final String METRICS_CONFIG_NAME = "my_metrics_config"; |
| 62 | private static final MetricsConfigKey KEY_V1 = new MetricsConfigKey(METRICS_CONFIG_NAME, 1); |
| 63 | private static final MetricsConfigKey KEY_V2 = new MetricsConfigKey(METRICS_CONFIG_NAME, 2); |
| 64 | private static final TelemetryProto.MetricsConfig METRICS_CONFIG_V1 = |
| 65 | TelemetryProto.MetricsConfig.newBuilder() |
| 66 | .setName(METRICS_CONFIG_NAME).setVersion(1).setScript("no-op").build(); |
| 67 | private static final TelemetryProto.MetricsConfig METRICS_CONFIG_V2 = |
| 68 | TelemetryProto.MetricsConfig.newBuilder() |
| 69 | .setName(METRICS_CONFIG_NAME).setVersion(2).setScript("no-op").build(); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 70 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 71 | private CountDownLatch mIdleHandlerLatch = new CountDownLatch(1); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 72 | private CarTelemetryService mService; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 73 | private File mTempSystemCarDir; |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 74 | private Handler mTelemetryHandler; |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 75 | private MetricsConfigStore mMetricsConfigStore; |
| 76 | private ResultStore mResultStore; |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 77 | |
| 78 | @Rule |
| 79 | public MockitoRule mMockitoRule = MockitoJUnit.rule(); |
| 80 | @Mock |
Rui Qiu | ac8b5ba | 2021-08-25 16:04:17 -0700 | [diff] [blame] | 81 | private CarPropertyService mMockCarPropertyService; |
| 82 | @Mock |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 83 | private Context mContext; |
| 84 | @Mock |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 85 | private ICarTelemetryServiceListener mMockListener; |
| 86 | @Mock |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 87 | private SystemInterface mMockSystemInterface; |
Rui Qiu | 3d3806b | 2021-09-22 11:42:45 -0700 | [diff] [blame] | 88 | @Mock |
| 89 | private SystemStateInterface mMockSystemStateInterface; |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 90 | |
| 91 | @Before |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 92 | public void setUp() throws Exception { |
| 93 | CarLocalServices.removeServiceForTest(SystemInterface.class); |
| 94 | CarLocalServices.addService(SystemInterface.class, mMockSystemInterface); |
| 95 | |
| 96 | mTempSystemCarDir = Files.createTempDirectory("telemetry_test").toFile(); |
| 97 | when(mMockSystemInterface.getSystemCarDir()).thenReturn(mTempSystemCarDir); |
Rui Qiu | 3d3806b | 2021-09-22 11:42:45 -0700 | [diff] [blame] | 98 | when(mMockSystemInterface.getSystemStateInterface()).thenReturn(mMockSystemStateInterface); |
Rui Qiu | a341898 | 2021-08-20 11:21:12 -0700 | [diff] [blame] | 99 | |
Rui Qiu | ac8b5ba | 2021-08-25 16:04:17 -0700 | [diff] [blame] | 100 | mService = new CarTelemetryService(mContext, mMockCarPropertyService); |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 101 | mService.init(); |
| 102 | mService.setListener(mMockListener); |
| 103 | |
| 104 | mTelemetryHandler = mService.getTelemetryHandler(); |
| 105 | mTelemetryHandler.getLooper().getQueue().addIdleHandler(() -> { |
| 106 | mIdleHandlerLatch.countDown(); |
| 107 | return true; |
| 108 | }); |
| 109 | waitForHandlerThreadToFinish(); |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 110 | |
| 111 | mMetricsConfigStore = mService.getMetricsConfigStore(); |
| 112 | mResultStore = mService.getResultStore(); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | @Test |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 116 | public void testAddMetricsConfig_newMetricsConfig_shouldSucceed() throws Exception { |
| 117 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 118 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 119 | waitForHandlerThreadToFinish(); |
| 120 | verify(mMockListener).onAddMetricsConfigStatus( |
| 121 | eq(KEY_V1), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_NONE)); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | @Test |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 125 | public void testAddMetricsConfig_duplicateMetricsConfig_shouldFail() throws Exception { |
| 126 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
| 127 | waitForHandlerThreadToFinish(); |
| 128 | verify(mMockListener).onAddMetricsConfigStatus( |
| 129 | eq(KEY_V1), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_NONE)); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 130 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 131 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 132 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 133 | waitForHandlerThreadToFinish(); |
| 134 | verify(mMockListener).onAddMetricsConfigStatus( |
| 135 | eq(KEY_V1), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_ALREADY_EXISTS)); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | @Test |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 139 | public void testAddMetricsConfig_invalidMetricsConfig_shouldFail() throws Exception { |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 140 | mService.addMetricsConfig(KEY_V1, "bad config".getBytes()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 141 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 142 | waitForHandlerThreadToFinish(); |
| 143 | verify(mMockListener).onAddMetricsConfigStatus( |
| 144 | eq(KEY_V1), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_PARSE_FAILED)); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 145 | } |
| 146 | |
| 147 | @Test |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 148 | public void testAddMetricsConfig_olderMetricsConfig_shouldFail() throws Exception { |
| 149 | mService.addMetricsConfig(KEY_V2, METRICS_CONFIG_V2.toByteArray()); |
| 150 | waitForHandlerThreadToFinish(); |
| 151 | verify(mMockListener).onAddMetricsConfigStatus( |
| 152 | eq(KEY_V2), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_NONE)); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 153 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 154 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 155 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 156 | waitForHandlerThreadToFinish(); |
| 157 | verify(mMockListener).onAddMetricsConfigStatus( |
| 158 | eq(KEY_V1), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_VERSION_TOO_OLD)); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | @Test |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 162 | public void testAddMetricsConfig_newerMetricsConfig_shouldReplaceAndDeleteOldResult() |
| 163 | throws Exception { |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 164 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 165 | mResultStore.putInterimResult(KEY_V1.getName(), new PersistableBundle()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 166 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 167 | mService.addMetricsConfig(KEY_V2, METRICS_CONFIG_V2.toByteArray()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 168 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 169 | waitForHandlerThreadToFinish(); |
| 170 | verify(mMockListener).onAddMetricsConfigStatus( |
| 171 | eq(KEY_V2), eq(CarTelemetryManager.ERROR_METRICS_CONFIG_NONE)); |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 172 | assertThat(mMetricsConfigStore.getActiveMetricsConfigs()) |
| 173 | .containsExactly(METRICS_CONFIG_V2); |
| 174 | assertThat(mResultStore.getInterimResult(KEY_V1.getName())).isNull(); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | @Test |
Rui Qiu | 9f80c7c | 2021-09-28 15:15:36 -0700 | [diff] [blame^] | 178 | public void testRemoveMetricsConfig_shouldDeleteConfigAndResult() throws Exception { |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 179 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 180 | mResultStore.putInterimResult(KEY_V1.getName(), new PersistableBundle()); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 181 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 182 | mService.removeMetricsConfig(KEY_V1); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 183 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 184 | waitForHandlerThreadToFinish(); |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 185 | assertThat(mMetricsConfigStore.getActiveMetricsConfigs()).isEmpty(); |
| 186 | assertThat(mResultStore.getInterimResult(KEY_V1.getName())).isNull(); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | @Test |
Rui Qiu | f721b13 | 2021-09-10 12:41:09 -0700 | [diff] [blame] | 190 | public void testRemoveAllMetricsConfigs_shouldRemoveConfigsAndResults() throws Exception { |
| 191 | MetricsConfigKey key = new MetricsConfigKey("test config", 2); |
| 192 | TelemetryProto.MetricsConfig config = |
| 193 | TelemetryProto.MetricsConfig.newBuilder().setName(key.getName()).build(); |
| 194 | mService.addMetricsConfig(key, config.toByteArray()); |
| 195 | mService.addMetricsConfig(KEY_V1, METRICS_CONFIG_V1.toByteArray()); |
| 196 | mResultStore.putInterimResult(KEY_V1.getName(), new PersistableBundle()); |
| 197 | mResultStore.putFinalResult(key.getName(), new PersistableBundle()); |
| 198 | |
| 199 | mService.removeAllMetricsConfigs(); |
| 200 | |
| 201 | waitForHandlerThreadToFinish(); |
| 202 | assertThat(mMetricsConfigStore.getActiveMetricsConfigs()).isEmpty(); |
| 203 | assertThat(mResultStore.getInterimResult(KEY_V1.getName())).isNull(); |
| 204 | assertThat(mResultStore.getFinalResult(key.getName(), /* deleteResult = */ false)).isNull(); |
| 205 | } |
| 206 | |
Rui Qiu | d5b4b0b | 2021-09-14 15:51:50 -0700 | [diff] [blame] | 207 | @Test |
| 208 | public void testSendFinishedReports_whenNoReport_shouldNotReceiveResponse() throws Exception { |
| 209 | mService.sendFinishedReports(KEY_V1); |
| 210 | |
| 211 | waitForHandlerThreadToFinish(); |
| 212 | verify(mMockListener, never()).onResult(any(), any()); |
| 213 | verify(mMockListener, never()).onError(any(), any()); |
| 214 | } |
| 215 | |
| 216 | @Test |
| 217 | public void testSendFinishedReports_whenFinalResult_shouldReceiveResult() throws Exception { |
| 218 | PersistableBundle finalResult = new PersistableBundle(); |
| 219 | finalResult.putBoolean("finished", true); |
| 220 | mResultStore.putFinalResult(KEY_V1.getName(), finalResult); |
| 221 | |
| 222 | mService.sendFinishedReports(KEY_V1); |
| 223 | |
| 224 | waitForHandlerThreadToFinish(); |
| 225 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| 226 | finalResult.writeToStream(bos); |
| 227 | verify(mMockListener).onResult(eq(KEY_V1), eq(bos.toByteArray())); |
| 228 | // result should have been deleted |
| 229 | assertThat(mResultStore.getFinalResult(KEY_V1.getName(), false)).isNull(); |
| 230 | } |
| 231 | |
| 232 | @Test |
| 233 | public void testSendFinishedReports_whenError_shouldReceiveError() throws Exception { |
| 234 | TelemetryProto.TelemetryError error = TelemetryProto.TelemetryError.newBuilder() |
| 235 | .setErrorType(TelemetryProto.TelemetryError.ErrorType.LUA_RUNTIME_ERROR) |
| 236 | .setMessage("test error") |
| 237 | .build(); |
| 238 | mResultStore.putError(KEY_V1.getName(), error); |
| 239 | |
| 240 | mService.sendFinishedReports(KEY_V1); |
| 241 | |
| 242 | waitForHandlerThreadToFinish(); |
| 243 | verify(mMockListener).onError(eq(KEY_V1), eq(error.toByteArray())); |
| 244 | // error should have been deleted |
| 245 | assertThat(mResultStore.getError(KEY_V1.getName(), false)).isNull(); |
| 246 | } |
| 247 | |
| 248 | @Test |
| 249 | public void testSendFinishedReports_whenListenerNotSet_shouldDoNothing() throws Exception { |
| 250 | PersistableBundle finalResult = new PersistableBundle(); |
| 251 | finalResult.putBoolean("finished", true); |
| 252 | mResultStore.putFinalResult(KEY_V1.getName(), finalResult); |
| 253 | mService.clearListener(); // no listener = no way to send back results |
| 254 | |
| 255 | mService.sendFinishedReports(KEY_V1); |
| 256 | |
| 257 | waitForHandlerThreadToFinish(); |
| 258 | // if listener is null, nothing should be done, result should still be in result store |
| 259 | assertThat(mResultStore.getFinalResult(KEY_V1.getName(), false).toString()) |
| 260 | .isEqualTo(finalResult.toString()); |
| 261 | } |
| 262 | |
Rui Qiu | 9b9341c | 2021-08-25 10:39:04 -0700 | [diff] [blame] | 263 | private void waitForHandlerThreadToFinish() throws Exception { |
| 264 | assertWithMessage("handler not idle in %sms", TIMEOUT_MS) |
| 265 | .that(mIdleHandlerLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue(); |
| 266 | mIdleHandlerLatch = new CountDownLatch(1); // reset idle handler condition |
| 267 | mTelemetryHandler.runWithScissors(() -> { }, TIMEOUT_MS); |
Rui Qiu | 8c415de | 2021-05-03 15:52:16 -0700 | [diff] [blame] | 268 | } |
| 269 | } |