1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.Application; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.BroadcastReceiver; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.IntentFilter; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.Configuration; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Handler; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Looper; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.mms.CarrierConfigValuesLoader; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.mms.MmsManager; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.CarrierConfigManager; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DataModel; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.receiver.SmsReceiver; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.ApnDatabase; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.BugleApnSettingsLoader; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.BugleUserAgentInfoLoader; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsConfig; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.ConversationDrawables; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.BugleGservices; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.BugleGservicesKeys; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.BuglePrefs; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.BuglePrefsKeys; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.DebugUtils; 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil; 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.OsUtil; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.PhoneUtils; 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Trace; 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.google.common.annotations.VisibleForTesting; 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.File; 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.lang.Thread.UncaughtExceptionHandler; 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The application object 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class BugleApplication extends Application implements UncaughtExceptionHandler { 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String TAG = LogUtil.BUGLE_TAG; 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private UncaughtExceptionHandler sSystemUncaughtExceptionHandler; 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static boolean sRunningTests = false; 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @VisibleForTesting 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected static void setTestsRunning() { 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sRunningTests = true; 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if we're running unit tests. 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static boolean isRunningTests() { 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return sRunningTests; 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onCreate() { 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Trace.beginSection("app.onCreate"); 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onCreate(); 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Note onCreate is called in both test and real application environments 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!sRunningTests) { 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Only create the factory if not running tests 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd FactoryImpl.register(getApplicationContext(), this); 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "BugleApplication.onCreate: FactoryImpl.register skipped for test run"); 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sSystemUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Thread.setDefaultUncaughtExceptionHandler(this); 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Trace.endSection(); 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onConfigurationChanged(final Configuration newConfig) { 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onConfigurationChanged(newConfig); 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Update conversation drawables when changing writing systems 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // (Right-To-Left / Left-To-Right) 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ConversationDrawables.get().updateDrawables(); 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Called by the "real" factory from FactoryImpl.register() (i.e. not run in tests) 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void initializeSync(final Factory factory) { 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Trace.beginSection("app.initializeSync"); 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Context context = factory.getApplicationContext(); 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final BugleGservices bugleGservices = factory.getBugleGservices(); 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final BuglePrefs buglePrefs = factory.getApplicationPrefs(); 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final DataModel dataModel = factory.getDataModel(); 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final CarrierConfigValuesLoader carrierConfigValuesLoader = 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd factory.getCarrierConfigValuesLoader(); 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd maybeStartProfiling(); 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleApplication.updateAppConfig(context); 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Initialize MMS lib 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd initMmsLib(context, bugleGservices, carrierConfigValuesLoader); 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Initialize APN database 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ApnDatabase.initializeAppContext(context); 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Fixup messages in flight if we crashed and send any pending 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd dataModel.onApplicationCreated(); 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Register carrier config change receiver 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastM()) { 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd registerCarrierConfigChangeReceiver(context); 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Trace.endSection(); 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static void registerCarrierConfigChangeReceiver(final Context context) { 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd context.registerReceiver(new BroadcastReceiver() { 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onReceive(Context context, Intent intent) { 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(TAG, "Carrier config changed. Reloading MMS config."); 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsConfig.loadAsync(); 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static void initMmsLib(final Context context, final BugleGservices bugleGservices, 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final CarrierConfigValuesLoader carrierConfigValuesLoader) { 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsManager.setApnSettingsLoader(new BugleApnSettingsLoader(context)); 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsManager.setCarrierConfigValuesLoader(carrierConfigValuesLoader); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsManager.setUserAgentInfoLoader(new BugleUserAgentInfoLoader(context)); 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsManager.setUseWakeLock(true); 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // If Gservices is configured not to use mms api, force MmsManager to always use 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // legacy mms sending logic 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsManager.setForceLegacyMms(!bugleGservices.getBoolean( 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleGservicesKeys.USE_MMS_API_IF_PRESENT, 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT)); 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd bugleGservices.registerForChanges(new Runnable() { 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void run() { 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsManager.setForceLegacyMms(!bugleGservices.getBoolean( 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleGservicesKeys.USE_MMS_API_IF_PRESENT, 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT)); 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static void updateAppConfig(final Context context) { 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Make sure we set the correct state for the SMS/MMS receivers 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd SmsReceiver.updateSmsReceiveHandler(context); 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Called from thread started in FactoryImpl.register() (i.e. not run in tests) 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void initializeAsync(final Factory factory) { 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Handle shared prefs upgrade & Load MMS Configuration 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Trace.beginSection("app.initializeAsync"); 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd maybeHandleSharedPrefsUpgrade(factory); 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsConfig.load(); 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Trace.endSection(); 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onLowMemory() { 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onLowMemory(); 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(TAG, "BugleApplication.onLowMemory"); 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Factory.get().reclaimMemory(); 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void uncaughtException(final Thread thread, final Throwable ex) { 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean background = getMainLooper().getThread() != thread; 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (background) { 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "Uncaught exception in background thread " + thread, ex); 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Handler handler = new Handler(getMainLooper()); 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd handler.post(new Runnable() { 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void run() { 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sSystemUncaughtExceptionHandler.uncaughtException(thread, ex); 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd sSystemUncaughtExceptionHandler.uncaughtException(thread, ex); 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void maybeStartProfiling() { 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // App startup profiling support. To use it: 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // adb shell setprop log.tag.BugleProfile DEBUG 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // # Start the app, wait for a 30s, download trace file: 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // adb pull /data/data/com.android.messaging/cache/startup.trace /tmp 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // # Open trace file (using adt/tools/traceview) 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (android.util.Log.isLoggable(LogUtil.PROFILE_TAG, android.util.Log.DEBUG)) { 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Start method tracing with a big enough buffer and let it run for 30s. 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Note we use a logging tag as we don't want to wait for gservices to start up. 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final File file = DebugUtils.getDebugFile("startup.trace", true); 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (file != null) { 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd android.os.Debug.startMethodTracing(file.getAbsolutePath(), 160 * 1024 * 1024); 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new Handler(Looper.getMainLooper()).postDelayed( 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new Runnable() { 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void run() { 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd android.os.Debug.stopMethodTracing(); 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Allow world to see trace file 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd DebugUtils.ensureReadable(file); 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(LogUtil.PROFILE_TAG, "Tracing complete - " 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + file.getAbsolutePath()); 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }, 30000); 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void maybeHandleSharedPrefsUpgrade(final Factory factory) { 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int existingVersion = factory.getApplicationPrefs().getInt( 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BuglePrefsKeys.SHARED_PREFERENCES_VERSION, 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BuglePrefsKeys.SHARED_PREFERENCES_VERSION_DEFAULT); 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int targetVersion = Integer.parseInt(getString(R.string.pref_version)); 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (targetVersion > existingVersion) { 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(LogUtil.BUGLE_TAG, "Upgrading shared prefs from " + existingVersion + 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd " to " + targetVersion); 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Perform upgrade on application-wide prefs. 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd factory.getApplicationPrefs().onUpgrade(existingVersion, targetVersion); 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Perform upgrade on each subscription's prefs. 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() { 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void runForSubscription(final int subId) { 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd factory.getSubscriptionPrefs(subId) 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .onUpgrade(existingVersion, targetVersion); 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd factory.getApplicationPrefs().putInt(BuglePrefsKeys.SHARED_PREFERENCES_VERSION, 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd targetVersion); 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final Exception ex) { 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Upgrade failed. Don't crash the app because we can always fall back to the 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // default settings. 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(LogUtil.BUGLE_TAG, "Failed to upgrade shared prefs", ex); 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (targetVersion < existingVersion) { 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We don't care about downgrade since real user shouldn't encounter this, so log it 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // and ignore any prefs migration. 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(LogUtil.BUGLE_TAG, "Shared prefs downgrade requested and ignored. " + 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd "oldVersion = " + existingVersion + ", newVersion = " + targetVersion); 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 263