From 95bb350f38d08beeabee68323b8514f3cbfd5db5 Mon Sep 17 00:00:00 2001 From: Paul Westbrook Date: Thu, 7 Mar 2013 23:00:47 -0800 Subject: [PATCH] Fix NPE when adding account with security policy When adding an Exchange account with a security policy, Email generates a notification to let the user enable the policy. The code that generates the notification attemptes to load the folder as part of the base notification. Before the account policy has been configured, it isn't possible to load the folder. We need to handle a null folder when generating the notification Also, imporoved the logging when an exception is thrown from the PolicyService Bug: 8341882 Change-Id: I33ff57adc3c130e8318910e352146b8ea56f9a2c --- .../android/email/NotificationController.java | 41 ++++++++++--------- .../android/email/service/PolicyService.java | 31 ++++++++++++-- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/com/android/email/NotificationController.java b/src/com/android/email/NotificationController.java index 7aacbe800..d4a6e9be0 100644 --- a/src/com/android/email/NotificationController.java +++ b/src/com/android/email/NotificationController.java @@ -312,27 +312,30 @@ public class NotificationController { UIProvider.FOLDERS_PROJECTION, null, null, null); if (folderCursor == null) { - LogUtils.e(LOG_TAG, "Null folder cursor for mailbox %s", + // This can happen when the notification is for the security policy notification + // that happens before the account is setup + LogUtils.w(LOG_TAG, "Null folder cursor for mailbox %s", uiAccount.settings.defaultInbox); - } - - Folder folder = null; - try { - if (folderCursor.moveToFirst()) { - folder = new Folder(folderCursor); - } - } finally { - folderCursor.close(); - } - - if (folder != null) { - final FolderPreferences folderPreferences = - new FolderPreferences(mContext, uiAccount.name, folder, true /* inbox */); - - ringtoneUri = folderPreferences.getNotificationRingtoneUri(); - vibrate = folderPreferences.isNotificationVibrateEnabled(); } else { - LogUtils.e(LOG_TAG, "Null folder for mailbox %s", uiAccount.settings.defaultInbox); + Folder folder = null; + try { + if (folderCursor.moveToFirst()) { + folder = new Folder(folderCursor); + } + } finally { + folderCursor.close(); + } + + if (folder != null) { + final FolderPreferences folderPreferences = new FolderPreferences( + mContext, uiAccount.name, folder, true /* inbox */); + + ringtoneUri = folderPreferences.getNotificationRingtoneUri(); + vibrate = folderPreferences.isNotificationVibrateEnabled(); + } else { + LogUtils.e(LOG_TAG, + "Null folder for mailbox %s", uiAccount.settings.defaultInbox); + } } } else { LogUtils.e(LOG_TAG, "Null uiAccount for account id %d", account.mId); diff --git a/src/com/android/email/service/PolicyService.java b/src/com/android/email/service/PolicyService.java index 2394eedd7..de8a50ca3 100644 --- a/src/com/android/email/service/PolicyService.java +++ b/src/com/android/email/service/PolicyService.java @@ -24,15 +24,25 @@ import android.os.IBinder; import com.android.email.SecurityPolicy; import com.android.emailcommon.provider.Policy; import com.android.emailcommon.service.IPolicyService; +import com.android.mail.utils.LogTag; +import com.android.mail.utils.LogUtils; public class PolicyService extends Service { + private static final String LOG_TAG = LogTag.getLogTag(); private SecurityPolicy mSecurityPolicy; private Context mContext; private final IPolicyService.Stub mBinder = new IPolicyService.Stub() { public boolean isActive(Policy policy) { - return mSecurityPolicy.isActive(policy); + try { + return mSecurityPolicy.isActive(policy); + } catch (RuntimeException e) { + // Catch, log and rethrow the exception, as otherwise when the exception is + // ultimately handled, the complete stack trace is losk + LogUtils.e(LOG_TAG, e, "Exception thrown during call to SecurityPolicy#isActive"); + throw e; + } } public void setAccountHoldFlag(long accountId, boolean newState) { @@ -40,11 +50,26 @@ public class PolicyService extends Service { } public void remoteWipe() { - mSecurityPolicy.remoteWipe(); + try { + mSecurityPolicy.remoteWipe(); + } catch (RuntimeException e) { + // Catch, log and rethrow the exception, as otherwise when the exception is + // ultimately handled, the complete stack trace is losk + LogUtils.e(LOG_TAG, e, "Exception thrown during call to SecurityPolicy#remoteWipe"); + throw e; + } } public void setAccountPolicy(long accountId, Policy policy, String securityKey) { - mSecurityPolicy.setAccountPolicy(accountId, policy, securityKey); + try { + mSecurityPolicy.setAccountPolicy(accountId, policy, securityKey); + } catch (RuntimeException e) { + // Catch, log and rethrow the exception, as otherwise when the exception is + // ultimately handled, the complete stack trace is losk + LogUtils.e(LOG_TAG, e, + "Exception thrown from call to SecurityPolicy#setAccountPolicy"); + throw e; + } } };