1 /* 2 * Copyright (C) 2009 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.pm.PackageManager; 21 import android.content.res.Resources; 22 import android.graphics.drawable.Drawable; 23 import android.os.Bundle; 24 import android.os.Parcelable; 25 import android.os.Process; 26 import android.os.UserHandle; 27 import android.util.Log; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.widget.AdapterView; 32 import android.widget.ArrayAdapter; 33 import android.widget.ImageView; 34 import android.widget.ListView; 35 import android.widget.TextView; 36 37 import com.android.internal.R; 38 39 import java.util.HashMap; 40 41 /** 42 * @hide 43 */ 44 public class ChooseAccountActivity extends Activity { 45 46 private static final String TAG = "AccountManager"; 47 48 private Parcelable[] mAccounts = null; 49 private AccountManagerResponse mAccountManagerResponse = null; 50 private Bundle mResult; 51 private int mCallingUid; 52 private String mCallingPackage; 53 54 private HashMap<String, AuthenticatorDescription> mTypeToAuthDescription 55 = new HashMap<String, AuthenticatorDescription>(); 56 57 @Override onCreate(Bundle savedInstanceState)58 public void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 getWindow().addSystemFlags( 61 android.view.WindowManager.LayoutParams 62 .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 63 mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS); 64 mAccountManagerResponse = 65 getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE); 66 67 // KEY_ACCOUNTS is a required parameter 68 if (mAccounts == null) { 69 setResult(RESULT_CANCELED); 70 finish(); 71 return; 72 } 73 74 mCallingUid = getLaunchedFromUid(); 75 mCallingPackage = getLaunchedFromPackage(); 76 77 if (UserHandle.isSameApp(mCallingUid, Process.SYSTEM_UID) && 78 getIntent().getStringExtra(AccountManager.KEY_ANDROID_PACKAGE_NAME) != null) { 79 mCallingPackage = getIntent().getStringExtra( 80 AccountManager.KEY_ANDROID_PACKAGE_NAME); 81 } 82 83 if (!UserHandle.isSameApp(mCallingUid, Process.SYSTEM_UID) && 84 getIntent().getStringExtra(AccountManager.KEY_ANDROID_PACKAGE_NAME) != null) { 85 Log.w(getClass().getSimpleName(), 86 "Non-system Uid: " + mCallingUid + " tried to override packageName \n"); 87 } 88 89 getAuthDescriptions(); 90 91 AccountInfo[] mAccountInfos = new AccountInfo[mAccounts.length]; 92 for (int i = 0; i < mAccounts.length; i++) { 93 mAccountInfos[i] = new AccountInfo(((Account) mAccounts[i]).name, 94 getDrawableForType(((Account) mAccounts[i]).type)); 95 } 96 97 setContentView(R.layout.choose_account); 98 99 // Setup the list 100 ListView list = findViewById(android.R.id.list); 101 // Use an existing ListAdapter that will map an array of strings to TextViews 102 list.setAdapter(new AccountArrayAdapter(this, 103 android.R.layout.simple_list_item_1, mAccountInfos)); 104 list.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 105 list.setTextFilterEnabled(true); 106 list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 107 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 108 onListItemClick((ListView)parent, v, position, id); 109 } 110 }); 111 } 112 getAuthDescriptions()113 private void getAuthDescriptions() { 114 for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) { 115 mTypeToAuthDescription.put(desc.type, desc); 116 } 117 } 118 getDrawableForType(String accountType)119 private Drawable getDrawableForType(String accountType) { 120 Drawable icon = null; 121 if(mTypeToAuthDescription.containsKey(accountType)) { 122 try { 123 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); 124 Context authContext = createPackageContext(desc.packageName, 0); 125 icon = authContext.getDrawable(desc.iconId); 126 } catch (PackageManager.NameNotFoundException e) { 127 // Nothing we can do much here, just log 128 if (Log.isLoggable(TAG, Log.WARN)) { 129 Log.w(TAG, "No icon name for account type " + accountType); 130 } 131 } catch (Resources.NotFoundException e) { 132 // Nothing we can do much here, just log 133 if (Log.isLoggable(TAG, Log.WARN)) { 134 Log.w(TAG, "No icon resource for account type " + accountType); 135 } 136 } 137 } 138 return icon; 139 } 140 onListItemClick(ListView l, View v, int position, long id)141 protected void onListItemClick(ListView l, View v, int position, long id) { 142 Account account = (Account) mAccounts[position]; 143 // Mark account as visible since user chose it. 144 AccountManager am = AccountManager.get(this); 145 Integer oldVisibility = am.getAccountVisibility(account, mCallingPackage); 146 if (oldVisibility != null 147 && oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE) { 148 am.setAccountVisibility(account, mCallingPackage, 149 AccountManager.VISIBILITY_USER_MANAGED_VISIBLE); 150 } 151 Log.d(TAG, "selected account " + account.toSafeString()); 152 Bundle bundle = new Bundle(); 153 bundle.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 154 bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 155 mResult = bundle; 156 finish(); 157 } 158 finish()159 public void finish() { 160 if (mAccountManagerResponse != null) { 161 if (mResult != null) { 162 mAccountManagerResponse.onResult(mResult); 163 } else { 164 mAccountManagerResponse.onError(AccountManager.ERROR_CODE_CANCELED, "canceled"); 165 } 166 } 167 super.finish(); 168 } 169 170 private static class AccountInfo { 171 final String name; 172 final Drawable drawable; 173 AccountInfo(String name, Drawable drawable)174 AccountInfo(String name, Drawable drawable) { 175 this.name = name; 176 this.drawable = drawable; 177 } 178 } 179 180 private static class ViewHolder { 181 ImageView icon; 182 TextView text; 183 } 184 185 private static class AccountArrayAdapter extends ArrayAdapter<AccountInfo> { 186 private LayoutInflater mLayoutInflater; 187 private AccountInfo[] mInfos; 188 AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos)189 public AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos) { 190 super(context, textViewResourceId, infos); 191 mInfos = infos; 192 mLayoutInflater = (LayoutInflater) context.getSystemService( 193 Context.LAYOUT_INFLATER_SERVICE); 194 } 195 196 @Override getView(int position, View convertView, ViewGroup parent)197 public View getView(int position, View convertView, ViewGroup parent) { 198 ViewHolder holder; 199 200 if (convertView == null) { 201 convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null); 202 holder = new ViewHolder(); 203 holder.text = (TextView) convertView.findViewById(R.id.account_row_text); 204 holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon); 205 convertView.setTag(holder); 206 } else { 207 holder = (ViewHolder) convertView.getTag(); 208 } 209 210 holder.text.setText(mInfos[position].name); 211 holder.icon.setImageDrawable(mInfos[position].drawable); 212 213 return convertView; 214 } 215 } 216 } 217