0ce31e26a85c8386e4e87baad79049dda439babb
[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.ACCOUNT";
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 @Override
65 protected void onCreate(Bundle savedInstanceState) {
66 super.onCreate(savedInstanceState);
67
68 /// Load of saved instance state: keep this always before initDataFromCurrentAccount()
69 if(savedInstanceState != null) {
70 mFile = savedInstanceState.getParcelable(FileActivity.EXTRA_FILE);
71 mAccount = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT);
72 } else {
73 mAccount = getIntent().getParcelableExtra(FileActivity.EXTRA_ACCOUNT);
74 mFile = getIntent().getParcelableExtra(FileActivity.EXTRA_FILE);
75 }
76
77 if (mAccount != null && AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), mAccount.name)) {
78 onAccountChanged();
79 }
80
81 }
82
83
84 /**
85 * Validate the ownCloud {@link Account} associated to the Activity any time it is
86 * started, and if not valid tries to move to a different Account.
87 */
88 @Override
89 protected void onStart() {
90 Log_OC.d(TAG, "onStart en FileActivity");
91 super.onStart();
92 /// Validate account, and try to fix if wrong
93 if (mAccount == null || !AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), mAccount.name)) {
94 if (!AccountUtils.accountsAreSetup(getApplicationContext())) {
95 /// no account available: force account creation
96 mAccount = null;
97 createFirstAccount();
98 mRedirectingToSetupAccount = true;
99
100 } else {
101 /// get 'last current account' as default account
102 mAccount = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
103 onAccountChanged();
104 }
105 }
106 }
107
108
109 /**
110 * Launches the account creation activity. To use when no ownCloud account is available
111 */
112 private void createFirstAccount() {
113 AccountManager am = AccountManager.get(getApplicationContext());
114 am.addAccount(AccountAuthenticator.ACCOUNT_TYPE,
115 AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD,
116 null,
117 null,
118 this,
119 new AccountCreationCallback(),
120 null);
121 }
122
123
124 /**
125 * {@inheritDoc}
126 */
127 @Override
128 protected void onSaveInstanceState(Bundle outState) {
129 super.onSaveInstanceState(outState);
130 outState.putParcelable(FileActivity.EXTRA_FILE, mFile);
131 outState.putParcelable(FileActivity.EXTRA_ACCOUNT, mAccount);
132 }
133
134
135 /**
136 * Getter for the main {@link OCFile} handled by the activity.
137 *
138 * @return Main {@link OCFile} handled by the activity.
139 */
140 public OCFile getFile() {
141 return mFile;
142 }
143
144
145 /**
146 * Setter for the main {@link OCFile} handled by the activity.
147 *
148 * @param file Main {@link OCFile} to be handled by the activity.
149 */
150 public void setFile(OCFile file) {
151 mFile = file;
152 }
153
154
155 /**
156 * Getter for the ownCloud {@link Account} where the main {@link OCFile} handled by the activity is located.
157 *
158 * @return OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located.
159 */
160 public Account getAccount() {
161 return mAccount;
162 }
163
164
165 /**
166 * @return 'True' when the Activity is finishing to enforce the setup of a new account.
167 */
168 protected boolean isRedirectingToSetupAccount() {
169 return mRedirectingToSetupAccount;
170 }
171
172
173 /**
174 * Helper class handling a callback from the {@link AccountManager} after the creation of
175 * a new ownCloud {@link Account} finished, successfully or not.
176 *
177 * At this moment, only called after the creation of the first account.
178 *
179 * @author David A. Velasco
180 */
181 public class AccountCreationCallback implements AccountManagerCallback<Bundle> {
182
183 @Override
184 public void run(AccountManagerFuture<Bundle> future) {
185 FileActivity.this.mRedirectingToSetupAccount = false;
186 if (future != null) {
187 try {
188 Bundle result;
189 result = future.getResult();
190 String name = result.getString(AccountManager.KEY_ACCOUNT_NAME);
191 String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
192 if (AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), name)) {
193 FileActivity.this.mAccount = new Account(name, type);
194 FileActivity.this.onAccountChanged();
195 }
196 } catch (OperationCanceledException e) {
197 Log_OC.e(TAG, "Account creation canceled");
198
199 } catch (Exception e) {
200 Log_OC.e(TAG, "Account creation finished in exception: ", e);
201 }
202
203 } else {
204 Log_OC.e(TAG, "Account creation callback with null bundle");
205 }
206 if (mAccount == null) {
207 finish();
208 }
209 }
210
211 }
212
213
214 /**
215 * Called when the ownCloud {@link Account} associated to the Activity was just updated.
216 *
217 * Child classes must grant that state depending on the {@link Account} is updated.
218 */
219 protected abstract void onAccountChanged();
220
221
222
223 public void openFile(OCFile file) {
224 if (file != null) {
225 String storagePath = file.getStoragePath();
226 String encodedStoragePath = WebdavUtils.encodePath(storagePath);
227
228 Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
229 intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
230 intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
231
232 Intent intentForGuessedMimeType = null;
233 if (storagePath.lastIndexOf('.') >= 0) {
234 String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
235 if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) {
236 intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW);
237 intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType);
238 intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
239 }
240 }
241
242 Intent chooserIntent = null;
243 if (intentForGuessedMimeType != null) {
244 chooserIntent = Intent.createChooser(intentForGuessedMimeType, getString(R.string.actionbar_open_with));
245 } else {
246 chooserIntent = Intent.createChooser(intentForSavedMimeType, getString(R.string.actionbar_open_with));
247 }
248
249 startActivity(chooserIntent);
250
251 } else {
252 Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
253 }
254 }
255
256 }