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