LauncherAppState.java revision e26d1008eb587303db25797ca02cc32464e45656
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.content.BroadcastReceiver; 20import android.content.Context; 21import android.content.Intent; 22import android.content.IntentFilter; 23import android.util.Log; 24 25import com.android.launcher3.compat.LauncherAppsCompat; 26import com.android.launcher3.compat.PackageInstallerCompat; 27import com.android.launcher3.compat.UserManagerCompat; 28import com.android.launcher3.config.ProviderConfig; 29import com.android.launcher3.dynamicui.ExtractionUtils; 30import com.android.launcher3.logging.FileLog; 31import com.android.launcher3.util.ConfigMonitor; 32import com.android.launcher3.util.TestingUtils; 33import com.android.launcher3.util.Thunk; 34 35import java.lang.ref.WeakReference; 36 37public class LauncherAppState { 38 39 public static final boolean PROFILE_STARTUP = ProviderConfig.IS_DOGFOOD_BUILD; 40 41 private final AppFilter mAppFilter; 42 @Thunk final LauncherModel mModel; 43 private final IconCache mIconCache; 44 private final WidgetPreviewLoader mWidgetCache; 45 46 @Thunk boolean mWallpaperChangedSinceLastCheck; 47 48 private static WeakReference<LauncherProvider> sLauncherProvider; 49 private static Context sContext; 50 51 private static LauncherAppState INSTANCE; 52 53 private InvariantDeviceProfile mInvariantDeviceProfile; 54 55 public static LauncherAppState getInstance() { 56 if (INSTANCE == null) { 57 INSTANCE = new LauncherAppState(); 58 } 59 return INSTANCE; 60 } 61 62 public static LauncherAppState getInstanceNoCreate() { 63 return INSTANCE; 64 } 65 66 public Context getContext() { 67 return sContext; 68 } 69 70 static void setLauncherProvider(LauncherProvider provider) { 71 if (sLauncherProvider != null) { 72 Log.w(Launcher.TAG, "setLauncherProvider called twice! old=" + 73 sLauncherProvider.get() + " new=" + provider); 74 } 75 sLauncherProvider = new WeakReference<>(provider); 76 77 // The content provider exists for the entire duration of the launcher main process and 78 // is the first component to get created. Initializing application context here ensures 79 // that LauncherAppState always exists in the main process. 80 sContext = provider.getContext().getApplicationContext(); 81 FileLog.setDir(sContext.getFilesDir()); 82 } 83 84 private LauncherAppState() { 85 if (sContext == null) { 86 throw new IllegalStateException("LauncherAppState inited before app context set"); 87 } 88 89 Log.v(Launcher.TAG, "LauncherAppState inited"); 90 91 if (TestingUtils.MEMORY_DUMP_ENABLED) { 92 TestingUtils.startTrackingMemory(sContext); 93 } 94 95 mInvariantDeviceProfile = new InvariantDeviceProfile(sContext); 96 mIconCache = new IconCache(sContext, mInvariantDeviceProfile); 97 mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache); 98 99 mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class)); 100 mModel = new LauncherModel(this, mIconCache, mAppFilter); 101 102 LauncherAppsCompat.getInstance(sContext).addOnAppsChangedCallback(mModel); 103 104 // Register intent receivers 105 IntentFilter filter = new IntentFilter(); 106 filter.addAction(Intent.ACTION_LOCALE_CHANGED); 107 // For handling managed profiles 108 filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED); 109 filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED); 110 filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_AVAILABLE); 111 filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_UNAVAILABLE); 112 // For extracting colors from the wallpaper 113 if (Utilities.isNycOrAbove()) { 114 // TODO: add a broadcast entry to the manifest for pre-N. 115 filter.addAction(Intent.ACTION_WALLPAPER_CHANGED); 116 } 117 118 sContext.registerReceiver(mModel, filter); 119 UserManagerCompat.getInstance(sContext).enableAndResetCache(); 120 if (!Utilities.ATLEAST_KITKAT) { 121 sContext.registerReceiver(new BroadcastReceiver() { 122 123 @Override 124 public void onReceive(Context context, Intent intent) { 125 mWallpaperChangedSinceLastCheck = true; 126 } 127 }, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); 128 } 129 new ConfigMonitor(sContext).register(); 130 131 ExtractionUtils.startColorExtractionServiceIfNecessary(sContext); 132 } 133 134 /** 135 * Call from Application.onTerminate(), which is not guaranteed to ever be called. 136 */ 137 public void onTerminate() { 138 sContext.unregisterReceiver(mModel); 139 final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext); 140 launcherApps.removeOnAppsChangedCallback(mModel); 141 PackageInstallerCompat.getInstance(sContext).onStop(); 142 } 143 144 /** 145 * Reloads the workspace items from the DB and re-binds the workspace. This should generally 146 * not be called as DB updates are automatically followed by UI update 147 */ 148 public void reloadWorkspace() { 149 mModel.resetLoadedState(false, true); 150 mModel.startLoaderFromBackground(); 151 } 152 153 LauncherModel setLauncher(Launcher launcher) { 154 sLauncherProvider.get().setLauncherProviderChangeListener(launcher); 155 mModel.initialize(launcher); 156 return mModel; 157 } 158 159 public IconCache getIconCache() { 160 return mIconCache; 161 } 162 163 public LauncherModel getModel() { 164 return mModel; 165 } 166 167 public WidgetPreviewLoader getWidgetCache() { 168 return mWidgetCache; 169 } 170 171 public boolean hasWallpaperChangedSinceLastCheck() { 172 boolean result = mWallpaperChangedSinceLastCheck; 173 mWallpaperChangedSinceLastCheck = false; 174 return result; 175 } 176 177 public InvariantDeviceProfile getInvariantDeviceProfile() { 178 return mInvariantDeviceProfile; 179 } 180} 181