LauncherAppState.java revision b9eb2865af05d9ade572e71934a9e6a50421aa7d
1cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler/* 2cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Copyright (C) 2013 The Android Open Source Project 3cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * 4cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License"); 5cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * you may not use this file except in compliance with the License. 6cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * You may obtain a copy of the License at 7cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * 8cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * http://www.apache.org/licenses/LICENSE-2.0 9cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * 10cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Unless required by applicable law or agreed to in writing, software 11cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS, 12cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * See the License for the specific language governing permissions and 14cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * limitations under the License. 15cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler */ 16cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 17cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerpackage com.android.launcher3; 18cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 19cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.app.SearchManager; 20b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.content.*; 21cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.content.res.Configuration; 22cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.database.ContentObserver; 23a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport android.net.Uri; 24a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport android.os.Debug; 25a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport android.os.Environment; 26cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.os.Handler; 27b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.os.IBinder; 28b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.util.Log; 29cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 30a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport java.io.File; 31a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport java.io.IOException; 32cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport java.lang.ref.WeakReference; 33a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport java.util.ArrayList; 34cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 35cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerpublic class LauncherAppState { 36cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private Context mContext; 37cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private LauncherModel mModel; 38cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private IconCache mIconCache; 39cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb; 40cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private static boolean sIsScreenLarge; 41cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private static float sScreenDensity; 42cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private static int sLongPressTimeout = 300; 43cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private static final String sSharedPreferencesKey = "com.android.launcher3.prefs"; 44c6e2f94fbace46b11d0ee57fed16c327d83262d4Bjorn Bringert private long mStarttime; 45cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 46924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler WeakReference<LauncherProvider> mLauncherProvider; 47cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 48cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private static final LauncherAppState INSTANCE = new LauncherAppState(); 49cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 50cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static LauncherAppState getInstance() { 51cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return INSTANCE; 52cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 53cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 54cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static void init(Context context) { 55cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler INSTANCE.initialize(context); 56cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 57cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 58cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public Context getContext() { 59cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mContext; 60cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 61cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 62cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private LauncherAppState() { } 63cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 64cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private void initialize(Context context) { 65b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler Log.v(Launcher.TAG, "LauncherAppState initialize() called in process " + android.os.Process.myPid()); 66b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler 67cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mContext = context; 68cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 69c6e2f94fbace46b11d0ee57fed16c327d83262d4Bjorn Bringert mStarttime = System.currentTimeMillis(); 70924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler 71b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler if (context.getResources().getBoolean(R.bool.debug_memory_enabled)) { 72b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler context.startService(new Intent(context, MemoryTracker.class) 73b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler .setAction(MemoryTracker.ACTION_START_TRACKING) 74b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler .putExtra("pid", android.os.Process.myPid()) 75b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler .putExtra("name", "L") 76b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler ); 77b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler } 78b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler 79b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler 80cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // set sIsScreenXLarge and sScreenDensity *before* creating icon cache 81cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler sIsScreenLarge = context.getResources().getBoolean(R.bool.is_large_screen); 82cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler sScreenDensity = context.getResources().getDisplayMetrics().density; 83cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 84cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mWidgetPreviewCacheDb = new WidgetPreviewLoader.CacheDb(context); 85cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mIconCache = new IconCache(context); 86cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel = new LauncherModel(context, mIconCache); 87cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 88cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // Register intent receivers 89cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 90cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 91cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 92cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addDataScheme("package"); 93cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler context.registerReceiver(mModel, filter); 94cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter = new IntentFilter(); 95cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 96cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 97cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_LOCALE_CHANGED); 98cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 99cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler context.registerReceiver(mModel, filter); 100cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter = new IntentFilter(); 101cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 102cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler context.registerReceiver(mModel, filter); 103cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter = new IntentFilter(); 104cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); 105cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler context.registerReceiver(mModel, filter); 106cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 107cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // Register for changes to the favorites 108cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler ContentResolver resolver = context.getContentResolver(); 109cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, 110cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mFavoritesObserver); 111cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 112cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 113cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler /** 114cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Call from Application.onTerminate(), which is not guaranteed to ever be called. 115cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler */ 116cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public void onTerminate() { 117cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mContext.unregisterReceiver(mModel); 118cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 119cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler ContentResolver resolver = mContext.getContentResolver(); 120cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler resolver.unregisterContentObserver(mFavoritesObserver); 121cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 122cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 123cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler /** 124cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Receives notifications whenever the user favorites have changed. 125cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler */ 126cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) { 127cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler @Override 128cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public void onChange(boolean selfChange) { 129cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // If the database has ever changed, then we really need to force a reload of the 130cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // workspace on the next load 131cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel.resetLoadedState(false, true); 132cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel.startLoaderFromBackground(); 133cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 134cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler }; 135cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 136cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherModel setLauncher(Launcher launcher) { 137cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel.initialize(launcher); 138cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mModel; 139cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 140cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 141cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler IconCache getIconCache() { 142cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mIconCache; 143cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 144cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 145cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherModel getModel() { 146cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mModel; 147cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 148cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 149cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler WidgetPreviewLoader.CacheDb getWidgetPreviewCacheDb() { 150cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mWidgetPreviewCacheDb; 151cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 152cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 153924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler void setLauncherProvider(LauncherProvider provider) { 154cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mLauncherProvider = new WeakReference<LauncherProvider>(provider); 155cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 156cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 157cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherProvider getLauncherProvider() { 158cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mLauncherProvider.get(); 159cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 160cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 161924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler /** 162924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler * @return Milliseconds since the application state was created. 163924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler */ 164924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler public long getUptime() { 165c6e2f94fbace46b11d0ee57fed16c327d83262d4Bjorn Bringert return System.currentTimeMillis() - mStarttime; 166924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler } 167924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler 168cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static String getSharedPreferencesKey() { 169cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return sSharedPreferencesKey; 170cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 171cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 172cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static boolean isScreenLarge() { 173cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return sIsScreenLarge; 174cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 175cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 176cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static boolean isScreenLandscape(Context context) { 177cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return context.getResources().getConfiguration().orientation == 178cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler Configuration.ORIENTATION_LANDSCAPE; 179cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 180cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 181cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static float getScreenDensity() { 182cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return sScreenDensity; 183cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 184cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 185cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static int getLongPressTimeout() { 186cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return sLongPressTimeout; 187cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 188cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler} 189