Run tests that rely on BlockedNumberProvider from secondary users.
The BlockedNumberProvider can only be accesses from the primary user. In
order to run tests on a secondary user, a singleton service is created
and invoked from the telecom ad telephony tests that use the
BlockedNumberProvider.
Test: cts-tradefed run cts-dev -m CtsTelephonyTestCases
... on prod pi device running primary and secondary user. See bug for
additional details.
bug: 121246456
Change-Id: Ieb3af346e2b0d15257abf6d60630db777964a3cc
Merged-In: Ieb3af346e2b0d15257abf6d60630db777964a3cc
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java
new file mode 100644
index 0000000..360c078
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import static android.provider.BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER;
+import static android.provider.BlockedNumberContract.BlockedNumbers.CONTENT_URI;
+
+import android.app.IntentService;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.util.Log;
+
+/**
+ * A service to handle interactions with the BlockedNumberProvider. The BlockedNumberProvider
+ * can only be accessed by the primary user. This service can be run as a singleton service
+ * which will then be able to access the BlockedNumberProvider from a test running in a
+ * secondary user.
+ */
+public class BlockedNumberService extends IntentService {
+
+ static final String INSERT_ACTION = "android.telecom.cts.InsertBlockedNumber";
+ static final String DELETE_ACTION = "android.telecom.cts.DeleteBlockedNumber";
+ static final String PHONE_NUMBER_EXTRA = "number";
+ static final String URI_EXTRA = "uri";
+ static final String ROWS_EXTRA = "rows";
+ static final String RESULT_RECEIVER_EXTRA = "resultReceiver";
+
+ private static final String TAG = "CtsBlockNumberSvc";
+
+ private ContentResolver mContentResolver;
+
+ public BlockedNumberService() {
+ super(BlockedNumberService.class.getName());
+ }
+
+ @Override
+ public void onHandleIntent(Intent intent) {
+ Log.i(TAG, "Starting BlockedNumberService service: " + intent);
+ if (intent == null) {
+ return;
+ }
+ Bundle bundle;
+ mContentResolver = getContentResolver();
+ switch (intent.getAction()) {
+ case INSERT_ACTION:
+ bundle = insertBlockedNumber(intent.getStringExtra(PHONE_NUMBER_EXTRA));
+ break;
+ case DELETE_ACTION:
+ bundle = deleteBlockedNumber(Uri.parse(intent.getStringExtra(URI_EXTRA)));
+ break;
+ default:
+ bundle = new Bundle();
+ break;
+ }
+ ResultReceiver receiver = intent.getParcelableExtra(RESULT_RECEIVER_EXTRA);
+ receiver.send(0, bundle);
+ }
+
+ private Bundle insertBlockedNumber(String number) {
+ Log.i(TAG, "insertBlockedNumber: " + number);
+
+ ContentValues cv = new ContentValues();
+ cv.put(COLUMN_ORIGINAL_NUMBER, number);
+ Uri uri = mContentResolver.insert(CONTENT_URI, cv);
+ Bundle bundle = new Bundle();
+ bundle.putString(URI_EXTRA, uri.toString());
+ return bundle;
+ }
+
+ private Bundle deleteBlockedNumber(Uri uri) {
+ Log.i(TAG, "deleteBlockedNumber: " + uri);
+
+ int rows = mContentResolver.delete(uri, null, null);
+ Bundle bundle = new Bundle();
+ bundle.putInt(ROWS_EXTRA, rows);
+ return bundle;
+ }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java
new file mode 100644
index 0000000..e5a0ce4
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import static com.android.compatibility.common.util.BlockedNumberService.DELETE_ACTION;
+import static com.android.compatibility.common.util.BlockedNumberService.INSERT_ACTION;
+import static com.android.compatibility.common.util.BlockedNumberService.PHONE_NUMBER_EXTRA;
+import static com.android.compatibility.common.util.BlockedNumberService.RESULT_RECEIVER_EXTRA;
+import static com.android.compatibility.common.util.BlockedNumberService.ROWS_EXTRA;
+import static com.android.compatibility.common.util.BlockedNumberService.URI_EXTRA;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utility for starting the blocked number service.
+ */
+public class BlockedNumberUtil {
+
+ private static final int TIMEOUT = 2;
+
+ private BlockedNumberUtil() {}
+
+ /** Insert a phone number into the blocked number provider and returns the resulting Uri. */
+ public static Uri insertBlockedNumber(Context context, String phoneNumber) {
+ Intent intent = new Intent(INSERT_ACTION);
+ intent.putExtra(PHONE_NUMBER_EXTRA, phoneNumber);
+
+ return Uri.parse(runBlockedNumberService(context, intent).getString(URI_EXTRA));
+ }
+
+ /** Remove a number from the blocked number provider and returns the number of rows deleted. */
+ public static int deleteBlockedNumber(Context context, Uri uri) {
+ Intent intent = new Intent(DELETE_ACTION);
+ intent.putExtra(URI_EXTRA, uri.toString());
+
+ return runBlockedNumberService(context, intent).getInt(ROWS_EXTRA);
+ }
+
+ /** Start the blocked number service. */
+ static Bundle runBlockedNumberService(Context context, Intent intent) {
+ // Temporarily allow background service
+ SystemUtil.runShellCommand("cmd deviceidle tempwhitelist " + context.getPackageName());
+
+ final Semaphore semaphore = new Semaphore(0);
+ final Bundle result = new Bundle();
+
+ ResultReceiver receiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ result.putAll(resultData);
+ semaphore.release();
+ }
+ };
+ intent.putExtra(RESULT_RECEIVER_EXTRA, receiver);
+ intent.setComponent(new ComponentName(context, BlockedNumberService.class));
+
+ context.startService(intent);
+
+ try {
+ TestCase.assertTrue(semaphore.tryAcquire(TIMEOUT, TimeUnit.SECONDS));
+ } catch (InterruptedException e) {
+ TestCase.fail("Timed out waiting for result from BlockedNumberService");
+ }
+ return result;
+ }
+}
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index cce9785..6d2ed72 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -71,6 +71,15 @@
</intent-filter>
</service>
+ <service android:name="com.android.compatibility.common.util.BlockedNumberService"
+ android:exported="true"
+ android:singleUser="true" >
+ <intent-filter>
+ <action android:name="android.telecom.cts.InsertBlockedNumber"/>
+ <action android:name="android.telecom.cts.DeleteBlockedNumber"/>
+ </intent-filter>
+ </service>
+
<receiver android:name="android.telecom.cts.MockMissedCallNotificationReceiver">
<intent-filter>
<action android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" />
diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
index 871f3e4..954112b 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
@@ -17,13 +17,14 @@
package android.telecom.cts;
import static android.telecom.cts.TestUtils.*;
+import static com.android.compatibility.common.util.BlockedNumberUtil.deleteBlockedNumber;
+import static com.android.compatibility.common.util.BlockedNumberUtil.insertBlockedNumber;
import android.app.UiModeManager;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.BlockedNumberContract;
import android.telecom.CallAudioState;
import android.telecom.Call;
import android.telecom.Connection;
@@ -393,17 +394,17 @@
assertNull(mInCallCallbacks.getService());
} finally {
if (blockedUri != null) {
- mContext.getContentResolver().delete(blockedUri, null, null);
+ unblockNumber(blockedUri);
}
}
}
private Uri blockNumber(Uri phoneNumberUri) {
- ContentValues cv = new ContentValues();
- cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
- phoneNumberUri.getSchemeSpecificPart());
- return mContext.getContentResolver().insert(
- BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+ return insertBlockedNumber(mContext, phoneNumberUri.getSchemeSpecificPart());
+ }
+
+ private int unblockNumber(Uri uri) {
+ return deleteBlockedNumber(mContext, uri);
}
public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() {
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
index b6840a3..2360145 100644
--- a/tests/tests/telephony/AndroidManifest.xml
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -30,6 +30,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"/>
<permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"
@@ -119,6 +120,15 @@
</service>
+ <service android:name="com.android.compatibility.common.util.BlockedNumberService"
+ android:exported="true"
+ android:singleUser="true" >
+ <intent-filter>
+ <action android:name="android.telecom.cts.InsertBlockedNumber"/>
+ <action android:name="android.telecom.cts.DeleteBlockedNumber"/>
+ </intent-filter>
+ </service>
+
<activity android:name="android.telephony.cts.StubDialerActvity">
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 74f9d13..89814aa 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -16,11 +16,12 @@
package android.telephony.cts;
+import static com.android.compatibility.common.util.BlockedNumberUtil.deleteBlockedNumber;
+import static com.android.compatibility.common.util.BlockedNumberUtil.insertBlockedNumber;
import android.app.PendingIntent;
import android.app.UiAutomation;
import android.content.BroadcastReceiver;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -29,7 +30,6 @@
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
-import android.provider.BlockedNumberContract;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
@@ -118,7 +118,7 @@
@Override
protected void tearDown() throws Exception {
if (mBlockedNumberUri != null) {
- mContext.getContentResolver().delete(mBlockedNumberUri, null, null);
+ unblockNumber(mBlockedNumberUri);
mBlockedNumberUri = null;
}
if (mTestAppSetAsDefaultSmsApp) {
@@ -398,17 +398,18 @@
getSmsManager().sendTextMessage(destAddr, null, text, sentIntent, deliveredIntent);
}
- private void blockNumber(String phoneNumber) {
- ContentValues cv = new ContentValues();
- cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER, phoneNumber);
- mBlockedNumberUri = mContext.getContentResolver().insert(
- BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+ private void blockNumber(String number) {
+ mBlockedNumberUri = insertBlockedNumber(mContext, number);
+ }
+
+ private void unblockNumber(Uri uri) {
+ deleteBlockedNumber(mContext, uri);
}
private void setDefaultSmsApp(boolean setToSmsApp)
throws Exception {
String command = String.format(
- "appops set %s WRITE_SMS %s",
+ "appops set --user 0 %s WRITE_SMS %s",
mContext.getPackageName(),
setToSmsApp ? "allow" : "default");
assertTrue("Setting default SMS app failed : " + setToSmsApp,