• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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