1 /*
2  * Copyright (C) 2022 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 package android.wearable.cts;
17 
18 import static android.app.wearable.WearableSensingDataRequest.getMaxRequestSize;
19 import static android.app.wearable.WearableSensingDataRequest.getRateLimit;
20 import static android.wearable.cts.CtsWearableSensingService.whenCallbackTriggeredRespondWithServiceStatus;
21 import static android.wearable.cts.CtsWearableSensingService.whenCallbackTriggeredRespondWithStatus;
22 
23 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
24 
25 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 
29 import static org.junit.Assert.assertThrows;
30 import static org.junit.Assume.assumeFalse;
31 import static org.junit.Assume.assumeTrue;
32 
33 import static java.util.concurrent.TimeUnit.SECONDS;
34 
35 import android.Manifest;
36 import android.app.PendingIntent;
37 import android.app.ambientcontext.AmbientContextManager;
38 import android.app.wearable.Flags;
39 import android.app.wearable.WearableSensingDataRequest;
40 import android.app.wearable.WearableSensingManager;
41 import android.content.Context;
42 import android.content.Intent;
43 import android.content.pm.PackageManager;
44 import android.os.Build.VERSION;
45 import android.os.Build.VERSION_CODES;
46 import android.os.ParcelFileDescriptor;
47 import android.os.PersistableBundle;
48 import android.os.SystemClock;
49 import android.os.UserHandle;
50 import android.platform.test.annotations.AppModeFull;
51 import android.platform.test.annotations.RequiresFlagsEnabled;
52 import android.platform.test.flag.junit.CheckFlagsRule;
53 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
54 import android.service.wearable.WearableSensingDataRequester;
55 import android.text.TextUtils;
56 
57 import androidx.test.InstrumentationRegistry;
58 import androidx.test.ext.junit.runners.AndroidJUnit4;
59 
60 import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
61 
62 import com.google.common.collect.Iterables;
63 
64 import org.junit.After;
65 import org.junit.Before;
66 import org.junit.Rule;
67 import org.junit.Test;
68 import org.junit.runner.RunWith;
69 
70 import java.io.InputStream;
71 import java.util.concurrent.CountDownLatch;
72 import java.util.concurrent.Executor;
73 import java.util.concurrent.atomic.AtomicInteger;
74 
75 /**
76  * This suite of test ensures that WearableSensingManagerService behaves correctly when properly
77  * bound to a WearableSensingService implementation.
78  */
79 @RunWith(AndroidJUnit4.class)
80 @AppModeFull(
81         reason = "PM will not recognize CtsWearableSensingService in instantMode.")
82 public class CtsWearableSensingServiceDeviceTest {
83     private static final String NAMESPACE_wearable_sensing = "wearable_sensing";
84     private static final String NAMESPACE_ambient_context = "ambient_context";
85 
86     private static final String KEY_SERVICE_ENABLED = "service_enabled";
87     private static final String FAKE_APP_PACKAGE = "foo.bar.baz";
88     private static final String CTS_PACKAGE_NAME =
89             CtsWearableSensingService.class.getPackage().getName();
90     private static final String CTS_SERVICE_NAME = CTS_PACKAGE_NAME + "/."
91             + CtsWearableSensingService.class.getSimpleName();
92     private static final int USER_ID = UserHandle.myUserId();
93     private static final int TEMPORARY_SERVICE_DURATION = 30000; // ms
94 
95     private static final String KEY_FOR_PROVIDE_DATA = "foo.bar.baz_key_for_provide_data";
96     private static final int VALUE_TO_SEND = 1000;
97     private static final String VALUE_TO_WRITE = "wearable_sensing";
98 
99     private static final int PLACEHOLDER_DATA_TYPE = 234;
100     private static final String DATA_REQUEST_DETAILS_KEY_1 = "k1";
101     private static final String DATA_REQUEST_DETAILS_KEY_2 = "k2";
102     private static final String DATA_REQUEST_DETAILS_VALUE_1 = "v1";
103     private static final int DATA_REQUEST_DETAILS_VALUE_2 = 98765;
104 
105     private final boolean mIsTestable =
106             !TextUtils.isEmpty(getAmbientContextDetectionServiceComponent());
107     private final Executor mExecutor = InstrumentationRegistry.getContext().getMainExecutor();
108     private Context mContext;
109     private WearableSensingManager mWearableSensingManager;
110     private PendingIntent mDataRequestObserverPendingIntent;
111     private WearableSensingDataRequest mDataRequest;
112     private WearableSensingDataRequest mLargeDataRequest;
113 
114     @Rule
115     public final DeviceConfigStateChangerRule mLookAllTheseRules =
116             new DeviceConfigStateChangerRule(getInstrumentation().getTargetContext(),
117                     NAMESPACE_wearable_sensing,
118                     KEY_SERVICE_ENABLED,
119                     "true");
120 
121     @Rule
122     public final DeviceConfigStateChangerRule mAmbientContextRules =
123             new DeviceConfigStateChangerRule(getInstrumentation().getTargetContext(),
124                     NAMESPACE_ambient_context,
125                     KEY_SERVICE_ENABLED,
126                     "true");
127 
128     @Rule
129     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
130 
131     @Before
setUp()132     public void setUp() throws Exception {
133         assumeTrue("VERSION.SDK_INT=" + VERSION.SDK_INT,
134                 VERSION.SDK_INT >= VERSION_CODES.UPSIDE_DOWN_CAKE);
135         mContext = getInstrumentation().getContext();
136         assumeFalse(isWatch(mContext));  // WearableSensingManagerService is not supported on WearOS
137         mWearableSensingManager = mContext.getSystemService(WearableSensingManager.class);
138         mDataRequestObserverPendingIntent = createDataRequestPendingIntent(mContext);
139         PersistableBundle dataRequestDetails = new PersistableBundle();
140         dataRequestDetails.putString(DATA_REQUEST_DETAILS_KEY_1, DATA_REQUEST_DETAILS_VALUE_1);
141         dataRequestDetails.putInt(DATA_REQUEST_DETAILS_KEY_2, DATA_REQUEST_DETAILS_VALUE_2);
142         mDataRequest =
143                 new WearableSensingDataRequest.Builder(PLACEHOLDER_DATA_TYPE)
144                         .setRequestDetails(dataRequestDetails)
145                         .build();
146         PersistableBundle largeDataRequestDetails = new PersistableBundle();
147         largeDataRequestDetails.putString(
148                 "myVeryVeryVeryVeryLargeKey1", "myVeryVeryVeryVeryLargeValue1");
149         largeDataRequestDetails.putString(
150                 "myVeryVeryVeryVeryLargeKey2", "myVeryVeryVeryVeryLargeValue2");
151         mLargeDataRequest =
152                 new WearableSensingDataRequest.Builder(PLACEHOLDER_DATA_TYPE)
153                         .setRequestDetails(largeDataRequestDetails)
154                         .build();
155         CtsWearableSensingService.reset();
156         CtsWearableSensingDataRequestBroadcastReceiver.reset();
157         clearTestableWearableSensingService();
158         destroyDataStream();
159         bindToTestableWearableSensingService();
160         createDataStream();
161     }
162 
163     @Test
testProvideDataStream_success()164     public void testProvideDataStream_success() {
165         CtsWearableSensingService.whenCallbackTriggeredRespondWithStatus(
166                 WearableSensingManager.STATUS_SUCCESS);
167 
168         provideDataStream();
169         CtsWearableSensingService.awaitResult();
170 
171         assertThat(getLastStatusCode()).isEqualTo(WearableSensingManager.STATUS_SUCCESS);
172     }
173 
174     @Test
testProvideDataStream_failure()175     public void testProvideDataStream_failure() {
176         whenCallbackTriggeredRespondWithStatus(WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
177 
178         provideDataStream();
179         CtsWearableSensingService.awaitResult();
180 
181         assertThat(getLastStatusCode()).isEqualTo(
182                 WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
183     }
184 
185     @Test
testProvideDataStream_writeData_reads()186     public void testProvideDataStream_writeData_reads() throws Exception {
187         whenCallbackTriggeredRespondWithStatus(WearableSensingManager.STATUS_SUCCESS);
188 
189         provideDataStream();
190         writeDataToStream();
191         CtsWearableSensingService.awaitResult();
192 
193         assertThat(readDataStream()).isEqualTo(VALUE_TO_WRITE);
194     }
195 
196     @Test
testProvideData_success()197     public void testProvideData_success() {
198         whenCallbackTriggeredRespondWithStatus(WearableSensingManager.STATUS_SUCCESS);
199 
200         provideData();
201         CtsWearableSensingService.awaitResult();
202 
203         assertThat(getLastStatusCode()).isEqualTo(WearableSensingManager.STATUS_SUCCESS);
204     }
205 
206     @Test
testProvideData_failure()207     public void testProvideData_failure() {
208         whenCallbackTriggeredRespondWithStatus(WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
209 
210         provideData();
211         CtsWearableSensingService.awaitResult();
212 
213         assertThat(getLastStatusCode()).isEqualTo(
214                 WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
215     }
216 
217     @Test
testProvideData_getsRightData()218     public void testProvideData_getsRightData() {
219         whenCallbackTriggeredRespondWithStatus(WearableSensingManager.STATUS_SUCCESS);
220 
221         provideData();
222         CtsWearableSensingService.awaitResult();
223 
224         assertThat(CtsWearableSensingService.getData().getInt(KEY_FOR_PROVIDE_DATA))
225                 .isEqualTo(VALUE_TO_SEND);
226     }
227 
228     @Test
startDetection_wearable_getsCall()229     public void startDetection_wearable_getsCall() {
230         assumeTrue("Feature not available on this device. Skipping test.", mIsTestable);
231 
232         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
233         whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
234 
235         callStartDetection();
236         CtsWearableSensingService.awaitResultAmbientContextDetectionService();
237 
238         assertThat(getLastStatusCodeAmbientDetectionService())
239                 .isEqualTo(AmbientContextManager.STATUS_SUCCESS);
240     }
241 
242     // Requesting for a detection start with mixed events will not be
243     @Test
startDetection_mixed_doesNotGetCall()244     public void startDetection_mixed_doesNotGetCall() {
245         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
246 
247         callStartDetectionMixed();
248 
249         CtsWearableSensingService.expectTimeOut();
250     }
251 
252     @Test
stopDetection_wearable_getsCall()253     public void stopDetection_wearable_getsCall() {
254         assumeTrue("Feature not available on this device. Skipping test.", mIsTestable);
255 
256         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
257         whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
258         callStartDetection();
259         CtsWearableSensingService.awaitResultAmbientContextDetectionService();
260 
261         callStopDetection();
262         CtsWearableSensingService.awaitResultAmbientContextDetectionService();
263 
264         assertThat(CtsWearableSensingService.getLastCallingPackage()).isEqualTo(FAKE_APP_PACKAGE);
265     }
266 
267     @Test
stopDetection_notWearable_doesNotGetCall()268     public void stopDetection_notWearable_doesNotGetCall() {
269         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
270         callStartDetectionDefault();
271         CtsWearableSensingService.expectTimeOut();
272 
273         callStopDetection();
274         CtsWearableSensingService.expectTimeOut();
275 
276         assertThat(CtsWearableSensingService.getLastCallingPackage()).isNull();
277     }
278 
279     @Test
queryServiceStatus_available()280     public void queryServiceStatus_available() {
281         assumeTrue("Feature not available on this device. Skipping test.", mIsTestable);
282 
283         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
284         whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
285 
286         callQueryWearableServiceStatus();
287         CtsWearableSensingService.awaitResultAmbientContextDetectionService();
288 
289         assertThat(getLastStatusCodeAmbientDetectionService())
290                 .isEqualTo(AmbientContextManager.STATUS_SUCCESS);
291     }
292 
293     @Test
queryDefaultServiceStatus_notCalled()294     public void queryDefaultServiceStatus_notCalled() {
295         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
296         whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
297 
298         callQueryServiceStatus();
299 
300         CtsWearableSensingService.expectTimeOut();
301     }
302 
303     @Test
queryMixedServiceStatus_notCalled()304     public void queryMixedServiceStatus_notCalled() {
305         setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
306         whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
307 
308         callQueryMixedServiceStatus();
309 
310         CtsWearableSensingService.expectTimeOut();
311     }
312 
313     @Test
314     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API)
sendDataRequest_isReceivedByObserver()315     public void sendDataRequest_isReceivedByObserver() throws Exception {
316         getInstrumentation()
317                 .getUiAutomation()
318                 .adoptShellPermissionIdentity(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE);
319         AtomicInteger dataRequestStatusRef =
320                 new AtomicInteger(WearableSensingManager.STATUS_UNKNOWN);
321         CountDownLatch dataRequestStatusLatch = new CountDownLatch(1);
322 
323         // send a request from WearableSensingService
324         registerAndGetDataRequester()
325                 .requestData(
326                         mDataRequest,
327                         (status) -> {
328                             dataRequestStatusRef.set(status);
329                             dataRequestStatusLatch.countDown();
330                         });
331 
332         CtsWearableSensingDataRequestBroadcastReceiver.awaitResult();
333         // assert that the broadcast receiver can receive the result
334         WearableSensingDataRequest receivedDataRequest =
335                 CtsWearableSensingDataRequestBroadcastReceiver.getLatestDataRequest();
336         assertThat(receivedDataRequest).isNotNull();
337         assertThat(receivedDataRequest.getDataType()).isEqualTo(PLACEHOLDER_DATA_TYPE);
338         PersistableBundle receivedDataRequestDetails = receivedDataRequest.getRequestDetails();
339         assertThat(receivedDataRequestDetails.getString(DATA_REQUEST_DETAILS_KEY_1))
340                 .isEqualTo(DATA_REQUEST_DETAILS_VALUE_1);
341         assertThat(receivedDataRequestDetails.getInt(DATA_REQUEST_DETAILS_KEY_2))
342                 .isEqualTo(DATA_REQUEST_DETAILS_VALUE_2);
343         assertThat(dataRequestStatusLatch.await(3, SECONDS)).isTrue();
344         assertThat(dataRequestStatusRef.get())
345                 .isEqualTo(WearableSensingDataRequester.STATUS_SUCCESS);
346         // Reset the rate limit to avoid interfering with other tests
347         resetDataRequestRateLimitWindowSize();
348     }
349 
350     @Test
351     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API)
sendDataRequest_requestTooLarge_notReceivedByObserver()352     public void sendDataRequest_requestTooLarge_notReceivedByObserver() throws Exception {
353         assumeTrue(
354                 "Data request is not larger than size limit, skipping test.",
355                 mLargeDataRequest.getDataSize() > getMaxRequestSize());
356         getInstrumentation()
357                 .getUiAutomation()
358                 .adoptShellPermissionIdentity(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE);
359         AtomicInteger dataRequestStatusRef =
360                 new AtomicInteger(WearableSensingManager.STATUS_UNKNOWN);
361         CountDownLatch dataRequestStatusLatch = new CountDownLatch(1);
362 
363         // send a large request from WearableSensingService
364         registerAndGetDataRequester()
365                 .requestData(
366                         mLargeDataRequest,
367                         (status) -> {
368                             dataRequestStatusRef.set(status);
369                             dataRequestStatusLatch.countDown();
370                         });
371 
372         // CtsWearableSensingDataRequestBroadcastReceiver throws an AssertionError on timeout
373         assertThrows(
374                 AssertionError.class,
375                 () -> CtsWearableSensingDataRequestBroadcastReceiver.awaitResult());
376         assertThat(dataRequestStatusLatch.await(3, SECONDS)).isTrue();
377         assertThat(dataRequestStatusRef.get())
378                 .isEqualTo(WearableSensingDataRequester.STATUS_TOO_LARGE);
379     }
380 
381     @Test
382     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API)
sendDataRequestsAtRateLimit_allReceivedByObserver()383     public void sendDataRequestsAtRateLimit_allReceivedByObserver() throws Exception {
384         getInstrumentation()
385                 .getUiAutomation()
386                 .adoptShellPermissionIdentity(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE);
387         CtsWearableSensingDataRequestBroadcastReceiver.setResultCountToAwait(
388                 getRateLimit());
389         WearableSensingDataRequester dataRequester = registerAndGetDataRequester();
390 
391         for (int i = 0; i < getRateLimit(); i++) {
392             dataRequester.requestData(mDataRequest, status -> {});
393         }
394 
395         CtsWearableSensingDataRequestBroadcastReceiver.awaitResult();
396         // no exception means all requests are received before timeout
397         // Reset the rate limit to avoid interfering with other tests
398         resetDataRequestRateLimitWindowSize();
399     }
400 
401     @Test
402     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API)
sendDataRequests_tooFrequent_notReceivedByObserver()403     public void sendDataRequests_tooFrequent_notReceivedByObserver() throws Exception {
404         getInstrumentation()
405                 .getUiAutomation()
406                 .adoptShellPermissionIdentity(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE);
407         CtsWearableSensingDataRequestBroadcastReceiver.setResultCountToAwait(
408                 getRateLimit());
409         WearableSensingDataRequester dataRequester = registerAndGetDataRequester();
410         AtomicInteger dataRequestStatusRef =
411                 new AtomicInteger(WearableSensingManager.STATUS_UNKNOWN);
412         CountDownLatch dataRequestStatusLatch = new CountDownLatch(1);
413 
414         // Reach the limit
415         for (int i = 0; i < getRateLimit(); i++) {
416             dataRequester.requestData(mDataRequest, status -> {});
417         }
418         CtsWearableSensingDataRequestBroadcastReceiver.awaitResult();
419         // Send one more
420         CtsWearableSensingDataRequestBroadcastReceiver.setResultCountToAwait(1);
421         dataRequester.requestData(
422                 mDataRequest,
423                 (status) -> {
424                         dataRequestStatusRef.set(status);
425                         dataRequestStatusLatch.countDown();
426                 });
427 
428         // CtsWearableSensingDataRequestBroadcastReceiver throws an AssertionError on timeout
429         assertThrows(
430                 AssertionError.class,
431                 () -> CtsWearableSensingDataRequestBroadcastReceiver.awaitResult());
432         assertThat(dataRequestStatusLatch.await(3, SECONDS)).isTrue();
433         assertThat(dataRequestStatusRef.get())
434                 .isEqualTo(WearableSensingDataRequester.STATUS_TOO_FREQUENT);
435         // Reset the rate limit to avoid interfering other tests
436         resetDataRequestRateLimitWindowSize();
437     }
438 
439     @Test
440     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API)
sendDataRequestsAtRateLimit_waitForOnePeriodThenSendAgain_isReceivedByObserver()441     public void sendDataRequestsAtRateLimit_waitForOnePeriodThenSendAgain_isReceivedByObserver()
442             throws Exception {
443         getInstrumentation()
444                 .getUiAutomation()
445                 .adoptShellPermissionIdentity(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE);
446         // Allows this test to wait just 20 seconds instead of the full getRateLimitWindowSize()
447         // The window cannot be smaller than 20 seconds. It is lower-bounded by
448         // com.android.server.utils.quota.QuotaTracker#MIN_WINDOW_SIZE_MS
449         setDataRequestRateLimitWindowSizeToTwentySeconds();
450         try {
451             CtsWearableSensingDataRequestBroadcastReceiver.setResultCountToAwait(getRateLimit());
452             WearableSensingDataRequester dataRequester = registerAndGetDataRequester();
453             AtomicInteger dataRequestStatusRef =
454                     new AtomicInteger(WearableSensingManager.STATUS_UNKNOWN);
455             CountDownLatch dataRequestStatusLatch = new CountDownLatch(1);
456 
457             // Reach the limit
458             for (int i = 0; i < getRateLimit(); i++) {
459                 dataRequester.requestData(mDataRequest, status -> {});
460             }
461             CtsWearableSensingDataRequestBroadcastReceiver.awaitResult();
462             // Wait for one window size (overridden to 20 seconds above) plus some buffer
463             SystemClock.sleep(20200);
464             // Send one more
465             CtsWearableSensingDataRequestBroadcastReceiver.setResultCountToAwait(1);
466             dataRequester.requestData(
467                     mDataRequest,
468                     (status) -> {
469                         dataRequestStatusRef.set(status);
470                         dataRequestStatusLatch.countDown();
471                     });
472 
473             CtsWearableSensingDataRequestBroadcastReceiver.awaitResult();
474             assertThat(dataRequestStatusLatch.await(3, SECONDS)).isTrue();
475             assertThat(dataRequestStatusRef.get())
476                     .isEqualTo(WearableSensingDataRequester.STATUS_SUCCESS);
477         } finally {
478             resetDataRequestRateLimitWindowSize();
479         }
480     }
481 
482     @After
tearDown()483     public void tearDown() {
484         clearTestableWearableSensingService();
485         clearTestableAmbientContextDetectionService();
486         destroyDataStream();
487         getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
488     }
489 
bindToTestableWearableSensingService()490     private void bindToTestableWearableSensingService() {
491         // On Manager, bind to test service
492         assertThat(getWearableSensingServiceComponent()).isNotEqualTo(CTS_SERVICE_NAME);
493         setTestableWearableSensingService(CTS_SERVICE_NAME);
494         assertThat(CTS_SERVICE_NAME).contains(getWearableSensingServiceComponent());
495     }
496 
getWearableSensingServiceComponent()497     private String getWearableSensingServiceComponent() {
498         return runShellCommand("cmd wearable_sensing get-bound-package %d", USER_ID);
499     }
500 
setTestableWearableSensingService(String service)501     private void setTestableWearableSensingService(String service) {
502         runShellCommand("cmd wearable_sensing set-temporary-service %d %s %d",
503                 USER_ID, service, TEMPORARY_SERVICE_DURATION);
504     }
505 
clearTestableWearableSensingService()506     private void clearTestableWearableSensingService() {
507         runShellCommand("cmd wearable_sensing set-temporary-service %d", USER_ID);
508     }
509 
callStartDetection()510     private void callStartDetection() {
511         runShellCommand("cmd ambient_context start-detection-wearable %d %s",
512                 USER_ID, FAKE_APP_PACKAGE);
513     }
514 
callStartDetectionMixed()515     private void callStartDetectionMixed() {
516         runShellCommand("cmd ambient_context start-detection-mixed %d %s",
517                 USER_ID, FAKE_APP_PACKAGE);
518     }
519 
callStartDetectionDefault()520     private void callStartDetectionDefault() {
521         runShellCommand("cmd ambient_context start-detection %d %s",
522                 USER_ID, FAKE_APP_PACKAGE);
523     }
524 
createDataStream()525     private void createDataStream() {
526         runShellCommand("cmd wearable_sensing create-data-stream");
527     }
528 
destroyDataStream()529     private void destroyDataStream() {
530         runShellCommand("cmd wearable_sensing destroy-data-stream");
531     }
532 
callStopDetection()533     private void callStopDetection() {
534         runShellCommand("cmd ambient_context stop-detection %d %s",
535                 USER_ID, FAKE_APP_PACKAGE);
536     }
537 
provideDataStream()538     private void provideDataStream() {
539         runShellCommand("cmd wearable_sensing provide-data-stream %d", USER_ID);
540     }
541 
provideData()542     private void provideData() {
543         runShellCommand("cmd wearable_sensing provide-data %d %s %d",
544                 USER_ID, KEY_FOR_PROVIDE_DATA, VALUE_TO_SEND);
545     }
546 
writeDataToStream()547     private void writeDataToStream() {
548         runShellCommand("cmd wearable_sensing write-to-data-stream %s", VALUE_TO_WRITE);
549     }
550 
readDataStream()551     private String readDataStream() throws Exception {
552         ParcelFileDescriptor pipe = CtsWearableSensingService.getParcelFileDescriptor();
553         InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pipe);
554         byte[] bytes = new byte[VALUE_TO_WRITE.getBytes().length];
555         is.read(bytes, 0, bytes.length);
556         return new String(bytes);
557     }
558 
getLastStatusCode()559     private int getLastStatusCode() {
560         return Integer.parseInt(runShellCommand(
561                 "cmd wearable_sensing get-last-status-code"));
562     }
563 
564     // This method will also reset the rate limit
setDataRequestRateLimitWindowSizeToTwentySeconds()565     private void setDataRequestRateLimitWindowSizeToTwentySeconds() {
566         runShellCommand("cmd wearable_sensing set-data-request-rate-limit-window-size 20");
567     }
568 
569     // This method will also reset the rate limit
resetDataRequestRateLimitWindowSize()570     private void resetDataRequestRateLimitWindowSize() {
571         runShellCommand("cmd wearable_sensing set-data-request-rate-limit-window-size 0");
572     }
573 
getLastStatusCodeAmbientDetectionService()574     private int getLastStatusCodeAmbientDetectionService() {
575         return Integer.parseInt(runShellCommand(
576                 "cmd ambient_context get-last-status-code"));
577     }
578 
setTestableAmbientContextDetectionService(String service)579     private void setTestableAmbientContextDetectionService(String service) {
580         runShellCommand("cmd ambient_context set-temporary-services %d %s %s %d",
581                 USER_ID, service, service, TEMPORARY_SERVICE_DURATION);
582     }
583 
callQueryServiceStatus()584     private void callQueryServiceStatus() {
585         runShellCommand("cmd ambient_context query-service-status %d %s",
586                 USER_ID, FAKE_APP_PACKAGE);
587     }
588 
callQueryWearableServiceStatus()589     private void callQueryWearableServiceStatus() {
590         runShellCommand("cmd ambient_context query-wearable-service-status %d %s",
591                 USER_ID, FAKE_APP_PACKAGE);
592     }
593 
callQueryMixedServiceStatus()594     private void callQueryMixedServiceStatus() {
595         runShellCommand("cmd ambient_context query-mixed-service-status %d %s",
596                 USER_ID, FAKE_APP_PACKAGE);
597     }
598 
clearTestableAmbientContextDetectionService()599     private void clearTestableAmbientContextDetectionService() {
600         runShellCommand("cmd ambient_context set-temporary-service %d", USER_ID);
601     }
602 
getAmbientContextDetectionServiceComponent()603     private String getAmbientContextDetectionServiceComponent() {
604         return runShellCommand("cmd ambient_context get-bound-package %s", USER_ID);
605     }
606 
registerAndGetDataRequester()607     private WearableSensingDataRequester registerAndGetDataRequester() {
608         mWearableSensingManager.registerDataRequestObserver(
609                 PLACEHOLDER_DATA_TYPE,
610                 mDataRequestObserverPendingIntent,
611                 mExecutor,
612                 (dataRequestObserverRegistrationStatus) -> {});
613         CtsWearableSensingService.awaitResult();
614         assertThat(CtsWearableSensingService.getDataRequesters(PLACEHOLDER_DATA_TYPE)).hasSize(1);
615         return Iterables.getOnlyElement(
616                 CtsWearableSensingService.getDataRequesters(PLACEHOLDER_DATA_TYPE));
617     }
618 
createDataRequestPendingIntent(Context context)619     private static PendingIntent createDataRequestPendingIntent(Context context) {
620         Intent intent =
621                 new Intent("cts.android.service.wearable.DataRequestReceiverAction")
622                         .setClass(context, CtsWearableSensingDataRequestBroadcastReceiver.class);
623         int unusedRequestCode = 0;
624         return PendingIntent.getBroadcast(
625                 context, unusedRequestCode, intent, PendingIntent.FLAG_MUTABLE);
626     }
627 
isWatch(Context context)628     private static boolean isWatch(Context context) {
629         PackageManager pm = context.getPackageManager();
630         return pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
631     }
632 }
633