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