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