1/* 2 * Copyright (C) 2018 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 17package com.android.car.settings.accounts; 18 19import android.accounts.Account; 20import android.car.user.CarUserManagerHelper; 21import android.content.Context; 22import android.content.pm.UserInfo; 23import android.support.annotation.VisibleForTesting; 24import android.text.TextUtils; 25 26import androidx.car.widget.ListItem; 27import androidx.car.widget.ListItemProvider; 28import androidx.car.widget.TextListItem; 29 30import com.android.car.settings.R; 31 32import java.util.ArrayList; 33import java.util.Collections; 34import java.util.Comparator; 35import java.util.List; 36 37/** 38 * Implementation of {@link ListItemProvider} for {@link AccountsListFragment}. 39 * Creates items that represent current user's accounts. 40 */ 41class AccountsItemProvider extends ListItemProvider { 42 private final List<ListItem> mItems = new ArrayList<>(); 43 private final Context mContext; 44 private final AccountClickListener mItemClickListener; 45 private final CarUserManagerHelper mCarUserManagerHelper; 46 private final AccountManagerHelper mAccountManagerHelper; 47 48 AccountsItemProvider(Context context, AccountClickListener itemClickListener, 49 CarUserManagerHelper carUserManagerHelper, AccountManagerHelper accountManagerHelper) { 50 mContext = context; 51 mItemClickListener = itemClickListener; 52 mCarUserManagerHelper = carUserManagerHelper; 53 mAccountManagerHelper = accountManagerHelper; 54 refreshItems(); 55 } 56 57 @Override 58 public ListItem get(int position) { 59 return mItems.get(position); 60 } 61 62 @Override 63 public int size() { 64 return mItems.size(); 65 } 66 67 /** 68 * Clears and recreates the list of items. 69 */ 70 public void refreshItems() { 71 mItems.clear(); 72 73 UserInfo currUserInfo = mCarUserManagerHelper.getCurrentProcessUserInfo(); 74 75 List<Account> accounts = getSortedUserAccounts(); 76 77 // Only add account-related items if the User can Modify Accounts 78 if (mCarUserManagerHelper.canCurrentProcessModifyAccounts()) { 79 // Add "Account for $User" title for a list of accounts. 80 mItems.add(createSubtitleItem( 81 mContext.getString(R.string.account_list_title, currUserInfo.name), 82 accounts.isEmpty() ? mContext.getString(R.string.no_accounts_added) : "")); 83 84 // Add an item for each account owned by the current user (1st and 3rd party accounts) 85 for (Account account : accounts) { 86 mItems.add(createAccountItem(account, account.type, currUserInfo)); 87 } 88 } 89 } 90 91 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) 92 List<Account> getSortedUserAccounts() { 93 List<Account> accounts = mAccountManagerHelper.getAccountsForCurrentUser(); 94 95 // Sort accounts 96 Collections.sort(accounts, Comparator.comparing( 97 (Account a) -> mAccountManagerHelper.getLabelForType(a.type).toString()) 98 .thenComparing(a -> a.name)); 99 100 return accounts; 101 } 102 103 // Creates a subtitle line for visual separation in the list 104 private ListItem createSubtitleItem(String title, String body) { 105 TextListItem item = new TextListItem(mContext); 106 item.setTitle(title); 107 item.setBody(body); 108 item.addViewBinder(viewHolder -> 109 viewHolder.getTitle().setTextAppearance(R.style.SettingsListHeader)); 110 // Hiding the divider after subtitle, since subtitle is a header for a group of items. 111 item.setHideDivider(true); 112 return item; 113 } 114 115 // Creates a line for an account that belongs to a given user 116 private ListItem createAccountItem(Account account, String accountType, 117 UserInfo userInfo) { 118 TextListItem item = new TextListItem(mContext); 119 item.setPrimaryActionIcon(mAccountManagerHelper.getDrawableForType(accountType), 120 /* useLargeIcon= */ false); 121 item.setTitle(account.name); 122 123 // Set item body = account label. 124 CharSequence itemBody = mAccountManagerHelper.getLabelForType(accountType); 125 if (!TextUtils.isEmpty(itemBody)) { 126 item.setBody(itemBody.toString()); 127 } 128 129 item.setOnClickListener(view -> mItemClickListener.onAccountClicked(account, userInfo)); 130 131 // setHideDivider = true will hide the divider to group the items together visually. 132 // All of those without a divider between them will be part of the same "group". 133 item.setHideDivider(true); 134 return item; 135 } 136 137 /** 138 * Interface for registering clicks on account items. 139 */ 140 interface AccountClickListener { 141 /** 142 * Invoked when a specific account is clicked on. 143 * 144 * @param account Account for which to display details. 145 * @param userInfo User who's the owner of the account. 146 */ 147 void onAccountClicked(Account account, UserInfo userInfo); 148 } 149} 150