blob: 0b264d411ab3f9817bf60e21e7176218e080c99f [file] [log] [blame]
Alexandre Savarddcd37402012-09-06 18:36:48 -04001/*
alision2ec64f92013-06-17 17:28:58 -04002 * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
Alexandre Savarddcd37402012-09-06 18:36:48 -04003 *
4 * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
alision2ec64f92013-06-17 17:28:58 -04005 * Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Alexandre Savarddcd37402012-09-06 18:36:48 -04006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * Additional permission under GNU GPL version 3 section 7:
22 *
23 * If you modify this program, or any covered work, by linking or
24 * combining it with the OpenSSL project's OpenSSL library (or a
25 * modified version of that library), containing parts covered by the
26 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
27 * grants you additional permission to convey the resulting work.
28 * Corresponding Source for a non-source form of such a combination
29 * shall include the source code for the parts of OpenSSL used as well
30 * as that of the covered work.
31 */
32
Alexandre Lision064e1e02013-10-01 16:18:42 -040033package org.sflphone.fragments;
34
Alexandre Lision933ef0a2013-10-15 17:28:40 -040035import java.util.ArrayList;
36
Alexandre Lision064e1e02013-10-01 16:18:42 -040037import org.sflphone.R;
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050038import org.sflphone.account.AccountDetail;
39import org.sflphone.model.Account;
Alexandre Lision933ef0a2013-10-15 17:28:40 -040040import org.sflphone.model.Codec;
41import org.sflphone.service.ISipService;
Alexandre Lisionc1849932013-10-24 10:09:32 -040042import org.sflphone.views.dragsortlv.DragSortListView;
Alexandre Savarddcd37402012-09-06 18:36:48 -040043
Alexandre Savard393ccab2012-09-11 15:01:20 -040044import android.app.Activity;
Alexandre Savard5e0b9472012-09-11 17:56:30 -040045import android.content.Context;
Alexandre Lision6e8931e2013-09-19 16:49:34 -040046import android.os.Bundle;
Alexandre Lision933ef0a2013-10-15 17:28:40 -040047import android.os.RemoteException;
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050048import android.preference.CheckBoxPreference;
Alexandre Savard393ccab2012-09-11 15:01:20 -040049import android.preference.Preference;
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050050import android.preference.Preference.OnPreferenceChangeListener;
Alexandre Savard393ccab2012-09-11 15:01:20 -040051import android.preference.PreferenceFragment;
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050052import android.util.Log;
Alexandre Lisionc1849932013-10-24 10:09:32 -040053import android.view.LayoutInflater;
Alexandre Savarddcd37402012-09-06 18:36:48 -040054import android.view.View;
Alexandre Lisiona3650992013-11-13 14:19:35 -050055import android.view.View.MeasureSpec;
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050056import android.view.ViewGroup;
Alexandre Lisionc1849932013-10-24 10:09:32 -040057import android.widget.AdapterView;
58import android.widget.AdapterView.OnItemClickListener;
59import android.widget.BaseAdapter;
60import android.widget.CheckBox;
Alexandre Lisiona3650992013-11-13 14:19:35 -050061import android.widget.LinearLayout;
62import android.widget.ListAdapter;
63import android.widget.ListView;
Alexandre Savard5e0b9472012-09-11 17:56:30 -040064import android.widget.TextView;
Alexandre Savarddcd37402012-09-06 18:36:48 -040065
Alexandre Lision933ef0a2013-10-15 17:28:40 -040066public class AudioManagementFragment extends PreferenceFragment {
Alexandre Lisiona3650992013-11-13 14:19:35 -050067 static final String TAG = AudioManagementFragment.class.getSimpleName();
Alexandre Savard12dc3ac2012-09-27 11:17:39 -040068
Alexandre Lision933ef0a2013-10-15 17:28:40 -040069 protected Callbacks mCallbacks = sDummyCallbacks;
70 ArrayList<Codec> codecs;
Alexandre Lisionc9c30b72013-11-18 16:27:26 -050071 private DragSortListView mCodecList;
Alexandre Lisiona3650992013-11-13 14:19:35 -050072 CodecAdapter listAdapter;
Alexandre Lision933ef0a2013-10-15 17:28:40 -040073 private static Callbacks sDummyCallbacks = new Callbacks() {
74
75 @Override
76 public ISipService getService() {
77 return null;
78 }
79
80 @Override
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050081 public Account getAccount() {
Alexandre Lision933ef0a2013-10-15 17:28:40 -040082 return null;
83 }
84
85 };
86
87 public interface Callbacks {
88
89 public ISipService getService();
90
Alexandre Lision68ee0ac2013-12-06 15:06:19 -050091 public Account getAccount();
Alexandre Lision933ef0a2013-10-15 17:28:40 -040092
Alexandre Savard12dc3ac2012-09-27 11:17:39 -040093 }
Alexandre Savarddcd37402012-09-06 18:36:48 -040094
95 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -040096 public void onAttach(Activity activity) {
97 super.onAttach(activity);
98 if (!(activity instanceof Callbacks)) {
99 throw new IllegalStateException("Activity must implement fragment's callbacks.");
100 }
101
102 mCallbacks = (Callbacks) activity;
103 try {
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500104 codecs = (ArrayList<Codec>) mCallbacks.getService().getAudioCodecList(mCallbacks.getAccount().getAccountID());
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400105 mCallbacks.getService().getRingtoneList();
Alexandre Lision933ef0a2013-10-15 17:28:40 -0400106 } catch (RemoteException e) {
107 e.printStackTrace();
108 }
109 }
110
111 @Override
112 public void onDetach() {
113 super.onDetach();
114 mCallbacks = sDummyCallbacks;
115 }
116
Alexandre Lisionc1849932013-10-24 10:09:32 -0400117 private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
118 @Override
119 public void drop(int from, int to) {
120 if (from != to) {
121 Codec item = listAdapter.getItem(from);
122 listAdapter.remove(item);
123 listAdapter.insert(item, to);
Alexandre Lision4df961d2013-10-16 13:44:49 -0400124 try {
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500125 mCallbacks.getService().setActiveCodecList(getActiveCodecList(), mCallbacks.getAccount().getAccountID());
Alexandre Lision4df961d2013-10-16 13:44:49 -0400126 } catch (RemoteException e) {
127 e.printStackTrace();
128 }
Alexandre Lisionc1849932013-10-24 10:09:32 -0400129 }
130 }
131 };
Alexandre Lisiona3650992013-11-13 14:19:35 -0500132
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500133 private ListView mPrefsList;
134
Alexandre Lisionc1849932013-10-24 10:09:32 -0400135 public ArrayList<String> getActiveCodecList() {
136 ArrayList<String> results = new ArrayList<String>();
137 for (int i = 0; i < listAdapter.getCount(); ++i) {
138 if (listAdapter.getItem(i).isEnabled()) {
139 results.add(listAdapter.getItem(i).getPayload().toString());
140 }
141 }
142 return results;
143 }
Alexandre Lisiona3650992013-11-13 14:19:35 -0500144
Alexandre Lisionc1849932013-10-24 10:09:32 -0400145 @Override
Alexandre Lisiona3650992013-11-13 14:19:35 -0500146 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Alexandre Lisionc1849932013-10-24 10:09:32 -0400147 super.onCreateView(inflater, container, savedInstanceState);
Alexandre Lisiona3650992013-11-13 14:19:35 -0500148 View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.frag_audio_mgmt, null);
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500149
150 mPrefsList = (ListView) rootView.findViewById(android.R.id.list);
Alexandre Lisionc9c30b72013-11-18 16:27:26 -0500151 mCodecList = (DragSortListView) rootView.findViewById(R.id.dndlistview);
152 mCodecList.setAdapter(listAdapter);
153 mCodecList.setDropListener(onDrop);
154 mCodecList.setOnItemClickListener(new OnItemClickListener() {
Alexandre Lisionc1849932013-10-24 10:09:32 -0400155
156 @Override
157 public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
158 listAdapter.getItem(pos).toggleState();
159 listAdapter.notifyDataSetChanged();
160 try {
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500161 mCallbacks.getService().setActiveCodecList(getActiveCodecList(), mCallbacks.getAccount().getAccountID());
Alexandre Lisionc1849932013-10-24 10:09:32 -0400162 } catch (RemoteException e) {
163 e.printStackTrace();
164 }
165
Alexandre Lision4df961d2013-10-16 13:44:49 -0400166 }
167 });
Alexandre Lisionc1849932013-10-24 10:09:32 -0400168 return rootView;
169 }
170
171 @Override
Alexandre Lisiona3650992013-11-13 14:19:35 -0500172 public void onViewCreated(View view, Bundle savedInstanceState) {
173 super.onViewCreated(view, savedInstanceState);
174 final LinearLayout holder = (LinearLayout) getView().findViewById(R.id.lv_holder);
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500175 final LinearLayout holder_prefs = (LinearLayout) getView().findViewById(R.id.lv_holder_prefs);
Alexandre Lisiona3650992013-11-13 14:19:35 -0500176 holder.post(new Runnable() {
177
178 @Override
179 public void run() {
Alexandre Lisionc9c30b72013-11-18 16:27:26 -0500180 setListViewHeight(mCodecList, holder);
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500181 setListViewHeight(mPrefsList, holder_prefs);
Alexandre Lisiona3650992013-11-13 14:19:35 -0500182 }
183 });
184
185 }
186
187 // Sets the ListView holder's height
188 public void setListViewHeight(ListView listView, LinearLayout llMain) {
189 ListAdapter listAdapter = listView.getAdapter();
190 if (listAdapter == null) {
191 return;
192 }
193
194 int totalHeight = 0;
195 int firstHeight = 0;
196 int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
197
198 for (int i = 0; i < listAdapter.getCount(); i++) {
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500199 View listItem = listAdapter.getView(i, null, listView);
200 listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
201 firstHeight = listItem.getMeasuredHeight();
Alexandre Lisiona3650992013-11-13 14:19:35 -0500202 totalHeight += firstHeight;
203 }
204
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500205 totalHeight += getView().findViewById(R.id.list_header_title).getMeasuredHeight();
206 Log.w(TAG, "totalHeight:" + totalHeight);
Alexandre Lisiona3650992013-11-13 14:19:35 -0500207
208 LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) llMain.getLayoutParams();
209
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500210 params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount()));
Alexandre Lisiona3650992013-11-13 14:19:35 -0500211 llMain.setLayoutParams(params);
212 getView().requestLayout();
213 }
214
215 @Override
Alexandre Lisionc1849932013-10-24 10:09:32 -0400216 public void onCreate(Bundle savedInstanceState) {
Alexandre Lisiona3650992013-11-13 14:19:35 -0500217 super.onCreate(savedInstanceState);
218
Alexandre Lisionc48c36a2013-11-12 16:26:10 -0500219 addPreferencesFromResource(R.xml.account_audio_prefs);
Alexandre Lisionc1849932013-10-24 10:09:32 -0400220 listAdapter = new CodecAdapter(getActivity());
221 listAdapter.setDataset(codecs);
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500222
223 setPreferenceDetails(mCallbacks.getAccount().getAdvancedDetails());
224 addPreferenceListener(mCallbacks.getAccount().getAdvancedDetails(), changeAudioPreferenceListener);
Alexandre Savarddcd37402012-09-06 18:36:48 -0400225 }
226
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500227 Preference.OnPreferenceChangeListener changeAudioPreferenceListener = new Preference.OnPreferenceChangeListener() {
228 @Override
Alexandre Savard393ccab2012-09-11 15:01:20 -0400229 public boolean onPreferenceChange(Preference preference, Object newValue) {
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500230 if (preference instanceof CheckBoxPreference) {
231 mCallbacks.getAccount().getAdvancedDetails().setDetailString(preference.getKey(), ((Boolean) newValue).toString());
232 } else {
233 preference.setSummary((CharSequence) newValue);
234 Log.i(TAG, "Changing" + preference.getKey() + " value:" + newValue);
235 mCallbacks.getAccount().getAdvancedDetails().setDetailString(preference.getKey(), ((CharSequence) newValue).toString());
236 }
237 mCallbacks.getAccount().notifyObservers();
238
Alexandre Savard393ccab2012-09-11 15:01:20 -0400239 return true;
240 }
241 };
242
Alexandre Lision68ee0ac2013-12-06 15:06:19 -0500243 Preference.OnPreferenceChangeListener changePreferenceListener = new Preference.OnPreferenceChangeListener() {
244 public boolean onPreferenceChange(Preference preference, Object newValue) {
245
246 if (preference instanceof CheckBoxPreference) {
247 mCallbacks.getAccount().getAdvancedDetails().setDetailString(preference.getKey(), ((Boolean) newValue).toString());
248 } else {
249 preference.setSummary((CharSequence) newValue);
250 Log.i(TAG, "Changing" + preference.getKey() + " value:" + newValue);
251 mCallbacks.getAccount().getAdvancedDetails().setDetailString(preference.getKey(), ((CharSequence) newValue).toString());
252
253 }
254
255 mCallbacks.getAccount().notifyObservers();
256 return true;
257 }
258 };
259
260 private void setPreferenceDetails(AccountDetail details) {
261 for (AccountDetail.PreferenceEntry p : details.getDetailValues()) {
262 Log.i(TAG, "setPreferenceDetails: pref " + p.mKey + " value " + p.mValue);
263 Preference pref = findPreference(p.mKey);
264 if (pref != null) {
265 if (!p.isTwoState) {
266 if (p.mKey.contentEquals("Account.dtmfType")){
267 pref.setDefaultValue(p.mValue.contentEquals("overrtp") ? "RTP" : "SIP");
268 pref.setSummary(p.mValue);
269 } else {
270 pref.setSummary(p.mValue);
271 }
272
273 } else {
274 ((CheckBoxPreference) pref).setChecked(p.mValue.contentEquals("true"));
275 }
276
277 } else {
278 Log.w(TAG, "pref not found");
279 }
280 }
281 }
282
283 private void addPreferenceListener(AccountDetail details, OnPreferenceChangeListener listener) {
284 for (AccountDetail.PreferenceEntry p : details.getDetailValues()) {
285 Log.i(TAG, "addPreferenceListener: pref " + p.mKey + p.mValue);
286 Preference pref = findPreference(p.mKey);
287 if (pref != null) {
288
289 pref.setOnPreferenceChangeListener(listener);
290
291 } else {
292 Log.w(TAG, "addPreferenceListener: pref not found");
293 }
294 }
295 }
296
Alexandre Lisionc1849932013-10-24 10:09:32 -0400297 public static class CodecAdapter extends BaseAdapter {
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400298
Alexandre Lisionc1849932013-10-24 10:09:32 -0400299 ArrayList<Codec> items;
300 private Context mContext;
301
302 public CodecAdapter(Context context) {
303 items = new ArrayList<Codec>();
304 mContext = context;
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400305 }
306
Alexandre Lisionc1849932013-10-24 10:09:32 -0400307 public void insert(Codec item, int to) {
308 items.add(to, item);
309 notifyDataSetChanged();
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400310 }
311
Alexandre Lisionc1849932013-10-24 10:09:32 -0400312 public void remove(Codec item) {
313 items.remove(item);
314 notifyDataSetChanged();
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400315 }
316
Alexandre Lisionc1849932013-10-24 10:09:32 -0400317 public ArrayList<Codec> getDataset() {
318 return items;
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400319 }
320
321 @Override
Alexandre Lisionc1849932013-10-24 10:09:32 -0400322 public int getCount() {
323 return items.size();
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400324 }
325
Alexandre Lisionc1849932013-10-24 10:09:32 -0400326 @Override
327 public Codec getItem(int position) {
328 return items.get(position);
329 }
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400330
Alexandre Lisionc1849932013-10-24 10:09:32 -0400331 @Override
332 public long getItemId(int position) {
333 return 0;
334 }
335
336 @Override
337 public int getItemViewType(int position) {
338 return 0;
339 }
340
341 @Override
342 public View getView(int pos, View convertView, ViewGroup parent) {
343 View rowView = convertView;
344 CodecView entryView = null;
345
346 if (rowView == null) {
347 LayoutInflater inflater = LayoutInflater.from(mContext);
348 rowView = inflater.inflate(R.layout.item_codec, null);
349
350 entryView = new CodecView();
351 entryView.name = (TextView) rowView.findViewById(R.id.codec_name);
Alexandre Lisionc1849932013-10-24 10:09:32 -0400352 entryView.samplerate = (TextView) rowView.findViewById(R.id.codec_samplerate);
Alexandre Lisionc1849932013-10-24 10:09:32 -0400353 entryView.enabled = (CheckBox) rowView.findViewById(R.id.codec_checked);
354 rowView.setTag(entryView);
355 } else {
356 entryView = (CodecView) rowView.getTag();
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400357 }
Alexandre Lision423aa132013-12-10 17:31:10 -0500358
359 if(items.get(pos).isSpeex())
360 entryView.samplerate.setVisibility(View.VISIBLE);
361 else
362 entryView.samplerate.setVisibility(View.GONE);
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400363
Alexandre Lisionc1849932013-10-24 10:09:32 -0400364 entryView.name.setText(items.get(pos).getName());
365 entryView.samplerate.setText(items.get(pos).getSampleRate());
Alexandre Lisionc1849932013-10-24 10:09:32 -0400366 entryView.enabled.setChecked(items.get(pos).isEnabled());
Alexandre Lision423aa132013-12-10 17:31:10 -0500367
Alexandre Lisionc1849932013-10-24 10:09:32 -0400368 return rowView;
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400369
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400370 }
371
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400372 @Override
Alexandre Lisionc1849932013-10-24 10:09:32 -0400373 public int getViewTypeCount() {
374 return 1;
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400375 }
376
377 @Override
Alexandre Lisionc1849932013-10-24 10:09:32 -0400378 public boolean hasStableIds() {
379 return true;
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400380 }
381
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400382 @Override
Alexandre Lisionc1849932013-10-24 10:09:32 -0400383 public boolean isEmpty() {
384 return getCount() == 0;
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400385 }
386
Alexandre Lisionc1849932013-10-24 10:09:32 -0400387 @Override
388 public boolean areAllItemsEnabled() {
389 return true;
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400390 }
391
Alexandre Lisionc1849932013-10-24 10:09:32 -0400392 @Override
393 public boolean isEnabled(int position) {
394 return true;
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400395 }
396
Alexandre Lisionc1849932013-10-24 10:09:32 -0400397 public void setDataset(ArrayList<Codec> codecs) {
398 items = new ArrayList<Codec>(codecs);
399 }
Alexandre Savarde2bb2592012-09-11 18:39:57 -0400400
Alexandre Lisionc1849932013-10-24 10:09:32 -0400401 /*********************
402 * ViewHolder Pattern
403 *********************/
404 public class CodecView {
405 public TextView name;
406 public TextView samplerate;
Alexandre Lisionc1849932013-10-24 10:09:32 -0400407 public CheckBox enabled;
Alexandre Savard5e0b9472012-09-11 17:56:30 -0400408 }
409 }
Alexandre Savarddcd37402012-09-06 18:36:48 -0400410}