1 /*
2  * Copyright (C) 2009 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.permissionpolicy.cts;
18 
19 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
20 import static com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import android.content.BroadcastReceiver;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.pm.PackageManager;
30 import android.net.Uri;
31 import android.os.Bundle;
32 import android.platform.test.annotations.AppModeFull;
33 import android.telecom.TelecomManager;
34 import android.util.Log;
35 
36 import androidx.test.platform.app.InstrumentationRegistry;
37 
38 import com.android.compatibility.common.util.SystemUtil;
39 
40 import org.junit.After;
41 import org.junit.Assert;
42 import org.junit.Before;
43 import org.junit.Test;
44 
45 import java.util.concurrent.CountDownLatch;
46 import java.util.concurrent.TimeUnit;
47 
48 /**
49  * Verify that processing outgoing calls requires Permission.
50  */
51 @AppModeFull(reason = "Instant apps cannot hold PROCESS_OUTGOING_CALL")
52 public class NoProcessOutgoingCallPermissionTest {
53     private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
54 
55     // Time to wait for call to be placed.
56     private static final int CALL_START_WAIT_TIME_SEC = 30;
57     // Time to wait for a broadcast to be received after we verify that the test app which has
58     // the proper permission got the broadcast
59     private static final int POST_CALL_START_WAIT_TIME_SEC = 5;
60 
61     private static final String APK_INSTALL_LOCATION =
62             "/data/local/tmp/cts-permissionpolicy/CtsProcessOutgoingCalls.apk";
63     private static final String LOG_TAG = "NoProcessOutgoingCallPermissionTest";
64 
65     private static final String ACTION_TEST_APP_RECEIVED_CALL =
66             "android.permissionpolicy.cts.TEST_APP_RECEIVED_CALL";
67     private static final String TEST_PKG_NAME = "android.permissionpolicy.cts.receivecallbroadcast";
68 
69     private final CountDownLatch mTestAppBroadcastLatch = new CountDownLatch(1);
70     private final CountDownLatch mSystemBroadcastLatch = new CountDownLatch(1);
71 
callPhone()72     private void callPhone() {
73         Uri uri = Uri.parse("tel:123456");
74         Intent intent = new Intent(Intent.ACTION_CALL, uri);
75         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
76         mContext.startActivity(intent);
77         Log.i(LOG_TAG, "Called phone: " + uri.toString());
78     }
79 
80     /**
81      * Verify that to process an outgoing call requires Permission.
82      * <p>Tests Permission:
83      *   {@link android.Manifest.permission#PROCESS_OUTGOING_CALLS}
84      */
85     // TODO: add back to LargeTest when test can cancel initiated call
86     @Test
testProcessOutgoingCall()87     public void testProcessOutgoingCall() throws InterruptedException {
88         final PackageManager pm = mContext.getPackageManager();
89         if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING) ||
90                 !pm.hasSystemFeature(PackageManager.FEATURE_SIP_VOIP)) {
91             return;
92         }
93 
94         OutgoingCallBroadcastReceiver rcvr = new OutgoingCallBroadcastReceiver();
95         IntentFilter filter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
96         filter.addAction(ACTION_TEST_APP_RECEIVED_CALL);
97         mContext.registerReceiver(rcvr, filter, Context.RECEIVER_EXPORTED);
98         // start the test app, so that it can receive the broadcast
99         mContext.startActivity(new Intent().setComponent(new ComponentName(TEST_PKG_NAME,
100                         TEST_PKG_NAME + ".ProcessOutgoingCallReceiver$BaseActivity"))
101                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
102 
103         callPhone();
104 
105         boolean testAppGotBroadcast =
106                 mTestAppBroadcastLatch.await(CALL_START_WAIT_TIME_SEC, TimeUnit.SECONDS);
107         Assert.assertTrue("Expected test app to receive broadcast within "
108                         + CALL_START_WAIT_TIME_SEC + " seconds", testAppGotBroadcast);
109         boolean testClassGotBroadcast =
110                 mSystemBroadcastLatch.await(POST_CALL_START_WAIT_TIME_SEC, TimeUnit.SECONDS);
111         Assert.assertFalse("Outgoing call processed without proper permissions",
112                 testClassGotBroadcast);
113     }
114 
115     @Before
installApp()116     public void installApp() {
117         String installResult = runShellCommandOrThrow("pm install -g " + APK_INSTALL_LOCATION);
118         assertThat(installResult.trim()).isEqualTo("Success");
119     }
120 
121     @After
endCall()122     public void endCall() {
123         SystemUtil.runWithShellPermissionIdentity(() -> {
124             mContext.getSystemService(TelecomManager.class).endCall();
125         });
126         runShellCommand("pm uninstall " + TEST_PKG_NAME);
127     }
128 
129     public class OutgoingCallBroadcastReceiver extends BroadcastReceiver {
onReceive(Context context, Intent intent)130         public void onReceive(Context context, Intent intent) {
131             if (ACTION_TEST_APP_RECEIVED_CALL.equals(intent.getAction())) {
132                 mTestAppBroadcastLatch.countDown();
133                 return;
134             }
135             Bundle xtrs = intent.getExtras();
136             Log.e(LOG_TAG, xtrs.toString());
137             mSystemBroadcastLatch.countDown();
138         }
139     }
140 
141 }
142 
143