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.assertTrue;
21 import static org.junit.Assert.fail;
22 
23 import android.content.Intent;
24 import android.net.Uri;
25 import android.os.Bundle;
26 import android.telephony.MbmsDownloadSession;
27 import android.telephony.cts.embmstestapp.CtsDownloadService;
28 import android.telephony.mbms.DownloadRequest;
29 import android.telephony.mbms.FileInfo;
30 import android.telephony.mbms.MbmsDownloadReceiver;
31 
32 import java.io.File;
33 import java.io.InputStream;
34 import java.util.Collections;
35 import java.util.List;
36 
37 import org.junit.After;
38 import org.junit.Before;
39 import org.junit.Test;
40 
41 public class MbmsDownloadFlowTest extends MbmsDownloadTestBase {
42     private File tempFileRootDir;
43 
44     @Before
setUp()45     public void setUp() throws Exception {
46         super.setUp();
47         tempFileRootDir = new File(mContext.getFilesDir(), "CtsTestDir");
48         tempFileRootDir.mkdir();
49         mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
50     }
51 
52     @After
tearDown()53     public void tearDown() throws Exception {
54         recursiveDelete(tempFileRootDir);
55         tempFileRootDir = null;
56         super.tearDown();
57     }
58 
59     @Test
testSingleFileDownloadFlow()60     public void testSingleFileDownloadFlow() throws Exception {
61         MbmsDownloadReceiverTest.AppIntentCapture captor =
62                 new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mHandler);
63         DownloadRequest request = downloadRequestTemplate
64                 .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
65                 .build();
66         mDownloadSession.download(request);
67         mMiddlewareControl.actuallyStartDownloadFlow();
68 
69         Uri fileUri = checkReceivedDownloadCompleteIntent(captor.getIntent(), request,
70                 CtsDownloadService.FILE_INFO_1);
71         checkFileContentIntegrity(CtsDownloadService.FILE_INFO_1, fileUri);
72         checkDownloadResultAck(1);
73     }
74 
75     @Test
testFileInSubdirectoryDownloadFlow()76     public void testFileInSubdirectoryDownloadFlow() throws Exception {
77         MbmsDownloadReceiverTest.AppIntentCapture captor =
78                 new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mHandler);
79         DownloadRequest request = new DownloadRequest.Builder(
80                 CtsDownloadService.SOURCE_URI_2, destinationDirectoryUri)
81                 .setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO)
82                 .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
83                 .build();
84 
85         mDownloadSession.download(request);
86         mMiddlewareControl.actuallyStartDownloadFlow();
87 
88         Uri fileUri = checkReceivedDownloadCompleteIntent(captor.getIntent(), request,
89                 CtsDownloadService.FILE_INFO_2);
90         // Make sure that the received file is placed in the proper subdirectory.
91         String file2RelativePath = CtsDownloadService.FILE_INFO_2.getUri().getPath().substring(
92                 CtsDownloadService.SOURCE_URI_2.getPath().length());
93         assertTrue("got path: " + fileUri.getPath() + ", should end with: " + file2RelativePath,
94                 fileUri.getPath().endsWith(file2RelativePath));
95         checkFileContentIntegrity(CtsDownloadService.FILE_INFO_2, fileUri);
96         checkDownloadResultAck(1);
97     }
98 
99     @Test
testMultiFileDownloadFlow()100     public void testMultiFileDownloadFlow() throws Exception {
101         MbmsDownloadReceiverTest.AppIntentCapture captor =
102                 new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mHandler);
103         DownloadRequest request = new DownloadRequest.Builder(
104                 CtsDownloadService.SOURCE_URI_3, destinationDirectoryUri)
105                 .setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO)
106                 .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
107                 .build();
108 
109         mDownloadSession.download(request);
110         mMiddlewareControl.actuallyStartDownloadFlow();
111 
112         for (Intent i : captor.getIntents(2)) {
113             FileInfo fileInfo = i.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
114             Uri fileUri = null;
115             if (CtsDownloadService.FILE_INFO_1.equals(fileInfo)) {
116                 fileUri = checkReceivedDownloadCompleteIntent(
117                         i, request, CtsDownloadService.FILE_INFO_1);
118             } else if (CtsDownloadService.FILE_INFO_2.equals(fileInfo)) {
119                 fileUri = checkReceivedDownloadCompleteIntent(
120                         i, request, CtsDownloadService.FILE_INFO_2);
121             } else {
122                 fail("Got unknown file info: " + fileInfo);
123             }
124             String relativePath = fileInfo.getUri().getPath().substring(
125                     CtsDownloadService.SOURCE_URI_3.getPath().length());
126             assertTrue("got path: " + fileUri.getPath() + ", should end with: " + relativePath,
127                     fileUri.getPath().endsWith(relativePath));
128             checkFileContentIntegrity(fileInfo, fileUri);
129         }
130         checkDownloadResultAck(2);
131     }
132 
133 
checkReceivedDownloadCompleteIntent(Intent downloadDoneIntent, DownloadRequest downloadRequest, FileInfo expectedFileInfo)134     private Uri checkReceivedDownloadCompleteIntent(Intent downloadDoneIntent,
135             DownloadRequest downloadRequest, FileInfo expectedFileInfo) {
136         assertEquals(MbmsDownloadReceiverTest.APP_INTENT_ACTION, downloadDoneIntent.getAction());
137         assertEquals(MbmsDownloadSession.RESULT_SUCCESSFUL,
138                 downloadDoneIntent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, -1));
139         assertEquals(downloadRequest,
140                 downloadDoneIntent.getParcelableExtra(
141                         MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST));
142         assertEquals(downloadRequest.getSubscriptionId(),
143                 ((DownloadRequest) downloadDoneIntent.getParcelableExtra(
144                         MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)).getSubscriptionId());
145         assertEquals(downloadRequest.getDestinationUri(),
146                 ((DownloadRequest) downloadDoneIntent.getParcelableExtra(
147                         MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)).getDestinationUri());
148         assertEquals(expectedFileInfo,
149                 downloadDoneIntent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO));
150         return downloadDoneIntent.getParcelableExtra(
151                 MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI);
152     }
153 
checkFileContentIntegrity(FileInfo fileInfo, Uri completedFileUri)154     private void checkFileContentIntegrity(FileInfo fileInfo, Uri completedFileUri)
155             throws Exception {
156         assertEquals(fileInfo.getUri().getLastPathSegment(),
157                 completedFileUri.getLastPathSegment());
158         InputStream is = mContext.getContentResolver().openInputStream(completedFileUri);
159         byte[] contents = new byte[CtsDownloadService.SAMPLE_FILE_DATA.length];
160         is.read(contents);
161         for (int i = 0; i < contents.length; i++) {
162             assertEquals(contents[i], CtsDownloadService.SAMPLE_FILE_DATA[i]);
163         }
164     }
165 
checkDownloadResultAck(int numAcks)166     private void checkDownloadResultAck(int numAcks) throws Exception {
167         // Poll until we get to the right number.
168         List<Bundle> downloadResultAck = Collections.emptyList();
169         long currentTime = System.currentTimeMillis();
170         while (System.currentTimeMillis() < currentTime + ASYNC_TIMEOUT) {
171             downloadResultAck = getMiddlewareCalls(CtsDownloadService.METHOD_DOWNLOAD_RESULT_ACK);
172             if (numAcks == downloadResultAck.size()) {
173                 break;
174             }
175             Thread.sleep(200);
176         }
177         assertEquals(numAcks, downloadResultAck.size());
178         downloadResultAck.forEach((ack) -> assertEquals(MbmsDownloadReceiver.RESULT_OK,
179                 ack.getInt(CtsDownloadService.ARGUMENT_RESULT_CODE, -1)));
180     }
181 }
182