LauncherAppState.java revision 2003c75ac43ecd66ee8a89142b7969feb993abe7
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.ComponentName; 21import android.content.Context; 22import android.content.Intent; 23import android.content.IntentFilter; 24import android.util.Log; 25 26import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; 27import com.android.launcher3.compat.LauncherAppsCompat; 28import com.android.launcher3.compat.PackageInstallerCompat; 29import com.android.launcher3.util.Thunk; 30 31import java.lang.ref.WeakReference; 32 33public class LauncherAppState { 34 35 private final AppFilter mAppFilter; 36 private final BuildInfo mBuildInfo; 37 @Thunk final LauncherModel mModel; 38 private final IconCache mIconCache; 39 private final WidgetPreviewLoader mWidgetCache; 40 41 private boolean mWallpaperChangedSinceLastCheck; 42 43 private static WeakReference<LauncherProvider> sLauncherProvider; 44 private static Context sContext; 45 46 private static LauncherAppState INSTANCE; 47 48 private InvariantDeviceProfile mInvariantDeviceProfile; 49 50 private LauncherAccessibilityDelegate mAccessibilityDelegate; 51 52 public static LauncherAppState getInstance() { 53 if (INSTANCE == null) { 54 INSTANCE = new LauncherAppState(); 55 } 56 return INSTANCE; 57 } 58 59 public static LauncherAppState getInstanceNoCreate() { 60 return INSTANCE; 61 } 62 63 public Context getContext() { 64 return sContext; 65 } 66 67 public static void setApplicationContext(Context context) { 68 if (sContext != null) { 69 Log.w(Launcher.TAG, "setApplicationContext called twice! old=" + sContext + " new=" + context); 70 } 71 sContext = context.getApplicationContext(); 72 } 73 74 private LauncherAppState() { 75 if (sContext == null) { 76 throw new IllegalStateException("LauncherAppState inited before app context set"); 77 } 78 79 Log.v(Launcher.TAG, "LauncherAppState inited"); 80 81 if (sContext.getResources().getBoolean(R.bool.debug_memory_enabled)) { 82 MemoryTracker.startTrackingMe(sContext, "L"); 83 } 84 85 mInvariantDeviceProfile = new InvariantDeviceProfile(sContext); 86 mIconCache = new IconCache(sContext, mInvariantDeviceProfile); 87 mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache); 88 89 mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class)); 90 mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class)); 91 mModel = new LauncherModel(this, mIconCache, mAppFilter); 92 93 LauncherAppsCompat.getInstance(sContext).addOnAppsChangedCallback(mModel); 94 95 // Register intent receivers 96 IntentFilter filter = new IntentFilter(); 97 filter.addAction(Intent.ACTION_LOCALE_CHANGED); 98 filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 99 filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); 100 // For handling managed profiles 101 filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED); 102 filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED); 103 104 sContext.registerReceiver(mModel, filter); 105 } 106 107 /** 108 * Call from Application.onTerminate(), which is not guaranteed to ever be called. 109 */ 110 public void onTerminate() { 111 sContext.unregisterReceiver(mModel); 112 final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext); 113 launcherApps.removeOnAppsChangedCallback(mModel); 114 PackageInstallerCompat.getInstance(sContext).onStop(); 115 } 116 117 /** 118 * Reloads the workspace items from the DB and re-binds the workspace. This should generally 119 * not be called as DB updates are automatically followed by UI update 120 */ 121 public void reloadWorkspace() { 122 mModel.resetLoadedState(false, true); 123 mModel.startLoaderFromBackground(); 124 } 125 126 LauncherModel setLauncher(Launcher launcher) { 127 getLauncherProvider().setLauncherProviderChangeListener(launcher); 128 mModel.initialize(launcher); 129 mAccessibilityDelegate = ((launcher != null) && Utilities.isLmpOrAbove()) ? 130 new LauncherAccessibilityDelegate(launcher) : null; 131 return mModel; 132 } 133 134 public LauncherAccessibilityDelegate getAccessibilityDelegate() { 135 return mAccessibilityDelegate; 136 } 137 138 public IconCache getIconCache() { 139 return mIconCache; 140 } 141 142 public LauncherModel getModel() { 143 return mModel; 144 } 145 146 /** 147 * TODO(winsonc, hyunyoungs): We need to respect this 148 */ 149 boolean shouldShowAppOrWidgetProvider(ComponentName componentName) { 150 return mAppFilter == null || mAppFilter.shouldShowApp(componentName); 151 } 152 153 static void setLauncherProvider(LauncherProvider provider) { 154 sLauncherProvider = new WeakReference<LauncherProvider>(provider); 155 } 156 157 static LauncherProvider getLauncherProvider() { 158 return sLauncherProvider.get(); 159 } 160 161 public static String getSharedPreferencesKey() { 162 return LauncherFiles.SHARED_PREFERENCES_KEY; 163 } 164 165 public WidgetPreviewLoader getWidgetCache() { 166 return mWidgetCache; 167 } 168 169 public void onWallpaperChanged() { 170 mWallpaperChangedSinceLastCheck = true; 171 } 172 173 public boolean hasWallpaperChangedSinceLastCheck() { 174 boolean result = mWallpaperChangedSinceLastCheck; 175 mWallpaperChangedSinceLastCheck = false; 176 return result; 177 } 178 179 public InvariantDeviceProfile getInvariantDeviceProfile() { 180 return mInvariantDeviceProfile; 181 } 182 183 public static boolean isDogfoodBuild() { 184 return getInstance().mBuildInfo.isDogfoodBuild(); 185 } 186} 187