DownloadRequest.java revision c984707ecf54d545a4a5809c6ce1d18bf7cee61e
1/*
2 * Copyright (C) 2014 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
17package com.android.mms.service;
18
19import com.google.android.mms.MmsException;
20import com.google.android.mms.pdu.GenericPdu;
21import com.google.android.mms.pdu.PduHeaders;
22import com.google.android.mms.pdu.PduParser;
23import com.google.android.mms.pdu.PduPersister;
24import com.google.android.mms.pdu.RetrieveConf;
25import com.google.android.mms.util.SqliteWrapper;
26
27import com.android.mms.service.exception.MmsHttpException;
28
29import android.app.Activity;
30import android.app.AppOpsManager;
31import android.app.PendingIntent;
32import android.content.ContentValues;
33import android.content.Context;
34import android.content.Intent;
35import android.database.sqlite.SQLiteException;
36import android.os.Binder;
37import android.os.UserHandle;
38import android.provider.Telephony;
39import android.telephony.TelephonyManager;
40import android.text.TextUtils;
41import android.util.Log;
42
43import java.util.List;
44
45/**
46 * Request to download an MMS
47 */
48public class DownloadRequest extends MmsRequest {
49    private static final String LOCATION_SELECTION =
50            Telephony.Mms.MESSAGE_TYPE + "=? AND " + Telephony.Mms.CONTENT_LOCATION + " =?";
51
52    private final String mLocationUrl;
53    private final PendingIntent mDownloadedIntent;
54
55    public DownloadRequest(RequestManager manager, long subId, String locationUrl,
56            PendingIntent downloadedIntent, String creator, ContentValues configOverrides) {
57        super(manager, null/*messageUri*/, subId, creator, configOverrides);
58        mLocationUrl = locationUrl;
59        mDownloadedIntent = downloadedIntent;
60    }
61
62    @Override
63    protected byte[] doHttp(Context context, MmsNetworkManager netMgr, ApnSettings apn)
64            throws MmsHttpException {
65        return doHttpForResolvedAddresses(context,
66                netMgr,
67                mLocationUrl,
68                null/*pdu*/,
69                HttpUtils.HTTP_GET_METHOD,
70                apn);
71    }
72
73    @Override
74    protected PendingIntent getPendingIntent() {
75        return mDownloadedIntent;
76    }
77
78    @Override
79    protected int getRunningQueue() {
80        return MmsService.QUEUE_INDEX_DOWNLOAD;
81    }
82
83    @Override
84    protected void updateStatus(Context context, int result, byte[] response) {
85        if (mRequestManager.getAutoPersistingPref()) {
86            storeInboxMessage(context, result, response);
87        }
88    }
89
90    private void storeInboxMessage(Context context, int result, byte[] response) {
91        if (response == null || response.length < 1) {
92            return;
93        }
94        final long identity = Binder.clearCallingIdentity();
95        try {
96            final GenericPdu pdu = (new PduParser(response)).parse();
97            if (pdu == null || !(pdu instanceof RetrieveConf)) {
98                Log.e(MmsService.TAG, "DownloadRequest.updateStatus: invalid parsed PDU");
99                return;
100            }
101            // Store the downloaded message
102            final PduPersister persister = PduPersister.getPduPersister(context);
103            mMessageUri = persister.persist(
104                    pdu,
105                    Telephony.Mms.Inbox.CONTENT_URI,
106                    true/*createThreadId*/,
107                    true/*groupMmsEnabled*/,
108                    null/*preOpenedFiles*/);
109            if (mMessageUri == null) {
110                Log.e(MmsService.TAG, "DownloadRequest.updateStatus: can not persist message");
111                return;
112            }
113            // Update some of the properties of the message
114            ContentValues values = new ContentValues(4);
115            values.put(Telephony.Mms.DATE, System.currentTimeMillis() / 1000L);
116            values.put(Telephony.Mms.READ, 0);
117            values.put(Telephony.Mms.SEEN, 0);
118            if (!TextUtils.isEmpty(mCreator)) {
119                values.put(Telephony.Mms.CREATOR, mCreator);
120            }
121            if (SqliteWrapper.update(
122                    context,
123                    context.getContentResolver(),
124                    mMessageUri,
125                    values,
126                    null/*where*/,
127                    null/*selectionArg*/) != 1) {
128                Log.e(MmsService.TAG, "DownloadRequest.updateStatus: can not update message");
129            }
130            // Delete the corresponding NotificationInd
131            SqliteWrapper.delete(context,
132                    context.getContentResolver(),
133                    Telephony.Mms.CONTENT_URI,
134                    LOCATION_SELECTION,
135                    new String[]{
136                            Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND),
137                            mLocationUrl
138                    }
139            );
140        } catch (MmsException e) {
141            Log.e(MmsService.TAG, "DownloadRequest.updateStatus: can not persist message", e);
142        } catch (SQLiteException e) {
143            Log.e(MmsService.TAG, "DownloadRequest.updateStatus: can not update message", e);
144        } catch (RuntimeException e) {
145            Log.e(MmsService.TAG, "DownloadRequest.updateStatus: can not parse response", e);
146        } finally {
147            Binder.restoreCallingIdentity(identity);
148        }
149    }
150
151    /**
152     * Try downloading via the carrier app by sending intent.
153     *
154     * @param context The context
155     */
156    public void tryDownloadingByCarrierApp(Context context) {
157        TelephonyManager telephonyManager =
158                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
159        Intent intent = new Intent(Telephony.Mms.Intents.MMS_DOWNLOAD_ACTION);
160        List<String> carrierPackages = telephonyManager.getCarrierPackageNamesForBroadcastIntent(
161                intent);
162
163        if (carrierPackages == null || carrierPackages.size() != 1) {
164            mRequestManager.addRunning(this);
165        } else {
166            intent.setPackage(carrierPackages.get(0));
167            intent.putExtra("url", mLocationUrl);
168            intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
169            context.sendOrderedBroadcastAsUser(
170                    intent,
171                    UserHandle.OWNER,
172                    android.Manifest.permission.RECEIVE_MMS,
173                    AppOpsManager.OP_RECEIVE_MMS,
174                    mCarrierAppResultReceiver,
175                    null/*scheduler*/,
176                    Activity.RESULT_CANCELED,
177                    null/*initialData*/,
178                    null/*initialExtras*/);
179        }
180    }
181}
182