LauncherAppState.java revision b9eb2865af05d9ade572e71934a9e6a50421aa7d
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;
20b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.content.*;
21cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.content.res.Configuration;
22cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.database.ContentObserver;
23a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport android.net.Uri;
24a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport android.os.Debug;
25a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport android.os.Environment;
26cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport android.os.Handler;
27b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.os.IBinder;
28b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandlerimport android.util.Log;
29cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
30a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport java.io.File;
31a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport java.io.IOException;
32cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerimport java.lang.ref.WeakReference;
33a127b7ad151dd1ae66d665a073e98984930c3d9dDaniel Sandlerimport java.util.ArrayList;
34cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
35cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandlerpublic class LauncherAppState {
36cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private Context mContext;
37cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private LauncherModel mModel;
38cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private IconCache mIconCache;
39cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb;
40cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private static boolean sIsScreenLarge;
41cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private static float sScreenDensity;
42cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private static int sLongPressTimeout = 300;
43cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private static final String sSharedPreferencesKey = "com.android.launcher3.prefs";
44c6e2f94fbace46b11d0ee57fed16c327d83262d4Bjorn Bringert    private long mStarttime;
45cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
46924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler    WeakReference<LauncherProvider> mLauncherProvider;
47cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
48cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private static final LauncherAppState INSTANCE = new LauncherAppState();
49cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
50cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static LauncherAppState getInstance() {
51cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return INSTANCE;
52cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
53cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
54cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static void init(Context context) {
55cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        INSTANCE.initialize(context);
56cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
57cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
58cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public Context getContext() {
59cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mContext;
60cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
61cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
62cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private LauncherAppState() { }
63cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
64cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private void initialize(Context context) {
65b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler        Log.v(Launcher.TAG, "LauncherAppState initialize() called in process " + android.os.Process.myPid());
66b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler
67cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mContext = context;
68cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
69c6e2f94fbace46b11d0ee57fed16c327d83262d4Bjorn Bringert        mStarttime = System.currentTimeMillis();
70924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler
71b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler        if (context.getResources().getBoolean(R.bool.debug_memory_enabled)) {
72b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler            context.startService(new Intent(context, MemoryTracker.class)
73b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler                    .setAction(MemoryTracker.ACTION_START_TRACKING)
74b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler                    .putExtra("pid", android.os.Process.myPid())
75b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler                    .putExtra("name", "L")
76b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler                    );
77b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler        }
78b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler
79b9eb2865af05d9ade572e71934a9e6a50421aa7dDaniel Sandler
80cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        // set sIsScreenXLarge and sScreenDensity *before* creating icon cache
81cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        sIsScreenLarge = context.getResources().getBoolean(R.bool.is_large_screen);
82cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        sScreenDensity = context.getResources().getDisplayMetrics().density;
83cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
84cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mWidgetPreviewCacheDb = new WidgetPreviewLoader.CacheDb(context);
85cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mIconCache = new IconCache(context);
86cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mModel = new LauncherModel(context, mIconCache);
87cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
88cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        // Register intent receivers
89cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
90cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
91cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
92cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addDataScheme("package");
93cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        context.registerReceiver(mModel, filter);
94cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter = new IntentFilter();
95cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
96cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
97cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
98cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
99cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        context.registerReceiver(mModel, filter);
100cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter = new IntentFilter();
101cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
102cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        context.registerReceiver(mModel, filter);
103cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter = new IntentFilter();
104cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
105cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        context.registerReceiver(mModel, filter);
106cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
107cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        // Register for changes to the favorites
108cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        ContentResolver resolver = context.getContentResolver();
109cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true,
110cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler                mFavoritesObserver);
111cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
112cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
113cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    /**
114cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     * Call from Application.onTerminate(), which is not guaranteed to ever be called.
115cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     */
116cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public void onTerminate() {
117cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mContext.unregisterReceiver(mModel);
118cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
119cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        ContentResolver resolver = mContext.getContentResolver();
120cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        resolver.unregisterContentObserver(mFavoritesObserver);
121cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
122cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
123cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    /**
124cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     * Receives notifications whenever the user favorites have changed.
125cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler     */
126cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) {
127cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        @Override
128cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        public void onChange(boolean selfChange) {
129cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler            // If the database has ever changed, then we really need to force a reload of the
130cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler            // workspace on the next load
131cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler            mModel.resetLoadedState(false, true);
132cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler            mModel.startLoaderFromBackground();
133cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        }
134cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    };
135cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
136cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    LauncherModel setLauncher(Launcher launcher) {
137cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mModel.initialize(launcher);
138cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mModel;
139cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
140cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
141cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    IconCache getIconCache() {
142cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mIconCache;
143cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
144cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
145cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    LauncherModel getModel() {
146cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mModel;
147cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
148cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
149cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    WidgetPreviewLoader.CacheDb getWidgetPreviewCacheDb() {
150cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mWidgetPreviewCacheDb;
151cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
152cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
153924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler    void setLauncherProvider(LauncherProvider provider) {
154cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        mLauncherProvider = new WeakReference<LauncherProvider>(provider);
155cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
156cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
157cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    LauncherProvider getLauncherProvider() {
158cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return mLauncherProvider.get();
159cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
160cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
161924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler    /**
162924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler     * @return Milliseconds since the application state was created.
163924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler     */
164924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler    public long getUptime() {
165c6e2f94fbace46b11d0ee57fed16c327d83262d4Bjorn Bringert        return System.currentTimeMillis() - mStarttime;
166924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler    }
167924b993c750e6de8537afb750c2d2b9932efbdacDaniel Sandler
168cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static String getSharedPreferencesKey() {
169cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return sSharedPreferencesKey;
170cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
171cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
172cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static boolean isScreenLarge() {
173cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return sIsScreenLarge;
174cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
175cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
176cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static boolean isScreenLandscape(Context context) {
177cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return context.getResources().getConfiguration().orientation ==
178cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler            Configuration.ORIENTATION_LANDSCAPE;
179cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
180cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
181cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static float getScreenDensity() {
182cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return sScreenDensity;
183cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
184cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler
185cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    public static int getLongPressTimeout() {
186cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler        return sLongPressTimeout;
187cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler    }
188cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler}
189