diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7d4df6cb4..12a7acb64 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -437,6 +437,19 @@ /> + + + + + + diff --git a/src/com/android/email/Email.java b/src/com/android/email/Email.java index 82ac1c0ca..d7cd4fd7c 100644 --- a/src/com/android/email/Email.java +++ b/src/com/android/email/Email.java @@ -21,6 +21,7 @@ import com.android.email.activity.MessageCompose; import com.android.email.service.AttachmentDownloadService; import com.android.email.service.MailService; import com.android.email.service.NotificationService; +import com.android.email.widget.WidgetConfiguration; import com.android.emailcommon.Logging; import com.android.emailcommon.TempDirectory; import com.android.emailcommon.provider.EmailContent; @@ -146,6 +147,11 @@ public class Email extends Application { enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); + pm.setComponentEnabledSetting( + new ComponentName(context, WidgetConfiguration.class), + enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); pm.setComponentEnabledSetting( new ComponentName(context, MailService.class), enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : @@ -160,7 +166,7 @@ public class Email extends Application { new ComponentName(context, NotificationService.class), enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - PackageManager.DONT_KILL_APP); + PackageManager.DONT_KILL_APP); if (enabled && pm.getComponentEnabledSetting( new ComponentName(context, MailService.class)) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { diff --git a/src/com/android/email/provider/WidgetProvider.java b/src/com/android/email/provider/WidgetProvider.java index 12f7b3ce3..18fe33fbf 100644 --- a/src/com/android/email/provider/WidgetProvider.java +++ b/src/com/android/email/provider/WidgetProvider.java @@ -19,6 +19,7 @@ package com.android.email.provider; import com.android.email.Email; import com.android.email.widget.EmailWidget; import com.android.email.widget.WidgetManager; +import com.android.emailcommon.Logging; import android.app.Service; import android.appwidget.AppWidgetManager; @@ -34,7 +35,7 @@ import java.io.PrintWriter; public class WidgetProvider extends AppWidgetProvider { @Override public void onEnabled(final Context context) { - if (Email.DEBUG) { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(EmailWidget.TAG, "onEnabled"); } super.onEnabled(context); @@ -42,7 +43,7 @@ public class WidgetProvider extends AppWidgetProvider { @Override public void onDisabled(Context context) { - if (Email.DEBUG) { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(EmailWidget.TAG, "onDisabled"); } context.stopService(new Intent(context, WidgetService.class)); @@ -51,7 +52,7 @@ public class WidgetProvider extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - if (Email.DEBUG) { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(EmailWidget.TAG, "onUpdate"); } super.onUpdate(context, appWidgetManager, appWidgetIds); @@ -60,7 +61,7 @@ public class WidgetProvider extends AppWidgetProvider { @Override public void onDeleted(Context context, int[] appWidgetIds) { - if (Email.DEBUG) { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(EmailWidget.TAG, "onDeleted"); } WidgetManager.getInstance().deleteWidgets(context, appWidgetIds); @@ -69,7 +70,7 @@ public class WidgetProvider extends AppWidgetProvider { @Override public void onReceive(final Context context, Intent intent) { - if (Email.DEBUG) { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(EmailWidget.TAG, "onReceive"); } super.onReceive(context, intent); diff --git a/src/com/android/email/widget/EmailWidget.java b/src/com/android/email/widget/EmailWidget.java index d4e3d41a3..9d7d7cc94 100644 --- a/src/com/android/email/widget/EmailWidget.java +++ b/src/com/android/email/widget/EmailWidget.java @@ -23,8 +23,8 @@ import com.android.email.activity.MessageCompose; import com.android.email.activity.UiUtilities; import com.android.email.activity.Welcome; import com.android.email.provider.WidgetProvider.WidgetService; +import com.android.emailcommon.Logging; import com.android.emailcommon.provider.EmailContent.Account; -import com.android.emailcommon.provider.EmailContent.AccountColumns; import com.android.emailcommon.provider.EmailContent.Message; import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.utility.EmailAsyncTask; @@ -32,7 +32,6 @@ import com.android.emailcommon.utility.EmailAsyncTask; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.Context; -import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; import android.content.Loader.OnLoadCompleteListener; @@ -92,16 +91,9 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, private static final Uri COMMAND_URI_VIEW_MESSAGE = COMMAND_URI.buildUpon().appendPath(COMMAND_NAME_VIEW_MESSAGE).build(); + // TODO Can this be moved to the loader and made a database 'LIMIT'? private static final int MAX_MESSAGE_LIST_COUNT = 25; - // TODO Temporary selection / projection to pick the first account defined. Remove once the - // account / mailbox picker activity is added - private static final String SORT_ID_ASCENDING = AccountColumns.ID + " ASC"; - private static final String[] ID_NAME_PROJECTION = - { AccountColumns.ID, AccountColumns.DISPLAY_NAME }; - private static final int ID_NAME_COLUMN_ID = 0; - private static final int ID_NAME_COLUMN_NAME = 1; - private static String sSubjectSnippetDivider; @SuppressWarnings("unused") private static String sConfigureText; @@ -161,27 +153,20 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, mResourceHelper = ResourceHelper.getInstance(mContext); } + /** + * Start loading the data. At this point nothing on the widget changes -- the current view + * will remain valid until the loader loads the latest data. + */ public void start() { - // TODO By default, pick an account to display the widget for. This should all be removed - // once the widget configuration activity is hooked up. - CursorLoader accountLoader = new CursorLoader( - mContext, Account.CONTENT_URI, ID_NAME_PROJECTION, null, null, SORT_ID_ASCENDING); - accountLoader.registerListener(1, new OnLoadCompleteListener() { - @Override - public void onLoadComplete(android.content.Loader loader, Cursor data) { - long accountId = Account.NO_ACCOUNT; - String accountName = null; - if (data != null && data.moveToFirst()) { - accountId = data.getLong(ID_NAME_COLUMN_ID); - accountName = data.getString(ID_NAME_COLUMN_NAME); - } - WidgetManager.saveWidgetPrefs( - mContext, mWidgetId, accountId, Mailbox.QUERY_ALL_INBOXES); - loadView(); - loader.reset(); - } - }); - accountLoader.startLoading(); + long accountId = WidgetManager.loadAccountIdPref(mContext, mWidgetId); + long mailboxId = WidgetManager.loadMailboxIdPref(mContext, mWidgetId); + // Legacy support; if preferences haven't been saved for this widget, load something + if (accountId == Account.NO_ACCOUNT) { + accountId = Account.ACCOUNT_ID_COMBINED_VIEW; + mailboxId = Mailbox.QUERY_ALL_INBOXES; + } + mAccountId = accountId; + mLoader.load(mAccountId, mailboxId); } private boolean isCursorValid() { @@ -199,16 +184,6 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, mWidgetManager.notifyAppWidgetViewDataChanged(mWidgetId, R.id.message_list); } - /** - * Start loading the data. At this point nothing on the widget changes -- the current view - * will remain valid until the loader loads the latest data. - */ - private void loadView() { - mAccountId = WidgetManager.loadAccountIdPref(mContext, mWidgetId); - final long mailboxId = WidgetManager.loadMailboxIdPref(mContext, mWidgetId); - mLoader.load(mAccountId, mailboxId); - } - /** * Convenience method for creating an onClickPendingIntent that launches another activity * directly. @@ -304,7 +279,7 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, */ private void updateHeader() { if (Email.DEBUG) { - Log.d(TAG, "updateWidget " + mWidgetId); + Log.d(TAG, "#updateHeader(); widgetId: " + mWidgetId); } // Get the widget layout @@ -505,6 +480,10 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, } public void onDeleted() { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { + Log.d(TAG, "#onDeleted(); widgetId: " + mWidgetId); + } + if (mLoader != null) { mLoader.reset(); } @@ -512,6 +491,10 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, @Override public void onDestroy() { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { + Log.d(TAG, "#onDestroy(); widgetId: " + mWidgetId); + } + if (mLoader != null) { mLoader.reset(); } @@ -519,6 +502,9 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory, @Override public void onCreate() { + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { + Log.d(TAG, "#onCreate(); widgetId: " + mWidgetId); + } } @Override diff --git a/src/com/android/email/widget/WidgetConfiguration.java b/src/com/android/email/widget/WidgetConfiguration.java new file mode 100644 index 000000000..a48ad6dd7 --- /dev/null +++ b/src/com/android/email/widget/WidgetConfiguration.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.email.widget; + +import android.app.Activity; +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; + +import com.android.email.R; +import com.android.email.activity.ShortcutPickerFragment.AccountShortcutPickerFragment; +import com.android.email.activity.ShortcutPickerFragment.PickerCallback; +import com.android.emailcommon.provider.EmailContent.Account; + +/** + * Activity to configure the Email widget. + */ +public class WidgetConfiguration extends Activity implements OnClickListener, PickerCallback { + /** ID of the newly created application widget */ + private int mAppWidgetId; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setResult(RESULT_CANCELED); + if (!AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(getIntent().getAction())) { + // finish() immediately if we aren't supposed to be here + finish(); + return; + } + + Intent intent = getIntent(); + Bundle extras = intent.getExtras(); + if (extras != null) { + mAppWidgetId = extras.getInt( + AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + } + + // Set handler for the "cancel" button + setContentView(R.layout.account_shortcut_picker); + findViewById(R.id.cancel).setOnClickListener(this); + + if (getFragmentManager().findFragmentById(R.id.shortcut_list) == null) { + // Load the account picking fragment if we haven't created a fragment yet + // NOTE: do not add to history as this will be the first fragment in the flow + AccountShortcutPickerFragment fragment = new AccountShortcutPickerFragment(); + getFragmentManager().beginTransaction().add(R.id.shortcut_list, fragment).commit(); + } + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.cancel: + finish(); + break; + } + } + + @Override + public void onSelected(Account account, long mailboxId) { + setupWidget(account, mailboxId); + finish(); + } + + @Override + public void onMissingData(boolean missingAccount, boolean missingMailbox) { + // TODO what's the proper handling if the mailbox list is '0'? display toast? + finish(); + } + + private void setupWidget(Account account, long mailboxId) { + // save user selected preferences & create initial widget view + WidgetManager.saveWidgetPrefs(this, mAppWidgetId, account.mId, mailboxId); + WidgetManager.getInstance().getOrCreateWidget(this, mAppWidgetId).start(); + + // Return "OK" result; make sure we pass along the original widget ID + Intent resultValue = new Intent(); + resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); + setResult(RESULT_OK, resultValue); + } +} diff --git a/src/com/android/email/widget/WidgetManager.java b/src/com/android/email/widget/WidgetManager.java index 40162b8a2..878e525c3 100644 --- a/src/com/android/email/widget/WidgetManager.java +++ b/src/com/android/email/widget/WidgetManager.java @@ -17,6 +17,7 @@ package com.android.email.widget; import com.android.email.Email; +import com.android.emailcommon.Logging; import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.provider.EmailContent.Account; @@ -71,8 +72,8 @@ public class WidgetManager { public synchronized EmailWidget getOrCreateWidget(Context context, int widgetId) { EmailWidget widget = WidgetManager.getInstance().get(widgetId); if (widget == null) { - if (Email.DEBUG) { - Log.d(EmailWidget.TAG, "Creating EmailWidget for id #" + widgetId); + if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { + Log.d(EmailWidget.TAG, "Create email widget; ID: " + widgetId); } widget = new EmailWidget(context, widgetId); WidgetManager.getInstance().put(widgetId, widget); @@ -123,17 +124,23 @@ public class WidgetManager { editor.apply(); // just want to clean up; don't care when preferences are actually removed } - /** Gets the saved account ID for the given widget */ + /** + * Returns the saved account ID for the given widget. Otherwise, {@link Account#NO_ACCOUNT} if + * the account ID was not previously saved. + */ static long loadAccountIdPref(Context context, int appWidgetId) { SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0); long accountId = prefs.getLong(ACCOUNT_ID_PREFIX + appWidgetId, Account.NO_ACCOUNT); return accountId; } - /** Gets the saved mailbox ID for the given widget */ + /** + * Returns the saved mailbox ID for the given widget. Otherwise, {@link Mailbox#NO_MAILBOX} if + * the mailbox ID was not previously saved. + */ static long loadMailboxIdPref(Context context, int appWidgetId) { SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0); - long accountId = prefs.getLong(MAILBOX_ID_PREFIX + appWidgetId, Mailbox.NO_MAILBOX); - return accountId; + long mailboxId = prefs.getLong(MAILBOX_ID_PREFIX + appWidgetId, Mailbox.NO_MAILBOX); + return mailboxId; } }