diff options
author | Mike Dodd <mdodd@google.com> | 2015-08-11 11:16:59 -0700 |
---|---|---|
committer | Mike Dodd <mdodd@google.com> | 2015-08-12 12:47:26 -0700 |
commit | d3b009ae55651f1e60950342468e3c37fdeb0796 (patch) | |
tree | bc4b489af52d0e2521e21167d2ad76a47256f348 /src/com/android/messaging/BugleApplication.java | |
parent | ef8c7abbcfc9c770385d6609a4b4bc70240ebdc4 (diff) | |
download | android_packages_apps_Messaging-d3b009ae55651f1e60950342468e3c37fdeb0796.tar.gz android_packages_apps_Messaging-d3b009ae55651f1e60950342468e3c37fdeb0796.tar.bz2 android_packages_apps_Messaging-d3b009ae55651f1e60950342468e3c37fdeb0796.zip |
Initial checkin of AOSP Messaging app.
b/23110861
Change-Id: I11db999bd10656801e618f78ab2b2ef74136fff1
Diffstat (limited to 'src/com/android/messaging/BugleApplication.java')
-rw-r--r-- | src/com/android/messaging/BugleApplication.java | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/src/com/android/messaging/BugleApplication.java b/src/com/android/messaging/BugleApplication.java new file mode 100644 index 0000000..a5aea9f --- /dev/null +++ b/src/com/android/messaging/BugleApplication.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2015 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.messaging; + +import android.app.Application; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Configuration; +import android.os.Handler; +import android.os.Looper; +import android.support.v7.mms.CarrierConfigValuesLoader; +import android.support.v7.mms.MmsManager; +import android.telephony.CarrierConfigManager; + +import com.android.messaging.datamodel.DataModel; +import com.android.messaging.receiver.SmsReceiver; +import com.android.messaging.sms.ApnDatabase; +import com.android.messaging.sms.BugleApnSettingsLoader; +import com.android.messaging.sms.BugleUserAgentInfoLoader; +import com.android.messaging.sms.MmsConfig; +import com.android.messaging.ui.ConversationDrawables; +import com.android.messaging.util.BugleGservices; +import com.android.messaging.util.BugleGservicesKeys; +import com.android.messaging.util.BuglePrefs; +import com.android.messaging.util.BuglePrefsKeys; +import com.android.messaging.util.DebugUtils; +import com.android.messaging.util.LogUtil; +import com.android.messaging.util.OsUtil; +import com.android.messaging.util.PhoneUtils; +import com.android.messaging.util.Trace; +import com.google.common.annotations.VisibleForTesting; + +import java.io.File; +import java.lang.Thread.UncaughtExceptionHandler; + +/** + * The application object + */ +public class BugleApplication extends Application implements UncaughtExceptionHandler { + private static final String TAG = LogUtil.BUGLE_TAG; + + private UncaughtExceptionHandler sSystemUncaughtExceptionHandler; + private static boolean sRunningTests = false; + + @VisibleForTesting + protected static void setTestsRunning() { + sRunningTests = true; + } + + /** + * @return true if we're running unit tests. + */ + public static boolean isRunningTests() { + return sRunningTests; + } + + @Override + public void onCreate() { + Trace.beginSection("app.onCreate"); + super.onCreate(); + + // Note onCreate is called in both test and real application environments + if (!sRunningTests) { + // Only create the factory if not running tests + FactoryImpl.register(getApplicationContext(), this); + } else { + LogUtil.e(TAG, "BugleApplication.onCreate: FactoryImpl.register skipped for test run"); + } + + sSystemUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(this); + Trace.endSection(); + } + + @Override + public void onConfigurationChanged(final Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + // Update conversation drawables when changing writing systems + // (Right-To-Left / Left-To-Right) + ConversationDrawables.get().updateDrawables(); + } + + // Called by the "real" factory from FactoryImpl.register() (i.e. not run in tests) + public void initializeSync(final Factory factory) { + Trace.beginSection("app.initializeSync"); + final Context context = factory.getApplicationContext(); + final BugleGservices bugleGservices = factory.getBugleGservices(); + final BuglePrefs buglePrefs = factory.getApplicationPrefs(); + final DataModel dataModel = factory.getDataModel(); + final CarrierConfigValuesLoader carrierConfigValuesLoader = + factory.getCarrierConfigValuesLoader(); + + maybeStartProfiling(); + + BugleApplication.updateAppConfig(context); + + // Initialize MMS lib + initMmsLib(context, bugleGservices, carrierConfigValuesLoader); + // Initialize APN database + ApnDatabase.initializeAppContext(context); + // Fixup messages in flight if we crashed and send any pending + dataModel.onApplicationCreated(); + // Register carrier config change receiver + if (OsUtil.isAtLeastM()) { + registerCarrierConfigChangeReceiver(context); + } + + Trace.endSection(); + } + + private static void registerCarrierConfigChangeReceiver(final Context context) { + context.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + LogUtil.i(TAG, "Carrier config changed. Reloading MMS config."); + MmsConfig.loadAsync(); + } + }, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); + } + + private static void initMmsLib(final Context context, final BugleGservices bugleGservices, + final CarrierConfigValuesLoader carrierConfigValuesLoader) { + MmsManager.setApnSettingsLoader(new BugleApnSettingsLoader(context)); + MmsManager.setCarrierConfigValuesLoader(carrierConfigValuesLoader); + MmsManager.setUserAgentInfoLoader(new BugleUserAgentInfoLoader(context)); + MmsManager.setUseWakeLock(true); + // If Gservices is configured not to use mms api, force MmsManager to always use + // legacy mms sending logic + MmsManager.setForceLegacyMms(!bugleGservices.getBoolean( + BugleGservicesKeys.USE_MMS_API_IF_PRESENT, + BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT)); + bugleGservices.registerForChanges(new Runnable() { + @Override + public void run() { + MmsManager.setForceLegacyMms(!bugleGservices.getBoolean( + BugleGservicesKeys.USE_MMS_API_IF_PRESENT, + BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT)); + } + }); + } + + public static void updateAppConfig(final Context context) { + // Make sure we set the correct state for the SMS/MMS receivers + SmsReceiver.updateSmsReceiveHandler(context); + } + + // Called from thread started in FactoryImpl.register() (i.e. not run in tests) + public void initializeAsync(final Factory factory) { + // Handle shared prefs upgrade & Load MMS Configuration + Trace.beginSection("app.initializeAsync"); + maybeHandleSharedPrefsUpgrade(factory); + MmsConfig.load(); + Trace.endSection(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + + if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { + LogUtil.d(TAG, "BugleApplication.onLowMemory"); + } + Factory.get().reclaimMemory(); + } + + @Override + public void uncaughtException(final Thread thread, final Throwable ex) { + final boolean background = getMainLooper().getThread() != thread; + if (background) { + LogUtil.e(TAG, "Uncaught exception in background thread " + thread, ex); + + final Handler handler = new Handler(getMainLooper()); + handler.post(new Runnable() { + + @Override + public void run() { + sSystemUncaughtExceptionHandler.uncaughtException(thread, ex); + } + }); + } else { + sSystemUncaughtExceptionHandler.uncaughtException(thread, ex); + } + } + + private void maybeStartProfiling() { + // App startup profiling support. To use it: + // adb shell setprop log.tag.BugleProfile DEBUG + // # Start the app, wait for a 30s, download trace file: + // adb pull /data/data/com.android.messaging/cache/startup.trace /tmp + // # Open trace file (using adt/tools/traceview) + if (android.util.Log.isLoggable(LogUtil.PROFILE_TAG, android.util.Log.DEBUG)) { + // Start method tracing with a big enough buffer and let it run for 30s. + // Note we use a logging tag as we don't want to wait for gservices to start up. + final File file = DebugUtils.getDebugFile("startup.trace", true); + if (file != null) { + android.os.Debug.startMethodTracing(file.getAbsolutePath(), 160 * 1024 * 1024); + new Handler(Looper.getMainLooper()).postDelayed( + new Runnable() { + @Override + public void run() { + android.os.Debug.stopMethodTracing(); + // Allow world to see trace file + DebugUtils.ensureReadable(file); + LogUtil.d(LogUtil.PROFILE_TAG, "Tracing complete - " + + file.getAbsolutePath()); + } + }, 30000); + } + } + } + + private void maybeHandleSharedPrefsUpgrade(final Factory factory) { + final int existingVersion = factory.getApplicationPrefs().getInt( + BuglePrefsKeys.SHARED_PREFERENCES_VERSION, + BuglePrefsKeys.SHARED_PREFERENCES_VERSION_DEFAULT); + final int targetVersion = Integer.parseInt(getString(R.string.pref_version)); + if (targetVersion > existingVersion) { + LogUtil.i(LogUtil.BUGLE_TAG, "Upgrading shared prefs from " + existingVersion + + " to " + targetVersion); + try { + // Perform upgrade on application-wide prefs. + factory.getApplicationPrefs().onUpgrade(existingVersion, targetVersion); + // Perform upgrade on each subscription's prefs. + PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() { + @Override + public void runForSubscription(final int subId) { + factory.getSubscriptionPrefs(subId) + .onUpgrade(existingVersion, targetVersion); + } + }); + factory.getApplicationPrefs().putInt(BuglePrefsKeys.SHARED_PREFERENCES_VERSION, + targetVersion); + } catch (final Exception ex) { + // Upgrade failed. Don't crash the app because we can always fall back to the + // default settings. + LogUtil.e(LogUtil.BUGLE_TAG, "Failed to upgrade shared prefs", ex); + } + } else if (targetVersion < existingVersion) { + // We don't care about downgrade since real user shouldn't encounter this, so log it + // and ignore any prefs migration. + LogUtil.e(LogUtil.BUGLE_TAG, "Shared prefs downgrade requested and ignored. " + + "oldVersion = " + existingVersion + ", newVersion = " + targetVersion); + } + } +} |