Merge remote-tracking branch 'remotes/upstream/bug_1251' into beta
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / Preferences.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author Bartek Przybylski
5 * @author David A. Velasco
6 * Copyright (C) 2011 Bartek Przybylski
7 * Copyright (C) 2015 ownCloud Inc.
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 */
22 package com.owncloud.android.ui.activity;
23
24 import android.accounts.Account;
25 import android.accounts.AccountManager;
26 import android.accounts.AccountManagerCallback;
27 import android.accounts.AccountManagerFuture;
28 import android.content.ComponentName;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.ServiceConnection;
32 import android.content.SharedPreferences;
33 import android.content.pm.PackageInfo;
34 import android.content.pm.PackageManager.NameNotFoundException;
35 import android.content.res.Configuration;
36 import android.net.Uri;
37 import android.os.AsyncTask;
38 import android.os.Bundle;
39 import android.os.Environment;
40 import android.os.Handler;
41 import android.os.IBinder;
42 import android.preference.CheckBoxPreference;
43 import android.preference.Preference;
44 import android.preference.Preference.OnPreferenceChangeListener;
45 import android.preference.Preference.OnPreferenceClickListener;
46 import android.preference.PreferenceActivity;
47 import android.preference.PreferenceCategory;
48 import android.preference.PreferenceManager;
49 import android.support.annotation.LayoutRes;
50 import android.support.annotation.Nullable;
51 import android.support.v7.app.ActionBar;
52 import android.support.v7.app.AlertDialog;
53 import android.support.v7.app.AppCompatDelegate;
54 import android.support.v7.widget.Toolbar;
55 import android.view.ContextMenu;
56 import android.view.ContextMenu.ContextMenuInfo;
57 import android.view.Menu;
58 import android.view.MenuInflater;
59 import android.view.MenuItem;
60 import android.view.View;
61 import android.view.ViewGroup;
62 import android.widget.AdapterView;
63 import android.widget.AdapterView.OnItemLongClickListener;
64 import android.widget.ArrayAdapter;
65 import android.widget.ListAdapter;
66 import android.widget.ListView;
67 import android.widget.Toast;
68
69 import com.owncloud.android.BuildConfig;
70 import com.owncloud.android.MainApp;
71 import com.owncloud.android.R;
72 import com.owncloud.android.authentication.AccountUtils;
73 import com.owncloud.android.authentication.AuthenticatorActivity;
74 import com.owncloud.android.datamodel.FileDataStorageManager;
75 import com.owncloud.android.datamodel.OCFile;
76 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
77 import com.owncloud.android.db.DbHandler;
78 import com.owncloud.android.files.FileOperationsHelper;
79 import com.owncloud.android.files.services.FileDownloader;
80 import com.owncloud.android.files.services.FileUploader;
81 import com.owncloud.android.lib.common.utils.Log_OC;
82 import com.owncloud.android.services.OperationsService;
83 import com.owncloud.android.ui.PreferenceWithLongSummary;
84 import com.owncloud.android.ui.RadioButtonPreference;
85 import com.owncloud.android.utils.DisplayUtils;
86
87 import java.io.BufferedReader;
88 import java.io.IOException;
89 import java.io.InputStreamReader;
90 import java.net.MalformedURLException;
91 import java.net.URL;
92 import java.util.concurrent.ExecutionException;
93 import java.io.File;
94
95
96 /**
97 * An Activity that allows the user to change the application's settings.
98 *
99 * It proxies the necessary calls via {@link android.support.v7.app.AppCompatDelegate} to be used
100 * with AppCompat.
101 */
102 public class Preferences extends PreferenceActivity
103 implements AccountManagerCallback<Boolean>, ComponentsGetter {
104
105 private static final String TAG = "OwnCloudPreferences";
106
107 private static final int ACTION_SELECT_UPLOAD_PATH = 1;
108 private static final int ACTION_SELECT_UPLOAD_VIDEO_PATH = 2;
109 private static final int ACTION_REQUEST_PASSCODE = 5;
110 private static final int ACTION_CONFIRM_PASSCODE = 6;
111 private static final int ACTION_SELECT_STORAGE_PATH = 3;
112 private static final int ACTION_PERFORM_MIGRATION = 4;
113
114 private DbHandler mDbHandler;
115 private CheckBoxPreference pCode;
116 private Preference pAboutApp;
117 private AppCompatDelegate mDelegate;
118
119 private PreferenceCategory mAccountsPrefCategory = null;
120 private final Handler mHandler = new Handler();
121 private String mAccountName;
122 private boolean mShowContextMenu = false;
123 private String mUploadPath;
124 private PreferenceCategory mPrefInstantUploadCategory;
125 private Preference mPrefInstantUpload;
126 private Preference mPrefInstantUploadPath;
127 private Preference mPrefInstantUploadPathWiFi;
128 private Preference mPrefInstantVideoUpload;
129 private Preference mPrefInstantVideoUploadPath;
130 private Preference mPrefInstantVideoUploadPathWiFi;
131 private String mUploadVideoPath;
132
133 protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
134 protected FileUploader.FileUploaderBinder mUploaderBinder = null;
135 private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
136 private PreferenceWithLongSummary mPrefStoragePath;
137 private String mStoragePath;
138
139
140 @SuppressWarnings("deprecation")
141 @Override
142 public void onCreate(Bundle savedInstanceState) {
143 getDelegate().installViewFactory();
144 getDelegate().onCreate(savedInstanceState);
145 super.onCreate(savedInstanceState);
146 mDbHandler = new DbHandler(getBaseContext());
147 addPreferencesFromResource(R.xml.preferences);
148
149 ActionBar actionBar = getSupportActionBar();
150 actionBar.setDisplayHomeAsUpEnabled(true);
151 actionBar.setTitle(R.string.actionbar_settings);
152
153 // For adding content description tag to a title field in the action bar
154 int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
155 View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
156 if (actionBarTitleView != null) { // it's null in Android 2.x
157 getWindow().getDecorView().findViewById(actionBarTitleId).
158 setContentDescription(getString(R.string.actionbar_settings));
159 }
160
161 // Load the accounts category for adding the list of accounts
162 mAccountsPrefCategory = (PreferenceCategory) findPreference("accounts_category");
163
164 ListView listView = getListView();
165 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
166 @Override
167 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
168 ListView listView = (ListView) parent;
169 ListAdapter listAdapter = listView.getAdapter();
170 Object obj = listAdapter.getItem(position);
171
172 if (obj != null && obj instanceof RadioButtonPreference) {
173 mShowContextMenu = true;
174 mAccountName = ((RadioButtonPreference) obj).getKey();
175
176 String[] items = {
177 getResources().getString(R.string.change_password),
178 getResources().getString(R.string.delete_account)
179 };
180 final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Preferences.this);
181 View convertView = getLayoutInflater().inflate(R.layout.alert_dialog_list_view, null);
182 alertDialogBuilder.setView(convertView);
183 ListView lv = (ListView) convertView.findViewById(R.id.list);
184 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
185 Preferences.this,R.layout.simple_dialog_list_item,items);
186 lv.setAdapter(adapter);
187
188 //Setup proper inline listener
189 final AlertDialog alertDialog = alertDialogBuilder.create();
190 lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
191 @Override
192 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
193 AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
194 Account accounts[] = am.getAccountsByType(MainApp.getAccountType());
195 for (Account a : accounts) {
196 if (a.name.equals(mAccountName)) {
197 if (position==0) {
198
199 // Change account password
200 Intent updateAccountCredentials = new Intent(Preferences.this, AuthenticatorActivity.class);
201 updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, a);
202 updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
203 AuthenticatorActivity.ACTION_UPDATE_TOKEN);
204 startActivity(updateAccountCredentials);
205 alertDialog.cancel();
206
207 } else if (position==1) {
208
209 // Remove account
210 am.removeAccount(a, Preferences.this, mHandler);
211 Log_OC.d(TAG, "Remove an account " + a.name);
212 alertDialog.cancel();
213 }
214 }
215 }
216 }
217 });
218 alertDialog.show();
219
220 View.OnLongClickListener longListener = (View.OnLongClickListener) obj;
221 return longListener.onLongClick(view);
222 }
223 return false;
224 }
225 });
226
227 // Load package info
228 String temp;
229 try {
230 PackageInfo pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
231 temp = pkg.versionName;
232 } catch (NameNotFoundException e) {
233 temp = "";
234 Log_OC.e(TAG, "Error while showing about dialog", e);
235 }
236 final String appVersion = temp;
237
238 // Register context menu for list of preferences.
239 registerForContextMenu(getListView());
240
241 pCode = (CheckBoxPreference) findPreference("set_pincode");
242 if (pCode != null) {
243 pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
244 @Override
245 public boolean onPreferenceChange(Preference preference, Object newValue) {
246 Intent i = new Intent(getApplicationContext(), PassCodeActivity.class);
247 Boolean incoming = (Boolean) newValue;
248
249 i.setAction(
250 incoming.booleanValue() ? PassCodeActivity.ACTION_REQUEST_WITH_RESULT :
251 PassCodeActivity.ACTION_CHECK_WITH_RESULT
252 );
253
254 startActivityForResult(i, incoming.booleanValue() ? ACTION_REQUEST_PASSCODE :
255 ACTION_CONFIRM_PASSCODE);
256
257 // Don't update just yet, we will decide on it in onActivityResult
258 return false;
259 }
260 });
261
262 }
263
264 final Preference pCacheSize = findPreference("pref_cache_size");
265 if (pCacheSize != null){
266 final SharedPreferences appPrefs =
267 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
268 Long cacheSize = ThumbnailsCacheManager.getMaxSize();
269 pCacheSize.setSummary(cacheSize + " Mb");
270 pCacheSize.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
271 @Override
272 public boolean onPreferenceChange(Preference preference, Object newValue) {
273 Long size = Long.decode((String) newValue);
274 if (ThumbnailsCacheManager.setMaxSize(size)){
275 appPrefs.edit().putString("pref_cache_size", size.toString());
276 pCacheSize.setSummary(size + " MB");
277 return true;
278 } else {
279 return false;
280 }
281 }
282 });
283 }
284
285 PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference("more");
286
287 boolean helpEnabled = getResources().getBoolean(R.bool.help_enabled);
288 Preference pHelp = findPreference("help");
289 if (pHelp != null ){
290 if (helpEnabled) {
291 pHelp.setOnPreferenceClickListener(new OnPreferenceClickListener() {
292 @Override
293 public boolean onPreferenceClick(Preference preference) {
294 String helpWeb =(String) getText(R.string.url_help);
295 if (helpWeb != null && helpWeb.length() > 0) {
296 Uri uriUrl = Uri.parse(helpWeb);
297 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
298 startActivity(intent);
299 }
300 return true;
301 }
302 });
303 } else {
304 preferenceCategory.removePreference(pHelp);
305 }
306
307 }
308
309 if (BuildConfig.DEBUG) {
310 Preference pLog = findPreference("log");
311 if (pLog != null ){
312 pLog.setOnPreferenceClickListener(new OnPreferenceClickListener() {
313 @Override
314 public boolean onPreferenceClick(Preference preference) {
315 Intent loggerIntent = new Intent(getApplicationContext(),
316 LogHistoryActivity.class);
317 startActivity(loggerIntent);
318 return true;
319 }
320 });
321 }
322 }
323
324 boolean recommendEnabled = getResources().getBoolean(R.bool.recommend_enabled);
325 Preference pRecommend = findPreference("recommend");
326 if (pRecommend != null){
327 if (recommendEnabled) {
328 pRecommend.setOnPreferenceClickListener(new OnPreferenceClickListener() {
329 @Override
330 public boolean onPreferenceClick(Preference preference) {
331
332 Intent intent = new Intent(Intent.ACTION_SENDTO);
333 intent.setType("text/plain");
334 intent.setData(Uri.parse(getString(R.string.mail_recommend)));
335 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
336
337 String appName = getString(R.string.app_name);
338 String downloadUrl = getString(R.string.url_app_download);
339 Account currentAccount = AccountUtils.
340 getCurrentOwnCloudAccount(Preferences.this);
341 String username = currentAccount.name.substring(0,
342 currentAccount.name.lastIndexOf('@'));
343
344 String recommendSubject = String.format(getString(R.string.recommend_subject),
345 appName);
346 String recommendText = String.format(getString(R.string.recommend_text),
347 appName, downloadUrl);
348
349 intent.putExtra(Intent.EXTRA_SUBJECT, recommendSubject);
350 intent.putExtra(Intent.EXTRA_TEXT, recommendText);
351 startActivity(intent);
352
353 return true;
354
355 }
356 });
357 } else {
358 preferenceCategory.removePreference(pRecommend);
359 }
360
361 }
362
363 boolean feedbackEnabled = getResources().getBoolean(R.bool.feedback_enabled);
364 Preference pFeedback = findPreference("feedback");
365 if (pFeedback != null){
366 if (feedbackEnabled) {
367 pFeedback.setOnPreferenceClickListener(new OnPreferenceClickListener() {
368 @Override
369 public boolean onPreferenceClick(Preference preference) {
370 String feedbackMail = (String) getText(R.string.mail_feedback);
371 String feedback = String.format("%s - android v%s", getText(R.string.prefs_feedback), appVersion);
372 Intent intent = new Intent(Intent.ACTION_SENDTO);
373
374 intent.setType("text/plain");
375 intent.putExtra(Intent.EXTRA_SUBJECT, feedback);
376
377 intent.setData(Uri.parse(feedbackMail));
378 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
379 startActivity(intent);
380
381 return true;
382 }
383 });
384 } else {
385 preferenceCategory.removePreference(pFeedback);
386 }
387
388 }
389
390 boolean imprintEnabled = getResources().getBoolean(R.bool.imprint_enabled);
391 Preference pImprint = findPreference("imprint");
392 if (pImprint != null) {
393 if (imprintEnabled) {
394 pImprint.setOnPreferenceClickListener(new OnPreferenceClickListener() {
395 @Override
396 public boolean onPreferenceClick(Preference preference) {
397 String imprintWeb = (String) getText(R.string.url_imprint);
398 if (imprintWeb != null && imprintWeb.length() > 0) {
399 Uri uriUrl = Uri.parse(imprintWeb);
400 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
401 startActivity(intent);
402 }
403 //ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG");
404 return true;
405 }
406 });
407 } else {
408 preferenceCategory.removePreference(pImprint);
409 }
410 }
411
412 mPrefStoragePath = (PreferenceWithLongSummary)findPreference("storage_path");
413 if (mPrefStoragePath != null) {
414
415 mPrefStoragePath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
416 @Override
417 public boolean onPreferenceClick(Preference preference) {
418 Intent intent = new Intent(Preferences.this, LocalDirectorySelectorActivity.class);
419 intent.putExtra(UploadFilesActivity.KEY_DIRECTORY_PATH, mStoragePath);
420 startActivityForResult(intent, ACTION_SELECT_STORAGE_PATH);
421 return true;
422 }
423 });
424
425 mPrefStoragePath.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
426 @Override
427 public boolean onPreferenceChange(Preference preference, Object newValue) {
428 MainApp.setStoragePath((String) newValue);
429 return true;
430 }
431 });
432 }
433
434 mPrefInstantUploadPath = (PreferenceWithLongSummary)findPreference("instant_upload_path");
435 if (mPrefInstantUploadPath != null){
436
437 mPrefInstantUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
438 @Override
439 public boolean onPreferenceClick(Preference preference) {
440 if (!mUploadPath.endsWith(OCFile.PATH_SEPARATOR)) {
441 mUploadPath += OCFile.PATH_SEPARATOR;
442 }
443 Intent intent = new Intent(Preferences.this, UploadPathActivity.class);
444 intent.putExtra(UploadPathActivity.KEY_INSTANT_UPLOAD_PATH, mUploadPath);
445 startActivityForResult(intent, ACTION_SELECT_UPLOAD_PATH);
446 return true;
447 }
448 });
449 }
450
451 mPrefInstantUploadCategory =
452 (PreferenceCategory) findPreference("instant_uploading_category");
453
454 mPrefInstantUploadPathWiFi = findPreference("instant_upload_on_wifi");
455 mPrefInstantUpload = findPreference("instant_uploading");
456
457 toggleInstantPictureOptions(((CheckBoxPreference) mPrefInstantUpload).isChecked());
458
459 mPrefInstantUpload.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
460
461 @Override
462 public boolean onPreferenceChange(Preference preference, Object newValue) {
463 toggleInstantPictureOptions((Boolean) newValue);
464 return true;
465 }
466 });
467
468 mPrefInstantVideoUploadPath = findPreference("instant_video_upload_path");
469 if (mPrefInstantVideoUploadPath != null){
470
471 mPrefInstantVideoUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
472 @Override
473 public boolean onPreferenceClick(Preference preference) {
474 if (!mUploadVideoPath.endsWith(OCFile.PATH_SEPARATOR)) {
475 mUploadVideoPath += OCFile.PATH_SEPARATOR;
476 }
477 Intent intent = new Intent(Preferences.this, UploadPathActivity.class);
478 intent.putExtra(UploadPathActivity.KEY_INSTANT_UPLOAD_PATH,
479 mUploadVideoPath);
480 startActivityForResult(intent, ACTION_SELECT_UPLOAD_VIDEO_PATH);
481 return true;
482 }
483 });
484 }
485
486 mPrefInstantVideoUploadPathWiFi = findPreference("instant_video_upload_on_wifi");
487 mPrefInstantVideoUpload = findPreference("instant_video_uploading");
488 toggleInstantVideoOptions(((CheckBoxPreference) mPrefInstantVideoUpload).isChecked());
489
490 mPrefInstantVideoUpload.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
491
492 @Override
493 public boolean onPreferenceChange(Preference preference, Object newValue) {
494 toggleInstantVideoOptions((Boolean) newValue);
495 return true;
496 }
497 });
498
499 /* About App */
500 pAboutApp = findPreference("about_app");
501 if (pAboutApp != null) {
502 pAboutApp.setTitle(String.format(getString(R.string.about_android),
503 getString(R.string.app_name)));
504 try {
505 Integer currentVersion = getPackageManager().getPackageInfo
506 (getPackageName(), 0).versionCode;
507 pAboutApp.setSummary(String.format(getString(R.string.about_version),
508 currentVersion));
509 } catch (NameNotFoundException e) {
510 }
511 }
512
513 loadInstantUploadPath();
514 loadStoragePath();
515 loadInstantUploadVideoPath();
516
517 /* ComponentsGetter */
518 mDownloadServiceConnection = newTransferenceServiceConnection();
519 if (mDownloadServiceConnection != null) {
520 bindService(new Intent(this, FileDownloader.class), mDownloadServiceConnection,
521 Context.BIND_AUTO_CREATE);
522 }
523 mUploadServiceConnection = newTransferenceServiceConnection();
524 if (mUploadServiceConnection != null) {
525 bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
526 Context.BIND_AUTO_CREATE);
527 }
528
529 /* Link to Beta apks */
530 Preference pBetaLink = findPreference("beta_link");
531 if (pBetaLink != null ){
532 pBetaLink.setOnPreferenceClickListener(new OnPreferenceClickListener() {
533 @Override
534 public boolean onPreferenceClick(Preference preference) {
535 Integer latestVersion = -1;
536 Integer currentVersion = -1;
537 try {
538 currentVersion = getPackageManager().getPackageInfo
539 (getPackageName(), 0).versionCode;
540 LoadingVersionNumberTask loadTask = new LoadingVersionNumberTask();
541 loadTask.execute();
542 latestVersion = loadTask.get();
543 } catch (InterruptedException | ExecutionException e) {
544 e.printStackTrace();
545 } catch (NameNotFoundException e) {
546 e.printStackTrace();
547 }
548 if (latestVersion == -1 || currentVersion == -1) {
549 Toast.makeText(getApplicationContext(), "No information available!",
550 Toast.LENGTH_SHORT).show();
551 }
552 if (latestVersion > currentVersion) {
553 String betaLinkWeb = (String) getText(R.string.beta_link) +
554 latestVersion + ".apk";
555 if (betaLinkWeb != null && betaLinkWeb.length() > 0) {
556 Uri uriUrl = Uri.parse(betaLinkWeb);
557 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
558 startActivity(intent);
559 return true;
560 }
561 } else {
562 Toast.makeText(getApplicationContext(), "No new version available!",
563 Toast.LENGTH_SHORT).show();
564 return true;
565 }
566 return true;
567 }
568 });
569 }
570
571 /* Link to Beta apks */
572 Preference pChangelogLink = findPreference("changelog_link");
573 if (pChangelogLink != null) {
574 pChangelogLink.setOnPreferenceClickListener(new OnPreferenceClickListener() {
575 @Override
576 public boolean onPreferenceClick(Preference preference) {
577 String betaLinkWeb = getString(R.string.changelog);
578 if (betaLinkWeb != null && betaLinkWeb.length() > 0) {
579 Uri uriUrl = Uri.parse(betaLinkWeb);
580 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
581 startActivity(intent);
582 return true;
583 }
584 return true;
585 }
586 });
587 }
588 }
589
590 private void toggleInstantPictureOptions(Boolean value){
591 if (value){
592 mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPathWiFi);
593 mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPath);
594 } else {
595 // mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPathWiFi);
596 // mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPath);
597 }
598 }
599
600 private void toggleInstantVideoOptions(Boolean value){
601 if (value){
602 mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPathWiFi);
603 mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPath);
604 } else {
605 // mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPathWiFi);
606 // mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPath);
607 }
608 }
609
610 @Override
611 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
612
613 // Filter for only showing contextual menu when long press on the
614 // accounts
615 if (mShowContextMenu) {
616 getMenuInflater().inflate(R.menu.account_picker_long_click, menu);
617 mShowContextMenu = false;
618 }
619 super.onCreateContextMenu(menu, v, menuInfo);
620 }
621
622 @Override
623 public void run(AccountManagerFuture<Boolean> future) {
624 if (future.isDone()) {
625 // after remove account
626 Account account = new Account(mAccountName, MainApp.getAccountType());
627 if (!AccountUtils.exists(account, MainApp.getAppContext())) {
628 // Cancel tranfers
629 if (mUploaderBinder != null) {
630 mUploaderBinder.cancel(account);
631 }
632 if (mDownloaderBinder != null) {
633 mDownloaderBinder.cancel(account);
634 }
635 }
636
637 Account a = AccountUtils.getCurrentOwnCloudAccount(this);
638 String accountName = "";
639 if (a == null) {
640 Account[] accounts = AccountManager.get(this)
641 .getAccountsByType(MainApp.getAccountType());
642 if (accounts.length != 0)
643 accountName = accounts[0].name;
644 AccountUtils.setCurrentOwnCloudAccount(this, accountName);
645 }
646 addAccountsCheckboxPreferences();
647 }
648 }
649
650 @Override
651 protected void onResume() {
652 super.onResume();
653 SharedPreferences appPrefs =
654 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
655 boolean state = appPrefs.getBoolean("set_pincode", false);
656 pCode.setChecked(state);
657
658 // Populate the accounts category with the list of accounts
659 addAccountsCheckboxPreferences();
660 }
661
662 @Override
663 public boolean onCreateOptionsMenu(Menu menu) {
664 super.onCreateOptionsMenu(menu);
665 return true;
666 }
667
668 @Override
669 public boolean onMenuItemSelected(int featureId, MenuItem item) {
670 super.onMenuItemSelected(featureId, item);
671 Intent intent;
672
673 switch (item.getItemId()) {
674 case android.R.id.home:
675 intent = new Intent(getBaseContext(), FileDisplayActivity.class);
676 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
677 startActivity(intent);
678 break;
679 default:
680 Log_OC.w(TAG, "Unknown menu item triggered");
681 return false;
682 }
683 return true;
684 }
685
686 @Override
687 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
688 super.onActivityResult(requestCode, resultCode, data);
689
690 if (requestCode == ACTION_SELECT_UPLOAD_PATH && resultCode == RESULT_OK){
691
692 OCFile folderToUpload = data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
693
694 mUploadPath = folderToUpload.getRemotePath();
695
696 mUploadPath = DisplayUtils.getPathWithoutLastSlash(mUploadPath);
697
698 // Show the path on summary preference
699 mPrefInstantUploadPath.setSummary(mUploadPath);
700
701 saveInstantUploadPathOnPreferences();
702
703 } else if (requestCode == ACTION_SELECT_UPLOAD_VIDEO_PATH && resultCode == RESULT_OK) {
704
705 OCFile folderToUploadVideo = data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
706
707 mUploadVideoPath = folderToUploadVideo.getRemotePath();
708
709 mUploadVideoPath = DisplayUtils.getPathWithoutLastSlash(mUploadVideoPath);
710
711 // Show the video path on summary preference
712 mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath);
713
714 saveInstantUploadVideoPathOnPreferences();
715 } else if (requestCode == ACTION_SELECT_STORAGE_PATH && resultCode == RESULT_OK) {
716 File currentStorageDir = new File(mStoragePath);
717 File upcomingStorageDir = new File(data.getStringExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES));
718
719 if (currentStorageDir != upcomingStorageDir) {
720 Intent migrationIntent = new Intent(this, StorageMigrationActivity.class);
721 migrationIntent.putExtra(StorageMigrationActivity.KEY_MIGRATION_SOURCE_DIR,
722 currentStorageDir.getAbsolutePath());
723 migrationIntent.putExtra(StorageMigrationActivity.KEY_MIGRATION_TARGET_DIR,
724 upcomingStorageDir.getAbsolutePath());
725 startActivityForResult(migrationIntent, ACTION_PERFORM_MIGRATION);
726 }
727 } else if (requestCode == ACTION_PERFORM_MIGRATION && resultCode == RESULT_OK) {
728 String resultStorageDir = data.getStringExtra(StorageMigrationActivity.KEY_MIGRATION_TARGET_DIR);
729 saveStoragePath(resultStorageDir);
730 } else if (requestCode == ACTION_REQUEST_PASSCODE && resultCode == RESULT_OK) {
731 String passcode = data.getStringExtra(PassCodeActivity.KEY_PASSCODE);
732 if (passcode != null && passcode.length() == 4) {
733 SharedPreferences.Editor appPrefs = PreferenceManager
734 .getDefaultSharedPreferences(getApplicationContext()).edit();
735
736 for (int i = 1; i <= 4; ++i) {
737 appPrefs.putString("PrefPinCode" + i, passcode.substring(i-1, i));
738 }
739 appPrefs.putBoolean("set_pincode", true);
740 appPrefs.commit();
741 Toast.makeText(this, R.string.pass_code_stored, Toast.LENGTH_LONG).show();
742 }
743 } else if (requestCode == ACTION_CONFIRM_PASSCODE && resultCode == RESULT_OK) {
744 if (data.getBooleanExtra(PassCodeActivity.KEY_CHECK_RESULT, false)) {
745
746 SharedPreferences.Editor appPrefs = PreferenceManager
747 .getDefaultSharedPreferences(getApplicationContext()).edit();
748 appPrefs.putBoolean("set_pincode", false);
749 appPrefs.commit();
750
751 Toast.makeText(this, R.string.pass_code_removed, Toast.LENGTH_LONG).show();
752 }
753 }
754 }
755
756 public ActionBar getSupportActionBar() {
757 return getDelegate().getSupportActionBar();
758 }
759
760 public void setSupportActionBar(@Nullable Toolbar toolbar) {
761 getDelegate().setSupportActionBar(toolbar);
762 }
763
764 @Override
765 public MenuInflater getMenuInflater() {
766 return getDelegate().getMenuInflater();
767 }
768
769 @Override
770 public void setContentView(@LayoutRes int layoutResID) {
771 getDelegate().setContentView(layoutResID);
772 }
773 @Override
774 public void setContentView(View view) {
775 getDelegate().setContentView(view);
776 }
777
778 @Override
779 public void setContentView(View view, ViewGroup.LayoutParams params) {
780 getDelegate().setContentView(view, params);
781 }
782
783 @Override
784 public void addContentView(View view, ViewGroup.LayoutParams params) {
785 getDelegate().addContentView(view, params);
786 }
787
788 @Override
789 protected void onPostResume() {
790 super.onPostResume();
791 getDelegate().onPostResume();
792 }
793
794 @Override
795 protected void onTitleChanged(CharSequence title, int color) {
796 super.onTitleChanged(title, color);
797 getDelegate().setTitle(title);
798 }
799
800 @Override
801 public void onConfigurationChanged(Configuration newConfig) {
802 super.onConfigurationChanged(newConfig);
803 getDelegate().onConfigurationChanged(newConfig);
804 }
805
806 @Override
807 protected void onPostCreate(Bundle savedInstanceState) {
808 super.onPostCreate(savedInstanceState);
809 getDelegate().onPostCreate(savedInstanceState);
810 }
811
812 @Override
813 protected void onDestroy() {
814 mDbHandler.close();
815
816 if (mDownloadServiceConnection != null) {
817 unbindService(mDownloadServiceConnection);
818 mDownloadServiceConnection = null;
819 }
820 if (mUploadServiceConnection != null) {
821 unbindService(mUploadServiceConnection);
822 mUploadServiceConnection = null;
823 }
824
825 super.onDestroy();
826 getDelegate().onDestroy();
827 }
828
829 @Override
830 protected void onStop() {
831 super.onStop();
832 getDelegate().onStop();
833 }
834
835 public void invalidateOptionsMenu() {
836 getDelegate().invalidateOptionsMenu();
837 }
838
839 private AppCompatDelegate getDelegate() {
840 if (mDelegate == null) {
841 mDelegate = AppCompatDelegate.create(this, null);
842 }
843 return mDelegate;
844 }
845
846 /**
847 * Create the list of accounts that has been added into the app
848 */
849 @SuppressWarnings("deprecation")
850 private void addAccountsCheckboxPreferences() {
851
852 // Remove accounts in case list is refreshing for avoiding to have
853 // duplicate items
854 if (mAccountsPrefCategory.getPreferenceCount() > 0) {
855 mAccountsPrefCategory.removeAll();
856 }
857
858 AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
859 Account accounts[] = am.getAccountsByType(MainApp.getAccountType());
860 Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
861
862 if (am.getAccountsByType(MainApp.getAccountType()).length == 0) {
863 // Show create account screen if there isn't any account
864 am.addAccount(MainApp.getAccountType(), null, null, null, this,
865 null,
866 null);
867 }
868 else {
869
870 for (Account a : accounts) {
871 RadioButtonPreference accountPreference = new RadioButtonPreference(this);
872 accountPreference.setKey(a.name);
873 // Handle internationalized domain names
874 accountPreference.setTitle(DisplayUtils.convertIdn(a.name, false));
875 mAccountsPrefCategory.addPreference(accountPreference);
876
877 // Check the current account that is being used
878 if (a.name.equals(currentAccount.name)) {
879 accountPreference.setChecked(true);
880 } else {
881 accountPreference.setChecked(false);
882 }
883
884 accountPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
885 @Override
886 public boolean onPreferenceChange(Preference preference, Object newValue) {
887 String key = preference.getKey();
888 AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
889 Account accounts[] = am.getAccountsByType(MainApp.getAccountType());
890 for (Account a : accounts) {
891 RadioButtonPreference p =
892 (RadioButtonPreference) findPreference(a.name);
893 if (key.equals(a.name)) {
894 boolean accountChanged = !p.isChecked();
895 p.setChecked(true);
896 AccountUtils.setCurrentOwnCloudAccount(
897 getApplicationContext(),
898 a.name
899 );
900 if (accountChanged) {
901 // restart the main activity
902 Intent i = new Intent(
903 Preferences.this,
904 FileDisplayActivity.class
905 );
906 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
907 i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
908 startActivity(i);
909 } else {
910 finish();
911 }
912 } else {
913 p.setChecked(false);
914 }
915 }
916 return (Boolean) newValue;
917 }
918 });
919
920 }
921
922 // Add Create Account preference at the end of account list if
923 // Multiaccount is enabled
924 if (getResources().getBoolean(R.bool.multiaccount_support)) {
925 createAddAccountPreference();
926 }
927
928 }
929 }
930
931 /**
932 * Create the preference for allow adding new accounts
933 */
934 private void createAddAccountPreference() {
935 Preference addAccountPref = new Preference(this);
936 addAccountPref.setKey("add_account");
937 addAccountPref.setTitle(getString(R.string.prefs_add_account));
938 mAccountsPrefCategory.addPreference(addAccountPref);
939
940 addAccountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
941 @Override
942 public boolean onPreferenceClick(Preference preference) {
943 AccountManager am = AccountManager.get(getApplicationContext());
944 am.addAccount(MainApp.getAccountType(), null, null, null, Preferences.this,
945 null, null);
946 return true;
947 }
948 });
949
950 }
951
952 /**
953 * Load upload path set on preferences
954 */
955 private void loadInstantUploadPath() {
956 SharedPreferences appPrefs =
957 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
958 mUploadPath = appPrefs.getString("instant_upload_path", getString(R.string.instant_upload_path));
959 mPrefInstantUploadPath.setSummary(mUploadPath);
960 }
961
962 /**
963 * Save storage path
964 */
965 private void saveStoragePath(String newStoragePath) {
966 SharedPreferences appPrefs =
967 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
968 mStoragePath = newStoragePath;
969 MainApp.setStoragePath(mStoragePath);
970 SharedPreferences.Editor editor = appPrefs.edit();
971 editor.putString("storage_path", mStoragePath);
972 editor.commit();
973 mPrefStoragePath.setSummary(mStoragePath);
974 }
975
976 /**
977 * Load storage path set on preferences
978 */
979 private void loadStoragePath() {
980 SharedPreferences appPrefs =
981 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
982 mStoragePath = appPrefs.getString("storage_path", Environment.getExternalStorageDirectory()
983 .getAbsolutePath());
984 mPrefStoragePath.setSummary(mStoragePath);
985 }
986
987 /**
988 * Save the "Instant Upload Path" on preferences
989 */
990 private void saveInstantUploadPathOnPreferences() {
991 SharedPreferences appPrefs =
992 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
993 SharedPreferences.Editor editor = appPrefs.edit();
994 editor.putString("instant_upload_path", mUploadPath);
995 editor.commit();
996 }
997
998 /**
999 * Load upload video path set on preferences
1000 */
1001 private void loadInstantUploadVideoPath() {
1002 mPrefInstantVideoUploadPath.setSummary(MainApp.getStoragePath());
1003 }
1004
1005 /**
1006 * Save the "Instant Video Upload Path" on preferences
1007 */
1008 private void saveInstantUploadVideoPathOnPreferences() {
1009 SharedPreferences appPrefs =
1010 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
1011 SharedPreferences.Editor editor = appPrefs.edit();
1012 editor.putString("instant_video_upload_path", mUploadVideoPath);
1013 editor.commit();
1014 }
1015
1016 // Methods for ComponentsGetter
1017 @Override
1018 public FileDownloader.FileDownloaderBinder getFileDownloaderBinder() {
1019 return mDownloaderBinder;
1020 }
1021
1022
1023 @Override
1024 public FileUploader.FileUploaderBinder getFileUploaderBinder() {
1025 return mUploaderBinder;
1026 }
1027
1028 @Override
1029 public OperationsService.OperationsServiceBinder getOperationsServiceBinder() {
1030 return null;
1031 }
1032
1033 @Override
1034 public FileDataStorageManager getStorageManager() {
1035 return null;
1036 }
1037
1038 @Override
1039 public FileOperationsHelper getFileOperationsHelper() {
1040 return null;
1041 }
1042
1043 protected ServiceConnection newTransferenceServiceConnection() {
1044 return new PreferencesServiceConnection();
1045 }
1046
1047 /** Defines callbacks for service binding, passed to bindService() */
1048 private class PreferencesServiceConnection implements ServiceConnection {
1049
1050 @Override
1051 public void onServiceConnected(ComponentName component, IBinder service) {
1052
1053 if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
1054 mDownloaderBinder = (FileDownloader.FileDownloaderBinder) service;
1055 } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
1056 Log_OC.d(TAG, "Upload service connected");
1057 mUploaderBinder = (FileUploader.FileUploaderBinder) service;
1058 }
1059 }
1060
1061 @Override
1062 public void onServiceDisconnected(ComponentName component) {
1063 if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
1064 Log_OC.d(TAG, "Download service suddenly disconnected");
1065 mDownloaderBinder = null;
1066 } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
1067 Log_OC.d(TAG, "Upload service suddenly disconnected");
1068 mUploaderBinder = null;
1069 }
1070 }
1071 };
1072
1073 /**
1074 *
1075 * Class for loading the version number
1076 *
1077 */
1078 private class LoadingVersionNumberTask extends AsyncTask<Void, Void, Integer> {
1079 protected Integer doInBackground(Void... args) {
1080 try {
1081 URL url = new URL("https://github.com/owncloud/android/raw/beta/apks/latest");
1082 BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
1083
1084 Integer latestVersion = Integer.parseInt(in.readLine());
1085 in.close();
1086
1087 return latestVersion;
1088
1089 } catch (MalformedURLException e) {
1090 e.printStackTrace();
1091 } catch (IOException e) {
1092 e.printStackTrace();
1093 }
1094 return -1;
1095 }
1096 }
1097 }