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.annotation.Nullable; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.ServiceConnection; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.os.Handler; 27 import android.os.HandlerThread; 28 import android.os.IBinder; 29 import android.os.RemoteException; 30 import android.telephony.MbmsDownloadSession; 31 import android.telephony.cts.embmstestapp.CtsDownloadService; 32 import android.telephony.cts.embmstestapp.ICtsDownloadMiddlewareControl; 33 import android.telephony.mbms.DownloadRequest; 34 import android.telephony.mbms.FileServiceInfo; 35 import android.telephony.mbms.MbmsDownloadSessionCallback; 36 import android.test.InstrumentationTestCase; 37 import android.util.Log; 38 39 import com.android.internal.os.SomeArgs; 40 41 import java.io.File; 42 import java.util.List; 43 import java.util.concurrent.BlockingQueue; 44 import java.util.concurrent.CountDownLatch; 45 import java.util.concurrent.Executor; 46 import java.util.concurrent.LinkedBlockingQueue; 47 import java.util.concurrent.TimeUnit; 48 import java.util.stream.Collectors; 49 50 public class MbmsDownloadTestBase extends InstrumentationTestCase { 51 protected static final int ASYNC_TIMEOUT = 10000; 52 53 protected static class TestCallback extends MbmsDownloadSessionCallback { 54 private final BlockingQueue<SomeArgs> mErrorCalls = new LinkedBlockingQueue<>(); 55 private final BlockingQueue<SomeArgs> mFileServicesUpdatedCalls = 56 new LinkedBlockingQueue<>(); 57 private final BlockingQueue<SomeArgs> mMiddlewareReadyCalls = new LinkedBlockingQueue<>(); 58 private int mNumErrorCalls = 0; 59 60 @Override 61 public void onError(int errorCode, @Nullable String message) { 62 mNumErrorCalls += 1; 63 SomeArgs args = SomeArgs.obtain(); 64 args.arg1 = errorCode; 65 args.arg2 = message; 66 mErrorCalls.add(args); 67 Log.i(MbmsDownloadTestBase.class.getSimpleName(), 68 "Got error: " + errorCode + ": " + message); 69 } 70 71 @Override 72 public void onFileServicesUpdated(List<FileServiceInfo> services) { 73 SomeArgs args = SomeArgs.obtain(); 74 args.arg1 = services; 75 mFileServicesUpdatedCalls.add(args); 76 } 77 78 @Override 79 public void onMiddlewareReady() { 80 mMiddlewareReadyCalls.add(SomeArgs.obtain()); 81 } 82 83 public SomeArgs waitOnError() { 84 try { 85 return mErrorCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 86 } catch (InterruptedException e) { 87 return null; 88 } 89 } 90 91 public boolean waitOnMiddlewareReady() { 92 try { 93 return mMiddlewareReadyCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS) != null; 94 } catch (InterruptedException e) { 95 return false; 96 } 97 } 98 99 public SomeArgs waitOnFileServicesUpdated() { 100 try { 101 return mFileServicesUpdatedCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 102 } catch (InterruptedException e) { 103 return null; 104 } 105 } 106 107 public int getNumErrorCalls() { 108 return mNumErrorCalls; 109 } 110 } 111 112 DownloadRequest.Builder downloadRequestTemplate; 113 Uri destinationDirectoryUri; 114 115 Context mContext; 116 HandlerThread mHandlerThread; 117 Handler mHandler; 118 Executor mCallbackExecutor; 119 ICtsDownloadMiddlewareControl mMiddlewareControl; 120 MbmsDownloadSession mDownloadSession; 121 TestCallback mCallback = new TestCallback(); 122 123 @Override 124 public void setUp() throws Exception { 125 mContext = getInstrumentation().getContext(); 126 mHandlerThread = new HandlerThread("EmbmsCtsTestWorker"); 127 mHandlerThread.start(); 128 mHandler = new Handler(mHandlerThread.getLooper()); 129 mCallbackExecutor = mHandler::post; 130 mCallback = new TestCallback(); 131 132 File destinationDirectory = new File(mContext.getFilesDir(), "downloads"); 133 destinationDirectory.mkdirs(); 134 destinationDirectoryUri = Uri.fromFile(destinationDirectory); 135 downloadRequestTemplate = new DownloadRequest.Builder( 136 CtsDownloadService.SOURCE_URI_1, destinationDirectoryUri) 137 .setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO); 138 getControlBinder(); 139 setupDownloadSession(); 140 } 141 142 @Override 143 public void tearDown() throws Exception { 144 mHandlerThread.quit(); 145 mDownloadSession.close(); 146 mMiddlewareControl.reset(); 147 } 148 149 private void setupDownloadSession() throws Exception { 150 mDownloadSession = MbmsDownloadSession.create( 151 mContext, mCallbackExecutor, mCallback); 152 assertNotNull(mDownloadSession); 153 assertTrue(mCallback.waitOnMiddlewareReady()); 154 assertEquals(0, mCallback.getNumErrorCalls()); 155 Bundle initializeCall = mMiddlewareControl.getDownloadSessionCalls().get(0); 156 assertEquals(CtsDownloadService.METHOD_INITIALIZE, 157 initializeCall.getString(CtsDownloadService.METHOD_NAME)); 158 } 159 160 private void getControlBinder() throws InterruptedException { 161 Intent bindIntent = new Intent(CtsDownloadService.CONTROL_INTERFACE_ACTION); 162 bindIntent.setComponent(CtsDownloadService.CONTROL_INTERFACE_COMPONENT); 163 final CountDownLatch bindLatch = new CountDownLatch(1); 164 165 boolean success = mContext.bindService(bindIntent, new ServiceConnection() { 166 @Override 167 public void onServiceConnected(ComponentName name, IBinder service) { 168 mMiddlewareControl = ICtsDownloadMiddlewareControl.Stub.asInterface(service); 169 bindLatch.countDown(); 170 } 171 172 @Override 173 public void onServiceDisconnected(ComponentName name) { 174 mMiddlewareControl = null; 175 } 176 }, Context.BIND_AUTO_CREATE); 177 if (!success) { 178 fail("Failed to get control interface -- bind error"); 179 } 180 bindLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 181 } 182 183 protected List<Bundle> getMiddlewareCalls(String methodName) throws RemoteException { 184 return (mMiddlewareControl.getDownloadSessionCalls()).stream() 185 .filter((elem) -> elem.getString(CtsDownloadService.METHOD_NAME).equals(methodName)) 186 .collect(Collectors.toList()); 187 } 188 189 protected static void recursiveDelete(File f) { 190 if (f.isDirectory()) { 191 for (File f1 : f.listFiles()) { 192 recursiveDelete(f1); 193 } 194 } 195 f.delete(); 196 } 197 }