1 /* 2 * Copyright (C) 2011 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 android.accounts; 17 18 import android.app.Activity; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.res.Resources; 23 import android.graphics.drawable.Drawable; 24 import android.os.Bundle; 25 import android.util.Log; 26 import android.view.LayoutInflater; 27 import android.view.View; 28 import android.view.ViewGroup; 29 import android.widget.AdapterView; 30 import android.widget.ArrayAdapter; 31 import android.widget.ImageView; 32 import android.widget.ListView; 33 import android.widget.TextView; 34 35 import com.android.internal.R; 36 37 import java.util.ArrayList; 38 import java.util.HashMap; 39 import java.util.HashSet; 40 import java.util.Map; 41 import java.util.Set; 42 43 /** 44 * @hide 45 */ 46 public class ChooseAccountTypeActivity extends Activity { 47 private static final String TAG = "AccountChooser"; 48 49 private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>(); 50 private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay; 51 52 @Override onCreate(Bundle savedInstanceState)53 public void onCreate(Bundle savedInstanceState) { 54 super.onCreate(savedInstanceState); 55 getWindow().addSystemFlags( 56 android.view.WindowManager.LayoutParams 57 .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 58 59 if (Log.isLoggable(TAG, Log.VERBOSE)) { 60 Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState=" 61 + savedInstanceState + ")"); 62 } 63 64 // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes 65 Set<String> setOfAllowableAccountTypes = null; 66 String[] validAccountTypes = getIntent().getStringArrayExtra( 67 ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY); 68 if (validAccountTypes != null) { 69 setOfAllowableAccountTypes = new HashSet<String>(validAccountTypes.length); 70 for (String type : validAccountTypes) { 71 setOfAllowableAccountTypes.add(type); 72 } 73 } 74 75 // create a map of account authenticators 76 buildTypeToAuthDescriptionMap(); 77 78 // Create a list of authenticators that are allowable. Filter out those that 79 // don't match the allowable account types, if provided. 80 mAuthenticatorInfosToDisplay = new ArrayList<AuthInfo>(mTypeToAuthenticatorInfo.size()); 81 for (Map.Entry<String, AuthInfo> entry: mTypeToAuthenticatorInfo.entrySet()) { 82 final String type = entry.getKey(); 83 final AuthInfo info = entry.getValue(); 84 if (setOfAllowableAccountTypes != null 85 && !setOfAllowableAccountTypes.contains(type)) { 86 continue; 87 } 88 mAuthenticatorInfosToDisplay.add(info); 89 } 90 91 if (mAuthenticatorInfosToDisplay.isEmpty()) { 92 Bundle bundle = new Bundle(); 93 bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "no allowable account types"); 94 setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 95 finish(); 96 return; 97 } 98 99 if (mAuthenticatorInfosToDisplay.size() == 1) { 100 setResultAndFinish(mAuthenticatorInfosToDisplay.get(0).desc.type); 101 return; 102 } 103 104 setContentView(R.layout.choose_account_type); 105 // Setup the list 106 ListView list = findViewById(android.R.id.list); 107 // Use an existing ListAdapter that will map an array of strings to TextViews 108 list.setAdapter(new AccountArrayAdapter(this, 109 android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay)); 110 list.setChoiceMode(ListView.CHOICE_MODE_NONE); 111 list.setTextFilterEnabled(false); 112 list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 113 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 114 setResultAndFinish(mAuthenticatorInfosToDisplay.get(position).desc.type); 115 } 116 }); 117 } 118 setResultAndFinish(final String type)119 private void setResultAndFinish(final String type) { 120 Bundle bundle = new Bundle(); 121 bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type); 122 setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 123 if (Log.isLoggable(TAG, Log.VERBOSE)) { 124 Log.v(TAG, "ChooseAccountTypeActivity.setResultAndFinish: " 125 + "selected account type " + type); 126 } 127 finish(); 128 } 129 buildTypeToAuthDescriptionMap()130 private void buildTypeToAuthDescriptionMap() { 131 for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) { 132 String name = null; 133 Drawable icon = null; 134 try { 135 Context authContext = createPackageContext(desc.packageName, 0); 136 icon = authContext.getDrawable(desc.iconId); 137 final CharSequence sequence = authContext.getResources().getText(desc.labelId); 138 if (sequence != null) { 139 name = sequence.toString(); 140 } 141 name = sequence.toString(); 142 } catch (PackageManager.NameNotFoundException e) { 143 // Nothing we can do much here, just log 144 if (Log.isLoggable(TAG, Log.WARN)) { 145 Log.w(TAG, "No icon name for account type " + desc.type); 146 } 147 } catch (Resources.NotFoundException e) { 148 // Nothing we can do much here, just log 149 if (Log.isLoggable(TAG, Log.WARN)) { 150 Log.w(TAG, "No icon resource for account type " + desc.type); 151 } 152 } 153 AuthInfo authInfo = new AuthInfo(desc, name, icon); 154 mTypeToAuthenticatorInfo.put(desc.type, authInfo); 155 } 156 } 157 158 private static class AuthInfo { 159 final AuthenticatorDescription desc; 160 final String name; 161 final Drawable drawable; 162 AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable)163 AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable) { 164 this.desc = desc; 165 this.name = name; 166 this.drawable = drawable; 167 } 168 } 169 170 private static class ViewHolder { 171 ImageView icon; 172 TextView text; 173 } 174 175 private static class AccountArrayAdapter extends ArrayAdapter<AuthInfo> { 176 private LayoutInflater mLayoutInflater; 177 private ArrayList<AuthInfo> mInfos; 178 AccountArrayAdapter(Context context, int textViewResourceId, ArrayList<AuthInfo> infos)179 public AccountArrayAdapter(Context context, int textViewResourceId, 180 ArrayList<AuthInfo> infos) { 181 super(context, textViewResourceId, infos); 182 mInfos = infos; 183 mLayoutInflater = (LayoutInflater) context.getSystemService( 184 Context.LAYOUT_INFLATER_SERVICE); 185 } 186 187 @Override getView(int position, View convertView, ViewGroup parent)188 public View getView(int position, View convertView, ViewGroup parent) { 189 ViewHolder holder; 190 191 if (convertView == null) { 192 convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null); 193 holder = new ViewHolder(); 194 holder.text = (TextView) convertView.findViewById(R.id.account_row_text); 195 holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon); 196 convertView.setTag(holder); 197 } else { 198 holder = (ViewHolder) convertView.getTag(); 199 } 200 201 holder.text.setText(mInfos.get(position).name); 202 holder.icon.setImageDrawable(mInfos.get(position).drawable); 203 204 return convertView; 205 } 206 } 207 } 208