1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage android.support.v7.mms;
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.PendingIntent;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentResolver;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcel;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.ParcelFileDescriptor;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcelable;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.Log;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.IOException;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.concurrent.Callable;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.concurrent.Future;
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.concurrent.TimeUnit;
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/**
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Request to download an MMS
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddclass DownloadRequest extends MmsRequest {
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    DownloadRequest(final String locationUrl, final Uri pduUri,
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final PendingIntent sentIntent) {
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super(locationUrl, pduUri, sentIntent);
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected boolean loadRequest(final Context context, final Bundle mmsConfig) {
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // No need to load PDU from app. Always true.
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return true;
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected boolean transferResponse(Context context, Intent fillIn, byte[] response) {
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return writePduToContentUri(context, mPduUri, response);
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected byte[] doHttp(Context context, MmsNetworkManager netMgr, ApnSettingsLoader.Apn apn,
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            Bundle mmsConfig, String userAgent, String uaProfUrl) throws MmsHttpException {
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final MmsHttpClient httpClient = netMgr.getHttpClient();
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return httpClient.execute(getHttpRequestUrl(apn), null/*pdu*/, MmsHttpClient.METHOD_GET,
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                !TextUtils.isEmpty(apn.getMmsProxy()), apn.getMmsProxy(), apn.getMmsProxyPort(),
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mmsConfig, userAgent, uaProfUrl);
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected String getHttpRequestUrl(final ApnSettingsLoader.Apn apn) {
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return mLocationUrl;
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Write pdu bytes to content provider uri
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     *
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param contentUri content provider uri to which bytes should be written
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param pdu Bytes to write
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @return true if all bytes successfully written else false
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public boolean writePduToContentUri(final Context context, final Uri contentUri,
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final byte[] pdu) {
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (contentUri == null || pdu == null) {
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return false;
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Callable<Boolean> copyDownloadedPduToOutput = new Callable<Boolean>() {
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public Boolean call() {
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                ParcelFileDescriptor.AutoCloseOutputStream outStream = null;
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                try {
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final ContentResolver cr = context.getContentResolver();
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final ParcelFileDescriptor pduFd = cr.openFileDescriptor(contentUri, "w");
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    outStream = new ParcelFileDescriptor.AutoCloseOutputStream(pduFd);
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    outStream.write(pdu);
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return true;
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } catch (IOException e) {
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    Log.e(MmsService.TAG, "Writing PDU to downloader: IO exception", e);
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return false;
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } finally {
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (outStream != null) {
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        try {
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            outStream.close();
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        } catch (IOException ex) {
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            // Ignore
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        };
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Future<Boolean> pendingResult =
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mPduTransferExecutor.submit(copyDownloadedPduToOutput);
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        try {
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return pendingResult.get(TASK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } catch (Exception e) {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // Typically a timeout occurred - cancel task
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            pendingResult.cancel(true);
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return false;
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static final Parcelable.Creator<DownloadRequest> CREATOR
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            = new Parcelable.Creator<DownloadRequest>() {
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public DownloadRequest createFromParcel(Parcel in) {
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return new DownloadRequest(in);
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        public DownloadRequest[] newArray(int size) {
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return new DownloadRequest[size];
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    };
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private DownloadRequest(Parcel in) {
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super(in);
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
133