BaseActivity.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. package com.owncloud.android.ui.activity;
  2. import android.accounts.Account;
  3. import android.accounts.AccountManager;
  4. import android.accounts.AccountManagerCallback;
  5. import android.accounts.AccountManagerFuture;
  6. import android.accounts.OperationCanceledException;
  7. import android.content.Intent;
  8. import android.content.SharedPreferences;
  9. import android.os.Bundle;
  10. import android.os.Handler;
  11. import com.nextcloud.client.account.UserAccountManager;
  12. import com.nextcloud.client.di.Injectable;
  13. import com.nextcloud.client.preferences.AppPreferences;
  14. import com.nextcloud.client.preferences.AppPreferencesImpl;
  15. import com.owncloud.android.MainApp;
  16. import com.owncloud.android.R;
  17. import com.owncloud.android.datamodel.FileDataStorageManager;
  18. import com.owncloud.android.datamodel.OCFile;
  19. import com.owncloud.android.lib.common.utils.Log_OC;
  20. import com.owncloud.android.lib.resources.status.OCCapability;
  21. import javax.inject.Inject;
  22. import androidx.annotation.Nullable;
  23. import androidx.appcompat.app.AppCompatActivity;
  24. /**
  25. * Base activity with common behaviour for activities dealing with ownCloud {@link Account}s .
  26. */
  27. public abstract class BaseActivity extends AppCompatActivity implements Injectable {
  28. private static final String TAG = BaseActivity.class.getSimpleName();
  29. /**
  30. * ownCloud {@link Account} where the main {@link OCFile} handled by the activity is located.
  31. */
  32. private Account currentAccount;
  33. /**
  34. * Capabilities of the server where {@link #currentAccount} lives.
  35. */
  36. private OCCapability capabilities;
  37. /**
  38. * Access point to the cached database for the current ownCloud {@link Account}.
  39. */
  40. private FileDataStorageManager storageManager;
  41. /**
  42. * Tracks whether the activity should be recreate()'d after a theme change
  43. */
  44. private boolean themeChangePending;
  45. private boolean paused;
  46. @Inject UserAccountManager accountManager;
  47. @Inject AppPreferences preferences;
  48. private AppPreferences.Listener onPreferencesChanged = new AppPreferences.Listener() {
  49. @Override
  50. public void onDarkThemeEnabledChanged(boolean enabled) {
  51. BaseActivity.this.onThemeSettingsChanged();
  52. }
  53. };
  54. public UserAccountManager getUserAccountManager() {
  55. return accountManager;
  56. }
  57. @Override
  58. protected void onPostCreate(@Nullable Bundle savedInstanceState) {
  59. super.onPostCreate(savedInstanceState);
  60. preferences.addListener(onPreferencesChanged);
  61. }
  62. @Override
  63. protected void onDestroy() {
  64. super.onDestroy();
  65. preferences.removeListener(onPreferencesChanged);
  66. }
  67. @Override
  68. protected void onPause() {
  69. super.onPause();
  70. paused = true;
  71. }
  72. @Override
  73. protected void onResume() {
  74. super.onResume();
  75. paused = false;
  76. if(themeChangePending) {
  77. recreate();
  78. }
  79. }
  80. @Override
  81. protected void onPostResume() {
  82. super.onPostResume();
  83. }
  84. @Override
  85. protected void onNewIntent(Intent intent) {
  86. super.onNewIntent(intent);
  87. Log_OC.v(TAG, "onNewIntent() start");
  88. Account current = accountManager.getCurrentAccount();
  89. if (current != null && currentAccount != null && !currentAccount.name.equals(current.name)) {
  90. currentAccount = current;
  91. }
  92. Log_OC.v(TAG, "onNewIntent() stop");
  93. }
  94. /**
  95. * Since ownCloud {@link Account}s can be managed from the system setting menu, the existence of the {@link
  96. * Account} associated to the instance must be checked every time it is restarted.
  97. */
  98. @Override
  99. protected void onRestart() {
  100. Log_OC.v(TAG, "onRestart() start");
  101. super.onRestart();
  102. boolean validAccount = currentAccount != null && accountManager.exists(currentAccount);
  103. if (!validAccount) {
  104. swapToDefaultAccount();
  105. }
  106. Log_OC.v(TAG, "onRestart() end");
  107. }
  108. private void onThemeSettingsChanged() {
  109. if(paused) {
  110. themeChangePending = true;
  111. } else {
  112. recreate();
  113. }
  114. }
  115. /**
  116. * Sets and validates the ownCloud {@link Account} associated to the Activity.
  117. *
  118. * If not valid, tries to swap it for other valid and existing ownCloud {@link Account}.
  119. *
  120. * @param account New {@link Account} to set.
  121. * @param savedAccount When 'true', account was retrieved from a saved instance state.
  122. */
  123. @Deprecated
  124. protected void setAccount(Account account, boolean savedAccount) {
  125. boolean validAccount = account != null && accountManager.setCurrentOwnCloudAccount(account.name);
  126. if (validAccount) {
  127. currentAccount = account;
  128. } else {
  129. swapToDefaultAccount();
  130. }
  131. }
  132. /**
  133. * Tries to swap the current ownCloud {@link Account} for other valid and existing.
  134. *
  135. * If no valid ownCloud {@link Account} exists, then the user is requested
  136. * to create a new ownCloud {@link Account}.
  137. */
  138. protected void swapToDefaultAccount() {
  139. // default to the most recently used account
  140. Account newAccount = accountManager.getCurrentAccount();
  141. if (newAccount == null) {
  142. /// no account available: force account creation
  143. createAccount(true);
  144. } else {
  145. currentAccount = newAccount;
  146. }
  147. }
  148. /**
  149. * Launches the account creation activity.
  150. *
  151. * @param mandatoryCreation When 'true', if an account is not created by the user, the app will be closed.
  152. * To use when no ownCloud account is available.
  153. */
  154. protected void createAccount(boolean mandatoryCreation) {
  155. AccountManager am = AccountManager.get(getApplicationContext());
  156. am.addAccount(MainApp.getAccountType(this),
  157. null,
  158. null,
  159. null,
  160. this,
  161. new AccountCreationCallback(mandatoryCreation),
  162. new Handler());
  163. }
  164. /**
  165. * Called when the ownCloud {@link Account} associated to the Activity was just updated.
  166. *
  167. * Child classes must grant that state depending on the {@link Account} is updated.
  168. */
  169. @Deprecated
  170. protected void onAccountSet() {
  171. if (getAccount() != null) {
  172. storageManager = new FileDataStorageManager(getAccount(), getContentResolver());
  173. capabilities = storageManager.getCapability(currentAccount.name);
  174. } else {
  175. Log_OC.e(TAG, "onAccountChanged was called with NULL account associated!");
  176. }
  177. }
  178. @Deprecated
  179. protected void setAccount(Account account) {
  180. currentAccount = account;
  181. }
  182. /**
  183. * Getter for the capabilities of the server where the current OC account lives.
  184. *
  185. * @return Capabilities of the server where the current OC account lives. Null if the account is not
  186. * set yet.
  187. */
  188. public OCCapability getCapabilities() {
  189. return capabilities;
  190. }
  191. /**
  192. * Getter for the ownCloud {@link Account} where the main {@link OCFile} handled by the activity
  193. * is located.
  194. *
  195. * @return OwnCloud {@link Account} where the main {@link OCFile} handled by the activity
  196. * is located.
  197. */
  198. public Account getAccount() {
  199. return currentAccount;
  200. }
  201. @Override
  202. protected void onStart() {
  203. super.onStart();
  204. if(currentAccount != null) {
  205. onAccountSet();
  206. }
  207. }
  208. public FileDataStorageManager getStorageManager() {
  209. return storageManager;
  210. }
  211. /**
  212. * Method that gets called when a new account has been successfully created.
  213. *
  214. * @param future
  215. */
  216. protected void onAccountCreationSuccessful(AccountManagerFuture<Bundle> future) {
  217. // no special handling in base activity
  218. Log_OC.d(TAG,"onAccountCreationSuccessful");
  219. }
  220. /**
  221. * Helper class handling a callback from the {@link AccountManager} after the creation of
  222. * a new ownCloud {@link Account} finished, successfully or not.
  223. */
  224. public class AccountCreationCallback implements AccountManagerCallback<Bundle> {
  225. boolean mMandatoryCreation;
  226. /**
  227. * Constructor
  228. *
  229. * @param mandatoryCreation When 'true', if an account was not created, the app is closed.
  230. */
  231. public AccountCreationCallback(boolean mandatoryCreation) {
  232. mMandatoryCreation = mandatoryCreation;
  233. }
  234. @Override
  235. public void run(AccountManagerFuture<Bundle> future) {
  236. boolean accountWasSet = false;
  237. if (future != null) {
  238. try {
  239. Bundle result;
  240. result = future.getResult();
  241. String name = result.getString(AccountManager.KEY_ACCOUNT_NAME);
  242. String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
  243. if (accountManager.setCurrentOwnCloudAccount(name)) {
  244. setAccount(new Account(name, type), false);
  245. accountWasSet = true;
  246. }
  247. onAccountCreationSuccessful(future);
  248. } catch (OperationCanceledException e) {
  249. Log_OC.d(TAG, "Account creation canceled");
  250. } catch (Exception e) {
  251. Log_OC.e(TAG, "Account creation finished in exception: ", e);
  252. }
  253. } else {
  254. Log_OC.e(TAG, "Account creation callback with null bundle");
  255. }
  256. if (mMandatoryCreation && !accountWasSet) {
  257. moveTaskToBack(true);
  258. }
  259. }
  260. }
  261. }