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