LauncherAppState.java revision 892c74d460ad98c6306420e1127c9aa3e505ba25
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.launcher3; 18 19import android.app.SearchManager; 20import android.content.*; 21import android.content.res.Configuration; 22import android.content.res.Resources; 23import android.database.ContentObserver; 24import android.os.Handler; 25import android.provider.Settings; 26import android.util.Log; 27import android.view.Display; 28 29import java.lang.ref.WeakReference; 30 31public class LauncherAppState { 32 private static final String TAG = "LauncherAppState"; 33 private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs"; 34 35 private LauncherModel mModel; 36 private IconCache mIconCache; 37 private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb; 38 private boolean mIsScreenLarge; 39 private float mScreenDensity; 40 private int mLongPressTimeout = 300; 41 42 private static WeakReference<LauncherProvider> sLauncherProvider; 43 private static Context sContext; 44 45 private static Object mLock = new Object(); 46 private static LauncherAppState INSTANCE; 47 48 private DynamicGrid mDynamicGrid; 49 50 public static LauncherAppState getInstance() { 51 if (INSTANCE == null) { 52 INSTANCE = new LauncherAppState(); 53 } 54 return INSTANCE; 55 } 56 57 public Context getContext() { 58 return sContext; 59 } 60 61 public static void setApplicationContext(Context context) { 62 if (sContext != null) { 63 Log.w(Launcher.TAG, "setApplicationContext called twice! old=" + sContext + " new=" + context); 64 } 65 sContext = context.getApplicationContext(); 66 } 67 68 private LauncherAppState() { 69 if (sContext == null) { 70 throw new IllegalStateException("LauncherAppState inited before app context set"); 71 } 72 73 Log.v(Launcher.TAG, "LauncherAppState inited"); 74 75 if (sContext.getResources().getBoolean(R.bool.debug_memory_enabled)) { 76 MemoryTracker.startTrackingMe(sContext, "L"); 77 } 78 79 // set sIsScreenXLarge and mScreenDensity *before* creating icon cache 80 mIsScreenLarge = isScreenLarge(sContext.getResources()); 81 mScreenDensity = sContext.getResources().getDisplayMetrics().density; 82 83 mWidgetPreviewCacheDb = new WidgetPreviewLoader.CacheDb(sContext); 84 mIconCache = new IconCache(sContext); 85 mModel = new LauncherModel(this, mIconCache); 86 87 // Register intent receivers 88 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 89 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 90 filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 91 filter.addDataScheme("package"); 92 sContext.registerReceiver(mModel, filter); 93 filter = new IntentFilter(); 94 filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 95 filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 96 filter.addAction(Intent.ACTION_LOCALE_CHANGED); 97 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 98 sContext.registerReceiver(mModel, filter); 99 filter = new IntentFilter(); 100 filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 101 sContext.registerReceiver(mModel, filter); 102 filter = new IntentFilter(); 103 filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); 104 sContext.registerReceiver(mModel, filter); 105 106 // Register for changes to the favorites 107 ContentResolver resolver = sContext.getContentResolver(); 108 resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, 109 mFavoritesObserver); 110 } 111 112 /** 113 * Call from Application.onTerminate(), which is not guaranteed to ever be called. 114 */ 115 public void onTerminate() { 116 sContext.unregisterReceiver(mModel); 117 118 ContentResolver resolver = sContext.getContentResolver(); 119 resolver.unregisterContentObserver(mFavoritesObserver); 120 } 121 122 /** 123 * Receives notifications whenever the user favorites have changed. 124 */ 125 private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) { 126 @Override 127 public void onChange(boolean selfChange) { 128 // If the database has ever changed, then we really need to force a reload of the 129 // workspace on the next load 130 mModel.resetLoadedState(false, true); 131 mModel.startLoaderFromBackground(); 132 } 133 }; 134 135 LauncherModel setLauncher(Launcher launcher) { 136 if (mModel == null) { 137 throw new IllegalStateException("setLauncher() called before init()"); 138 } 139 mModel.initialize(launcher); 140 return mModel; 141 } 142 143 IconCache getIconCache() { 144 return mIconCache; 145 } 146 147 LauncherModel getModel() { 148 return mModel; 149 } 150 151 WidgetPreviewLoader.CacheDb getWidgetPreviewCacheDb() { 152 return mWidgetPreviewCacheDb; 153 } 154 155 static void setLauncherProvider(LauncherProvider provider) { 156 sLauncherProvider = new WeakReference<LauncherProvider>(provider); 157 } 158 159 static LauncherProvider getLauncherProvider() { 160 return sLauncherProvider.get(); 161 } 162 163 public static String getSharedPreferencesKey() { 164 return SHARED_PREFERENCES_KEY; 165 } 166 167 DeviceProfile initDynamicGrid(Context context, int minWidth, int minHeight, 168 int width, int height, 169 int availableWidth, int availableHeight) { 170 boolean created = false; 171 if (mDynamicGrid == null) { 172 mDynamicGrid = new DynamicGrid(context.getResources(), 173 minWidth, minHeight, width, height, 174 availableWidth, availableHeight); 175 created = true; 176 } 177 178 // Update the icon size 179 DeviceProfile grid = mDynamicGrid.getDeviceProfile(); 180 Utilities.setIconSize(grid.iconSizePx); 181 grid.updateFromConfiguration(context.getResources(), width, height, 182 availableWidth, availableHeight); 183 return grid; 184 } 185 DynamicGrid getDynamicGrid() { 186 return mDynamicGrid; 187 } 188 189 public boolean isScreenLarge() { 190 return mIsScreenLarge; 191 } 192 193 // Need a version that doesn't require an instance of LauncherAppState for the wallpaper picker 194 public static boolean isScreenLarge(Resources res) { 195 return res.getBoolean(R.bool.is_large_tablet); 196 } 197 198 public static boolean isScreenLandscape(Context context) { 199 return context.getResources().getConfiguration().orientation == 200 Configuration.ORIENTATION_LANDSCAPE; 201 } 202 203 public float getScreenDensity() { 204 return mScreenDensity; 205 } 206 207 public int getLongPressTimeout() { 208 return mLongPressTimeout; 209 } 210} 211