MailActivityEmail.java revision 7e75afadb152659e3a237c62e4d95cefb60e228d
1/* 2 * Copyright (C) 2008 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.email2.ui; 18 19import android.content.ComponentName; 20import android.content.ContentResolver; 21import android.content.Context; 22import android.content.Intent; 23import android.content.UriMatcher; 24import android.content.pm.PackageManager; 25import android.database.Cursor; 26import android.net.Uri; 27import android.os.Bundle; 28 29import com.android.email.NotificationController; 30import com.android.email.Preferences; 31import com.android.email.provider.EmailProvider; 32import com.android.email.service.AttachmentService; 33import com.android.email.service.EmailServiceUtils; 34import com.android.emailcommon.Logging; 35import com.android.emailcommon.TempDirectory; 36import com.android.emailcommon.provider.Account; 37import com.android.emailcommon.provider.EmailContent; 38import com.android.emailcommon.provider.Mailbox; 39import com.android.emailcommon.service.EmailServiceProxy; 40import com.android.emailcommon.utility.EmailAsyncTask; 41import com.android.emailcommon.utility.IntentUtilities; 42import com.android.emailcommon.utility.Utility; 43import com.android.mail.providers.Folder; 44import com.android.mail.providers.UIProvider; 45import com.android.mail.utils.LogTag; 46import com.android.mail.utils.LogUtils; 47import com.android.mail.utils.Utils; 48 49public class MailActivityEmail extends com.android.mail.ui.MailActivity { 50 /** 51 * If this is enabled there will be additional logging information sent to 52 * LogUtils.d, including protocol dumps. 53 * 54 * This should only be used for logs that are useful for debbuging user problems, 55 * not for internal/development logs. 56 * 57 * This can be enabled by typing "debug" in the AccountFolderList activity. 58 * Changing the value to 'true' here will likely have no effect at all! 59 * 60 * TODO: rename this to sUserDebug, and rename LOGD below to DEBUG. 61 */ 62 public static boolean DEBUG; 63 64 public static final String LOG_TAG = LogTag.getLogTag(); 65 66 // Exchange debugging flags (passed to Exchange, when available, via EmailServiceProxy) 67 public static boolean DEBUG_EXCHANGE; 68 public static boolean DEBUG_VERBOSE; 69 public static boolean DEBUG_FILE; 70 71 private static final int MATCH_LEGACY_SHORTCUT_INTENT = 1; 72 /** 73 * A matcher for data URI's that specify conversation list info. 74 */ 75 private static final UriMatcher sUrlMatcher = new UriMatcher(UriMatcher.NO_MATCH); 76 static { 77 sUrlMatcher.addURI( 78 EmailProvider.LEGACY_AUTHORITY, "view/mailbox", MATCH_LEGACY_SHORTCUT_INTENT); 79 } 80 81 82 /** 83 * Asynchronous version of {@link #setServicesEnabledSync(Context)}. Use when calling from 84 * UI thread (or lifecycle entry points.) 85 */ 86 public static void setServicesEnabledAsync(final Context context) { 87 EmailAsyncTask.runAsyncParallel(new Runnable() { 88 @Override 89 public void run() { 90 setServicesEnabledSync(context); 91 } 92 }); 93 } 94 95 /** 96 * Called throughout the application when the number of accounts has changed. This method 97 * enables or disables the Compose activity, the boot receiver and the service based on 98 * whether any accounts are configured. 99 * 100 * Blocking call - do not call from UI/lifecycle threads. 101 * 102 * @return true if there are any accounts configured. 103 */ 104 public static boolean setServicesEnabledSync(Context context) { 105 // Make sure we're initialized 106 EmailContent.init(context); 107 Cursor c = null; 108 try { 109 c = context.getContentResolver().query( 110 Account.CONTENT_URI, 111 Account.ID_PROJECTION, 112 null, null, null); 113 boolean enable = c != null && c.getCount() > 0; 114 setServicesEnabled(context, enable); 115 return enable; 116 } finally { 117 if (c != null) { 118 c.close(); 119 } 120 } 121 } 122 123 private static void setServicesEnabled(Context context, boolean enabled) { 124 PackageManager pm = context.getPackageManager(); 125 pm.setComponentEnabledSetting( 126 new ComponentName(context, AttachmentService.class), 127 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : 128 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 129 PackageManager.DONT_KILL_APP); 130 131 // Start/stop the various services depending on whether there are any accounts 132 // TODO: Make sure that the AttachmentService responds to this request as it 133 // expects a particular set of data in the intents that it receives or it ignores. 134 startOrStopService(enabled, context, new Intent(context, AttachmentService.class)); 135 NotificationController.getInstance(context).watchForMessages(); 136 } 137 138 /** 139 * Starts or stops the service as necessary. 140 * @param enabled If {@code true}, the service will be started. Otherwise, it will be stopped. 141 * @param context The context to manage the service with. 142 * @param intent The intent of the service to be managed. 143 */ 144 private static void startOrStopService(boolean enabled, Context context, Intent intent) { 145 if (enabled) { 146 context.startService(intent); 147 } else { 148 context.stopService(intent); 149 } 150 } 151 152 @Override 153 public void onCreate(Bundle bundle) { 154 final Intent intent = getIntent(); 155 final Uri data = intent != null ? intent.getData() : null; 156 if (data != null) { 157 final int match = sUrlMatcher.match(data); 158 switch (match) { 159 case MATCH_LEGACY_SHORTCUT_INTENT: { 160 final long mailboxId = IntentUtilities.getMailboxIdFromIntent(intent); 161 final Mailbox mailbox = Mailbox.restoreMailboxWithId(this, mailboxId); 162 if (mailbox == null) { 163 LogUtils.e(LOG_TAG, "unable to restore mailbox"); 164 break; 165 } 166 167 final Intent viewIntent = getViewIntent(mailbox.mAccountKey, mailboxId); 168 if (viewIntent != null) { 169 setIntent(viewIntent); 170 } 171 break; 172 } 173 } 174 } 175 176 super.onCreate(bundle); 177 final Preferences prefs = Preferences.getPreferences(this); 178 DEBUG = prefs.getEnableDebugLogging(); 179 enableStrictMode(prefs.getEnableStrictMode()); 180 TempDirectory.setTempDirectory(this); 181 182 // Enable logging in the EAS service, so it starts up as early as possible. 183 updateLoggingFlags(this); 184 185 // Make sure all required services are running when the app is started (can prevent 186 // issues after an adb sync/install) 187 setServicesEnabledAsync(this); 188 } 189 190 /** 191 * Load enabled debug flags from the preferences and update the EAS debug flag. 192 */ 193 public static void updateLoggingFlags(Context context) { 194 Preferences prefs = Preferences.getPreferences(context); 195 int debugLogging = prefs.getEnableDebugLogging() ? EmailServiceProxy.DEBUG_BIT : 0; 196 int verboseLogging = 197 prefs.getEnableExchangeLogging() ? EmailServiceProxy.DEBUG_VERBOSE_BIT : 0; 198 int fileLogging = 199 prefs.getEnableExchangeFileLogging() ? EmailServiceProxy.DEBUG_FILE_BIT : 0; 200 int enableStrictMode = 201 prefs.getEnableStrictMode() ? EmailServiceProxy.DEBUG_ENABLE_STRICT_MODE : 0; 202 int debugBits = debugLogging | verboseLogging | fileLogging | enableStrictMode; 203 EmailServiceUtils.setRemoteServicesLogging(context, debugBits); 204 } 205 206 /** 207 * Internal, utility method for logging. 208 * The calls to log() must be guarded with "if (Email.LOGD)" for performance reasons. 209 */ 210 public static void log(String message) { 211 LogUtils.d(Logging.LOG_TAG, message); 212 } 213 214 public static void enableStrictMode(boolean enabled) { 215 Utility.enableStrictMode(enabled); 216 } 217 218 private Intent getViewIntent(long accountId, long mailboxId) { 219 final ContentResolver contentResolver = getContentResolver(); 220 221 final Cursor accountCursor = contentResolver.query( 222 EmailProvider.uiUri("uiaccount", accountId), 223 UIProvider.ACCOUNTS_PROJECTION_NO_CAPABILITIES, 224 null, null, null); 225 226 if (accountCursor == null) { 227 LogUtils.e(LOG_TAG, "Null account cursor for mAccountId %d", accountId); 228 return null; 229 } 230 231 com.android.mail.providers.Account account = null; 232 try { 233 if (accountCursor.moveToFirst()) { 234 account = com.android.mail.providers.Account.builder().buildFrom(accountCursor); 235 } 236 } finally { 237 accountCursor.close(); 238 } 239 240 241 final Cursor folderCursor = contentResolver.query( 242 EmailProvider.uiUri("uifolder", mailboxId), 243 UIProvider.FOLDERS_PROJECTION, null, null, null); 244 245 if (folderCursor == null) { 246 LogUtils.e(LOG_TAG, "Null folder cursor for account %d, mailbox %d", 247 accountId, mailboxId); 248 return null; 249 } 250 251 Folder folder = null; 252 try { 253 if (folderCursor.moveToFirst()) { 254 folder = new Folder(folderCursor); 255 } else { 256 LogUtils.e(LOG_TAG, "Empty folder cursor for account %d, mailbox %d", 257 accountId, mailboxId); 258 return null; 259 } 260 } finally { 261 folderCursor.close(); 262 } 263 264 return Utils.createViewFolderIntent(this, folder.folderUri.fullUri, account); 265 } 266} 267