DownloadManager.java revision 66dde9460badebf8e740275cabde9cca256006eb
1/* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mms.util; 19 20import com.android.internal.telephony.TelephonyIntents; 21import com.android.internal.telephony.TelephonyProperties; 22import com.android.mms.R; 23import com.android.mms.ui.MessagingPreferenceActivity; 24import com.google.android.mms.MmsException; 25import com.google.android.mms.pdu.EncodedStringValue; 26import com.google.android.mms.pdu.NotificationInd; 27import com.google.android.mms.pdu.PduPersister; 28import com.google.android.mms.util.SqliteWrapper; 29 30import android.content.BroadcastReceiver; 31import android.content.ContentValues; 32import android.content.Context; 33import android.content.Intent; 34import android.content.IntentFilter; 35import android.content.SharedPreferences; 36import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 37import android.database.Cursor; 38import android.net.Uri; 39import android.os.Handler; 40import android.os.SystemProperties; 41import android.preference.PreferenceManager; 42import android.provider.Telephony.Mms; 43import android.telephony.ServiceState; 44import android.util.Config; 45import android.util.Log; 46import android.widget.Toast; 47 48public class DownloadManager { 49 private static final String TAG = "DownloadManager"; 50 private static final boolean DEBUG = false; 51 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 52 53 private static final int DEFERRED_MASK = 0x04; 54 55 public static final int STATE_UNSTARTED = 0x80; 56 public static final int STATE_DOWNLOADING = 0x81; 57 public static final int STATE_TRANSIENT_FAILURE = 0x82; 58 public static final int STATE_PERMANENT_FAILURE = 0x87; 59 60 private final Context mContext; 61 private final Handler mHandler; 62 private final SharedPreferences mPreferences; 63 private boolean mAutoDownload; 64 65 private final OnSharedPreferenceChangeListener mPreferencesChangeListener = 66 new OnSharedPreferenceChangeListener() { 67 public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 68 if (MessagingPreferenceActivity.AUTO_RETRIEVAL.equals(key) 69 || MessagingPreferenceActivity.RETRIEVAL_DURING_ROAMING.equals(key)) { 70 if (LOCAL_LOGV) { 71 Log.v(TAG, "Preferences updated."); 72 } 73 74 synchronized (sInstance) { 75 mAutoDownload = getAutoDownloadState(prefs); 76 if (LOCAL_LOGV) { 77 Log.v(TAG, "mAutoDownload ------> " + mAutoDownload); 78 } 79 } 80 } 81 } 82 }; 83 84 private final BroadcastReceiver mRoamingStateListener = 85 new BroadcastReceiver() { 86 @Override 87 public void onReceive(Context context, Intent intent) { 88 if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(intent.getAction())) { 89 if (LOCAL_LOGV) { 90 Log.v(TAG, "Service state changed: " + intent.getExtras()); 91 } 92 93 ServiceState state = ServiceState.newFromBundle(intent.getExtras()); 94 boolean isRoaming = state.getRoaming(); 95 if (LOCAL_LOGV) { 96 Log.v(TAG, "roaming ------> " + isRoaming); 97 } 98 synchronized (sInstance) { 99 mAutoDownload = getAutoDownloadState(mPreferences, isRoaming); 100 if (LOCAL_LOGV) { 101 Log.v(TAG, "mAutoDownload ------> " + mAutoDownload); 102 } 103 } 104 } 105 } 106 }; 107 108 private static DownloadManager sInstance; 109 110 private DownloadManager(Context context) { 111 mContext = context; 112 mHandler = new Handler(); 113 mPreferences = PreferenceManager.getDefaultSharedPreferences(context); 114 mPreferences.registerOnSharedPreferenceChangeListener(mPreferencesChangeListener); 115 116 context.registerReceiver( 117 mRoamingStateListener, 118 new IntentFilter(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)); 119 120 mAutoDownload = getAutoDownloadState(mPreferences); 121 if (LOCAL_LOGV) { 122 Log.v(TAG, "mAutoDownload ------> " + mAutoDownload); 123 } 124 } 125 126 public boolean isAuto() { 127 return mAutoDownload; 128 } 129 130 public static void init(Context context) { 131 if (LOCAL_LOGV) { 132 Log.v(TAG, "DownloadManager.init()"); 133 } 134 135 if (sInstance != null) { 136 Log.w(TAG, "Already initialized."); 137 } 138 sInstance = new DownloadManager(context); 139 } 140 141 public static DownloadManager getInstance() { 142 if (sInstance == null) { 143 throw new IllegalStateException("Uninitialized."); 144 } 145 return sInstance; 146 } 147 148 static boolean getAutoDownloadState(SharedPreferences prefs) { 149 return getAutoDownloadState(prefs, isRoaming()); 150 } 151 152 static boolean getAutoDownloadState(SharedPreferences prefs, boolean roaming) { 153 boolean autoDownload = prefs.getBoolean( 154 MessagingPreferenceActivity.AUTO_RETRIEVAL, true); 155 156 if (LOCAL_LOGV) { 157 Log.v(TAG, "auto download without roaming -> " + autoDownload); 158 } 159 160 if (autoDownload) { 161 boolean alwaysAuto = prefs.getBoolean( 162 MessagingPreferenceActivity.RETRIEVAL_DURING_ROAMING, false); 163 164 if (LOCAL_LOGV) { 165 Log.v(TAG, "auto download during roaming -> " + alwaysAuto); 166 } 167 168 if (!roaming || alwaysAuto) { 169 return true; 170 } 171 } 172 return false; 173 } 174 175 static boolean isRoaming() { 176 String roaming = SystemProperties.get( 177 TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null); 178 if (LOCAL_LOGV) { 179 Log.v(TAG, "roaming ------> " + roaming); 180 } 181 return "true".equals(roaming); 182 } 183 184 public void markState(final Uri uri, int state) { 185 // Notify user if downloading permanently failed. 186 if (state == STATE_PERMANENT_FAILURE) { 187 mHandler.post(new Runnable() { 188 public void run() { 189 try { 190 Toast.makeText(mContext, getMessage(uri), 191 Toast.LENGTH_LONG).show(); 192 } catch (MmsException e) { 193 Log.e(TAG, e.getMessage(), e); 194 } 195 } 196 }); 197 } else if (!mAutoDownload) { 198 state |= DEFERRED_MASK; 199 } 200 201 // Use the STATUS field to store the state of downloading process 202 // because it's useless for M-Notification.ind. 203 ContentValues values = new ContentValues(1); 204 values.put(Mms.STATUS, state); 205 SqliteWrapper.update(mContext, mContext.getContentResolver(), 206 uri, values, null, null); 207 } 208 209 private String getMessage(Uri uri) throws MmsException { 210 NotificationInd ind = (NotificationInd) PduPersister 211 .getPduPersister(mContext).load(uri); 212 213 EncodedStringValue v = ind.getSubject(); 214 String subject = (v != null) ? v.getString() 215 : mContext.getString(R.string.no_subject); 216 217 v = ind.getFrom(); 218 String from = (v != null) 219 ? ContactInfoCache.getInstance().getContactName(v.getString()) 220 : mContext.getString(R.string.unknown_sender); 221 222 return mContext.getString(R.string.dl_failure_notification, subject, from); 223 } 224 225 public int getState(Uri uri) { 226 Cursor cursor = SqliteWrapper.query(mContext, mContext.getContentResolver(), 227 uri, new String[] {Mms.STATUS}, null, null, null); 228 229 if (cursor != null) { 230 try { 231 if (cursor.moveToFirst()) { 232 return cursor.getInt(0) &~ DEFERRED_MASK; 233 } 234 } finally { 235 cursor.close(); 236 } 237 } 238 return STATE_UNSTARTED; 239 } 240} 241