1 /*
2  * Copyright (C) 2012 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 
17 package com.android.email.provider;
18 
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.content.SharedPreferences;
22 import android.database.Cursor;
23 import android.net.Uri;
24 
25 import com.android.emailcommon.provider.Account;
26 import com.android.emailcommon.provider.Mailbox;
27 import com.android.mail.providers.Folder;
28 import com.android.mail.providers.UIProvider;
29 import com.android.mail.utils.LogTag;
30 import com.android.mail.utils.LogUtils;
31 import com.android.mail.widget.BaseWidgetProvider;
32 import com.android.mail.widget.WidgetService;
33 
34 public class WidgetProvider extends BaseWidgetProvider {
35     private static final String LEGACY_PREFS_NAME = "com.android.email.widget.WidgetManager";
36     private static final String LEGACY_ACCOUNT_ID_PREFIX = "accountId_";
37     private static final String LEGACY_MAILBOX_ID_PREFIX = "mailboxId_";
38 
39     private static final String LOG_TAG = LogTag.getLogTag();
40 
41     /**
42      * Remove preferences when deleting widget
43      */
44     @Override
onDeleted(Context context, int[] appWidgetIds)45     public void onDeleted(Context context, int[] appWidgetIds) {
46         super.onDeleted(context, appWidgetIds);
47 
48         // Remove any legacy Email widget information
49         final SharedPreferences prefs = context.getSharedPreferences(LEGACY_PREFS_NAME, 0);
50         final SharedPreferences.Editor editor = prefs.edit();
51         for (int widgetId : appWidgetIds) {
52             // Remove the account in the preference
53             editor.remove(LEGACY_ACCOUNT_ID_PREFIX + widgetId);
54             editor.remove(LEGACY_MAILBOX_ID_PREFIX + widgetId);
55         }
56         editor.apply();
57     }
58 
59     @Override
getAccountObject( Context context, String accountUri)60     protected com.android.mail.providers.Account getAccountObject(
61             Context context, String accountUri) {
62         final ContentResolver resolver = context.getContentResolver();
63         final Cursor accountCursor = resolver.query(Uri.parse(accountUri),
64                 UIProvider.ACCOUNTS_PROJECTION_NO_CAPABILITIES, null, null, null);
65 
66         return getPopulatedAccountObject(accountCursor);
67     }
68 
69 
70     @Override
isAccountValid(Context context, com.android.mail.providers.Account account)71     protected boolean isAccountValid(Context context, com.android.mail.providers.Account account) {
72         if (account != null) {
73             final ContentResolver resolver = context.getContentResolver();
74             final Cursor accountCursor = resolver.query(account.uri,
75                     UIProvider.ACCOUNTS_PROJECTION_NO_CAPABILITIES, null, null, null);
76             if (accountCursor != null) {
77                 try {
78                     return accountCursor.getCount() > 0;
79                 } finally {
80                     accountCursor.close();
81                 }
82             }
83         }
84         return false;
85     }
86 
87     @Override
migrateLegacyWidgetInformation(Context context, int widgetId)88     protected void migrateLegacyWidgetInformation(Context context, int widgetId) {
89         final SharedPreferences prefs = context.getSharedPreferences(LEGACY_PREFS_NAME, 0);
90         final SharedPreferences.Editor editor = prefs.edit();
91 
92         long accountId = loadAccountIdPref(context, widgetId);
93         long mailboxId = loadMailboxIdPref(context, widgetId);
94         // Legacy support; if preferences haven't been saved for this widget, load something
95         if (accountId == Account.NO_ACCOUNT || mailboxId == Mailbox.NO_MAILBOX) {
96             LogUtils.d(LOG_TAG, "Couldn't load account or mailbox.  accountId: %d" +
97                     " mailboxId: %d widgetId %d", accountId, mailboxId, widgetId);
98             return;
99         }
100 
101         accountId = migrateLegacyWidgetAccountId(accountId);
102         mailboxId = migrateLegacyWidgetMailboxId(mailboxId, accountId);
103 
104         // Get Account and folder objects for the account id and mailbox id
105         final com.android.mail.providers.Account uiAccount = getAccount(context, accountId);
106         final Folder uiFolder = EmailProvider.getFolder(context, mailboxId);
107 
108         if (uiAccount != null && uiFolder != null) {
109             WidgetService.saveWidgetInformation(context, widgetId, uiAccount,
110                     uiFolder.folderUri.fullUri.toString());
111 
112             updateWidgetInternal(context, widgetId, uiAccount, uiFolder.type, uiFolder.capabilities,
113                     uiFolder.folderUri.fullUri, uiFolder.conversationListUri, uiFolder.name);
114 
115             // Now remove the old legacy preference value
116             editor.remove(LEGACY_ACCOUNT_ID_PREFIX + widgetId);
117             editor.remove(LEGACY_MAILBOX_ID_PREFIX + widgetId);
118         }
119         editor.apply();
120     }
121 
migrateLegacyWidgetAccountId(long accountId)122     private static long migrateLegacyWidgetAccountId(long accountId) {
123         if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
124             return EmailProvider.COMBINED_ACCOUNT_ID;
125         }
126         return accountId;
127     }
128 
129     /**
130      * @param accountId The migrated accountId
131      * @return
132      */
migrateLegacyWidgetMailboxId(long mailboxId, long accountId)133     private static long migrateLegacyWidgetMailboxId(long mailboxId, long accountId) {
134         if (mailboxId == Mailbox.QUERY_ALL_INBOXES) {
135             return EmailProvider.getVirtualMailboxId(accountId, Mailbox.TYPE_INBOX);
136         } else if (mailboxId == Mailbox.QUERY_ALL_UNREAD) {
137             return EmailProvider.getVirtualMailboxId(accountId, Mailbox.TYPE_UNREAD);
138         }
139         return mailboxId;
140     }
141 
getAccount(Context context, long accountId)142     private static com.android.mail.providers.Account getAccount(Context context, long accountId) {
143         final ContentResolver resolver = context.getContentResolver();
144         final Cursor ac = resolver.query(EmailProvider.uiUri("uiaccount", accountId),
145                 UIProvider.ACCOUNTS_PROJECTION_NO_CAPABILITIES, null, null, null);
146 
147         com.android.mail.providers.Account uiAccount = getPopulatedAccountObject(ac);
148 
149         return uiAccount;
150     }
151 
getPopulatedAccountObject( final Cursor accountCursor)152     private static com.android.mail.providers.Account getPopulatedAccountObject(
153             final Cursor accountCursor) {
154         if (accountCursor == null) {
155             LogUtils.e(LOG_TAG, "Null account cursor");
156             return null;
157         }
158 
159         com.android.mail.providers.Account uiAccount = null;
160         try {
161             if (accountCursor.moveToFirst()) {
162                  uiAccount = com.android.mail.providers.Account.builder().buildFrom(accountCursor);
163             }
164         } finally {
165             accountCursor.close();
166         }
167         return uiAccount;
168     }
169 
170     /**
171      * Returns the saved account ID for the given widget. Otherwise,
172      * {@link com.android.emailcommon.provider.Account#NO_ACCOUNT} if
173      * the account ID was not previously saved.
174      */
loadAccountIdPref(Context context, int appWidgetId)175     static long loadAccountIdPref(Context context, int appWidgetId) {
176         final SharedPreferences prefs = context.getSharedPreferences(LEGACY_PREFS_NAME, 0);
177         long accountId = prefs.getLong(LEGACY_ACCOUNT_ID_PREFIX + appWidgetId, Account.NO_ACCOUNT);
178         return accountId;
179     }
180 
181     /**
182      * Returns the saved mailbox ID for the given widget. Otherwise,
183      * {@link com.android.emailcommon.provider.Mailbox#NO_MAILBOX} if
184      * the mailbox ID was not previously saved.
185      */
loadMailboxIdPref(Context context, int appWidgetId)186     static long loadMailboxIdPref(Context context, int appWidgetId) {
187         final SharedPreferences prefs = context.getSharedPreferences(LEGACY_PREFS_NAME, 0);
188         long mailboxId = prefs.getLong(LEGACY_MAILBOX_ID_PREFIX + appWidgetId, Mailbox.NO_MAILBOX);
189         return mailboxId;
190     }
191 }
192