1 /* 2 * Copyright (C) 2023 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 android.healthconnect.cts.showmigrationinfointent; 18 19 import static android.Manifest.permission.MIGRATE_HEALTH_CONNECT_DATA; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import android.app.UiAutomation; 24 import android.content.Context; 25 import android.health.connect.HealthConnectManager; 26 import android.health.connect.migration.MigrationException; 27 import android.healthconnect.cts.utils.AssumptionCheckerRule; 28 import android.healthconnect.cts.utils.TestUtils; 29 import android.os.Build; 30 import android.os.OutcomeReceiver; 31 import android.os.ext.SdkExtensions; 32 import android.platform.test.annotations.AppModeFull; 33 34 import androidx.test.platform.app.InstrumentationRegistry; 35 import androidx.test.runner.AndroidJUnit4; 36 37 import org.junit.After; 38 import org.junit.Before; 39 import org.junit.Rule; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 import java.util.Collections; 44 import java.util.concurrent.CountDownLatch; 45 import java.util.concurrent.Executors; 46 import java.util.concurrent.TimeUnit; 47 import java.util.concurrent.atomic.AtomicReference; 48 49 @AppModeFull(reason = "HealthConnectManager is not accessible to instant apps") 50 @RunWith(AndroidJUnit4.class) 51 public class ShowMigrationInfoIntentAbsentTest { 52 private Context mContext; 53 private HealthConnectManager mManager; 54 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 55 56 @Rule 57 public AssumptionCheckerRule mSupportedHardwareRule = 58 new AssumptionCheckerRule( 59 TestUtils::isHardwareSupported, "Tests should run on supported hardware only."); 60 61 @Before setUp()62 public void setUp() { 63 mContext = InstrumentationRegistry.getInstrumentation().getContext(); 64 mManager = mContext.getSystemService(HealthConnectManager.class); 65 TestUtils.deleteAllStagedRemoteData(); 66 } 67 68 @After tearDown()69 public void tearDown() { 70 TestUtils.deleteAllStagedRemoteData(); 71 } 72 73 @Test(expected = MigrationException.class) testInsertMinDataMigrationSdkExtensionVersion_throwsException()74 public void testInsertMinDataMigrationSdkExtensionVersion_throwsException() 75 throws InterruptedException { 76 int version = SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + 1; 77 uiAutomation.adoptShellPermissionIdentity(MIGRATE_HEALTH_CONNECT_DATA); 78 TestUtils.insertMinDataMigrationSdkExtensionVersion(version); 79 uiAutomation.dropShellPermissionIdentity(); 80 } 81 82 @Test(expected = MigrationException.class) testStartMigration_throwsException()83 public void testStartMigration_throwsException() throws InterruptedException { 84 uiAutomation.adoptShellPermissionIdentity(MIGRATE_HEALTH_CONNECT_DATA); 85 TestUtils.startMigration(); 86 uiAutomation.dropShellPermissionIdentity(); 87 } 88 89 @Test(expected = MigrationException.class) testFinishMigration_throwsException()90 public void testFinishMigration_throwsException() throws InterruptedException { 91 uiAutomation.adoptShellPermissionIdentity(MIGRATE_HEALTH_CONNECT_DATA); 92 TestUtils.finishMigration(); 93 uiAutomation.dropShellPermissionIdentity(); 94 } 95 96 @Test(expected = MigrationException.class) testWriteMigrationData_throwsException()97 public void testWriteMigrationData_throwsException() throws InterruptedException { 98 uiAutomation.adoptShellPermissionIdentity(MIGRATE_HEALTH_CONNECT_DATA); 99 writeMigrationData(); 100 uiAutomation.dropShellPermissionIdentity(); 101 } 102 writeMigrationData()103 private void writeMigrationData() throws InterruptedException { 104 CountDownLatch latch = new CountDownLatch(1); 105 AtomicReference<MigrationException> migrationExceptionAtomicReference = 106 new AtomicReference<>(); 107 mManager.writeMigrationData( 108 Collections.emptyList(), 109 Executors.newSingleThreadExecutor(), 110 new OutcomeReceiver<>() { 111 112 @Override 113 public void onResult(Void result) { 114 latch.countDown(); 115 } 116 117 @Override 118 public void onError(MigrationException exception) { 119 migrationExceptionAtomicReference.set(exception); 120 latch.countDown(); 121 } 122 }); 123 assertThat(latch.await(3, TimeUnit.SECONDS)).isTrue(); 124 if (migrationExceptionAtomicReference.get() != null) { 125 throw migrationExceptionAtomicReference.get(); 126 } 127 } 128 } 129