1 /* 2 * Copyright (C) 2016 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 package com.android.contacts.model.account; 17 18 import android.app.Activity; 19 import android.app.Fragment; 20 import android.app.LoaderManager; 21 import android.content.Context; 22 import android.content.IntentFilter; 23 import android.content.Loader; 24 import android.os.Bundle; 25 26 import com.android.contacts.model.AccountTypeManager; 27 import com.android.contacts.util.concurrent.ListenableFutureLoader; 28 import com.google.common.base.Objects; 29 import com.google.common.base.Predicate; 30 import com.google.common.base.Predicates; 31 import com.google.common.util.concurrent.ListenableFuture; 32 33 import java.util.List; 34 35 /** 36 * Loads the accounts from AccountTypeManager 37 */ 38 public class AccountsLoader extends ListenableFutureLoader<List<AccountInfo>> { 39 private final AccountTypeManager mAccountTypeManager; 40 private final Predicate<AccountInfo> mFilter; 41 AccountsLoader(Context context)42 public AccountsLoader(Context context) { 43 this(context, Predicates.<AccountInfo>alwaysTrue()); 44 } 45 AccountsLoader(Context context, Predicate<AccountInfo> filter)46 public AccountsLoader(Context context, Predicate<AccountInfo> filter) { 47 super(context, new IntentFilter(AccountTypeManager.BROADCAST_ACCOUNTS_CHANGED)); 48 mAccountTypeManager = AccountTypeManager.getInstance(context); 49 mFilter = filter; 50 } 51 52 @Override loadData()53 protected ListenableFuture<List<AccountInfo>> loadData() { 54 return mAccountTypeManager.filterAccountsAsync(mFilter); 55 } 56 57 @Override isSameData(List<AccountInfo> previous, List<AccountInfo> next)58 protected boolean isSameData(List<AccountInfo> previous, List<AccountInfo> next) { 59 return Objects.equal(AccountInfo.extractAccounts(previous), 60 AccountInfo.extractAccounts(next)); 61 } 62 63 64 public interface AccountsListener { onAccountsLoaded(List<AccountInfo> accounts)65 void onAccountsLoaded(List<AccountInfo> accounts); 66 } 67 68 /** 69 * Loads the accounts into the target fragment using {@link LoaderManager} 70 * 71 * <p>This is a convenience method to reduce the 72 * boilerplate needed when implementing {@link android.app.LoaderManager.LoaderCallbacks} 73 * in the simple case that the fragment wants to just load the accounts directly</p> 74 * <p>Note that changing the filter between invocations in the same component will not work 75 * properly because the loader is cached.</p> 76 */ loadAccounts( final FragmentType fragment, int loaderId, final Predicate<AccountInfo> filter)77 public static <FragmentType extends Fragment & AccountsListener> void loadAccounts( 78 final FragmentType fragment, int loaderId, final Predicate<AccountInfo> filter) { 79 loadAccounts( 80 fragment.getActivity(), fragment.getLoaderManager(), loaderId, filter, fragment); 81 } 82 83 /** 84 * Same as {@link #loadAccounts(Fragment, int, Predicate)} for an Activity 85 */ loadAccounts( final ActivityType activity, int id, final Predicate<AccountInfo> filter)86 public static <ActivityType extends Activity & AccountsListener> void loadAccounts( 87 final ActivityType activity, int id, final Predicate<AccountInfo> filter) { 88 loadAccounts(activity, activity.getLoaderManager(), id, filter, activity); 89 } 90 loadAccounts(final Context context, LoaderManager loaderManager, int id, final Predicate<AccountInfo> filter, final AccountsListener listener)91 private static void loadAccounts(final Context context, LoaderManager loaderManager, int id, 92 final Predicate<AccountInfo> filter, final AccountsListener listener) { 93 loaderManager.initLoader(id, null, 94 new LoaderManager.LoaderCallbacks<List<AccountInfo>>() { 95 @Override 96 public Loader<List<AccountInfo>> onCreateLoader(int id, Bundle args) { 97 return new AccountsLoader(context, filter); 98 } 99 100 @Override 101 public void onLoadFinished( 102 Loader<List<AccountInfo>> loader, List<AccountInfo> data) { 103 listener.onAccountsLoaded(data); 104 } 105 106 @Override 107 public void onLoaderReset(Loader<List<AccountInfo>> loader) { 108 } 109 }); 110 } 111 } 112