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