replicant-packages_apps_Email/src/com/android/email/Email.java
Mindy Pereira 30003e582f Show correct error when adding widget with no email accts on device.
If the WidgetConfiguration service is disabled until the user adds an account,
adding the widget just fails badly as there is no service registered
to handed an APPWIDGET_CONFIGURE intent.
Fixes b/5613821 App isn't installed toast message when creating widget for Email without any account

Change-Id: I98003eadf71fb944d3c0902f7e132ca7c5b67571
2011-11-28 16:30:12 -08:00

273 lines
11 KiB
Java

/*
* Copyright (C) 2008 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;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.util.Log;
import com.android.email.activity.MessageCompose;
import com.android.email.activity.ShortcutPicker;
import com.android.email.service.AttachmentDownloadService;
import com.android.email.service.MailService;
import com.android.email.widget.WidgetConfiguration;
import com.android.emailcommon.Logging;
import com.android.emailcommon.TempDirectory;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.service.EmailServiceProxy;
import com.android.emailcommon.utility.EmailAsyncTask;
import com.android.emailcommon.utility.Utility;
public class Email extends Application {
/**
* If this is enabled there will be additional logging information sent to
* Log.d, including protocol dumps.
*
* This should only be used for logs that are useful for debbuging user problems,
* not for internal/development logs.
*
* This can be enabled by typing "debug" in the AccountFolderList activity.
* Changing the value to 'true' here will likely have no effect at all!
*
* TODO: rename this to sUserDebug, and rename LOGD below to DEBUG.
*/
public static boolean DEBUG;
// Exchange debugging flags (passed to Exchange, when available, via EmailServiceProxy)
public static boolean DEBUG_EXCHANGE;
public static boolean DEBUG_EXCHANGE_VERBOSE;
public static boolean DEBUG_EXCHANGE_FILE;
/**
* If true, inhibit hardware graphics acceleration in UI (for a/b testing)
*/
public static boolean sDebugInhibitGraphicsAcceleration = false;
/**
* Specifies how many messages will be shown in a folder by default. This number is set
* on each new folder and can be incremented with "Load more messages..." by the
* VISIBLE_LIMIT_INCREMENT
*/
public static final int VISIBLE_LIMIT_DEFAULT = 25;
/**
* Number of additional messages to load when a user selects "Load more messages..."
*/
public static final int VISIBLE_LIMIT_INCREMENT = 25;
/**
* This is used to force stacked UI to return to the "welcome" screen any time we change
* the accounts list (e.g. deleting accounts in the Account Manager preferences.)
*/
private static boolean sAccountsChangedNotification = false;
private static String sMessageDecodeErrorString;
private static Thread sUiThread;
/**
* Asynchronous version of {@link #setServicesEnabledSync(Context)}. Use when calling from
* UI thread (or lifecycle entry points.)
*
* @param context
*/
public static void setServicesEnabledAsync(final Context context) {
EmailAsyncTask.runAsyncParallel(new Runnable() {
@Override
public void run() {
setServicesEnabledSync(context);
}
});
}
/**
* Called throughout the application when the number of accounts has changed. This method
* enables or disables the Compose activity, the boot receiver and the service based on
* whether any accounts are configured.
*
* Blocking call - do not call from UI/lifecycle threads.
*
* @param context
* @return true if there are any accounts configured.
*/
public static boolean setServicesEnabledSync(Context context) {
Cursor c = null;
try {
c = context.getContentResolver().query(
Account.CONTENT_URI,
Account.ID_PROJECTION,
null, null, null);
boolean enable = c.getCount() > 0;
setServicesEnabled(context, enable);
return enable;
} finally {
if (c != null) {
c.close();
}
}
}
private static void setServicesEnabled(Context context, boolean enabled) {
PackageManager pm = context.getPackageManager();
if (!enabled && pm.getComponentEnabledSetting(
new ComponentName(context, MailService.class)) ==
PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
/*
* If no accounts now exist but the service is still enabled we're about to disable it
* so we'll reschedule to kill off any existing alarms.
*/
MailService.actionReschedule(context);
}
pm.setComponentEnabledSetting(
new ComponentName(context, MessageCompose.class),
enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(
new ComponentName(context, ShortcutPicker.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 :
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(
new ComponentName(context, AttachmentDownloadService.class),
enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
if (enabled && pm.getComponentEnabledSetting(
new ComponentName(context, MailService.class)) ==
PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
/*
* And now if accounts do exist then we've just enabled the service and we want to
* schedule alarms for the new accounts.
*/
MailService.actionReschedule(context);
}
// Start/stop the various services depending on whether there are any accounts
startOrStopService(enabled, context, new Intent(context, AttachmentDownloadService.class));
NotificationController.getInstance(context).watchForMessages(enabled);
}
/**
* Starts or stops the service as necessary.
* @param enabled If {@code true}, the service will be started. Otherwise, it will be stopped.
* @param context The context to manage the service with.
* @param intent The intent of the service to be managed.
*/
private static void startOrStopService(boolean enabled, Context context, Intent intent) {
if (enabled) {
context.startService(intent);
} else {
context.stopService(intent);
}
}
@Override
public void onCreate() {
super.onCreate();
sUiThread = Thread.currentThread();
Preferences prefs = Preferences.getPreferences(this);
DEBUG = prefs.getEnableDebugLogging();
sDebugInhibitGraphicsAcceleration = prefs.getInhibitGraphicsAcceleration();
enableStrictMode(prefs.getEnableStrictMode());
TempDirectory.setTempDirectory(this);
// Tie MailRefreshManager to the Controller.
RefreshManager.getInstance(this);
// Reset all accounts to default visible window
Controller.getInstance(this).resetVisibleLimits();
// Enable logging in the EAS service, so it starts up as early as possible.
updateLoggingFlags(this);
// Get a helper string used deep inside message decoders (which don't have context)
sMessageDecodeErrorString = getString(R.string.message_decode_error);
// Make sure all required services are running when the app is started (can prevent
// issues after an adb sync/install)
setServicesEnabledAsync(this);
}
/**
* Load enabled debug flags from the preferences and update the EAS debug flag.
*/
public static void updateLoggingFlags(Context context) {
Preferences prefs = Preferences.getPreferences(context);
int debugLogging = prefs.getEnableDebugLogging() ? EmailServiceProxy.DEBUG_BIT : 0;
int verboseLogging =
prefs.getEnableExchangeLogging() ? EmailServiceProxy.DEBUG_VERBOSE_BIT : 0;
int fileLogging =
prefs.getEnableExchangeFileLogging() ? EmailServiceProxy.DEBUG_FILE_BIT : 0;
int enableStrictMode =
prefs.getEnableStrictMode() ? EmailServiceProxy.DEBUG_ENABLE_STRICT_MODE : 0;
int debugBits = debugLogging | verboseLogging | fileLogging | enableStrictMode;
Controller.getInstance(context).serviceLogging(debugBits);
}
/**
* Internal, utility method for logging.
* The calls to log() must be guarded with "if (Email.LOGD)" for performance reasons.
*/
public static void log(String message) {
Log.d(Logging.LOG_TAG, message);
}
/**
* Called by the accounts reconciler to notify that accounts have changed, or by "Welcome"
* to clear the flag.
* @param setFlag true to set the notification flag, false to clear it
*/
public static synchronized void setNotifyUiAccountsChanged(boolean setFlag) {
sAccountsChangedNotification = setFlag;
}
/**
* Called from activity onResume() functions to check for an accounts-changed condition, at
* which point they should finish() and jump to the Welcome activity.
*/
public static synchronized boolean getNotifyUiAccountsChanged() {
return sAccountsChangedNotification;
}
public static void warnIfUiThread() {
if (Thread.currentThread().equals(sUiThread)) {
Log.w(Logging.LOG_TAG, "Method called on the UI thread", new Exception("STACK TRACE"));
}
}
/**
* Retrieve a simple string that can be used when message decoders encounter bad data.
* This is provided here because the protocol decoders typically don't have mContext.
*/
public static String getMessageDecodeErrorString() {
return sMessageDecodeErrorString != null ? sMessageDecodeErrorString : "";
}
public static void enableStrictMode(boolean enabled) {
Utility.enableStrictMode(enabled);
}
}