1cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler/*
2cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Copyright (C) 2013 The Android Open Source Project
3cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler *
4cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License");
5cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * you may not use this file except in compliance with the License.
6cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * You may obtain a copy of the License at
7cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler *
8cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler *      http://www.apache.org/licenses/LICENSE-2.0
9cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler *
10cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * Unless required by applicable law or agreed to in writing, software
11cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS,
12cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * See the License for the specific language governing permissions and
14cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler * limitations under the License.
15cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler */
16cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
17cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerpackage com.android.launcher3;
18cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
19cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.app.SearchManager;
20e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.Context;
21e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.Intent;
22e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.IntentFilter;
23823fd5090209017a029460e7dbd8ab9d51d013ddSunny Goyalimport android.os.UserManager;
24b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.util.Log;
2571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
2683a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
27ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherAppsCompat;
284390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat;
29823fd5090209017a029460e7dbd8ab9d51d013ddSunny Goyalimport com.android.launcher3.compat.UserManagerCompat;
30091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
3171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
32cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport java.lang.ref.WeakReference;
33cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
34c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyalpublic class LauncherAppState {
35aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren
3616f3ea870aac47292cd6cbe1a4b4343173097aa9Nilesh Agrawal    private final AppFilter mAppFilter;
3716f3ea870aac47292cd6cbe1a4b4343173097aa9Nilesh Agrawal    private final BuildInfo mBuildInfo;
38091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk final LauncherModel mModel;
39e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal    private final IconCache mIconCache;
405b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal    private final WidgetPreviewLoader mWidgetCache;
41e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal
42a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka    private boolean mWallpaperChangedSinceLastCheck;
43cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
44e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    private static WeakReference<LauncherProvider> sLauncherProvider;
45e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    private static Context sContext;
46cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
47e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    private static LauncherAppState INSTANCE;
48cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
492e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen    private InvariantDeviceProfile mInvariantDeviceProfile;
507779d62308b87ca26e3be47df836893f6f7693ecSunny Goyal
51c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    private LauncherAccessibilityDelegate mAccessibilityDelegate;
525f8afe6280eae34620067696173e71943e1a30a3Winson Chung
53cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static LauncherAppState getInstance() {
54e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        if (INSTANCE == null) {
55e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler            INSTANCE = new LauncherAppState();
56e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        }
57cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return INSTANCE;
58cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
59cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
60d8fe6de10d5ffc293f771b070bd1361a027757bbChris Wren    public static LauncherAppState getInstanceNoCreate() {
61d8fe6de10d5ffc293f771b070bd1361a027757bbChris Wren        return INSTANCE;
62d8fe6de10d5ffc293f771b070bd1361a027757bbChris Wren    }
63d8fe6de10d5ffc293f771b070bd1361a027757bbChris Wren
64cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public Context getContext() {
65e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        return sContext;
66cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
67cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
68e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    public static void setApplicationContext(Context context) {
69e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        if (sContext != null) {
70e060b0b3c72b93b47031f0f33bf18b121fb99333Daniel Sandler            Log.w(Launcher.TAG, "setApplicationContext called twice! old=" + sContext + " new=" + context);
71e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        }
72e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        sContext = context.getApplicationContext();
73e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    }
74b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler
75e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    private LauncherAppState() {
76e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        if (sContext == null) {
77e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler            throw new IllegalStateException("LauncherAppState inited before app context set");
78e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        }
79cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
80e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        Log.v(Launcher.TAG, "LauncherAppState inited");
81924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler
82e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        if (sContext.getResources().getBoolean(R.bool.debug_memory_enabled)) {
83e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler            MemoryTracker.startTrackingMe(sContext, "L");
84b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler        }
85b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler
862e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen        mInvariantDeviceProfile = new InvariantDeviceProfile(sContext);
872e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen        mIconCache = new IconCache(sContext, mInvariantDeviceProfile);
88383c507c47a5abf3258fc04220f37c366f983a97Sunny Goyal        mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache);
891307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert
901307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert        mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class));
9116f3ea870aac47292cd6cbe1a4b4343173097aa9Nilesh Agrawal        mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class));
921307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert        mModel = new LauncherModel(this, mIconCache, mAppFilter);
9327595796b3c0373d1a1d56af9a30392bc7016624Sunny Goyal
9427595796b3c0373d1a1d56af9a30392bc7016624Sunny Goyal        LauncherAppsCompat.getInstance(sContext).addOnAppsChangedCallback(mModel);
95cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
96cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        // Register intent receivers
97ed13187a745866483139e2878037e1f8427ce567Kenny Guy        IntentFilter filter = new IntentFilter();
98cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
99cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
100957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal        // For handling managed profiles
101957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);
102957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);
103957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal
104e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        sContext.registerReceiver(mModel, filter);
105823fd5090209017a029460e7dbd8ab9d51d013ddSunny Goyal        UserManagerCompat.getInstance(sContext).enableAndResetCache();
106cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
1071317e2dd4a2fb097d1e54759536d515fdeca2c3eKenny Guy
108cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    /**
109cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     * Call from Application.onTerminate(), which is not guaranteed to ever be called.
110cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     */
111cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public void onTerminate() {
112e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        sContext.unregisterReceiver(mModel);
1131317e2dd4a2fb097d1e54759536d515fdeca2c3eKenny Guy        final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
114c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy        launcherApps.removeOnAppsChangedCallback(mModel);
1154390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal        PackageInstallerCompat.getInstance(sContext).onStop();
116cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
117cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
118cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    /**
1191d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal     * Reloads the workspace items from the DB and re-binds the workspace. This should generally
1201d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal     * not be called as DB updates are automatically followed by UI update
121cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     */
1221d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal    public void reloadWorkspace() {
1231d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal        mModel.resetLoadedState(false, true);
1241d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal        mModel.startLoaderFromBackground();
1251d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal    }
126cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
127cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    LauncherModel setLauncher(Launcher launcher) {
128383c507c47a5abf3258fc04220f37c366f983a97Sunny Goyal        getLauncherProvider().setLauncherProviderChangeListener(launcher);
129cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mModel.initialize(launcher);
1309fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        mAccessibilityDelegate = ((launcher != null) && Utilities.ATLEAST_LOLLIPOP) ?
13171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal            new LauncherAccessibilityDelegate(launcher) : null;
132cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mModel;
133cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
134cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
1353f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song    public LauncherAccessibilityDelegate getAccessibilityDelegate() {
13671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal        return mAccessibilityDelegate;
13771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal    }
13871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal
139349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal    public IconCache getIconCache() {
140cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mIconCache;
141cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
142cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
14318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal    public LauncherModel getModel() {
144cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mModel;
145cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
146cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
147e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler    static void setLauncherProvider(LauncherProvider provider) {
148e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        sLauncherProvider = new WeakReference<LauncherProvider>(provider);
149cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
150cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
151e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal    public static LauncherProvider getLauncherProvider() {
152e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler        return sLauncherProvider.get();
153924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler    }
154924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler
155cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static String getSharedPreferencesKey() {
15628db280b7af14614f2b168ea8c5d496cda650321Helena Josol        return LauncherFiles.SHARED_PREFERENCES_KEY;
157cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
158cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
1595b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal    public WidgetPreviewLoader getWidgetCache() {
1605b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal        return mWidgetCache;
1615b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal    }
1627501adf4b71bb17d0785a5939efbcac4b39125c3Winson Chung
163a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka    public void onWallpaperChanged() {
164a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka        mWallpaperChangedSinceLastCheck = true;
165a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka    }
166a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka
167a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka    public boolean hasWallpaperChangedSinceLastCheck() {
168a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka        boolean result = mWallpaperChangedSinceLastCheck;
169a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka        mWallpaperChangedSinceLastCheck = false;
170a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka        return result;
171a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka    }
172a6a0547fa6df0769fcd107a2e5f7c7d527fa0700Michael Jurka
1732e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen    public InvariantDeviceProfile getInvariantDeviceProfile() {
1742e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen        return mInvariantDeviceProfile;
1752e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen    }
1762e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen
177eedb00a674358bb88dce1e0d3a90bd6cb9e97cfcJorim Jaggi    public static boolean isDogfoodBuild() {
178eedb00a674358bb88dce1e0d3a90bd6cb9e97cfcJorim Jaggi        return getInstance().mBuildInfo.isDogfoodBuild();
179eedb00a674358bb88dce1e0d3a90bd6cb9e97cfcJorim Jaggi    }
180cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler}
181