LauncherAppState.java revision e060b0b3c72b93b47031f0f33bf18b121fb99333
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; 23cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.os.Handler; 24b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.util.Log; 25cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 26cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport java.lang.ref.WeakReference; 27cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 28cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerpublic class LauncherAppState { 29e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs"; 30e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler 31cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private LauncherModel mModel; 32cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private IconCache mIconCache; 33cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb; 34e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private boolean mIsScreenLarge; 35e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private float mScreenDensity; 36e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private int mLongPressTimeout = 300; 37cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 38e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private static WeakReference<LauncherProvider> sLauncherProvider; 39e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private static Context sContext; 40cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 41e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private static Object mLock = new Object(); 42e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private static LauncherAppState INSTANCE; 43cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 44cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static LauncherAppState getInstance() { 45e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler if (INSTANCE == null) { 46e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler INSTANCE = new LauncherAppState(); 47e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler } 48cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return INSTANCE; 49cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 50cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 51cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public Context getContext() { 52e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler return sContext; 53cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 54cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 55e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler public static void setApplicationContext(Context context) { 56e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler if (sContext != null) { 57e060b0b3c72b93b47031f0f33bf18b121fb99333Daniel Sandler Log.w(Launcher.TAG, "setApplicationContext called twice! old=" + sContext + " new=" + context); 58e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler } 59e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sContext = context.getApplicationContext(); 60e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler } 61b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler 62e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler private LauncherAppState() { 63e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler if (sContext == null) { 64e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler throw new IllegalStateException("LauncherAppState inited before app context set"); 65e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler } 66cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 67e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler Log.v(Launcher.TAG, "LauncherAppState inited"); 68924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler 69e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler if (sContext.getResources().getBoolean(R.bool.debug_memory_enabled)) { 70e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler MemoryTracker.startTrackingMe(sContext, "L"); 71b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler } 72b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler 73e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler // set sIsScreenXLarge and mScreenDensity *before* creating icon cache 74e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mIsScreenLarge = sContext.getResources().getBoolean(R.bool.is_large_screen); 75e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mScreenDensity = sContext.getResources().getDisplayMetrics().density; 76b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler 77e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mWidgetPreviewCacheDb = new WidgetPreviewLoader.CacheDb(sContext); 78e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mIconCache = new IconCache(sContext); 79e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mModel = new LauncherModel(this, mIconCache); 80cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 81cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // Register intent receivers 82cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 83cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 84cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 85cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addDataScheme("package"); 86e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sContext.registerReceiver(mModel, filter); 87cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter = new IntentFilter(); 88cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 89cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 90cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_LOCALE_CHANGED); 91cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 92e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sContext.registerReceiver(mModel, filter); 93cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter = new IntentFilter(); 94cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 95e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sContext.registerReceiver(mModel, filter); 96cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter = new IntentFilter(); 97cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); 98e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sContext.registerReceiver(mModel, filter); 99cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 100cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // Register for changes to the favorites 101e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler ContentResolver resolver = sContext.getContentResolver(); 102cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, 103cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mFavoritesObserver); 104cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 105cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 106cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler /** 107cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Call from Application.onTerminate(), which is not guaranteed to ever be called. 108cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler */ 109cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public void onTerminate() { 110e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sContext.unregisterReceiver(mModel); 111cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 112e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler ContentResolver resolver = sContext.getContentResolver(); 113cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler resolver.unregisterContentObserver(mFavoritesObserver); 114cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 115cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 116cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler /** 117cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Receives notifications whenever the user favorites have changed. 118cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler */ 119cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) { 120cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler @Override 121cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public void onChange(boolean selfChange) { 122cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // If the database has ever changed, then we really need to force a reload of the 123cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // workspace on the next load 124cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel.resetLoadedState(false, true); 125cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel.startLoaderFromBackground(); 126cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 127cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler }; 128cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 129cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherModel setLauncher(Launcher launcher) { 130e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler if (mModel == null) { 131e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler throw new IllegalStateException("setLauncher() called before init()"); 132e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler } 133cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mModel.initialize(launcher); 134cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mModel; 135cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 136cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 137cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler IconCache getIconCache() { 138cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mIconCache; 139cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 140cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 141cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherModel getModel() { 142cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mModel; 143cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 144cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 145cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler WidgetPreviewLoader.CacheDb getWidgetPreviewCacheDb() { 146cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return mWidgetPreviewCacheDb; 147cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 148cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 149e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler static void setLauncherProvider(LauncherProvider provider) { 150e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler sLauncherProvider = new WeakReference<LauncherProvider>(provider); 151cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 152cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 153e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler static LauncherProvider getLauncherProvider() { 154e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler return sLauncherProvider.get(); 155924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler } 156924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler 157cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static String getSharedPreferencesKey() { 158e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler return SHARED_PREFERENCES_KEY; 159cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 160cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 161e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler public boolean isScreenLarge() { 162e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler return mIsScreenLarge; 163cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 164cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 165cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler public static boolean isScreenLandscape(Context context) { 166cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler return context.getResources().getConfiguration().orientation == 167cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler Configuration.ORIENTATION_LANDSCAPE; 168cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 169cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 170e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler public float getScreenDensity() { 171e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler return mScreenDensity; 172cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 173cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler 174e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler public int getLongPressTimeout() { 175e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler return mLongPressTimeout; 176cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler } 177cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler} 178