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.util.Log;
24 
25 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
26 import com.android.launcher3.compat.LauncherAppsCompat;
27 import com.android.launcher3.compat.PackageInstallerCompat;
28 import com.android.launcher3.compat.UserManagerCompat;
29 import com.android.launcher3.config.FeatureFlags;
30 import com.android.launcher3.util.ConfigMonitor;
31 import com.android.launcher3.util.TestingUtils;
32 import com.android.launcher3.util.Thunk;
33 
34 import java.lang.ref.WeakReference;
35 
36 public 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     private 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 
getInstance()54     public static LauncherAppState getInstance() {
55         if (INSTANCE == null) {
56             INSTANCE = new LauncherAppState();
57         }
58         return INSTANCE;
59     }
60 
getInstanceNoCreate()61     public static LauncherAppState getInstanceNoCreate() {
62         return INSTANCE;
63     }
64 
getContext()65     public Context getContext() {
66         return sContext;
67     }
68 
setApplicationContext(Context context)69     public static void setApplicationContext(Context context) {
70         if (sContext != null) {
71             Log.w(Launcher.TAG, "setApplicationContext called twice! old=" + sContext + " new=" + context);
72         }
73         sContext = context.getApplicationContext();
74     }
75 
LauncherAppState()76     private LauncherAppState() {
77         if (sContext == null) {
78             throw new IllegalStateException("LauncherAppState inited before app context set");
79         }
80 
81         Log.v(Launcher.TAG, "LauncherAppState inited");
82 
83         if (TestingUtils.MEMORY_DUMP_ENABLED) {
84             TestingUtils.startTrackingMemory(sContext);
85         }
86 
87         mInvariantDeviceProfile = new InvariantDeviceProfile(sContext);
88         mIconCache = new IconCache(sContext, mInvariantDeviceProfile);
89         mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache);
90 
91         mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_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         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_AVAILABLE);
104         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_UNAVAILABLE);
105 
106         sContext.registerReceiver(mModel, filter);
107         UserManagerCompat.getInstance(sContext).enableAndResetCache();
108         new ConfigMonitor(sContext).register();
109 
110         sContext.registerReceiver(
111                 new WallpaperChangedReceiver(), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
112     }
113 
114     /**
115      * Call from Application.onTerminate(), which is not guaranteed to ever be called.
116      */
onTerminate()117     public void onTerminate() {
118         sContext.unregisterReceiver(mModel);
119         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
120         launcherApps.removeOnAppsChangedCallback(mModel);
121         PackageInstallerCompat.getInstance(sContext).onStop();
122     }
123 
124     /**
125      * Reloads the workspace items from the DB and re-binds the workspace. This should generally
126      * not be called as DB updates are automatically followed by UI update
127      */
reloadWorkspace()128     public void reloadWorkspace() {
129         mModel.resetLoadedState(false, true);
130         mModel.startLoaderFromBackground();
131     }
132 
setLauncher(Launcher launcher)133     LauncherModel setLauncher(Launcher launcher) {
134         getLauncherProvider().setLauncherProviderChangeListener(launcher);
135         mModel.initialize(launcher);
136         mAccessibilityDelegate = ((launcher != null) && Utilities.ATLEAST_LOLLIPOP) ?
137             new LauncherAccessibilityDelegate(launcher) : null;
138         return mModel;
139     }
140 
getAccessibilityDelegate()141     public LauncherAccessibilityDelegate getAccessibilityDelegate() {
142         return mAccessibilityDelegate;
143     }
144 
getIconCache()145     public IconCache getIconCache() {
146         return mIconCache;
147     }
148 
getModel()149     public LauncherModel getModel() {
150         return mModel;
151     }
152 
setLauncherProvider(LauncherProvider provider)153     static void setLauncherProvider(LauncherProvider provider) {
154         sLauncherProvider = new WeakReference<LauncherProvider>(provider);
155     }
156 
getLauncherProvider()157     public static LauncherProvider getLauncherProvider() {
158         return sLauncherProvider.get();
159     }
160 
getWidgetCache()161     public WidgetPreviewLoader getWidgetCache() {
162         return mWidgetCache;
163     }
164 
onWallpaperChanged()165     public void onWallpaperChanged() {
166         mWallpaperChangedSinceLastCheck = true;
167     }
168 
hasWallpaperChangedSinceLastCheck()169     public boolean hasWallpaperChangedSinceLastCheck() {
170         boolean result = mWallpaperChangedSinceLastCheck;
171         mWallpaperChangedSinceLastCheck = false;
172         return result;
173     }
174 
getInvariantDeviceProfile()175     public InvariantDeviceProfile getInvariantDeviceProfile() {
176         return mInvariantDeviceProfile;
177     }
178 
isDogfoodBuild()179     public static boolean isDogfoodBuild() {
180         return FeatureFlags.IS_ALPHA_BUILD || FeatureFlags.IS_DEV_BUILD;
181     }
182 }
183