1ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng/* 2ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Copyright (C) 2009 The Android Open Source Project 3ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 4ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * you may not use this file except in compliance with the License. 6ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * You may obtain a copy of the License at 7ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 8ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 9ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 10ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Unless required by applicable law or agreed to in writing, software 11ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * See the License for the specific language governing permissions and 14ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * limitations under the License. 15ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 16ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 17ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengpackage com.android.contacts.common.list; 18ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 19ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.app.ActionBar; 20ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.app.Activity; 21ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.app.AlertDialog; 22ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.app.LoaderManager.LoaderCallbacks; 23ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.app.ProgressDialog; 24ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.AsyncTaskLoader; 25ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.ContentProviderOperation; 26ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.ContentResolver; 27ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.ContentValues; 28ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.Context; 29ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.DialogInterface; 30ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.Intent; 31ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.Loader; 32ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.OperationApplicationException; 33ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.SharedPreferences; 34ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.database.Cursor; 35ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.net.Uri; 36ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.os.Bundle; 37ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.os.RemoteException; 38ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.preference.PreferenceManager; 39ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract; 40ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract.Groups; 41ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract.Settings; 42ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.util.Log; 43ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.view.ContextMenu; 44ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.view.LayoutInflater; 45ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.view.MenuItem; 46ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.view.MenuItem.OnMenuItemClickListener; 47ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.view.View; 48ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.view.ViewGroup; 49ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.widget.BaseExpandableListAdapter; 50ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.widget.CheckBox; 51ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.widget.ExpandableListAdapter; 52ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.widget.ExpandableListView; 53ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.widget.ExpandableListView.ExpandableListContextMenuInfo; 54ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.widget.TextView; 55ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 56ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.R; 57ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.model.AccountTypeManager; 58ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.model.ValuesDelta; 59ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.model.account.AccountType; 60ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.model.account.AccountWithDataSet; 61ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.model.account.GoogleAccountType; 62ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.util.EmptyService; 63ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.util.LocalizedNameResolver; 64ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.util.WeakAsyncTask; 65ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.google.common.collect.Lists; 66ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 67ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport java.util.ArrayList; 68ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport java.util.Collections; 69ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport java.util.Comparator; 70ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport java.util.Iterator; 71ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 72ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng/** 73ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Shows a list of all available {@link Groups} available, letting the user 74ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * select which ones they want to be visible. 75ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 76ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengpublic class CustomContactListFilterActivity extends Activity 77ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng implements View.OnClickListener, ExpandableListView.OnChildClickListener, 78ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng LoaderCallbacks<CustomContactListFilterActivity.AccountSet> 79ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng{ 80ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final String TAG = "CustomContactListFilterActivity"; 81ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 82ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int ACCOUNT_SET_LOADER_ID = 1; 83ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 84ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private ExpandableListView mList; 85ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private DisplayAdapter mAdapter; 86ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 87ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private SharedPreferences mPrefs; 88ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 89ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 90ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onCreate(Bundle icicle) { 91ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super.onCreate(icicle); 92ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng setContentView(R.layout.contact_list_filter_custom); 93ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 94ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mList = (ExpandableListView) findViewById(android.R.id.list); 95ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mList.setOnChildClickListener(this); 96ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mList.setHeaderDividersEnabled(true); 97ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPrefs = PreferenceManager.getDefaultSharedPreferences(this); 98ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAdapter = new DisplayAdapter(this); 99ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 100ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final LayoutInflater inflater = getLayoutInflater(); 101ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 102ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng findViewById(R.id.btn_done).setOnClickListener(this); 103ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng findViewById(R.id.btn_discard).setOnClickListener(this); 104ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 105ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mList.setOnCreateContextMenuListener(this); 106ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 107ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mList.setAdapter(mAdapter); 108ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 109ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ActionBar actionBar = getActionBar(); 110ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (actionBar != null) { 111ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // android.R.id.home will be triggered in onOptionsItemSelected() 112ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng actionBar.setDisplayHomeAsUpEnabled(true); 113ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 114ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 115ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 116ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public static class CustomFilterConfigurationLoader extends AsyncTaskLoader<AccountSet> { 117ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 118ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private AccountSet mAccountSet; 119ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 120ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public CustomFilterConfigurationLoader(Context context) { 121ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super(context); 122ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 123ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 124ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 125ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public AccountSet loadInBackground() { 126ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Context context = getContext(); 127ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context); 128ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentResolver resolver = context.getContentResolver(); 129ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 130ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountSet accounts = new AccountSet(); 131ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng for (AccountWithDataSet account : accountTypes.getAccounts(false)) { 132ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountType accountType = accountTypes.getAccountTypeForAccount(account); 133ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (accountType.isExtension() && !account.hasData(context)) { 134ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Extension with no data -- skip. 135ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng continue; 136ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 137ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 138ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng AccountDisplay accountDisplay = 139ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng new AccountDisplay(resolver, account.name, account.type, account.dataSet); 140ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 141ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Uri.Builder groupsUri = Groups.CONTENT_URI.buildUpon() 142ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .appendQueryParameter(Groups.ACCOUNT_NAME, account.name) 143ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .appendQueryParameter(Groups.ACCOUNT_TYPE, account.type); 144ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (account.dataSet != null) { 145ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng groupsUri.appendQueryParameter(Groups.DATA_SET, account.dataSet).build(); 146ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 147ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng android.content.EntityIterator iterator = 148ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ContactsContract.Groups.newEntityIterator(resolver.query( 149ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng groupsUri.build(), null, null, null, null)); 150ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 151ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng boolean hasGroups = false; 152ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 153ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Create entries for each known group 154ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng while (iterator.hasNext()) { 155ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentValues values = iterator.next().getEntityValues(); 156ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta group = GroupDelta.fromBefore(values); 157ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng accountDisplay.addGroup(group); 158ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng hasGroups = true; 159ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 160ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Create single entry handling ungrouped status 161ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng accountDisplay.mUngrouped = 162ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng GroupDelta.fromSettings(resolver, account.name, account.type, 163ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.dataSet, hasGroups); 164ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng accountDisplay.addGroup(accountDisplay.mUngrouped); 165ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } finally { 166ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng iterator.close(); 167ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 168ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 169ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng accounts.add(accountDisplay); 170ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 171ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 172ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return accounts; 173ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 174ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 175ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 176ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void deliverResult(AccountSet cursor) { 177ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (isReset()) { 178ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return; 179ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 180ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 181ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAccountSet = cursor; 182ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 183ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (isStarted()) { 184ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super.deliverResult(cursor); 185ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 186ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 187ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 188ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 189ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onStartLoading() { 190ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mAccountSet != null) { 191ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng deliverResult(mAccountSet); 192ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 193ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (takeContentChanged() || mAccountSet == null) { 194ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng forceLoad(); 195ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 196ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 197ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 198ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 199ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onStopLoading() { 200ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng cancelLoad(); 201ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 202ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 203ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 204ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onReset() { 205ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super.onReset(); 206ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng onStopLoading(); 207ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAccountSet = null; 208ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 209ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 210ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 211ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 212ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onStart() { 213ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng getLoaderManager().initLoader(ACCOUNT_SET_LOADER_ID, null, this); 214ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super.onStart(); 215ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 216ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 217ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 218ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public Loader<AccountSet> onCreateLoader(int id, Bundle args) { 219ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return new CustomFilterConfigurationLoader(this); 220ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 221ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 222ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 223ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void onLoadFinished(Loader<AccountSet> loader, AccountSet data) { 224ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAdapter.setAccounts(data); 225ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 226ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 227ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 228ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void onLoaderReset(Loader<AccountSet> loader) { 229ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAdapter.setAccounts(null); 230ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 231ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 232ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int DEFAULT_SHOULD_SYNC = 1; 233ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int DEFAULT_VISIBLE = 0; 234ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 235ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 236ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Entry holding any changes to {@link Groups} or {@link Settings} rows, 237ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * such as {@link Groups#SHOULD_SYNC} or {@link Groups#GROUP_VISIBLE}. 238ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 239ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected static class GroupDelta extends ValuesDelta { 240ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private boolean mUngrouped = false; 241ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private boolean mAccountHasGroups; 242ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 243ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private GroupDelta() { 244ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super(); 245ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 246ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 247ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 248ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Build {@link GroupDelta} from the {@link Settings} row for the given 249ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * {@link Settings#ACCOUNT_NAME}, {@link Settings#ACCOUNT_TYPE}, and 250ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * {@link Settings#DATA_SET}. 251ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 252ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public static GroupDelta fromSettings(ContentResolver resolver, String accountName, 253ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String accountType, String dataSet, boolean accountHasGroups) { 254ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Uri.Builder settingsUri = Settings.CONTENT_URI.buildUpon() 255ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .appendQueryParameter(Settings.ACCOUNT_NAME, accountName) 256ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .appendQueryParameter(Settings.ACCOUNT_TYPE, accountType); 257ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (dataSet != null) { 258ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng settingsUri.appendQueryParameter(Settings.DATA_SET, dataSet); 259ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 260ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Cursor cursor = resolver.query(settingsUri.build(), new String[] { 261ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Settings.SHOULD_SYNC, Settings.UNGROUPED_VISIBLE 262ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }, null, null, null); 263ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 264ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 265ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentValues values = new ContentValues(); 266ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.ACCOUNT_NAME, accountName); 267ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.ACCOUNT_TYPE, accountType); 268ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.DATA_SET, dataSet); 269ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 270ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor != null && cursor.moveToFirst()) { 271ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Read existing values when present 272ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.SHOULD_SYNC, cursor.getInt(0)); 273ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.UNGROUPED_VISIBLE, cursor.getInt(1)); 274ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return fromBefore(values).setUngrouped(accountHasGroups); 275ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 276ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Nothing found, so treat as create 277ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.SHOULD_SYNC, DEFAULT_SHOULD_SYNC); 278ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng values.put(Settings.UNGROUPED_VISIBLE, DEFAULT_VISIBLE); 279ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return fromAfter(values).setUngrouped(accountHasGroups); 280ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 281ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } finally { 282ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor != null) cursor.close(); 283ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 284ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 285ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 286ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public static GroupDelta fromBefore(ContentValues before) { 287ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta entry = new GroupDelta(); 288ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng entry.mBefore = before; 289ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng entry.mAfter = new ContentValues(); 290ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return entry; 291ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 292ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 293ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public static GroupDelta fromAfter(ContentValues after) { 294ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta entry = new GroupDelta(); 295ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng entry.mBefore = null; 296ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng entry.mAfter = after; 297ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return entry; 298ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 299ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 300ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected GroupDelta setUngrouped(boolean accountHasGroups) { 301ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mUngrouped = true; 302ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAccountHasGroups = accountHasGroups; 303ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return this; 304ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 305ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 306ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 307ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean beforeExists() { 308ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return mBefore != null; 309ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 310ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 311ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean getShouldSync() { 312ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return getAsInteger(mUngrouped ? Settings.SHOULD_SYNC : Groups.SHOULD_SYNC, 313ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng DEFAULT_SHOULD_SYNC) != 0; 314ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 315ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 316ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean getVisible() { 317ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return getAsInteger(mUngrouped ? Settings.UNGROUPED_VISIBLE : Groups.GROUP_VISIBLE, 318ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng DEFAULT_VISIBLE) != 0; 319ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 320ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 321ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void putShouldSync(boolean shouldSync) { 322ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng put(mUngrouped ? Settings.SHOULD_SYNC : Groups.SHOULD_SYNC, shouldSync ? 1 : 0); 323ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 324ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 325ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void putVisible(boolean visible) { 326ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng put(mUngrouped ? Settings.UNGROUPED_VISIBLE : Groups.GROUP_VISIBLE, visible ? 1 : 0); 327ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 328ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 329ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private String getAccountType() { 330ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return (mBefore == null ? mAfter : mBefore).getAsString(Settings.ACCOUNT_TYPE); 331ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 332ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 333ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public CharSequence getTitle(Context context) { 334ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mUngrouped) { 335ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final String customAllContactsName = 336ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng LocalizedNameResolver.getAllContactsName(context, getAccountType()); 337ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (customAllContactsName != null) { 338ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return customAllContactsName; 339ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 340ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mAccountHasGroups) { 341ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return context.getText(R.string.display_ungrouped); 342ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 343ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return context.getText(R.string.display_all_contacts); 344ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 345ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 346ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Integer titleRes = getAsInteger(Groups.TITLE_RES); 347ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (titleRes != null) { 348ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final String packageName = getAsString(Groups.RES_PACKAGE); 349ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return context.getPackageManager().getText(packageName, titleRes, null); 350ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 351ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return getAsString(Groups.TITLE); 352ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 353ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 354ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 355ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 356ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 357ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Build a possible {@link ContentProviderOperation} to persist any 358ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * changes to the {@link Groups} or {@link Settings} row described by 359ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * this {@link GroupDelta}. 360ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 361ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public ContentProviderOperation buildDiff() { 362ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (isInsert()) { 363ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Only allow inserts for Settings 364ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mUngrouped) { 365ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAfter.remove(mIdColumn); 366ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return ContentProviderOperation.newInsert(Settings.CONTENT_URI) 367ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .withValues(mAfter) 368ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .build(); 369ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 370ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng else { 371ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng throw new IllegalStateException("Unexpected diff"); 372ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 373ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else if (isUpdate()) { 374ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mUngrouped) { 375ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String accountName = this.getAsString(Settings.ACCOUNT_NAME); 376ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String accountType = this.getAsString(Settings.ACCOUNT_TYPE); 377ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String dataSet = this.getAsString(Settings.DATA_SET); 378ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng StringBuilder selection = new StringBuilder(Settings.ACCOUNT_NAME + "=? AND " 379ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng + Settings.ACCOUNT_TYPE + "=?"); 380ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String[] selectionArgs; 381ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (dataSet == null) { 382ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng selection.append(" AND " + Settings.DATA_SET + " IS NULL"); 383ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng selectionArgs = new String[] {accountName, accountType}; 384ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 385ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng selection.append(" AND " + Settings.DATA_SET + "=?"); 386ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng selectionArgs = new String[] {accountName, accountType, dataSet}; 387ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 388ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return ContentProviderOperation.newUpdate(Settings.CONTENT_URI) 389ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .withSelection(selection.toString(), selectionArgs) 390ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .withValues(mAfter) 391ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .build(); 392ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 393ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return ContentProviderOperation.newUpdate( 394ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng addCallerIsSyncAdapterParameter(Groups.CONTENT_URI)) 395ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .withSelection(Groups._ID + "=" + this.getId(), null) 396ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .withValues(mAfter) 397ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .build(); 398ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 399ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 400ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return null; 401ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 402ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 403ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 404ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 405ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static Uri addCallerIsSyncAdapterParameter(Uri uri) { 406ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return uri.buildUpon() 407ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") 408ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .build(); 409ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 410ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 411ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 412ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * {@link Comparator} to sort by {@link Groups#_ID}. 413ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 414ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static Comparator<GroupDelta> sIdComparator = new Comparator<GroupDelta>() { 415ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public int compare(GroupDelta object1, GroupDelta object2) { 416ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Long id1 = object1.getId(); 417ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Long id2 = object2.getId(); 418ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (id1 == null && id2 == null) { 419ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return 0; 420ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else if (id1 == null) { 421ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return -1; 422ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else if (id2 == null) { 423ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return 1; 424ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else if (id1 < id2) { 425ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return -1; 426ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else if (id1 > id2) { 427ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return 1; 428ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 429ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return 0; 430ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 431ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 432ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }; 433ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 434ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 435ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Set of all {@link AccountDisplay} entries, one for each source. 436ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 437ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected static class AccountSet extends ArrayList<AccountDisplay> { 438ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public ArrayList<ContentProviderOperation> buildDiff() { 439ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 440ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng for (AccountDisplay account : this) { 441ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.buildDiff(diff); 442ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 443ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return diff; 444ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 445ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 446ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 447ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 448ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * {@link GroupDelta} details for a single {@link AccountWithDataSet}, usually shown as 449ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * children under a single expandable group. 450ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 451ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected static class AccountDisplay { 452ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public final String mName; 453ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public final String mType; 454ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public final String mDataSet; 455ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 456ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public GroupDelta mUngrouped; 457ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public ArrayList<GroupDelta> mSyncedGroups = Lists.newArrayList(); 458ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public ArrayList<GroupDelta> mUnsyncedGroups = Lists.newArrayList(); 459ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 460ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 461ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Build an {@link AccountDisplay} covering all {@link Groups} under the 462ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * given {@link AccountWithDataSet}. 463ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 464ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public AccountDisplay(ContentResolver resolver, String accountName, String accountType, 465ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String dataSet) { 466ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mName = accountName; 467ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mType = accountType; 468ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mDataSet = dataSet; 469ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 470ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 471ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 472ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Add the given {@link GroupDelta} internally, filing based on its 473ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * {@link GroupDelta#getShouldSync()} status. 474ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 475ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private void addGroup(GroupDelta group) { 476ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (group.getShouldSync()) { 477ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mSyncedGroups.add(group); 478ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 479ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mUnsyncedGroups.add(group); 480ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 481ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 482ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 483ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 484ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Set the {@link GroupDelta#putShouldSync(boolean)} value for all 485ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * children {@link GroupDelta} rows. 486ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 487ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void setShouldSync(boolean shouldSync) { 488ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Iterator<GroupDelta> oppositeChildren = shouldSync ? 489ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mUnsyncedGroups.iterator() : mSyncedGroups.iterator(); 490ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng while (oppositeChildren.hasNext()) { 491ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta child = oppositeChildren.next(); 492ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng setShouldSync(child, shouldSync, false); 493ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng oppositeChildren.remove(); 494ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 495ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 496ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 497ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void setShouldSync(GroupDelta child, boolean shouldSync) { 498ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng setShouldSync(child, shouldSync, true); 499ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 500ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 501ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 502ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Set {@link GroupDelta#putShouldSync(boolean)}, and file internally 503ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * based on updated state. 504ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 505ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void setShouldSync(GroupDelta child, boolean shouldSync, boolean attemptRemove) { 506ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng child.putShouldSync(shouldSync); 507ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (shouldSync) { 508ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (attemptRemove) { 509ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mUnsyncedGroups.remove(child); 510ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 511ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mSyncedGroups.add(child); 512ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Collections.sort(mSyncedGroups, sIdComparator); 513ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 514ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (attemptRemove) { 515ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mSyncedGroups.remove(child); 516ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 517ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mUnsyncedGroups.add(child); 518ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 519ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 520ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 521ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 522ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Build set of {@link ContentProviderOperation} to persist any user 523ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * changes to {@link GroupDelta} rows under this {@link AccountWithDataSet}. 524ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 525ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void buildDiff(ArrayList<ContentProviderOperation> diff) { 526ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng for (GroupDelta group : mSyncedGroups) { 527ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentProviderOperation oper = group.buildDiff(); 528ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (oper != null) diff.add(oper); 529ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 530ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng for (GroupDelta group : mUnsyncedGroups) { 531ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentProviderOperation oper = group.buildDiff(); 532ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (oper != null) diff.add(oper); 533ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 534ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 535ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 536ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 537ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 538ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * {@link ExpandableListAdapter} that shows {@link GroupDelta} settings, 539ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * grouped by {@link AccountWithDataSet} type. Shows footer row when any groups are 540ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * unsynced, as determined through {@link AccountDisplay#mUnsyncedGroups}. 541ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 542ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected static class DisplayAdapter extends BaseExpandableListAdapter { 543ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private Context mContext; 544ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private LayoutInflater mInflater; 545ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private AccountTypeManager mAccountTypes; 546ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private AccountSet mAccounts; 547ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 548ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private boolean mChildWithPhones = false; 549ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 550ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public DisplayAdapter(Context context) { 551ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mContext = context; 552ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 553ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAccountTypes = AccountTypeManager.getInstance(context); 554ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 555ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 556ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void setAccounts(AccountSet accounts) { 557ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAccounts = accounts; 558ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng notifyDataSetChanged(); 559ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 560ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 561ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 562ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * In group descriptions, show the number of contacts with phone 563ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * numbers, in addition to the total contacts. 564ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 565ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void setChildDescripWithPhones(boolean withPhones) { 566ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mChildWithPhones = withPhones; 567ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 568ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 569ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 570ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 571ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ViewGroup parent) { 572ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (convertView == null) { 573ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng convertView = mInflater.inflate( 574ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.layout.custom_contact_list_filter_account, parent, false); 575ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 576ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 577ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final TextView text1 = (TextView)convertView.findViewById(android.R.id.text1); 578ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final TextView text2 = (TextView)convertView.findViewById(android.R.id.text2); 579ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 580ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountDisplay account = (AccountDisplay)this.getGroup(groupPosition); 581ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 582ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountType accountType = mAccountTypes.getAccountType( 583ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.mType, account.mDataSet); 584ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 585ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text1.setText(account.mName); 586ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text1.setVisibility(account.mName == null ? View.GONE : View.VISIBLE); 587ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text2.setText(accountType.getDisplayLabel(mContext)); 588ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 589ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return convertView; 590ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 591ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 592ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 593ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 594ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng View convertView, ViewGroup parent) { 595ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (convertView == null) { 596ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng convertView = mInflater.inflate( 597ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.layout.custom_contact_list_filter_group, parent, false); 598ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 599ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 600ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final TextView text1 = (TextView)convertView.findViewById(android.R.id.text1); 601ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final TextView text2 = (TextView)convertView.findViewById(android.R.id.text2); 602ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final CheckBox checkbox = (CheckBox)convertView.findViewById(android.R.id.checkbox); 603ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 604ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountDisplay account = mAccounts.get(groupPosition); 605ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta child = (GroupDelta)this.getChild(groupPosition, childPosition); 606ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (child != null) { 607ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Handle normal group, with title and checkbox 608ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final boolean groupVisible = child.getVisible(); 609ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng checkbox.setVisibility(View.VISIBLE); 610ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng checkbox.setChecked(groupVisible); 611ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 612ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final CharSequence groupTitle = child.getTitle(mContext); 613ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text1.setText(groupTitle); 614ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text2.setVisibility(View.GONE); 615ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 616ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // When unknown child, this is "more" footer view 617ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng checkbox.setVisibility(View.GONE); 618ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text1.setText(R.string.display_more_groups); 619ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng text2.setVisibility(View.GONE); 620ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 621ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 622ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return convertView; 623ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 624ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 625ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 626ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public Object getChild(int groupPosition, int childPosition) { 627ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountDisplay account = mAccounts.get(groupPosition); 628ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final boolean validChild = childPosition >= 0 629ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng && childPosition < account.mSyncedGroups.size(); 630ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (validChild) { 631ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return account.mSyncedGroups.get(childPosition); 632ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 633ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return null; 634ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 635ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 636ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 637ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 638ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public long getChildId(int groupPosition, int childPosition) { 639ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta child = (GroupDelta)getChild(groupPosition, childPosition); 640ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (child != null) { 641ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Long childId = child.getId(); 642ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return childId != null ? childId : Long.MIN_VALUE; 643ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 644ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return Long.MIN_VALUE; 645ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 646ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 647ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 648ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 649ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public int getChildrenCount(int groupPosition) { 650ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Count is any synced groups, plus possible footer 651ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountDisplay account = mAccounts.get(groupPosition); 652ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final boolean anyHidden = account.mUnsyncedGroups.size() > 0; 653ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return account.mSyncedGroups.size() + (anyHidden ? 1 : 0); 654ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 655ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 656ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 657ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public Object getGroup(int groupPosition) { 658ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return mAccounts.get(groupPosition); 659ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 660ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 661ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 662ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public int getGroupCount() { 663ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mAccounts == null) { 664ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return 0; 665ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 666ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return mAccounts.size(); 667ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 668ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 669ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 670ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public long getGroupId(int groupPosition) { 671ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return groupPosition; 672ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 673ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 674ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 675ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean hasStableIds() { 676ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return true; 677ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 678ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 679ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 680ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean isChildSelectable(int groupPosition, int childPosition) { 681ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return true; 682ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 683ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 684ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 685ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** {@inheritDoc} */ 686ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void onClick(View view) { 687ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng switch (view.getId()) { 688ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng case R.id.btn_done: { 689ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng this.doSaveAction(); 690ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng break; 691ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 692ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng case R.id.btn_discard: { 693ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng this.finish(); 694ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng break; 695ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 696ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 697ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 698ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 699ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 700ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Handle any clicks on {@link ExpandableListAdapter} children, which 701ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * usually mean toggling its visible state. 702ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 703ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 704ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean onChildClick(ExpandableListView parent, View view, int groupPosition, 705ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng int childPosition, long id) { 706ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final CheckBox checkbox = (CheckBox)view.findViewById(android.R.id.checkbox); 707ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 708ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountDisplay account = (AccountDisplay)mAdapter.getGroup(groupPosition); 709ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta child = (GroupDelta)mAdapter.getChild(groupPosition, childPosition); 710ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (child != null) { 711ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng checkbox.toggle(); 712ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng child.putVisible(checkbox.isChecked()); 713ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 714ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Open context menu for bringing back unsynced 715ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng this.openContextMenu(view); 716ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 717ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return true; 718ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 719ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 720ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // TODO: move these definitions to framework constants when we begin 721ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // defining this mode through <sync-adapter> tags 722ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int SYNC_MODE_UNSUPPORTED = 0; 723ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int SYNC_MODE_UNGROUPED = 1; 724ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int SYNC_MODE_EVERYTHING = 2; 725ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 726ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected int getSyncMode(AccountDisplay account) { 727ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // TODO: read sync mode through <sync-adapter> definition 728ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (GoogleAccountType.ACCOUNT_TYPE.equals(account.mType) && account.mDataSet == null) { 729ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return SYNC_MODE_EVERYTHING; 730ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 731ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return SYNC_MODE_UNSUPPORTED; 732ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 733ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 734ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 735ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 736ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void onCreateContextMenu(ContextMenu menu, View view, 737ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ContextMenu.ContextMenuInfo menuInfo) { 738ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super.onCreateContextMenu(menu, view, menuInfo); 739ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 740ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Bail if not working with expandable long-press, or if not child 741ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (!(menuInfo instanceof ExpandableListContextMenuInfo)) return; 742ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 743ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo; 744ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); 745ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition); 746ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 747ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Skip long-press on expandable parents 748ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (childPosition == -1) return; 749ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 750ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AccountDisplay account = (AccountDisplay)mAdapter.getGroup(groupPosition); 751ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta child = (GroupDelta)mAdapter.getChild(groupPosition, childPosition); 752ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 753ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Ignore when selective syncing unsupported 754ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final int syncMode = getSyncMode(account); 755ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (syncMode == SYNC_MODE_UNSUPPORTED) return; 756ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 757ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (child != null) { 758ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng showRemoveSync(menu, account, child, syncMode); 759ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 760ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng showAddSync(menu, account, syncMode); 761ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 762ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 763ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 764ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void showRemoveSync(ContextMenu menu, final AccountDisplay account, 765ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final GroupDelta child, final int syncMode) { 766ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final CharSequence title = child.getTitle(this); 767ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 768ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng menu.setHeaderTitle(title); 769ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng menu.add(R.string.menu_sync_remove).setOnMenuItemClickListener( 770ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng new OnMenuItemClickListener() { 771ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean onMenuItemClick(MenuItem item) { 772ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng handleRemoveSync(account, child, syncMode, title); 773ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return true; 774ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 775ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }); 776ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 777ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 778ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void handleRemoveSync(final AccountDisplay account, final GroupDelta child, 779ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final int syncMode, CharSequence title) { 780ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final boolean shouldSyncUngrouped = account.mUngrouped.getShouldSync(); 781ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (syncMode == SYNC_MODE_EVERYTHING && shouldSyncUngrouped 782ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng && !child.equals(account.mUngrouped)) { 783ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Warn before removing this group when it would cause ungrouped to stop syncing 784ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final AlertDialog.Builder builder = new AlertDialog.Builder(this); 785ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final CharSequence removeMessage = this.getString( 786ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.string.display_warn_remove_ungrouped, title); 787ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng builder.setTitle(R.string.menu_sync_remove); 788ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng builder.setMessage(removeMessage); 789ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng builder.setNegativeButton(android.R.string.cancel, null); 790ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 791ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void onClick(DialogInterface dialog, int which) { 792ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Mark both this group and ungrouped to stop syncing 793ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.setShouldSync(account.mUngrouped, false); 794ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.setShouldSync(child, false); 795ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAdapter.notifyDataSetChanged(); 796ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 797ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }); 798ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng builder.show(); 799ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 800ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Mark this group to not sync 801ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.setShouldSync(child, false); 802ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAdapter.notifyDataSetChanged(); 803ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 804ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 805ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 806ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void showAddSync(ContextMenu menu, final AccountDisplay account, final int syncMode) { 807ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng menu.setHeaderTitle(R.string.dialog_sync_add); 808ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 809ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Create item for each available, unsynced group 810ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng for (final GroupDelta child : account.mUnsyncedGroups) { 811ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (!child.getShouldSync()) { 812ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final CharSequence title = child.getTitle(this); 813ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng menu.add(title).setOnMenuItemClickListener(new OnMenuItemClickListener() { 814ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean onMenuItemClick(MenuItem item) { 815ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Adding specific group for syncing 816ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (child.mUngrouped && syncMode == SYNC_MODE_EVERYTHING) { 817ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.setShouldSync(true); 818ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 819ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng account.setShouldSync(child, true); 820ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 821ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mAdapter.notifyDataSetChanged(); 822ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return true; 823ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 824ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }); 825ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 826ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 827ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 828ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 829ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @SuppressWarnings("unchecked") 830ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private void doSaveAction() { 831ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mAdapter == null || mAdapter.mAccounts == null) { 832ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng finish(); 833ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return; 834ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 835ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 836ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng setResult(RESULT_OK); 837ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 838ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ArrayList<ContentProviderOperation> diff = mAdapter.mAccounts.buildDiff(); 839ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (diff.isEmpty()) { 840ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng finish(); 841ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return; 842ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 843ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 844ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng new UpdateTask(this).execute(diff); 845ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 846ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 847ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 848ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Background task that persists changes to {@link Groups#GROUP_VISIBLE}, 849ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * showing spinner dialog to user while updating. 850ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 851ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public static class UpdateTask extends 852ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng WeakAsyncTask<ArrayList<ContentProviderOperation>, Void, Void, Activity> { 853ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private ProgressDialog mProgress; 854ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 855ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public UpdateTask(Activity target) { 856ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super(target); 857ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 858ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 859ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** {@inheritDoc} */ 860ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 861ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onPreExecute(Activity target) { 862ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Context context = target; 863ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 864ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mProgress = ProgressDialog.show( 865ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng context, null, context.getText(R.string.savingDisplayGroups)); 866ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 867ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Before starting this task, start an empty service to protect our 868ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // process from being reclaimed by the system. 869ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng context.startService(new Intent(context, EmptyService.class)); 870ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 871ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 872ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** {@inheritDoc} */ 873ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 874ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected Void doInBackground( 875ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Activity target, ArrayList<ContentProviderOperation>... params) { 876ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Context context = target; 877ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentValues values = new ContentValues(); 878ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ContentResolver resolver = context.getContentResolver(); 879ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 880ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 881ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ArrayList<ContentProviderOperation> diff = params[0]; 882ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng resolver.applyBatch(ContactsContract.AUTHORITY, diff); 883ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } catch (RemoteException e) { 884ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Log.e(TAG, "Problem saving display groups", e); 885ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } catch (OperationApplicationException e) { 886ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Log.e(TAG, "Problem saving display groups", e); 887ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 888ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 889ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return null; 890ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 891ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 892ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** {@inheritDoc} */ 893ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 894ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onPostExecute(Activity target, Void result) { 895ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Context context = target; 896ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 897ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 898ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mProgress.dismiss(); 899ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } catch (Exception e) { 900ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Log.e(TAG, "Error dismissing progress dialog", e); 901ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 902ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 903ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng target.finish(); 904ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 905ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Stop the service that was protecting us 906ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng context.stopService(new Intent(context, EmptyService.class)); 907ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 908ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 909ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 910ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 911ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public boolean onOptionsItemSelected(MenuItem item) { 912ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng switch (item.getItemId()) { 913ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng case android.R.id.home: 914ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Pretend cancel. 915ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng setResult(Activity.RESULT_CANCELED); 916ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng finish(); 917ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return true; 918ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng default: 919ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng break; 920ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 921ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return super.onOptionsItemSelected(item); 922ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 923ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng} 924