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