AppPreferencesImpl.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. * ownCloud Android client application
  3. *
  4. * @author David A. Velasco
  5. * @author Chris Narkiewicz Chris Narkiewicz
  6. * Copyright (C) 2016 ownCloud Inc.
  7. * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. package com.nextcloud.client.preferences;
  22. import android.accounts.Account;
  23. import android.annotation.SuppressLint;
  24. import android.content.Context;
  25. import android.content.SharedPreferences;
  26. import com.nextcloud.client.account.CurrentAccountProvider;
  27. import com.nextcloud.client.account.UserAccountManagerImpl;
  28. import com.owncloud.android.datamodel.ArbitraryDataProvider;
  29. import com.owncloud.android.datamodel.FileDataStorageManager;
  30. import com.owncloud.android.datamodel.OCFile;
  31. import com.owncloud.android.ui.activity.PassCodeActivity;
  32. import com.owncloud.android.ui.activity.SettingsActivity;
  33. import com.owncloud.android.utils.FileSortOrder;
  34. import static com.owncloud.android.ui.fragment.OCFileListFragment.FOLDER_LAYOUT_LIST;
  35. /**
  36. * Helper to simplify reading of Preferences all around the app
  37. */
  38. public final class AppPreferencesImpl implements AppPreferences {
  39. /**
  40. * Constant to access value of last path selected by the user to upload a file shared from other app.
  41. * Value handled by the app without direct access in the UI.
  42. */
  43. public static final String AUTO_PREF__LAST_SEEN_VERSION_CODE = "lastSeenVersionCode";
  44. public static final String STORAGE_PATH = "storage_path";
  45. private static final String AUTO_PREF__LAST_UPLOAD_PATH = "last_upload_path";
  46. private static final String AUTO_PREF__UPLOAD_FROM_LOCAL_LAST_PATH = "upload_from_local_last_path";
  47. private static final String AUTO_PREF__UPLOAD_FILE_EXTENSION_MAP_URL = "prefs_upload_file_extension_map_url";
  48. private static final String AUTO_PREF__UPLOAD_FILE_EXTENSION_URL = "prefs_upload_file_extension_url";
  49. private static final String AUTO_PREF__UPLOADER_BEHAVIOR = "prefs_uploader_behaviour";
  50. private static final String AUTO_PREF__GRID_COLUMNS = "grid_columns";
  51. private static final String AUTO_PREF__SHOW_DETAILED_TIMESTAMP = "detailed_timestamp";
  52. private static final String PREF__INSTANT_UPLOADING = "instant_uploading";
  53. private static final String PREF__INSTANT_VIDEO_UPLOADING = "instant_video_uploading";
  54. private static final String PREF__SHOW_HIDDEN_FILES = "show_hidden_files_pref";
  55. private static final String PREF__LEGACY_CLEAN = "legacyClean";
  56. private static final String PREF__KEYS_MIGRATION = "keysMigration";
  57. private static final String PREF__FIX_STORAGE_PATH = "storagePathFix";
  58. private static final String PREF__KEYS_REINIT = "keysReinit";
  59. private static final String PREF__AUTO_UPLOAD_UPDATE_PATH = "autoUploadPathUpdate";
  60. private static final String PREF__PUSH_TOKEN = "pushToken";
  61. private static final String PREF__AUTO_UPLOAD_SPLIT_OUT = "autoUploadEntriesSplitOut";
  62. private static final String PREF__AUTO_UPLOAD_INIT = "autoUploadInit";
  63. private static final String PREF__FOLDER_SORT_ORDER = "folder_sort_order";
  64. private static final String PREF__FOLDER_LAYOUT = "folder_layout";
  65. private static final String PREF__LOCK_TIMESTAMP = "lock_timestamp";
  66. private static final String PREF__SHOW_MEDIA_SCAN_NOTIFICATIONS = "show_media_scan_notifications";
  67. private static final String PREF__LOCK = SettingsActivity.PREFERENCE_LOCK;
  68. private static final String PREF__SELECTED_ACCOUNT_NAME = "select_oc_account";
  69. private static final String PREF__MIGRATED_USER_ID = "migrated_user_id";
  70. private final Context context;
  71. private final SharedPreferences preferences;
  72. private final CurrentAccountProvider currentAccountProvider;
  73. public static AppPreferences fromContext(Context context) {
  74. final CurrentAccountProvider currentAccountProvider = UserAccountManagerImpl.fromContext(context);
  75. final SharedPreferences prefs = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
  76. return new AppPreferencesImpl(context, prefs, currentAccountProvider);
  77. }
  78. AppPreferencesImpl(Context appContext, SharedPreferences preferences, CurrentAccountProvider currentAccountProvider) {
  79. this.context = appContext;
  80. this.preferences = preferences;
  81. this.currentAccountProvider = currentAccountProvider;
  82. }
  83. @Override
  84. public void setKeysReInitEnabled() {
  85. preferences.edit().putBoolean(PREF__KEYS_REINIT, true).apply();
  86. }
  87. @Override
  88. public boolean isKeysReInitEnabled() {
  89. return preferences.getBoolean(PREF__KEYS_REINIT, false);
  90. }
  91. @Override
  92. public void setPushToken(String pushToken) {
  93. preferences.edit().putString(PREF__PUSH_TOKEN, pushToken).apply();
  94. }
  95. @Override
  96. public String getPushToken() {
  97. return preferences.getString(PREF__PUSH_TOKEN, "");
  98. }
  99. @Override
  100. public boolean instantPictureUploadEnabled() {
  101. return preferences.getBoolean(PREF__INSTANT_UPLOADING, false);
  102. }
  103. @Override
  104. public boolean instantVideoUploadEnabled() {
  105. return preferences.getBoolean(PREF__INSTANT_VIDEO_UPLOADING, false);
  106. }
  107. @Override
  108. public boolean isShowHiddenFilesEnabled() {
  109. return preferences.getBoolean(PREF__SHOW_HIDDEN_FILES, false);
  110. }
  111. @Override
  112. public void setShowHiddenFilesEnabled(boolean enabled) {
  113. preferences.edit().putBoolean(PREF__SHOW_HIDDEN_FILES, enabled).apply();
  114. }
  115. @Override
  116. public int getUploadUrlFileExtensionUrlSelectedPos() {
  117. return preferences.getInt(AUTO_PREF__UPLOAD_FILE_EXTENSION_URL, 0);
  118. }
  119. @Override
  120. public void setUploadUrlFileExtensionUrlSelectedPos(int selectedPos) {
  121. preferences.edit().putInt(AUTO_PREF__UPLOAD_FILE_EXTENSION_URL, selectedPos).apply();
  122. }
  123. @Override
  124. public int getUploadMapFileExtensionUrlSelectedPos() {
  125. return preferences.getInt(AUTO_PREF__UPLOAD_FILE_EXTENSION_MAP_URL, 0);
  126. }
  127. @Override
  128. public void setUploadMapFileExtensionUrlSelectedPos(int selectedPos) {
  129. preferences.edit().putInt(AUTO_PREF__UPLOAD_FILE_EXTENSION_MAP_URL, selectedPos).apply();
  130. }
  131. @Override
  132. public String getUploadFromLocalLastPath() {
  133. return preferences.getString(AUTO_PREF__UPLOAD_FROM_LOCAL_LAST_PATH, "");
  134. }
  135. @Override
  136. public void setUploadFromLocalLastPath(String path) {
  137. preferences.edit().putString(AUTO_PREF__UPLOAD_FROM_LOCAL_LAST_PATH, path).apply();
  138. }
  139. @Override
  140. public String getLastUploadPath() {
  141. return preferences.getString(AUTO_PREF__LAST_UPLOAD_PATH, "");
  142. }
  143. @Override
  144. public void setLastUploadPath(String path) {
  145. preferences.edit().putString(AUTO_PREF__LAST_UPLOAD_PATH, path).apply();
  146. }
  147. @Override
  148. public String getLockPreference() {
  149. return preferences.getString(PREF__LOCK, SettingsActivity.LOCK_NONE);
  150. }
  151. @Override
  152. public void setLockPreference(String lockPreference) {
  153. preferences.edit().putString(PREF__LOCK, lockPreference).apply();
  154. }
  155. @Override
  156. public void setPassCode(String d1, String d2, String d3, String d4) {
  157. preferences
  158. .edit()
  159. .putString(PassCodeActivity.PREFERENCE_PASSCODE_D1, d1)
  160. .putString(PassCodeActivity.PREFERENCE_PASSCODE_D2, d2)
  161. .putString(PassCodeActivity.PREFERENCE_PASSCODE_D3, d3)
  162. .putString(PassCodeActivity.PREFERENCE_PASSCODE_D4, d4)
  163. .apply();
  164. }
  165. @Override
  166. public String[] getPassCode() {
  167. return new String[] {
  168. preferences.getString(PassCodeActivity.PREFERENCE_PASSCODE_D1, null),
  169. preferences.getString(PassCodeActivity.PREFERENCE_PASSCODE_D2, null),
  170. preferences.getString(PassCodeActivity.PREFERENCE_PASSCODE_D3, null),
  171. preferences.getString(PassCodeActivity.PREFERENCE_PASSCODE_D4, null),
  172. };
  173. }
  174. @Override
  175. public boolean isFingerprintUnlockEnabled() {
  176. return preferences.getBoolean(SettingsActivity.PREFERENCE_USE_FINGERPRINT, false);
  177. }
  178. @Override
  179. public String getFolderLayout(OCFile folder) {
  180. return getFolderPreference(context,
  181. currentAccountProvider.getCurrentAccount(),
  182. PREF__FOLDER_LAYOUT,
  183. folder,
  184. FOLDER_LAYOUT_LIST);
  185. }
  186. @Override
  187. public void setFolderLayout(OCFile folder, String layout_name) {
  188. setFolderPreference(context,
  189. currentAccountProvider.getCurrentAccount(),
  190. PREF__FOLDER_LAYOUT,
  191. folder,
  192. layout_name);
  193. }
  194. @Override
  195. public FileSortOrder getSortOrderByFolder(OCFile folder) {
  196. return FileSortOrder.sortOrders.get(getFolderPreference(context,
  197. currentAccountProvider.getCurrentAccount(),
  198. PREF__FOLDER_SORT_ORDER,
  199. folder,
  200. FileSortOrder.sort_a_to_z.name));
  201. }
  202. @Override
  203. public void setSortOrder(OCFile folder, FileSortOrder sortOrder) {
  204. setFolderPreference(context,
  205. currentAccountProvider.getCurrentAccount(),
  206. PREF__FOLDER_SORT_ORDER,
  207. folder,
  208. sortOrder.name);
  209. }
  210. @Override
  211. public FileSortOrder getSortOrderByType(FileSortOrder.Type type) {
  212. return getSortOrderByType(type, FileSortOrder.sort_a_to_z);
  213. }
  214. @Override
  215. public FileSortOrder getSortOrderByType(FileSortOrder.Type type, FileSortOrder defaultOrder) {
  216. Account account = currentAccountProvider.getCurrentAccount();
  217. if (account == null) {
  218. return defaultOrder;
  219. }
  220. ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
  221. String value = dataProvider.getValue(account.name, PREF__FOLDER_SORT_ORDER + "_" + type);
  222. return value.isEmpty() ? defaultOrder : FileSortOrder.sortOrders.get(value);
  223. }
  224. @Override
  225. public void setSortOrder(FileSortOrder.Type type, FileSortOrder sortOrder) {
  226. Account account = currentAccountProvider.getCurrentAccount();
  227. if (account == null) {
  228. throw new IllegalArgumentException("Account may not be null!");
  229. }
  230. ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
  231. dataProvider.storeOrUpdateKeyValue(account.name, PREF__FOLDER_SORT_ORDER + "_" + type, sortOrder.name);
  232. }
  233. @Override
  234. public boolean isLegacyClean() {
  235. return preferences.getBoolean(PREF__LEGACY_CLEAN, false);
  236. }
  237. @Override
  238. public void setLegacyClean(boolean isLegacyClean) {
  239. preferences.edit().putBoolean(PREF__LEGACY_CLEAN, isLegacyClean).apply();
  240. }
  241. @Override
  242. public boolean isKeysMigrationEnabled() {
  243. return preferences.getBoolean(PREF__KEYS_MIGRATION, false);
  244. }
  245. @Override
  246. public void setKeysMigrationEnabled(boolean keysMigration) {
  247. preferences.edit().putBoolean(PREF__KEYS_MIGRATION, keysMigration).apply();
  248. }
  249. @Override
  250. public boolean isStoragePathFixEnabled() {
  251. return preferences.getBoolean(PREF__FIX_STORAGE_PATH, false);
  252. }
  253. @Override
  254. public void setStoragePathFixEnabled(boolean storagePathFixEnabled) {
  255. preferences.edit().putBoolean(PREF__FIX_STORAGE_PATH, storagePathFixEnabled).apply();
  256. }
  257. @Override
  258. public boolean isAutoUploadPathsUpdateEnabled() {
  259. return preferences.getBoolean(PREF__AUTO_UPLOAD_UPDATE_PATH, false);
  260. }
  261. @Override
  262. public void setAutoUploadPathsUpdateEnabled(boolean pathUpdate) {
  263. preferences.edit().putBoolean(PREF__AUTO_UPLOAD_UPDATE_PATH, pathUpdate).apply();
  264. }
  265. @Override
  266. public boolean isAutoUploadSplitEntriesEnabled() {
  267. return preferences.getBoolean(PREF__AUTO_UPLOAD_SPLIT_OUT, false);
  268. }
  269. @Override
  270. public void setAutoUploadSplitEntriesEnabled(boolean splitOut) {
  271. preferences.edit().putBoolean(PREF__AUTO_UPLOAD_SPLIT_OUT, splitOut).apply();
  272. }
  273. @Override
  274. public boolean isAutoUploadInitialized() {
  275. return preferences.getBoolean(PREF__AUTO_UPLOAD_INIT, false);
  276. }
  277. @Override
  278. public void setAutoUploadInit(boolean autoUploadInit) {
  279. preferences.edit().putBoolean(PREF__AUTO_UPLOAD_INIT, autoUploadInit).apply();
  280. }
  281. @Override
  282. public int getUploaderBehaviour() {
  283. return preferences.getInt(AUTO_PREF__UPLOADER_BEHAVIOR, 1);
  284. }
  285. @Override
  286. public void setUploaderBehaviour(int uploaderBehaviour) {
  287. preferences.edit().putInt(AUTO_PREF__UPLOADER_BEHAVIOR, uploaderBehaviour).apply();
  288. }
  289. /**
  290. * Gets the grid columns which the user has set last.
  291. *
  292. * @return grid columns grid columns
  293. */
  294. @Override
  295. public float getGridColumns() {
  296. return preferences.getFloat(AUTO_PREF__GRID_COLUMNS, 4.0f);
  297. }
  298. /**
  299. * Saves the grid columns which the user has set last.
  300. *
  301. * @param gridColumns the uploader behavior
  302. */
  303. @Override
  304. public void setGridColumns(float gridColumns) {
  305. preferences.edit().putFloat(AUTO_PREF__GRID_COLUMNS, gridColumns).apply();
  306. }
  307. @Override
  308. public int getLastSeenVersionCode() {
  309. return preferences.getInt(AUTO_PREF__LAST_SEEN_VERSION_CODE, 0);
  310. }
  311. @Override
  312. public void setLastSeenVersionCode(int versionCode) {
  313. preferences.edit().putInt(AUTO_PREF__LAST_SEEN_VERSION_CODE, versionCode).apply();
  314. }
  315. @Override
  316. public long getLockTimestamp() {
  317. return preferences.getLong(PREF__LOCK_TIMESTAMP, 0);
  318. }
  319. @Override
  320. public void setLockTimestamp(long timestamp) {
  321. preferences.edit().putLong(PREF__LOCK_TIMESTAMP, timestamp).apply();
  322. }
  323. @Override
  324. public boolean isShowDetailedTimestampEnabled() {
  325. return preferences.getBoolean(AUTO_PREF__SHOW_DETAILED_TIMESTAMP, false);
  326. }
  327. @Override
  328. public void setShowDetailedTimestampEnabled(boolean showDetailedTimestamp) {
  329. preferences.edit().putBoolean(AUTO_PREF__SHOW_DETAILED_TIMESTAMP, showDetailedTimestamp).apply();
  330. }
  331. @Override
  332. public boolean isShowMediaScanNotifications() {
  333. return preferences.getBoolean(PREF__SHOW_MEDIA_SCAN_NOTIFICATIONS, true);
  334. }
  335. @Override
  336. public void setShowMediaScanNotifications(boolean value) {
  337. preferences.edit().putBoolean(PREF__SHOW_MEDIA_SCAN_NOTIFICATIONS, value).apply();
  338. }
  339. @Override
  340. public void removeLegacyPreferences() {
  341. preferences.edit()
  342. .remove("instant_uploading")
  343. .remove("instant_video_uploading")
  344. .remove("instant_upload_path")
  345. .remove("instant_upload_path_use_subfolders")
  346. .remove("instant_upload_on_wifi")
  347. .remove("instant_upload_on_charging")
  348. .remove("instant_video_upload_path")
  349. .remove("instant_video_upload_path_use_subfolders")
  350. .remove("instant_video_upload_on_wifi")
  351. .remove("instant_video_uploading")
  352. .remove("instant_video_upload_on_charging")
  353. .remove("prefs_instant_behaviour")
  354. .apply();
  355. }
  356. @Override
  357. public void clear() {
  358. preferences.edit().clear().apply();
  359. }
  360. @Override
  361. public String getStoragePath(String defaultPath) {
  362. return preferences.getString(STORAGE_PATH, defaultPath);
  363. }
  364. @SuppressLint("ApplySharedPref")
  365. @Override
  366. public void setStoragePath(String path) {
  367. preferences.edit().putString(STORAGE_PATH, path).commit(); // commit synchronously
  368. }
  369. /**
  370. * Removes keys migration key from shared preferences.
  371. */
  372. @SuppressLint("ApplySharedPref")
  373. @Override
  374. public void removeKeysMigrationPreference() {
  375. preferences.edit().remove(AppPreferencesImpl.PREF__KEYS_MIGRATION).commit(); // commit synchronously
  376. }
  377. @Override
  378. public String getCurrentAccountName() {
  379. return preferences.getString(PREF__SELECTED_ACCOUNT_NAME, null);
  380. }
  381. @Override
  382. public void setCurrentAccountName(String accountName) {
  383. preferences.edit().putString(PREF__SELECTED_ACCOUNT_NAME, accountName).apply();
  384. }
  385. @Override
  386. public boolean isUserIdMigrated() {
  387. return preferences.getBoolean(PREF__MIGRATED_USER_ID, false);
  388. }
  389. @Override
  390. public void setMigratedUserId(boolean value) {
  391. preferences.edit().putBoolean(PREF__MIGRATED_USER_ID, value).apply();
  392. }
  393. /**
  394. * Get preference value for a folder.
  395. * If folder is not set itself, it finds an ancestor that is set.
  396. *
  397. * @param context Context object.
  398. * @param preferenceName Name of the preference to lookup.
  399. * @param folder Folder.
  400. * @param defaultValue Fallback value in case no ancestor is set.
  401. * @return Preference value
  402. */
  403. private static String getFolderPreference(final Context context,
  404. final Account account,
  405. final String preferenceName,
  406. final OCFile folder,
  407. final String defaultValue) {
  408. if (account == null) {
  409. return defaultValue;
  410. }
  411. ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
  412. FileDataStorageManager storageManager = new FileDataStorageManager(account, context.getContentResolver());
  413. String value = dataProvider.getValue(account.name, getKeyFromFolder(preferenceName, folder));
  414. OCFile prefFolder = folder;
  415. while (prefFolder != null && value.isEmpty()) {
  416. prefFolder = storageManager.getFileById(prefFolder.getParentId());
  417. value = dataProvider.getValue(account.name, getKeyFromFolder(preferenceName, prefFolder));
  418. }
  419. return value.isEmpty() ? defaultValue : value;
  420. }
  421. /**
  422. * Set preference value for a folder.
  423. *
  424. * @param context Context object.
  425. * @param preferenceName Name of the preference to set.
  426. * @param folder Folder.
  427. * @param value Preference value to set.
  428. */
  429. private static void setFolderPreference(final Context context,
  430. final Account account,
  431. final String preferenceName,
  432. final OCFile folder,
  433. final String value) {
  434. if (account == null) {
  435. throw new IllegalArgumentException("Account may not be null!");
  436. }
  437. ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
  438. dataProvider.storeOrUpdateKeyValue(account.name, getKeyFromFolder(preferenceName, folder), value);
  439. }
  440. private static String getKeyFromFolder(String preferenceName, OCFile folder) {
  441. final String folderIdString = String.valueOf(folder != null ? folder.getFileId() :
  442. FileDataStorageManager.ROOT_PARENT_ID);
  443. return preferenceName + "_" + folderIdString;
  444. }
  445. }