Removed toast message for updating credentials when user manually accessed to the...
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / FileActivity.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 package com.owncloud.android.ui.activity;
20
21 import android.accounts.Account;
22 import android.accounts.AccountManager;
23 import android.accounts.AccountManagerCallback;
24 import android.accounts.AccountManagerFuture;
25 import android.accounts.OperationCanceledException;
26 import android.content.Intent;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.webkit.MimeTypeMap;
30
31 import com.actionbarsherlock.app.SherlockFragmentActivity;
32 import com.owncloud.android.AccountUtils;
33 import com.owncloud.android.Log_OC;
34 import com.owncloud.android.R;
35 import com.owncloud.android.authentication.AccountAuthenticator;
36 import com.owncloud.android.datamodel.OCFile;
37
38 import eu.alefzero.webdav.WebdavUtils;
39
40 /**
41 * Activity with common behaviour for activities handling {@link OCFile}s in ownCloud {@link Account}s .
42 *
43 * @author David A. Velasco
44 */
45 public abstract class FileActivity extends SherlockFragmentActivity {
46
47 public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE";
48 public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT";
49 public static final String EXTRA_WAITING_TO_PREVIEW = "com.owncloud.android.ui.activity.WAITING_TO_PREVIEW";
50
51 public static final String TAG = FileActivity.class.getSimpleName();
52
53
54 /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located. */
55 private Account mAccount;
56
57 /** Main {@link OCFile} handled by the activity.*/
58 private OCFile mFile;
59
60 /** Flag to signal that the activity will is finishing to enforce the creation of an ownCloud {@link Account} */
61 private boolean mRedirectingToSetupAccount = false;
62
63
64 /**
65 * Loads the cownCloud {@link Account} and main {@link OCFile} to be handled by the instance of
66 * the {@link FileActivity}.
67 *
68 * Grants that a valid ownCloud {@link Account} is associated to the instance, or that the user
69 * is requested to create a new one.
70 */
71 @Override
72 protected void onCreate(Bundle savedInstanceState) {
73 super.onCreate(savedInstanceState);
74
75 if(savedInstanceState != null) {
76 mFile = savedInstanceState.getParcelable(FileActivity.EXTRA_FILE);
77 mAccount = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT);
78 } else {
79 mAccount = getIntent().getParcelableExtra(FileActivity.EXTRA_ACCOUNT);
80 mFile = getIntent().getParcelableExtra(FileActivity.EXTRA_FILE);
81 }
82
83 grantValidAccount();
84 if (mAccount != null) {
85 onAccountSet(savedInstanceState != null);
86 }
87 }
88
89
90 /**
91 * Since ownCloud {@link Account}s can be managed from the system setting menu,
92 * the existence of the {@link Account} associated to the instance must be checked
93 * every time it is restarted.
94 */
95 @Override
96 protected void onRestart() {
97 super.onRestart();
98
99 Account oldAccount = mAccount;
100 grantValidAccount();
101 if (mAccount != null && !mAccount.equals(oldAccount)) {
102 onAccountSet(false);
103 }
104 }
105
106
107 /**
108 * Validates the ownCloud {@link Account} associated to the Activity any time it is restarted.
109 *
110 * If not valid, tries to swap it for other valid and existing ownCloud {@link Account}.
111 *
112 * If no valid ownCloud {@link Account} exists, mAccount is set to NULL and the user is requested
113 * to create a new ownCloud {@link Account}.
114 */
115 private void grantValidAccount() {
116 boolean validAccount = (mAccount != null && AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), mAccount.name));
117 if (!validAccount) {
118 // get most recently used account as default account
119 mAccount = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
120 if (mAccount == null) {
121 /// no account available: force account creation
122 createFirstAccount();
123 mRedirectingToSetupAccount = true;
124 }
125 }
126 }
127
128
129 /**
130 * Launches the account creation activity. To use when no ownCloud account is available
131 */
132 private void createFirstAccount() {
133 AccountManager am = AccountManager.get(getApplicationContext());
134 am.addAccount(AccountAuthenticator.ACCOUNT_TYPE,
135 AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD,
136 null,
137 null,
138 this,
139 new AccountCreationCallback(),
140 null);
141 }
142
143
144 /**
145 * {@inheritDoc}
146 */
147 @Override
148 protected void onSaveInstanceState(Bundle outState) {
149 super.onSaveInstanceState(outState);
150 outState.putParcelable(FileActivity.EXTRA_FILE, mFile);
151 outState.putParcelable(FileActivity.EXTRA_ACCOUNT, mAccount);
152 }
153
154
155 /**
156 * Getter for the main {@link OCFile} handled by the activity.
157 *
158 * @return Main {@link OCFile} handled by the activity.
159 */
160 public OCFile getFile() {
161 return mFile;
162 }
163
164
165 /**
166 * Setter for the main {@link OCFile} handled by the activity.
167 *
168 * @param file Main {@link OCFile} to be handled by the activity.
169 */
170 public void setFile(OCFile file) {
171 mFile = file;
172 }
173
174
175 /**
176 * Getter for the ownCloud {@link Account} where the main {@link OCFile} handled by the activity is located.
177 *
178 * @return OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located.
179 */
180 public Account getAccount() {
181 return mAccount;
182 }
183
184
185 /**
186 * @return 'True' when the Activity is finishing to enforce the setup of a new account.
187 */
188 protected boolean isRedirectingToSetupAccount() {
189 return mRedirectingToSetupAccount;
190 }
191
192
193 /**
194 * Helper class handling a callback from the {@link AccountManager} after the creation of
195 * a new ownCloud {@link Account} finished, successfully or not.
196 *
197 * At this moment, only called after the creation of the first account.
198 *
199 * @author David A. Velasco
200 */
201 public class AccountCreationCallback implements AccountManagerCallback<Bundle> {
202
203 @Override
204 public void run(AccountManagerFuture<Bundle> future) {
205 FileActivity.this.mRedirectingToSetupAccount = false;
206 if (future != null) {
207 try {
208 Bundle result;
209 result = future.getResult();
210 String name = result.getString(AccountManager.KEY_ACCOUNT_NAME);
211 String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
212 if (AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), name)) {
213 FileActivity.this.mAccount = new Account(name, type);
214 FileActivity.this.onAccountSet(false);
215 }
216 } catch (OperationCanceledException e) {
217 Log_OC.e(TAG, "Account creation canceled");
218
219 } catch (Exception e) {
220 Log_OC.e(TAG, "Account creation finished in exception: ", e);
221 }
222
223 } else {
224 Log_OC.e(TAG, "Account creation callback with null bundle");
225 }
226 if (mAccount == null) {
227 finish();
228 }
229 }
230
231 }
232
233
234 /**
235 * Called when the ownCloud {@link Account} associated to the Activity was just updated.
236 *
237 * Child classes must grant that state depending on the {@link Account} is updated.
238 */
239 protected abstract void onAccountSet(boolean stateWasRecovered);
240
241
242
243 public void openFile(OCFile file) {
244 if (file != null) {
245 String storagePath = file.getStoragePath();
246 String encodedStoragePath = WebdavUtils.encodePath(storagePath);
247
248 Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
249 intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
250 intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
251
252 Intent intentForGuessedMimeType = null;
253 if (storagePath.lastIndexOf('.') >= 0) {
254 String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
255 if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) {
256 intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW);
257 intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType);
258 intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
259 }
260 }
261
262 Intent chooserIntent = null;
263 if (intentForGuessedMimeType != null) {
264 chooserIntent = Intent.createChooser(intentForGuessedMimeType, getString(R.string.actionbar_open_with));
265 } else {
266 chooserIntent = Intent.createChooser(intentForSavedMimeType, getString(R.string.actionbar_open_with));
267 }
268
269 startActivity(chooserIntent);
270
271 } else {
272 Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
273 }
274 }
275
276 }