package vandy.mooc.model.services; import vandy.mooc.common.DownloadUtils; import vandy.mooc.common.LifecycleLoggingService; import vandy.mooc.model.aidl.DownloadRequest; import vandy.mooc.model.aidl.DownloadResults; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; /** * This class handles downloads using asynchronous AIDL interactions. * The component that binds to this service should receive an * IBinder. This IBinder should be an instance of DownloadRequest, * which extends IBinder. The component can then interact with this * service by making normal calls on the DownloadRequest * object. Specifically, the component can ask this service to * download an image, passing in a DownloadResults object. Once the * download is finished, this service should send the pathname of the * downloaded file back to the calling component by calling sendPath() * on the DownloadResults object. * * AIDL is an example of the Broker Pattern, in which all interprocess * communication details are hidden behind the AIDL interfaces. */ public class DownloadBoundServiceAsync extends LifecycleLoggingService { /** * Make an explicit Intent that will start this service when * passed to bindService(). * * @param context The context of the calling component. */ public static Intent makeIntent(Context context) { // Create an explicit Intent and return it to the caller. return new Intent(context, DownloadBoundServiceAsync.class); } /** * The concrete implementation of the AIDL Interface * DownloadRequest. We extend the Stub class, which implements * DownloadRequest, so that Android can properly handle calls * across process boundaries. * * This implementation plays the role of Invoker in the Broker * Pattern. */ DownloadRequest.Stub mDownloadRequestImpl = new DownloadRequest.Stub() { /** * Download the image at the given Uri and return a * pathname to the file on the Android file system by * calling the sendPath() method on the provided Results * * Use the methods defined in DownloadUtils for code brevity. */ @Override public void downloadImage(Uri uri, DownloadResults results) throws RemoteException { // Download the file using the appropriate helper // method in DownloadUtils and then send the pathname // back to the client via the Results object. results.sendPath(DownloadUtils.downloadFile (DownloadBoundServiceAsync.this, uri)); } }; /** * Called when a component calls bindService() with the proper * intent. Return the concrete implementation of DownloadRequest * cast as an IBinder. */ @Override public IBinder onBind(Intent intent) { return mDownloadRequestImpl; } }