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 android.devicepolicy.cts; 18 19 import static com.android.bedstead.nene.permissions.CommonPermissions.INTERACT_ACROSS_USERS; 20 import static com.android.queryable.queries.ActivityQuery.activity; 21 import static com.android.queryable.queries.IntentFilterQuery.intentFilter; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.junit.Assume.assumeFalse; 26 import static org.junit.Assume.assumeTrue; 27 import static org.testng.Assert.assertThrows; 28 29 import android.app.admin.ManagedSubscriptionsPolicy; 30 import android.app.admin.RemoteDevicePolicyManager; 31 import android.app.role.RoleManager; 32 import android.content.ComponentName; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.pm.PackageManager; 36 import android.provider.Settings; 37 import android.provider.Telephony; 38 import android.telephony.TelephonyManager; 39 40 import com.android.bedstead.harrier.BedsteadJUnit4; 41 import com.android.bedstead.harrier.DeviceState; 42 import com.android.bedstead.harrier.annotations.EnsureGlobalSettingSet; 43 import com.android.bedstead.harrier.annotations.EnsureHasPermission; 44 import com.android.bedstead.harrier.annotations.Postsubmit; 45 import com.android.bedstead.harrier.annotations.RequireNotHeadlessSystemUserMode; 46 import com.android.bedstead.harrier.annotations.enterprise.CanSetPolicyTest; 47 import com.android.bedstead.harrier.annotations.enterprise.CannotSetPolicyTest; 48 import com.android.bedstead.harrier.annotations.enterprise.PolicyDoesNotApplyTest; 49 import com.android.bedstead.harrier.policies.DefaultSmsApplication; 50 import com.android.bedstead.harrier.policies.DefaultSmsApplicationSystemOnly; 51 import com.android.bedstead.nene.TestApis; 52 import com.android.bedstead.remotedpc.RemotePolicyManager; 53 import com.android.bedstead.testapp.TestApp; 54 import com.android.bedstead.testapp.TestAppInstance; 55 56 import org.junit.Before; 57 import org.junit.ClassRule; 58 import org.junit.Ignore; 59 import org.junit.Rule; 60 import org.junit.runner.RunWith; 61 62 import java.util.Objects; 63 64 // TODO(b/198442101): Add tests for the COPE case when we can sideload system apps 65 @RunWith(BedsteadJUnit4.class) 66 public final class DefaultSmsApplicationTest { 67 @ClassRule 68 @Rule 69 public static DeviceState sDeviceState = new DeviceState(); 70 71 private static final Context sContext = TestApis.context().instrumentedContext(); 72 private static final TestApp sSmsApp = sDeviceState.testApps() 73 .query() 74 .whereActivities().contains( 75 activity().where().intentFilters().contains( 76 intentFilter().where().actions().contains(Intent.ACTION_SENDTO))) 77 .get(); 78 private static final String FAKE_SMS_APP_NAME = "FakeSmsAppName"; 79 80 private ComponentName mAdmin; 81 private RemoteDevicePolicyManager mDpm; 82 private TelephonyManager mTelephonyManager; 83 private RoleManager mRoleManager; 84 85 @Before setUp()86 public void setUp() { 87 RemotePolicyManager dpc = sDeviceState.dpc(); 88 mAdmin = dpc.componentName(); 89 mDpm = dpc.devicePolicyManager(); 90 mTelephonyManager = sContext.getSystemService(TelephonyManager.class); 91 mRoleManager = sContext.getSystemService(RoleManager.class); 92 } 93 94 // TODO: Add tests for SetDefaultSmsApplicationSystemOnly 95 96 // TODO(b/198588696): Add support is @RequireSmsCapable and @RequireNotSmsCapable 97 @Postsubmit(reason = "new test") 98 @CanSetPolicyTest(policy = DefaultSmsApplication.class) 99 @RequireNotHeadlessSystemUserMode(reason = "b/279731298") 100 @EnsureGlobalSettingSet(key = 101 Settings.Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS, value = "1") setDefaultSmsApplication_works()102 public void setDefaultSmsApplication_works() { 103 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 104 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 105 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 106 ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS)); 107 } 108 assumeTrue(isSmsCapable()); 109 String previousSmsAppName = getDefaultSmsPackage(); 110 try (TestAppInstance smsApp = sSmsApp.install()) { 111 mDpm.setDefaultSmsApplication(mAdmin, smsApp.packageName()); 112 assertThat(getDefaultSmsPackage()).isEqualTo(smsApp.packageName()); 113 } finally { 114 mDpm.setDefaultSmsApplication(mAdmin, previousSmsAppName); 115 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 116 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 117 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 118 ManagedSubscriptionsPolicy.TYPE_ALL_PERSONAL_SUBSCRIPTIONS)); 119 } 120 } 121 } 122 123 // TODO(b/198588696): Add support is @RequireSmsCapable and @RequireNotSmsCapable 124 @Postsubmit(reason = "new test") 125 @PolicyDoesNotApplyTest(policy = DefaultSmsApplication.class) 126 @EnsureGlobalSettingSet(key = 127 Settings.Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS, value = "1") 128 @EnsureHasPermission(INTERACT_ACROSS_USERS) setDefaultSmsApplication_unchanged()129 public void setDefaultSmsApplication_unchanged() { 130 assumeTrue(isSmsCapable()); 131 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 132 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 133 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 134 ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS)); 135 } 136 String previousSmsAppInTest = getDefaultSmsPackage(); 137 String previousSmsAppInDpc = getDefaultSmsPackageInDpc(); 138 try (TestAppInstance smsApp = sSmsApp.install(sDeviceState.dpc().user())) { 139 mDpm.setDefaultSmsApplication(mAdmin, smsApp.packageName()); 140 141 assertThat(Telephony.Sms.getDefaultSmsPackage(sContext)) 142 .isEqualTo(previousSmsAppInTest); 143 } finally { 144 mDpm.setDefaultSmsApplication(mAdmin, previousSmsAppInDpc); 145 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 146 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 147 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 148 ManagedSubscriptionsPolicy.TYPE_ALL_PERSONAL_SUBSCRIPTIONS)); 149 } 150 } 151 } 152 153 // TODO(b/198588696): Add support is @RequireSmsCapable and @RequireNotSmsCapable 154 @Postsubmit(reason = "new test") 155 @CanSetPolicyTest(policy = DefaultSmsApplication.class) 156 @EnsureGlobalSettingSet(key = 157 Settings.Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS, value = "1") setDefaultSmsApplication_smsPackageDoesNotExist_unchanged()158 public void setDefaultSmsApplication_smsPackageDoesNotExist_unchanged() { 159 assumeTrue(isSmsCapable()); 160 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 161 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 162 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 163 ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS)); 164 } 165 String previousSmsAppName = getDefaultSmsPackage(); 166 167 mDpm.setDefaultSmsApplication(mAdmin, FAKE_SMS_APP_NAME); 168 169 try { 170 assertThat(getDefaultSmsPackage()).isEqualTo(previousSmsAppName); 171 } finally { 172 mDpm.setDefaultSmsApplication(mAdmin, previousSmsAppName); 173 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 174 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 175 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 176 ManagedSubscriptionsPolicy.TYPE_ALL_PERSONAL_SUBSCRIPTIONS)); 177 } 178 } 179 } 180 181 @Postsubmit(reason = "new test") 182 @CanSetPolicyTest(policy = {DefaultSmsApplication.class, DefaultSmsApplicationSystemOnly.class}) setDefaultSmsApplication_nullAdmin_throwsException()183 public void setDefaultSmsApplication_nullAdmin_throwsException() { 184 try (TestAppInstance smsApp = sSmsApp.install()) { 185 186 assertThrows(NullPointerException.class, () -> 187 mDpm.setDefaultSmsApplication( 188 /* admin= */ null, smsApp.packageName())); 189 } 190 } 191 192 // TODO(b/198588696): Add support is @RequireSmsCapable and @RequireNotSmsCapable 193 @Postsubmit(reason = "new test") 194 @CanSetPolicyTest(policy = DefaultSmsApplication.class) 195 @EnsureGlobalSettingSet(key = 196 Settings.Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS, value = "1") setDefaultSmsApplication_notSmsCapable_unchanged()197 public void setDefaultSmsApplication_notSmsCapable_unchanged() { 198 assumeFalse(isSmsCapable()); 199 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 200 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 201 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 202 ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS)); 203 } 204 String previousSmsAppName = getDefaultSmsPackage(); 205 try (TestAppInstance smsApp = sSmsApp.install()) { 206 207 mDpm.setDefaultSmsApplication(mAdmin, smsApp.packageName()); 208 209 // ROLE_SMS behaviour(SmsRoleBehaviour.java) changes based on the 210 // ManagedSubscriptionsPolicy on the work profile, so asserting isSmsCapable here again 211 // to check that if device is actually smsCapable or else assert that default sms app 212 // does not changes. 213 assertThat(isSmsCapable() || Objects.equals(getDefaultSmsPackage(), 214 previousSmsAppName)).isTrue(); 215 } finally { 216 mDpm.setDefaultSmsApplication(mAdmin, previousSmsAppName); 217 //TODO(b/273529454): replace with EnsureTelephonyEnabledInUser annotation 218 if (mDpm.isOrganizationOwnedDeviceWithManagedProfile()) { 219 mDpm.setManagedSubscriptionsPolicy(new ManagedSubscriptionsPolicy( 220 ManagedSubscriptionsPolicy.TYPE_ALL_PERSONAL_SUBSCRIPTIONS)); 221 } 222 } 223 } 224 225 @Ignore("b/300397938") 226 @Postsubmit(reason = "new test") 227 // We don't include non device admin states as passing a null admin is a NullPointerException 228 @CannotSetPolicyTest(policy = { 229 DefaultSmsApplication.class, DefaultSmsApplicationSystemOnly.class}, 230 includeNonDeviceAdminStates = false) setDefaultSmsApplication_invalidAdmin_throwsException()231 public void setDefaultSmsApplication_invalidAdmin_throwsException() { 232 try (TestAppInstance smsApp = sSmsApp.install()) { 233 234 assertThrows(SecurityException.class, () -> 235 mDpm.setDefaultSmsApplication(mAdmin, smsApp.packageName())); 236 } 237 } 238 getDefaultSmsPackage()239 private String getDefaultSmsPackage() { 240 return Telephony.Sms.getDefaultSmsPackage(sContext); 241 } 242 getDefaultSmsPackageInDpc()243 private String getDefaultSmsPackageInDpc() { 244 // TODO(268461966): Make the call via the dpc 245 try { 246 return Telephony.Sms.getDefaultSmsPackage( 247 sContext.createPackageContextAsUser( 248 sDeviceState.dpc().packageName(), 249 /* flags= */ 0, 250 sDeviceState.dpc().user().userHandle())); 251 } catch (PackageManager.NameNotFoundException e) { 252 throw new RuntimeException(e); 253 } 254 } 255 isSmsCapable()256 private boolean isSmsCapable() { 257 return mTelephonyManager.isSmsCapable() 258 || (mRoleManager != null && mRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); 259 } 260 } 261