blob: 7f4b099303ab5e439c541b97f9bb615217dd8e95 [file] [log] [blame]
alisiona4325152013-04-19 11:10:03 -04001package com.savoirfairelinux.sflphone.adapters;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.Stack;
6
7import android.app.Activity;
8import android.content.Context;
9import android.net.Uri;
10import android.os.RemoteException;
11import android.util.Log;
12import android.view.LayoutInflater;
13import android.view.View;
14import android.view.ViewGroup;
15import android.widget.BaseAdapter;
16import android.widget.RadioButton;
17import android.widget.TextView;
18
19import com.savoirfairelinux.sflphone.R;
20import com.savoirfairelinux.sflphone.account.AccountDetailBasic;
21import com.savoirfairelinux.sflphone.service.ISipService;
22
23public class AccountSelectionAdapter extends BaseAdapter {
24
25 private static final String TAG = AccountSelectionAdapter.class.getSimpleName();
26
27 ArrayList<String> accountIDs;
28 Context mContext;
29 AccountManager accManager;
30 ISipService service;
31 int selectedAccount = 0;
32
33 public AccountSelectionAdapter(Context cont, ISipService s, ArrayList<String> newList) {
34 super();
35 accountIDs = newList;
36 mContext = cont;
37 service = s;
38 accManager = new AccountManager(mContext);
39 }
40
41 @Override
42 public int getCount() {
43 return accountIDs.size();
44 }
45
46 @Override
47 public String getItem(int pos) {
48 return accountIDs.get(pos);
49 }
50
51 @Override
52 public long getItemId(int pos) {
53 return 0;
54 }
55
56 @Override
57 public View getView(int pos, View convertView, ViewGroup parent) {
58 View rowView = convertView;
59 AccountView entryView = null;
60
61 if (rowView == null) {
62 LayoutInflater inflater = LayoutInflater.from(mContext);
63 rowView = inflater.inflate(R.layout.item_account, null);
64
65 entryView = new AccountView();
66 entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
67 entryView.host = (TextView) rowView.findViewById(R.id.account_host);
68 entryView.select = (RadioButton) rowView.findViewById(R.id.account_checked);
69 rowView.setTag(entryView);
70 } else {
71 entryView = (AccountView) rowView.getTag();
72 }
73
74 accManager.displayAccountDetails(accountIDs.get(pos), entryView);
75 if(pos == selectedAccount){
76 entryView.select.setChecked(true);
77 }
78
79 return rowView;
80 }
81
82 /*********************
83 * ViewHolder Pattern
84 *********************/
85 public class AccountView {
86 public TextView alias;
87 public TextView host;
88 public RadioButton select;
89 }
90
91 /**
92 * Asynchronous account details retriever
93 */
94 public class AccountManager {
95
96 // private static final String TAG = ImageManager.class.getSimpleName();
97
98 private HashMap<String, HashMap<String, String>> accountMap = new HashMap<String, HashMap<String, String>>();
99 private AccountQueue accountQueue = new AccountQueue();
100 private Thread accountLoaderThread = new Thread(new AccountQueueManager());
101
102
103 public AccountManager(Context context) {
104 accountLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);
105
106 }
107
108 public void displayAccountDetails(String id, AccountView account) {
109
110 if (accountMap.containsKey(id)) {
111
112 HashMap<String, String> details = accountMap.get(id);
113 account.alias.setText(details.get(AccountDetailBasic.CONFIG_ACCOUNT_ALIAS));
114 account.host.setText(details.get(AccountDetailBasic.CONFIG_ACCOUNT_HOSTNAME));
115
116 } else {
117 queueAccount(id, account);
118 }
119 }
120
121 private void queueAccount(String id, AccountView row) {
122 // This ImageView might have been used for other images, so we clear
123 // the queue of old tasks before starting.
124 accountQueue.Clean(row);
125 AccountRef p = new AccountRef(id, row);
126
127 synchronized (accountQueue.accountRefsStack) {
128 accountQueue.accountRefsStack.push(p);
129 accountQueue.accountRefsStack.notifyAll();
130 }
131
132 // Start thread if it's not started yet
133 if (accountLoaderThread.getState() == Thread.State.NEW) {
134 accountLoaderThread.start();
135 }
136 }
137
138 /** Classes **/
139
140 private class AccountRef {
141 public String accountID;
142 public AccountView row;
143
144 public AccountRef(String u, AccountView i) {
145 accountID = u;
146 row = i;
147 }
148 }
149
150 private class AccountQueue {
151 private Stack<AccountRef> accountRefsStack = new Stack<AccountRef>();
152
153 // removes all instances of this account
154 public void Clean(AccountView view) {
155
156 for (int i = 0; i < accountRefsStack.size();) {
157 if (accountRefsStack.get(i).row == view)
158 accountRefsStack.remove(i);
159 else
160 ++i;
161 }
162 }
163 }
164
165 private class AccountQueueManager implements Runnable {
166 @Override
167 public void run() {
168 try {
169 while (true) {
170 // Thread waits until there are accountsID in the queue to be retrieved
171 if (accountQueue.accountRefsStack.size() == 0) {
172 synchronized (accountQueue.accountRefsStack) {
173 accountQueue.accountRefsStack.wait();
174 }
175 }
176
177 // When we have accounts to load
178 if (accountQueue.accountRefsStack.size() != 0) {
179 AccountRef accountToLoad;
180
181 synchronized (accountQueue.accountRefsStack) {
182 accountToLoad = accountQueue.accountRefsStack.pop();
183 }
184
185 HashMap<String, String> details = (HashMap<String, String>) service.getAccountDetails(accountToLoad.accountID);
186 accountMap.put(accountToLoad.accountID, details);
187 AccountDisplayer accDisplayer = new AccountDisplayer(details, accountToLoad.row);
188 Activity a = (Activity) mContext;
189
190 a.runOnUiThread(accDisplayer);
191
192 }
193
194 if (Thread.interrupted())
195 break;
196 }
197 } catch (InterruptedException e) {
198 Log.e(TAG, e.toString());
199 } catch (RemoteException e) {
200 Log.e(TAG, e.toString());
201 }
202 }
203 }
204
205 // Used to display details in the UI thread
206 private class AccountDisplayer implements Runnable {
207 HashMap<String, String> displayDetails;
208 AccountView displayRow;
209
210 public AccountDisplayer(HashMap<String, String> details, AccountView row) {
211 displayRow = row;
212 displayDetails = details;
213 }
214
215 public void run() {
216 displayRow.alias.setText(displayDetails.get(AccountDetailBasic.CONFIG_ACCOUNT_ALIAS));
217 displayRow.host.setText(displayDetails.get(AccountDetailBasic.CONFIG_ACCOUNT_HOSTNAME));
218 }
219 }
220
221 public void removeFromCache(Uri uri) {
222 if (accountMap.containsKey(uri)) {
223 accountMap.remove(uri);
224 }
225 }
226 }
227
228 public void setSelectedAccount(int pos) {
229 selectedAccount = pos;
230 }
231
232}