• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.telephony.embms.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 
24 import android.content.BroadcastReceiver;
25 import android.content.ContentResolver;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.net.Uri;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.telephony.MbmsDownloadSession;
33 import android.telephony.cts.embmstestapp.CtsDownloadService;
34 import android.telephony.mbms.DownloadRequest;
35 import android.telephony.mbms.MbmsDownloadReceiver;
36 import android.telephony.mbms.UriPathPair;
37 import android.telephony.mbms.vendor.VendorUtils;
38 
39 import java.io.File;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.Objects;
43 import java.util.concurrent.BlockingQueue;
44 import java.util.concurrent.LinkedBlockingQueue;
45 import java.util.concurrent.TimeUnit;
46 import java.util.stream.Collectors;
47 import org.junit.After;
48 import org.junit.Before;
49 import org.junit.Test;
50 
51 public class MbmsDownloadReceiverTest extends MbmsDownloadTestBase {
52     private static final String CTS_BROADCAST_PERMISSION =
53             "android.telephony.embms.cts.permission.TEST_BROADCAST";
54     private static final String TEST_SERVICE_ID = "service_id";
55 
56     public static final String APP_INTENT_ACTION =
57             "android.telephony.embms.cts.ACTION_TEST_DOWNLOAD_COMPLETE";
58 
59     public static class AppIntentCapture {
60         private final BlockingQueue<Intent> mReceivedIntent = new LinkedBlockingQueue<>();
61         private final BroadcastReceiver mAppIntentReceiver = new BroadcastReceiver() {
62             @Override
63             public void onReceive(Context context, Intent intent) {
64                 mReceivedIntent.add(intent);
65             }
66         };
67         private Context mContext;
68 
AppIntentCapture(Context context, Handler handler)69         public AppIntentCapture(Context context, Handler handler) {
70             mContext = context;
71             IntentFilter filter = new IntentFilter(APP_INTENT_ACTION);
72             mContext.registerReceiver(mAppIntentReceiver, filter, null, handler);
73         }
74 
getIntent()75         public Intent getIntent() {
76             return getIntent(true);
77         }
78 
getIntent(boolean unregister)79         public Intent getIntent(boolean unregister) {
80             try {
81                 Intent result = mReceivedIntent.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
82                 if (unregister) {
83                     mContext.unregisterReceiver(mAppIntentReceiver);
84                 }
85                 return result;
86             } catch (InterruptedException e) {
87                 fail("test was interrupted");
88                 return null;
89             }
90         }
91 
getIntents(int numExpected)92         public List<Intent> getIntents(int numExpected) {
93             ArrayList<Intent> result = new ArrayList<>(numExpected);
94             for (int i = 0; i < numExpected; i++) {
95                 result.add(getIntent(false));
96             }
97             mContext.unregisterReceiver(mAppIntentReceiver);
98             return result;
99         }
100     }
101 
102     private MbmsDownloadReceiver mReceiver;
103     private File tempFileRootDir;
104     private String tempFileRootDirPath;
105     private DownloadRequest testDownloadRequest;
106 
107     @Before
setUp()108     public void setUp() throws Exception {
109         super.setUp();
110         testDownloadRequest = downloadRequestTemplate
111                 .setAppIntent(new Intent(APP_INTENT_ACTION))
112                 .build();
113         mReceiver = new MbmsDownloadReceiver();
114         IntentFilter filter = new IntentFilter();
115         filter.addAction(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
116         filter.addAction(VendorUtils.ACTION_CLEANUP);
117         filter.addAction(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
118         mContext.registerReceiver(mReceiver, filter);
119         tempFileRootDir = new File(mContext.getFilesDir(), "CtsTestDir");
120         tempFileRootDir.mkdir();
121         tempFileRootDirPath = tempFileRootDir.getCanonicalPath();
122         try {
123             mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
124         } catch (IllegalStateException e) {
125             tearDown();
126             throw e;
127         }
128     }
129 
130     @After
tearDown()131     public void tearDown() throws Exception {
132         recursiveDelete(tempFileRootDir);
133         tempFileRootDir = null;
134         super.tearDown();
135     }
136 
137     @Test
testMalformedIntents()138     public void testMalformedIntents() throws Exception {
139         Intent downloadCompleteIntent = new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
140         sendBroadcastAndValidate(downloadCompleteIntent,
141                 MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
142 
143         Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
144         sendBroadcastAndValidate(fdRequestIntent,
145                 MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
146 
147         Intent cleanupIntent = new Intent(VendorUtils.ACTION_CLEANUP);
148         sendBroadcastAndValidate(cleanupIntent,
149                 MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
150     }
151 
152     @Test
testBadTempFileDirectory()153     public void testBadTempFileDirectory() throws Exception {
154         Intent cleanupIntent = new Intent(VendorUtils.ACTION_CLEANUP);
155         populateIntentWithCommonFields(cleanupIntent);
156         cleanupIntent.putParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE,
157                 new ArrayList<>(0));
158         cleanupIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT, "this is not a directory path");
159         sendBroadcastAndValidate(cleanupIntent,
160                 MbmsDownloadReceiver.RESULT_BAD_TEMP_FILE_ROOT);
161     }
162 
163     @Test
testDownloadFailureIntent()164     public void testDownloadFailureIntent() throws Exception {
165         Intent intentForReceiverTest = new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
166         populateIntentWithCommonFields(intentForReceiverTest);
167         intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
168                 MbmsDownloadSession.RESULT_CANCELLED);
169         intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST,
170                 testDownloadRequest);
171 
172         AppIntentCapture intentCaptor = new AppIntentCapture(mContext, mHandler);
173 
174         sendBroadcastAndValidate(intentForReceiverTest, MbmsDownloadReceiver.RESULT_OK);
175         Intent receivedIntent = intentCaptor.getIntent();
176 
177         assertEquals(MbmsDownloadSession.RESULT_CANCELLED,
178                 receivedIntent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, -1));
179 
180         assertEquals(testDownloadRequest,
181                 receivedIntent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST));
182     }
183 
184     @Test
testBadDownloadToken()185     public void testBadDownloadToken() {
186         // Set up a perfectly valid download completion intent, and expect it to fail because the
187         // download token hasn't been written.
188         Intent intentForReceiverTest = new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
189         populateIntentWithCommonFields(intentForReceiverTest);
190         intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
191                 MbmsDownloadSession.RESULT_SUCCESSFUL);
192         intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST,
193                 testDownloadRequest);
194         intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO,
195                 CtsDownloadService.FILE_INFO_1);
196         intentForReceiverTest.putExtra(VendorUtils.EXTRA_FINAL_URI,
197                 Uri.fromFile(new File(new File(tempFileRootDir, TEST_SERVICE_ID), "file1")));
198 
199         sendBroadcastAndValidate(intentForReceiverTest,
200                 MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
201     }
202 
203     @Test
testRequestNoFileDescriptors()204     public void testRequestNoFileDescriptors() throws Exception {
205         Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
206         populateIntentWithCommonFields(fdRequestIntent);
207 
208         Bundle b = sendBroadcastAndValidate(fdRequestIntent, MbmsDownloadReceiver.RESULT_OK);
209         assertTrue(b == null || b.isEmpty());
210     }
211 
212     @Test
testRequestNewFileDescriptors()213     public void testRequestNewFileDescriptors() throws Exception {
214         Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
215         populateIntentWithCommonFields(fdRequestIntent);
216         fdRequestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 5);
217 
218         Bundle result = sendBroadcastAndValidate(fdRequestIntent, MbmsDownloadReceiver.RESULT_OK);
219         List<UriPathPair> freeUris = result.getParcelableArrayList(VendorUtils.EXTRA_FREE_URI_LIST);
220         assertNotNull(freeUris);
221         assertEquals(5, freeUris.size());
222         for (UriPathPair pathPair : freeUris) {
223             assertEquals(ContentResolver.SCHEME_CONTENT, pathPair.getContentUri().getScheme());
224             assertEquals(ContentResolver.SCHEME_FILE, pathPair.getFilePathUri().getScheme());
225         }
226     }
227 
228     @Test
testRequestRefreshedFileDescriptors()229     public void testRequestRefreshedFileDescriptors() throws Exception {
230         // Set up a few temp files that we can request again
231         Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
232         populateIntentWithCommonFields(fdRequestIntent);
233         fdRequestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 2);
234 
235         Bundle result = sendBroadcastAndValidate(fdRequestIntent, MbmsDownloadReceiver.RESULT_OK);
236         List<UriPathPair> freeUris = result.getParcelableArrayList(VendorUtils.EXTRA_FREE_URI_LIST);
237 
238         Intent fdRefreshIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
239         populateIntentWithCommonFields(fdRefreshIntent);
240         fdRefreshIntent.putParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST,
241                 new ArrayList<>(freeUris.stream().map(UriPathPair::getFilePathUri)
242                         .collect(Collectors.toList())));
243         Bundle result2 = sendBroadcastAndValidate(fdRefreshIntent, MbmsDownloadReceiver.RESULT_OK);
244         List<UriPathPair> refreshUris =
245                 result2.getParcelableArrayList(VendorUtils.EXTRA_PAUSED_URI_LIST);
246         assertEquals(freeUris.size(), refreshUris.size());
247         for (UriPathPair pathPair : refreshUris) {
248             assertTrue(freeUris.stream()
249                     .anyMatch((originalPair) ->
250                             originalPair.getFilePathUri().equals(pathPair.getFilePathUri())));
251         }
252     }
253 
sendBroadcastAndValidate(Intent intent, int expectedCode)254     private Bundle sendBroadcastAndValidate(Intent intent, int expectedCode) {
255         BlockingQueue<Bundle> receivedExtras = new LinkedBlockingQueue<>();
256         BlockingQueue<Integer> receivedCode = new LinkedBlockingQueue<>();
257         mContext.sendOrderedBroadcast(intent, CTS_BROADCAST_PERMISSION,
258                 new BroadcastReceiver() {
259                     @Override
260                     public void onReceive(Context context, Intent intent) {
261                         receivedExtras.add(getResultExtras(true));
262                         receivedCode.add(getResultCode());
263                     }
264                 }, mHandler, -1, null, null);
265 
266         try {
267             assertEquals(expectedCode,
268                     (int) receivedCode.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS));
269             return receivedExtras.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
270         } catch (InterruptedException e) {
271             fail("Test interrupted");
272             return null;
273         }
274     }
275 
bundleEquals(Bundle a, Bundle b)276     private boolean bundleEquals(Bundle a, Bundle b) {
277         if (a == null && b == null) {
278             return true;
279         }
280         if (a == null || b == null) {
281             return false;
282         }
283         for (String aKey : a.keySet()) {
284             if (!Objects.equals(a.get(aKey), b.get(aKey))) {
285                 return false;
286             }
287         }
288 
289         for (String bKey : b.keySet()) {
290             if (!Objects.equals(b.get(bKey), a.get(bKey))) {
291                 return false;
292             }
293         }
294 
295         return true;
296     }
297 
populateIntentWithCommonFields(Intent intent)298     private void populateIntentWithCommonFields(Intent intent) {
299         intent.putExtra(VendorUtils.EXTRA_SERVICE_ID, TEST_SERVICE_ID);
300         intent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT, tempFileRootDirPath);
301     }
302 
303 }
304