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