PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/jitsi/android/gui/account/AccountsListActivity.java

https://gitlab.com/yorty.ruiz/jitsi-android
Java | 424 lines | 266 code | 51 blank | 107 comment | 20 complexity | 96dbe8f09a108b2d3dad1503cf3732ae MD5 | raw file
  1. /*
  2. * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
  3. *
  4. * Copyright @ 2015 Atlassian Pty Ltd
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.jitsi.android.gui.account;
  19. import net.java.sip.communicator.service.protocol.*;
  20. import net.java.sip.communicator.util.*;
  21. import net.java.sip.communicator.util.account.*;
  22. import org.jitsi.R;
  23. import org.jitsi.android.*;
  24. import org.jitsi.android.gui.*;
  25. import org.jitsi.android.gui.account.settings.*;
  26. import org.jitsi.android.gui.util.*;
  27. import org.jitsi.service.osgi.*;
  28. import android.content.*;
  29. import android.view.*;
  30. import android.widget.*;
  31. import java.util.*;
  32. /**
  33. * The activity display list of currently stored accounts
  34. * showing it's protocol and current status.
  35. *
  36. * @author Pawel Domas
  37. */
  38. public class AccountsListActivity
  39. extends OSGiActivity
  40. {
  41. /**
  42. * The logger
  43. */
  44. private static final Logger logger
  45. = Logger.getLogger(AccountsListActivity.class);
  46. /**
  47. * The list adapter for accounts
  48. */
  49. private AccountStatusListAdapter listAdapter;
  50. /**
  51. * The {@link AccountManager} used to operate on {@link AccountID}s
  52. */
  53. private AccountManager accountManager;
  54. /**
  55. * Stores clicked account in member field, as context info is not available.
  56. * That's because account list contains on/off buttons and that prevents
  57. * from "normal" list item clicks/long clicks handling.
  58. */
  59. private Account clickedAccount;
  60. /**
  61. * Keeps track of displayed "in progress" dialog during account
  62. * registration.
  63. */
  64. private static long progressDialog;
  65. /**
  66. * Keeps track of thread used to register accounts and prevents from
  67. * starting multiple at one time.
  68. */
  69. private static AccountEnableThread accEnableThread;
  70. @Override
  71. protected void onCreate(android.os.Bundle savedInstanceState)
  72. {
  73. super.onCreate(savedInstanceState);
  74. if(AndroidGUIActivator.bundleContext == null)
  75. {
  76. // No OSGi Exists
  77. logger.error("OSGi not initialized");
  78. finish();
  79. return;
  80. }
  81. setContentView(R.layout.account_list);
  82. this.accountManager
  83. = ServiceUtils.getService(AndroidGUIActivator.bundleContext,
  84. AccountManager.class);
  85. }
  86. @Override
  87. protected void onResume()
  88. {
  89. // Need to refresh the list each time
  90. // in case account might be removed in other Activity.
  91. // Also it can't be removed on "unregistered" event,
  92. // because on/off buttons will cause the account to disappear
  93. accountsInit();
  94. super.onResume();
  95. }
  96. @Override
  97. protected void onDestroy()
  98. {
  99. // Unregisters presence status listeners
  100. if(listAdapter != null)
  101. {
  102. listAdapter.deinitStatusListeners();
  103. }
  104. super.onDestroy();
  105. }
  106. /**
  107. * {@inheritDoc}
  108. */
  109. @Override
  110. public boolean onCreateOptionsMenu(Menu menu)
  111. {
  112. super.onCreateOptionsMenu(menu);
  113. getMenuInflater().inflate(R.menu.account_settings_menu, menu);
  114. return true;
  115. }
  116. /**
  117. * {@inheritDoc}
  118. */
  119. @Override
  120. public boolean onOptionsItemSelected(MenuItem item)
  121. {
  122. if(item.getItemId() == R.id.add_account)
  123. {
  124. startActivity(AccountLoginActivity.class);
  125. return true;
  126. }
  127. return super.onOptionsItemSelected(item);
  128. }
  129. /**
  130. * Initializes the accounts table.
  131. */
  132. private void accountsInit()
  133. {
  134. // Create accounts array
  135. Collection<AccountID> accountIDCollection =
  136. AccountUtils.getStoredAccounts();
  137. // Create account list adapter
  138. listAdapter =
  139. new AccountStatusListAdapter(accountIDCollection);
  140. // Puts the adapter into accounts ListView
  141. ListView lv = (ListView)findViewById(R.id.accountListView);
  142. lv.setAdapter(listAdapter);
  143. }
  144. /**
  145. * {@inheritDoc}
  146. */
  147. @Override
  148. public void onCreateContextMenu(ContextMenu menu, View v,
  149. ContextMenu.ContextMenuInfo menuInfo)
  150. {
  151. super.onCreateContextMenu(menu, v, menuInfo);
  152. getMenuInflater().inflate(R.menu.account_ctx_menu, menu);
  153. // Set menu title
  154. menu.setHeaderTitle(clickedAccount.getAccountName());
  155. MenuItem accountSettings = menu.findItem(R.id.account_settings);
  156. accountSettings.setVisible(
  157. clickedAccount.getProtocolProvider() != null);
  158. }
  159. @Override
  160. public boolean onContextItemSelected(MenuItem item)
  161. {
  162. int id = item.getItemId();
  163. if(id == R.id.remove)
  164. {
  165. RemoveAccountDialog
  166. .create(this, clickedAccount.getAccountID(),
  167. new RemoveAccountDialog.OnAccountRemovedListener()
  168. {
  169. @Override
  170. public void onAccountRemoved(AccountID accID)
  171. {
  172. listAdapter.remove(clickedAccount);
  173. }
  174. })
  175. .show();
  176. return true;
  177. }
  178. else if(id == R.id.account_settings)
  179. {
  180. Intent preferences
  181. = AccountPreferencesActivity
  182. .getIntent(this, clickedAccount.getAccountID());
  183. startActivity(preferences);
  184. return true;
  185. }
  186. return super.onContextItemSelected(item);
  187. }
  188. /**
  189. * Starts the {@link PresenceStatusActivity} for clicked {@link Account}
  190. *
  191. * @param account the <tt>Account</tt> for which settings will be opened.
  192. */
  193. private void startPresenceActivity(Account account)
  194. {
  195. Intent statusIntent = new Intent( getBaseContext(),
  196. PresenceStatusActivity.class);
  197. statusIntent.putExtra( PresenceStatusActivity.INTENT_ACCOUNT_ID,
  198. account.getAccountID().getAccountUniqueID());
  199. startActivity(statusIntent);
  200. }
  201. /**
  202. * Class responsible for creating list row Views
  203. */
  204. class AccountStatusListAdapter
  205. extends AccountsListAdapter
  206. {
  207. /**
  208. * Toast instance
  209. */
  210. private Toast offlineToast;
  211. /**
  212. * Creates new instance of {@link AccountStatusListAdapter}
  213. * @param accounts array of currently stored accounts
  214. */
  215. AccountStatusListAdapter(Collection<AccountID> accounts)
  216. {
  217. super( AccountsListActivity.this,
  218. R.layout.account_enable_row, -1,
  219. accounts, false);
  220. }
  221. /**
  222. * {@inheritDoc}
  223. */
  224. @Override
  225. protected View getView( boolean isDropDown,
  226. final Account account,
  227. ViewGroup parent,
  228. LayoutInflater inflater)
  229. {
  230. // Creates the list view
  231. View rowView = super.getView(isDropDown, account, parent, inflater);
  232. rowView.setClickable(true);
  233. rowView.setOnClickListener(new View.OnClickListener()
  234. {
  235. @Override
  236. public void onClick(View v)
  237. {
  238. // Start only for registered accounts
  239. if(account.getProtocolProvider() != null)
  240. {
  241. startPresenceActivity(account);
  242. }
  243. else
  244. {
  245. String msg = getString(
  246. R.string.service_gui_ACCOUNT_DISCONNECTED,
  247. account.getAccountName());
  248. if(offlineToast == null)
  249. {
  250. offlineToast = Toast.makeText(
  251. AccountsListActivity.this,
  252. msg, Toast.LENGTH_SHORT);
  253. }
  254. else
  255. {
  256. offlineToast.setText(msg);
  257. }
  258. offlineToast.show();
  259. }
  260. }
  261. });
  262. rowView.setOnLongClickListener(new View.OnLongClickListener()
  263. {
  264. @Override
  265. public boolean onLongClick(View v)
  266. {
  267. registerForContextMenu(v);
  268. clickedAccount = account;
  269. openContextMenu(v);
  270. return true;
  271. }
  272. });
  273. ToggleButton button =
  274. (ToggleButton) rowView.findViewById(
  275. R.id.accountToggleButton);
  276. button.setChecked(account.isEnabled());
  277. button.setOnCheckedChangeListener(
  278. new CompoundButton.OnCheckedChangeListener()
  279. {
  280. public void onCheckedChanged( CompoundButton compoundButton,
  281. boolean enable)
  282. {
  283. if(accEnableThread != null)
  284. {
  285. logger.error("Ongoing operation in progress");
  286. return;
  287. }
  288. logger.debug("Toggle " + account + " -> " + enable);
  289. // Prevents from switching the state after key pressed.
  290. // Refresh will be triggered by the thread when it finishes
  291. // the operation.
  292. compoundButton.setChecked(account.isEnabled());
  293. accEnableThread =
  294. new AccountEnableThread( account.getAccountID(),
  295. enable );
  296. String message = enable
  297. ? getString( R.string.service_gui_CONNECTING_ACCOUNT,
  298. account.getAccountName() )
  299. : getString( R.string.service_gui_DISCONNECTING_ACCOUNT,
  300. account.getAccountName() );
  301. progressDialog
  302. = ProgressDialogFragment.showProgressDialog(
  303. getString(R.string.service_gui_INFO),
  304. message);
  305. accEnableThread.start();
  306. }
  307. });
  308. return rowView;
  309. }
  310. }
  311. /**
  312. * The thread that runs enable/disable operations
  313. */
  314. class AccountEnableThread
  315. extends Thread
  316. {
  317. /**
  318. * The {@link AccountID} that will be enabled or disabled
  319. */
  320. private final AccountID account;
  321. /**
  322. * Flag decides whether account shall be disabled or enabled
  323. */
  324. private final boolean enable;
  325. /**
  326. * Creates new instance of {@link AccountEnableThread}
  327. *
  328. * @param account the {@link AccountID} that will be enabled
  329. * or disabled
  330. * @param enable flag indicates if this is enable or
  331. * disable operation
  332. */
  333. AccountEnableThread( AccountID account, boolean enable)
  334. {
  335. this.account = account;
  336. this.enable = enable;
  337. }
  338. @Override
  339. public void run()
  340. {
  341. try
  342. {
  343. if (enable)
  344. accountManager.loadAccount(account);
  345. else
  346. accountManager.unloadAccount(account);
  347. }
  348. catch (OperationFailedException e)
  349. {
  350. AndroidUtils.showAlertDialog(
  351. JitsiApplication.getGlobalContext(),
  352. getString(R.string.service_gui_ERROR),
  353. "Failed to " + (enable ? "load" : "unload")
  354. + " "+account );
  355. logger.error(e.getMessage(), e);
  356. }
  357. finally
  358. {
  359. if(DialogActivity.waitForDialogOpened(progressDialog))
  360. {
  361. DialogActivity.closeDialog(
  362. JitsiApplication.getGlobalContext(), progressDialog);
  363. }
  364. else
  365. {
  366. logger.error(
  367. "Failed to wait for the dialog: " + progressDialog );
  368. }
  369. accEnableThread = null;
  370. }
  371. }
  372. }
  373. }