1 /*
2  * Copyright (C) 2015 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 package com.android.phone.vvm.omtp.fetch;
17 
18 import android.content.BroadcastReceiver;
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.database.Cursor;
23 import android.net.ConnectivityManager;
24 import android.net.Network;
25 import android.net.NetworkRequest;
26 import android.net.Uri;
27 import android.provider.VoicemailContract;
28 import android.provider.VoicemailContract.Voicemails;
29 import android.telecom.PhoneAccountHandle;
30 import android.telephony.TelephonyManager;
31 import android.text.TextUtils;
32 import android.util.Log;
33 
34 import com.android.phone.PhoneUtils;
35 import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
36 import com.android.phone.vvm.omtp.imap.ImapHelper;
37 import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
38 import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
39 
40 import java.util.concurrent.Executor;
41 import java.util.concurrent.Executors;
42 
43 public class FetchVoicemailReceiver extends BroadcastReceiver {
44 
45     private static final String TAG = "FetchVoicemailReceiver";
46 
47     final static String[] PROJECTION = new String[] {
48             Voicemails.SOURCE_DATA,      // 0
49             Voicemails.PHONE_ACCOUNT_ID, // 1
50     };
51 
52     public static final int SOURCE_DATA = 0;
53     public static final int PHONE_ACCOUNT_ID = 1;
54 
55     // Timeout used to call ConnectivityManager.requestNetwork
56     private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
57 
58     // Number of retries
59     private static final int NETWORK_RETRY_COUNT = 3;
60 
61     private ContentResolver mContentResolver;
62     private Uri mUri;
63     private NetworkRequest mNetworkRequest;
64     private VvmNetworkRequestCallback mNetworkCallback;
65     private Context mContext;
66     private String mUid;
67     private ConnectivityManager mConnectivityManager;
68     private PhoneAccountHandle mPhoneAccount;
69     private int mRetryCount = NETWORK_RETRY_COUNT;
70 
71     @Override
onReceive(final Context context, Intent intent)72     public void onReceive(final Context context, Intent intent) {
73         if (VoicemailContract.ACTION_FETCH_VOICEMAIL.equals(intent.getAction())) {
74             mContext = context;
75             mContentResolver = context.getContentResolver();
76             mUri = intent.getData();
77 
78             if (mUri == null) {
79                 Log.w(TAG, VoicemailContract.ACTION_FETCH_VOICEMAIL + " intent sent with no data");
80                 return;
81             }
82 
83             if (!context.getPackageName().equals(
84                     mUri.getQueryParameter(VoicemailContract.PARAM_KEY_SOURCE_PACKAGE))) {
85                 // Ignore if the fetch request is for a voicemail not from this package.
86                 return;
87             }
88 
89             Cursor cursor = mContentResolver.query(mUri, PROJECTION, null, null, null);
90             if (cursor == null) {
91                 return;
92             }
93             try {
94                 if (cursor.moveToFirst()) {
95                     mUid = cursor.getString(SOURCE_DATA);
96                     String accountId = cursor.getString(PHONE_ACCOUNT_ID);
97                     if (TextUtils.isEmpty(accountId)) {
98                         TelephonyManager telephonyManager = (TelephonyManager)
99                                 context.getSystemService(Context.TELEPHONY_SERVICE);
100                         accountId = telephonyManager.getSimSerialNumber();
101 
102                         if (TextUtils.isEmpty(accountId)) {
103                             Log.e(TAG, "Account null and no default sim found.");
104                             return;
105                         }
106                     }
107 
108                     mPhoneAccount = PhoneUtils.makePstnPhoneAccountHandle(accountId);
109                     if (!OmtpVvmSourceManager.getInstance(context)
110                             .isVvmSourceRegistered(mPhoneAccount)) {
111                         Log.w(TAG, "Account not registered - cannot retrieve message.");
112                         return;
113                     }
114 
115                     int subId = PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount);
116                     OmtpVvmCarrierConfigHelper carrierConfigHelper =
117                             new OmtpVvmCarrierConfigHelper(context, subId);
118 
119                     mNetworkCallback = new fetchVoicemailNetworkRequestCallback(context,
120                             mPhoneAccount);
121                     mNetworkCallback.requestNetwork();
122                 }
123             } finally {
124                 cursor.close();
125             }
126         }
127     }
128 
129     private class fetchVoicemailNetworkRequestCallback extends VvmNetworkRequestCallback {
130 
fetchVoicemailNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount)131         public fetchVoicemailNetworkRequestCallback(Context context,
132                 PhoneAccountHandle phoneAccount) {
133             super(context, phoneAccount);
134         }
135 
136         @Override
onAvailable(final Network network)137         public void onAvailable(final Network network) {
138             super.onAvailable(network);
139             fetchVoicemail(network);
140         }
141     }
142 
fetchVoicemail(final Network network)143     private void fetchVoicemail(final Network network) {
144         Executor executor = Executors.newCachedThreadPool();
145         executor.execute(new Runnable() {
146             @Override
147             public void run() {
148                 try {
149                     while (mRetryCount > 0) {
150                         ImapHelper imapHelper = new ImapHelper(mContext, mPhoneAccount, network);
151                         if (!imapHelper.isSuccessfullyInitialized()) {
152                             Log.w(TAG, "Can't retrieve Imap credentials.");
153                             return;
154                         }
155 
156                         boolean success = imapHelper.fetchVoicemailPayload(
157                                 new VoicemailFetchedCallback(mContext, mUri), mUid);
158                         if (!success && mRetryCount > 0) {
159                             mRetryCount--;
160                         } else {
161                             return;
162                         }
163                     }
164                 } finally {
165                     if (mNetworkCallback != null) {
166                         mNetworkCallback.releaseNetwork();
167                     }
168                 }
169             }
170         });
171     }
172 }
173