13069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk/* 23069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * Copyright (C) 2015 The Android Open Source Project 33069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * 43069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 53069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * you may not use this file except in compliance with the License. 63069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * You may obtain a copy of the License at 73069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * 83069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 93069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * 103069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * Unless required by applicable law or agreed to in writing, software 113069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 123069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * See the License for the specific language governing permissions and 143069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk * limitations under the License. 153069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk */ 163069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkpackage com.android.settings.dashboard; 173069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 183069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport android.app.Activity; 198ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.content.BroadcastReceiver; 20c06457326509ec625d90b26828d6cc1417f4d9a3Jason Monkimport android.content.ComponentName; 218ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.content.IntentFilter; 228ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.os.Bundle; 238ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.os.Handler; 248ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.os.HandlerThread; 258ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.os.Looper; 268ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monkimport android.os.Message; 275673ced93cda4a48872c1452122ee278da3aa17aJason Monkimport android.os.Process; 283069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport android.util.ArrayMap; 29a8a029f8eb8ca51a19ce20206ce307761cfd86baJason Monkimport android.util.ArraySet; 303069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport android.util.Log; 31011362d9f15a3acb96b59e833059825a232db133Fan Zhang 323069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport com.android.settings.SettingsActivity; 333069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport com.android.settingslib.drawer.DashboardCategory; 34011362d9f15a3acb96b59e833059825a232db133Fan Zhangimport com.android.settingslib.drawer.SettingsDrawerActivity; 35d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monkimport com.android.settingslib.drawer.Tile; 363069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 373069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport java.lang.reflect.Field; 383069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport java.util.ArrayList; 393069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkimport java.util.List; 403069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 413069581512bcb9687cb8d79675f6c4950c9ac087Jason Monkpublic class SummaryLoader { 423069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk private static final boolean DEBUG = DashboardSummary.DEBUG; 433069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk private static final String TAG = "SummaryLoader"; 443069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 458c4ca41d2595925d108dad82959faddb676a392dJason Monk public static final String SUMMARY_PROVIDER_FACTORY = "SUMMARY_PROVIDER_FACTORY"; 468c4ca41d2595925d108dad82959faddb676a392dJason Monk 473069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk private final Activity mActivity; 48c06457326509ec625d90b26828d6cc1417f4d9a3Jason Monk private final ArrayMap<SummaryProvider, ComponentName> mSummaryMap = new ArrayMap<>(); 49d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monk private final List<Tile> mTiles = new ArrayList<>(); 503069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 51fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk private final Worker mWorker; 52fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk private final Handler mHandler; 53fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk private final HandlerThread mWorkerThread; 54fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk 558c4ca41d2595925d108dad82959faddb676a392dJason Monk private DashboardAdapter mAdapter; 569425839379d862604d4b5a7b9161540f598f64f6Jason Monk private boolean mListening; 578d8de1490536468bbc1061abca0f78ab0b682b3bJason Monk private boolean mWorkerListening; 58a8a029f8eb8ca51a19ce20206ce307761cfd86baJason Monk private ArraySet<BroadcastReceiver> mReceivers = new ArraySet<>(); 593069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 60fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk public SummaryLoader(Activity activity, List<DashboardCategory> categories) { 61fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mHandler = new Handler(); 625673ced93cda4a48872c1452122ee278da3aa17aJason Monk mWorkerThread = new HandlerThread("SummaryLoader", Process.THREAD_PRIORITY_BACKGROUND); 63fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mWorkerThread.start(); 64fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mWorker = new Worker(mWorkerThread.getLooper()); 653069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk mActivity = activity; 663069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk for (int i = 0; i < categories.size(); i++) { 67d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monk List<Tile> tiles = categories.get(i).tiles; 683069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk for (int j = 0; j < tiles.size(); j++) { 69d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monk Tile tile = tiles.get(j); 70fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget(); 713069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 723069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 733069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 743069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 75fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk public void release() { 76816959889ef41012c86fd76bfc173b75d7150158Jason Monk mWorkerThread.quitSafely(); 779425839379d862604d4b5a7b9161540f598f64f6Jason Monk // Make sure we aren't listening. 789425839379d862604d4b5a7b9161540f598f64f6Jason Monk setListeningW(false); 79fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk } 80fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk 818c4ca41d2595925d108dad82959faddb676a392dJason Monk public void setAdapter(DashboardAdapter adapter) { 828c4ca41d2595925d108dad82959faddb676a392dJason Monk mAdapter = adapter; 838c4ca41d2595925d108dad82959faddb676a392dJason Monk } 848c4ca41d2595925d108dad82959faddb676a392dJason Monk 85fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk public void setSummary(SummaryProvider provider, final CharSequence summary) { 86c06457326509ec625d90b26828d6cc1417f4d9a3Jason Monk final ComponentName component= mSummaryMap.get(provider); 87fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mHandler.post(new Runnable() { 88fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk @Override 89fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk public void run() { 90c06457326509ec625d90b26828d6cc1417f4d9a3Jason Monk // Since tiles are not always cached (like on locale change for instance), 91c06457326509ec625d90b26828d6cc1417f4d9a3Jason Monk // we need to always get the latest one. 92011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (!(mActivity instanceof SettingsDrawerActivity)) { 93011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (DEBUG) { 94011362d9f15a3acb96b59e833059825a232db133Fan Zhang Log.d(TAG, "Can't get category list."); 95011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 96011362d9f15a3acb96b59e833059825a232db133Fan Zhang return; 97011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 98011362d9f15a3acb96b59e833059825a232db133Fan Zhang final List<DashboardCategory> categories = 99011362d9f15a3acb96b59e833059825a232db133Fan Zhang ((SettingsDrawerActivity) mActivity).getDashboardCategories(); 100011362d9f15a3acb96b59e833059825a232db133Fan Zhang final Tile tile = getTileFromCategory(categories, component); 101011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (tile == null) { 102011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (DEBUG) { 103011362d9f15a3acb96b59e833059825a232db133Fan Zhang Log.d(TAG, "Can't find tile for " + component); 104011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 105011362d9f15a3acb96b59e833059825a232db133Fan Zhang return; 106011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 107011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (DEBUG) { 108011362d9f15a3acb96b59e833059825a232db133Fan Zhang Log.d(TAG, "setSummary " + tile.title + " - " + summary); 109011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 110fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk tile.summary = summary; 111fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mAdapter.notifyChanged(tile); 112fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk } 113fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk }); 1143069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1153069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 1168b986f5f7345d2f012792634950669759b9be0ddJason Monk /** 1178b986f5f7345d2f012792634950669759b9be0ddJason Monk * Only call from the main thread. 1188b986f5f7345d2f012792634950669759b9be0ddJason Monk */ 1193069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk public void setListening(boolean listening) { 1208b986f5f7345d2f012792634950669759b9be0ddJason Monk if (mListening == listening) return; 1218b986f5f7345d2f012792634950669759b9be0ddJason Monk mListening = listening; 1228b986f5f7345d2f012792634950669759b9be0ddJason Monk // Unregister listeners immediately. 1238b986f5f7345d2f012792634950669759b9be0ddJason Monk for (int i = 0; i < mReceivers.size(); i++) { 124a8a029f8eb8ca51a19ce20206ce307761cfd86baJason Monk mActivity.unregisterReceiver(mReceivers.valueAt(i)); 1258ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk } 1268b986f5f7345d2f012792634950669759b9be0ddJason Monk mReceivers.clear(); 1278d8de1490536468bbc1061abca0f78ab0b682b3bJason Monk mWorker.removeMessages(Worker.MSG_SET_LISTENING); 128fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk mWorker.obtainMessage(Worker.MSG_SET_LISTENING, listening ? 1 : 0, 0).sendToTarget(); 1293069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1303069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 131d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monk private SummaryProvider getSummaryProvider(Tile tile) { 1323069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (!mActivity.getPackageName().equals(tile.intent.getComponent().getPackageName())) { 1333069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk // Not within Settings, can't load Summary directly. 1343069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk // TODO: Load summary indirectly. 1353069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk return null; 1363069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1373069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk Bundle metaData = getMetaData(tile); 1383069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (metaData == null) { 1393069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (DEBUG) Log.d(TAG, "No metadata specified for " + tile.intent.getComponent()); 1403069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk return null; 1413069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1423069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk String clsName = metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS); 1433069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (clsName == null) { 1443069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (DEBUG) Log.d(TAG, "No fragment specified for " + tile.intent.getComponent()); 1453069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk return null; 1463069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1473069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk try { 1483069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk Class<?> cls = Class.forName(clsName); 1493069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk Field field = cls.getField(SUMMARY_PROVIDER_FACTORY); 1503069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk SummaryProviderFactory factory = (SummaryProviderFactory) field.get(null); 1513069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk return factory.createSummaryProvider(mActivity, this); 1523069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } catch (ClassNotFoundException e) { 1533069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (DEBUG) Log.d(TAG, "Couldn't find " + clsName, e); 1543069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } catch (NoSuchFieldException e) { 1553069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (DEBUG) Log.d(TAG, "Couldn't find " + SUMMARY_PROVIDER_FACTORY, e); 1563069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } catch (ClassCastException e) { 1573069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (DEBUG) Log.d(TAG, "Couldn't cast " + SUMMARY_PROVIDER_FACTORY, e); 1583069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } catch (IllegalAccessException e) { 1593069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk if (DEBUG) Log.d(TAG, "Couldn't get " + SUMMARY_PROVIDER_FACTORY, e); 1603069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1613069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk return null; 1623069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1633069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 164d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monk private Bundle getMetaData(Tile tile) { 165fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk return tile.metaData; 1663069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 1673069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 1688ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk /** 1698ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk * Registers a receiver and automatically unregisters it when the activity is stopping. 1708ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk * This ensures that the receivers are unregistered immediately, since most summary loader 1718ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk * operations are asynchronous. 1728ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk */ 1738b986f5f7345d2f012792634950669759b9be0ddJason Monk public void registerReceiver(final BroadcastReceiver receiver, final IntentFilter filter) { 1748b986f5f7345d2f012792634950669759b9be0ddJason Monk mActivity.runOnUiThread(new Runnable() { 1758b986f5f7345d2f012792634950669759b9be0ddJason Monk @Override 1768b986f5f7345d2f012792634950669759b9be0ddJason Monk public void run() { 1778b986f5f7345d2f012792634950669759b9be0ddJason Monk if (!mListening) { 1788b986f5f7345d2f012792634950669759b9be0ddJason Monk return; 1798b986f5f7345d2f012792634950669759b9be0ddJason Monk } 1808b986f5f7345d2f012792634950669759b9be0ddJason Monk mReceivers.add(receiver); 1818b986f5f7345d2f012792634950669759b9be0ddJason Monk mActivity.registerReceiver(receiver, filter); 1828ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk } 1838b986f5f7345d2f012792634950669759b9be0ddJason Monk }); 1848ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk } 1858ab081e304b978602823b5f7fa81a673e98b4bb2Jason Monk 1869425839379d862604d4b5a7b9161540f598f64f6Jason Monk private synchronized void setListeningW(boolean listening) { 1878d8de1490536468bbc1061abca0f78ab0b682b3bJason Monk if (mWorkerListening == listening) return; 1888d8de1490536468bbc1061abca0f78ab0b682b3bJason Monk mWorkerListening = listening; 1899425839379d862604d4b5a7b9161540f598f64f6Jason Monk if (DEBUG) Log.d(TAG, "Listening " + listening); 1909425839379d862604d4b5a7b9161540f598f64f6Jason Monk for (SummaryProvider p : mSummaryMap.keySet()) { 1910842797a25af0383b25b039f8d5436d861134157Jason Monk try { 1920842797a25af0383b25b039f8d5436d861134157Jason Monk p.setListening(listening); 1930842797a25af0383b25b039f8d5436d861134157Jason Monk } catch (Exception e) { 1940842797a25af0383b25b039f8d5436d861134157Jason Monk Log.d(TAG, "Problem in setListening", e); 1950842797a25af0383b25b039f8d5436d861134157Jason Monk } 1969425839379d862604d4b5a7b9161540f598f64f6Jason Monk } 1979425839379d862604d4b5a7b9161540f598f64f6Jason Monk } 1989425839379d862604d4b5a7b9161540f598f64f6Jason Monk 1999425839379d862604d4b5a7b9161540f598f64f6Jason Monk private synchronized void makeProviderW(Tile tile) { 2009425839379d862604d4b5a7b9161540f598f64f6Jason Monk SummaryProvider provider = getSummaryProvider(tile); 2019425839379d862604d4b5a7b9161540f598f64f6Jason Monk if (provider != null) { 2029425839379d862604d4b5a7b9161540f598f64f6Jason Monk if (DEBUG) Log.d(TAG, "Creating " + tile); 203c06457326509ec625d90b26828d6cc1417f4d9a3Jason Monk mSummaryMap.put(provider, tile.intent.getComponent()); 2049425839379d862604d4b5a7b9161540f598f64f6Jason Monk } 2059425839379d862604d4b5a7b9161540f598f64f6Jason Monk } 2069425839379d862604d4b5a7b9161540f598f64f6Jason Monk 207011362d9f15a3acb96b59e833059825a232db133Fan Zhang private Tile getTileFromCategory(List<DashboardCategory> categories, ComponentName component) { 208011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (categories == null) { 209011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (DEBUG) { 210011362d9f15a3acb96b59e833059825a232db133Fan Zhang Log.d(TAG, "Category is null, can't find tile"); 211011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 212011362d9f15a3acb96b59e833059825a232db133Fan Zhang return null; 213011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 214011362d9f15a3acb96b59e833059825a232db133Fan Zhang final int categorySize = categories.size(); 215011362d9f15a3acb96b59e833059825a232db133Fan Zhang for (int i = 0; i < categorySize; i++) { 216011362d9f15a3acb96b59e833059825a232db133Fan Zhang final DashboardCategory category = categories.get(i); 217011362d9f15a3acb96b59e833059825a232db133Fan Zhang final int tileCount = category.tiles.size(); 218011362d9f15a3acb96b59e833059825a232db133Fan Zhang for (int j = 0; j < tileCount; j++) { 219011362d9f15a3acb96b59e833059825a232db133Fan Zhang final Tile tile = category.tiles.get(j); 220011362d9f15a3acb96b59e833059825a232db133Fan Zhang if (component.equals(tile.intent.getComponent())) { 221011362d9f15a3acb96b59e833059825a232db133Fan Zhang return tile; 222011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 223011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 224011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 225011362d9f15a3acb96b59e833059825a232db133Fan Zhang return null; 226011362d9f15a3acb96b59e833059825a232db133Fan Zhang } 227011362d9f15a3acb96b59e833059825a232db133Fan Zhang 2283069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk public interface SummaryProvider { 2293069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk void setListening(boolean listening); 2303069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 2313069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk 2323069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk public interface SummaryProviderFactory { 2333069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk SummaryProvider createSummaryProvider(Activity activity, SummaryLoader summaryLoader); 2343069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk } 235fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk 236fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk private class Worker extends Handler { 237fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk private static final int MSG_GET_PROVIDER = 1; 238fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk private static final int MSG_SET_LISTENING = 2; 239fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk 240fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk public Worker(Looper looper) { 241fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk super(looper); 242fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk } 243fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk 244fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk @Override 245fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk public void handleMessage(Message msg) { 246fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk switch (msg.what) { 247fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk case MSG_GET_PROVIDER: 248d4f03ec86f9e8b7b108fc63684e23f5c0fb2a864Jason Monk Tile tile = (Tile) msg.obj; 2499425839379d862604d4b5a7b9161540f598f64f6Jason Monk makeProviderW(tile); 250fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk break; 251fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk case MSG_SET_LISTENING: 252fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk boolean listening = msg.arg1 != 0; 2539425839379d862604d4b5a7b9161540f598f64f6Jason Monk setListeningW(listening); 254fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk break; 255fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk } 256fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk } 257fd2c7224185bef301cfaa7de6fe1af22cab8df2fJason Monk } 2583069581512bcb9687cb8d79675f6c4950c9ac087Jason Monk} 259