Merge pull request #118 from owncloud/loggingtool

This can go in by now.
This commit is contained in:
David A. Velasco 2013-04-15 04:51:36 -07:00
commit 5a25a6a698
61 changed files with 5308 additions and 4929 deletions

View file

@ -1,174 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
Copyright (C) 2012-2013 ownCloud Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<manifest package="com.owncloud.android"
android:versionCode="104000"
android:versionName="1.4.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="13" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
</uses-permission>
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/Theme.ownCloud">
<activity
android:name=".ui.activity.FileDisplayActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.activity.UploadFilesActivity">
</activity>
<activity android:name=".ui.activity.InstantUploadActivity">
</activity>
<activity android:name=".ui.activity.FailedUploadActivity" android:theme="@android:style/Theme.Dialog" android:excludeFromRecents="true"/>
<activity android:name=".Uploader" >
<intent-filter>
<action android:name="android.intent.action.SEND" >
</action>
<category android:name="android.intent.category.DEFAULT" >
</category>
<data android:mimeType="*/*" >
</data>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" >
</action>
<category android:name="android.intent.category.DEFAULT" >
</category>
<data android:mimeType="*/*" >
</data>
</intent-filter>
</activity>
<activity
android:name=".ui.activity.Preferences"
android:theme="@style/Theme.ownCloud" >
</activity>
<activity android:name=".ui.activity.PreferencesNewSessionewSession" >
</activity>
<activity android:name="com.owncloud.android.ui.preview.PreviewImageActivity" />
<activity android:name="com.owncloud.android.ui.preview.PreviewVideoActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
</activity>
<service
android:name=".authenticator.AccountAuthenticatorService"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
<service
android:name=".syncadapter.FileSyncService"
android:exported="true" >
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter_files" />
</service>
<provider
android:name=".providers.FileContentProvider"
android:authorities="org.owncloud"
android:enabled="true"
android:exported="false"
android:label="@string/sync_string_files"
android:syncable="true" >
</provider>
<activity
android:name=".ui.activity.AuthenticatorActivity"
android:exported="true"
android:theme="@style/Theme.ownCloud.noActionBar" >
<intent-filter>
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".files.services.FileDownloader" />
<service android:name=".files.services.FileUploader" />
<service android:name=".media.MediaService" />
<activity android:name=".ui.activity.FileDetailActivity" />
<activity android:name=".ui.activity.PinCodeActivity" />
<activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
<activity android:name=".extensions.ExtensionsListActivity"></activity>
<activity android:name=".ui.activity.AccountSelectActivity" android:uiOptions="none" android:label="@string/prefs_accounts"></activity>
<activity android:name=".ui.activity.ConflictsResolveActivity"/>
<activity android:name=".ui.activity.GenericExplanationActivity"/>
<activity android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity"/>
<?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
Copyright (C) 2012-2013 ownCloud Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<manifest package="com.owncloud.android"
android:versionCode="104000"
android:versionName="1.4.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="13" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
</uses-permission>
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/Theme.ownCloud">
<activity
android:name=".ui.activity.FileDisplayActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.activity.UploadFilesActivity">
</activity>
<activity android:name=".ui.activity.InstantUploadActivity">
</activity>
<activity android:name=".ui.activity.FailedUploadActivity" android:theme="@android:style/Theme.Dialog" android:excludeFromRecents="true"/>
<activity android:name=".Uploader" >
<intent-filter>
<action android:name="android.intent.action.SEND" >
</action>
<category android:name="android.intent.category.DEFAULT" >
</category>
<data android:mimeType="*/*" >
</data>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" >
</action>
<category android:name="android.intent.category.DEFAULT" >
</category>
<data android:mimeType="*/*" >
</data>
</intent-filter>
</activity>
<activity
android:name=".ui.activity.Preferences"
android:theme="@style/Theme.ownCloud" >
</activity>
<activity android:name=".ui.activity.PreferencesNewSessionewSession" >
</activity>
<activity android:name="com.owncloud.android.ui.preview.PreviewImageActivity" />
<activity android:name="com.owncloud.android.ui.preview.PreviewVideoActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
</activity>
<service
android:name=".authenticator.AccountAuthenticatorService"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
<service
android:name=".syncadapter.FileSyncService"
android:exported="true" >
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter_files" />
</service>
<provider
android:name=".providers.FileContentProvider"
android:authorities="org.owncloud"
android:enabled="true"
android:exported="false"
android:label="@string/sync_string_files"
android:syncable="true" >
</provider>
<activity
android:name=".ui.activity.AuthenticatorActivity"
android:exported="true"
android:theme="@style/Theme.ownCloud.noActionBar" >
<intent-filter>
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".files.services.FileDownloader" />
<service android:name=".files.services.FileUploader" />
<service android:name=".media.MediaService" />
<activity android:name=".ui.activity.FileDetailActivity" />
<activity android:name=".ui.activity.PinCodeActivity" />
<activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
<activity android:name=".extensions.ExtensionsListActivity"></activity>
<activity android:name=".ui.activity.AccountSelectActivity" android:uiOptions="none" android:label="@string/prefs_accounts"></activity>
<activity android:name=".ui.activity.ConflictsResolveActivity"/>
<activity android:name=".ui.activity.GenericExplanationActivity"/>
<activity android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity"/>
<activity android:name=".ui.activity.LogHistoryActivity"/>
<service android:name=".files.services.InstantUploadService" />
<receiver android:name=".files.InstantUploadBroadcastReceiver">
<intent-filter>
<action android:name="com.android.camera.NEW_PICTURE" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<receiver android:name=".files.BootupBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".files.services.FileObserverService"/>
</application>
</manifest>
<receiver android:name=".files.InstantUploadBroadcastReceiver">
<intent-filter>
<action android:name="com.android.camera.NEW_PICTURE" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<receiver android:name=".files.BootupBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".files.services.FileObserverService"/>
</application>
</manifest>

19
res/layout/log_item.xml Normal file
View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView android:id="@+id/log_item_single"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:textStyle="bold"
android:textSize="22dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
</LinearLayout>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF0000"
android:text="No data"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom">
<Button android:id="@+id/deleteLogHistoryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/prefs_log_delete_history_button"/>
</LinearLayout>
</LinearLayout>

View file

@ -24,7 +24,6 @@
<item android:id="@+id/action_create_dir" android:title="@string/actionbar_mkdir" android:icon="@drawable/ic_action_create_dir" android:orderInCategory="2" />
<item android:id="@+id/action_upload" android:title="@string/actionbar_upload" android:icon="@drawable/ic_action_upload" android:orderInCategory="2" />
<item android:id="@+id/action_settings" android:title="@string/actionbar_settings" android:icon="@android:drawable/ic_menu_preferences" android:orderInCategory="2" />
<item android:id="@+id/action_about_app" android:title="@string/about_title" android:icon="@android:drawable/ic_menu_info_details" android:orderInCategory="2" />
<!-- <item android:id="@+id/search" android:title="@string/actionbar_search" android:icon="@drawable/ic_action_search"></item>-->
</menu>

View file

@ -14,7 +14,8 @@
<string name="main_settings">Settings</string>
<string name="main_tit_accsetup">Setup Account</string>
<string name="main_wrn_accsetup">There is no account set up on your device. In order to use this App, you need to create one.</string>
<string name="about_message">%1$s Android App\n\nversion: %2$s</string>
<string name="about_android">%1$s Android App</string>
<string name="about_version">version %1$s</string>
<string name="actionbar_sync">Refresh</string>
<string name="actionbar_upload">Upload</string>
<string name="actionbar_upload_from_apps">Content from other apps</string>
@ -40,6 +41,12 @@
<string name="prefs_pincode_summary">Protect your client</string>
<string name="prefs_instant_upload">Enable instant uploads</string>
<string name="prefs_instant_upload_summary">Instantly upload photos taken by camera</string>
<string name="prefs_log_title">Enable Logging</string>
<string name="prefs_log_summary">This is used to log problems</string>
<string name="prefs_log_title_history">Logging History</string>
<string name="prefs_log_summary_history">This shows the recorded logs</string>
<string name="prefs_log_delete_history_button">Delete History</string>
<string name="auth_host_url">URL</string>
<string name="auth_username">Username</string>
<string name="auth_password">Password</string>
@ -169,14 +176,14 @@
<item>60</item>
</string-array>
<string name="auth_trying_to_login">Trying to login</string>
<string name="auth_trying_to_login">Trying to login...</string>
<string name="auth_no_net_conn_title">No network connection</string>
<string name="auth_no_net_conn_message">No network connection has been detected, check your Internet connection and try again.</string>
<string name="auth_connect_anyway">Connect anyway</string>
<string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
<string name="auth_nossl_plain_ok_message">The Application cannot establish a secure connection to the server. A non secure connection is available. You may continue or cancel.</string>
<string name="auth_connection_established">Connection established</string>
<string name="auth_testing_connection">Testing connection</string>
<string name="auth_testing_connection">Testing connection...</string>
<string name="auth_not_configured_title">Malformed server configuration</string>
<string name="auth_not_configured_message">It seems that your server instance is not correctly configured. Contact your administrator for more details.</string>
<string name="auth_unknown_error_title">Unknown error occurred!</string>

View file

@ -32,8 +32,19 @@
<CheckBoxPreference android:key="instant_uploading"
android:title="@string/prefs_instant_upload"
android:summary="@string/prefs_instant_upload_summary"/>
<CheckBoxPreference android:dependency="instant_uploading" android:disableDependentsState="true" android:title="@string/instant_upload_on_wifi" android:key="instant_upload_on_wifi"/>
<CheckBoxPreference android:dependency="instant_uploading"
android:disableDependentsState="true"
android:title="@string/instant_upload_on_wifi"
android:key="instant_upload_on_wifi"/>
<CheckBoxPreference android:key="log_to_file"
android:title="@string/prefs_log_title"
android:summary="@string/prefs_log_summary"/>
<Preference android:key="log_history"
android:title="@string/prefs_log_title_history"
android:summary="@string/prefs_log_summary_history"/>
<Preference android:id="@+id/about_app"
android:title="@string/about_title"
android:key="about_app" />
</PreferenceCategory>

View file

@ -0,0 +1,127 @@
package com.owncloud.android;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.util.Log;
public class Log_OC {
private static boolean isEnabled = false;
private static File logFile;
private static File folder;
private static BufferedWriter buf;
public static void i(String TAG, String message){
// Printing the message to LogCat console
Log.i(TAG, message);
// Write the log message to the file
appendLog(TAG+" : "+message);
}
public static void d(String TAG, String message){
Log.d(TAG, message);
appendLog(TAG+" : "+message);
}
public static void d(String TAG, String message, Exception e) {
Log.d(TAG, message, e);
appendLog(TAG+" : "+ message+" Exception : "+e.getStackTrace());
}
public static void e(String TAG, String message){
Log.e(TAG, message);
appendLog(TAG+" : "+message);
}
public static void e(String TAG, String message, Throwable e) {
Log.e(TAG, message, e);
appendLog(TAG+" : "+ message+" Exception : "+e.getStackTrace());
}
public static void v(String TAG, String message){
Log.v(TAG, message);
appendLog(TAG+" : "+message);
}
public static void w(String TAG, String message) {
Log.w(TAG,message);
appendLog(TAG+" : "+message);
}
public static void wtf(String TAG, String message) {
Log.wtf(TAG,message);
appendLog(TAG+" : "+message);
}
public static void startLogging(String logPath) {
folder = new File(logPath);
logFile = new File(folder+File.separator+"log.txt");
if (!folder.exists()) {
folder.mkdirs();
}
if (logFile.exists()) {
logFile.delete();
}
try {
logFile.createNewFile();
buf = new BufferedWriter(new FileWriter(logFile, true));
isEnabled = true;
appendPhoneInfo();
}catch (IOException e){
e.printStackTrace();
}
}
public static void stopLogging() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.getDefault());
String currentDateandTime = sdf.format(new Date());
if (logFile != null) {
logFile.renameTo(new File(folder+File.separator+"Owncloud_"+currentDateandTime+".log"));
isEnabled = false;
try {
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void appendPhoneInfo() {
appendLog("Model : " + android.os.Build.MODEL);
appendLog("Brand : " + android.os.Build.BRAND);
appendLog("Product : " + android.os.Build.PRODUCT);
appendLog("Device : " + android.os.Build.DEVICE);
appendLog("Version-Codename : " + android.os.Build.VERSION.CODENAME);
appendLog("Version-Release : " + android.os.Build.VERSION.RELEASE);
}
private static void appendLog(String text) {
if (isEnabled) {
try {
buf.append(text);
buf.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View file

@ -1,407 +1,407 @@
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.Vector;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.network.OwnCloudClientUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.owncloud.android.R;
import eu.alefzero.webdav.WebdavClient;
/**
* This can be used to upload things to an ownCloud instance.
*
* @author Bartek Przybylski
*
*/
public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
private static final String TAG = "ownCloudUploader";
private Account mAccount;
private AccountManager mAccountManager;
private Stack<String> mParents;
private ArrayList<Parcelable> mStreamsToUpload;
private boolean mCreateDir;
private String mUploadPath;
private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
private DataStorageManager mStorageManager;
private OCFile mFile;
private final static int DIALOG_NO_ACCOUNT = 0;
private final static int DIALOG_WAITING = 1;
private final static int DIALOG_NO_STREAM = 2;
private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
//private final static int DIALOG_GET_DIRNAME = 4;
private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mParents = new Stack<String>();
mParents.add("");
/*if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
prepareStreamsToUpload();*/
if (prepareStreamsToUpload()) {
mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
if (accounts.length == 0) {
Log.i(TAG, "No ownCloud account is available");
showDialog(DIALOG_NO_ACCOUNT);
} else if (accounts.length > 1) {
Log.i(TAG, "More then one ownCloud is available");
showDialog(DIALOG_MULTIPLE_ACCOUNT);
} else {
mAccount = accounts[0];
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
populateDirectoryList();
}
} else {
showDialog(DIALOG_NO_STREAM);
}
}
@Override
protected Dialog onCreateDialog(final int id) {
final AlertDialog.Builder builder = new Builder(this);
switch (id) {
case DIALOG_WAITING:
ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
return pDialog;
case DIALOG_NO_ACCOUNT:
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.uploader_wrn_no_account_title);
builder.setMessage(String.format(getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
builder.setCancelable(false);
builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
// using string value since in API7 this
// constatn is not defined
// in API7 < this constatant is defined in
// Settings.ADD_ACCOUNT_SETTINGS
// and Settings.EXTRA_AUTHORITIES
Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
} else {
// since in API7 there is no direct call for
// account setup, so we need to
// show our own AccountSetupAcricity, get
// desired results and setup
// everything for ourself
Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
}
}
});
builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
return builder.create();
/*case DIALOG_GET_DIRNAME:
final EditText dirName = new EditText(getBaseContext());
builder.setView(dirName);
builder.setTitle(R.string.uploader_info_dirname);
String pathToUpload;
if (mParents.empty()) {
pathToUpload = "/";
} else {
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), null,
null, null, null);
mCursor.moveToFirst();
pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))
+ mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20"); // TODO don't make this ; use WebdavUtils.encode in the right moment
}
a a = new a(pathToUpload, dirName);
builder.setPositiveButton(R.string.common_ok, a);
builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
return builder.create();*/
case DIALOG_MULTIPLE_ACCOUNT:
CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
for (int i = 0; i < ac.length; ++i) {
ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;
}
builder.setTitle(R.string.common_choose_account);
builder.setItems(ac, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
populateDirectoryList();
}
});
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.cancel();
finish();
}
});
return builder.create();
case DIALOG_NO_STREAM:
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.uploader_wrn_no_content_title);
builder.setMessage(R.string.uploader_wrn_no_content_text);
builder.setCancelable(false);
builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
return builder.create();
default:
throw new IllegalArgumentException("Unknown dialog id: " + id);
}
}
class a implements OnClickListener {
String mPath;
EditText mDirname;
public a(String path, EditText dirname) {
mPath = path;
mDirname = dirname;
}
@Override
public void onClick(DialogInterface dialog, int which) {
Uploader.this.mUploadPath = mPath + mDirname.getText().toString();
Uploader.this.mCreateDir = true;
uploadFiles();
}
}
@Override
public void onBackPressed() {
if (mParents.size() <= 1) {
super.onBackPressed();
return;
} else {
mParents.pop();
populateDirectoryList();
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// click on folder in the list
Log.d(TAG, "on item click");
Vector<OCFile> tmpfiles = mStorageManager.getDirectoryContent(mFile);
if (tmpfiles.size() <= 0) return;
// filter on dirtype
Vector<OCFile> files = new Vector<OCFile>();
for (OCFile f : tmpfiles)
if (f.isDirectory())
files.add(f);
if (files.size() < position) {
throw new IndexOutOfBoundsException("Incorrect item selected");
}
mParents.push(files.get(position).getFileName());
populateDirectoryList();
}
@Override
public void onClick(View v) {
// click on button
switch (v.getId()) {
case R.id.uploader_choose_folder:
mUploadPath = ""; // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
for (String p : mParents)
mUploadPath += p + OCFile.PATH_SEPARATOR;
Log.d(TAG, "Uploading file to dir " + mUploadPath);
uploadFiles();
break;
/*case android.R.id.button1: // dynamic action for create aditional dir
showDialog(DIALOG_GET_DIRNAME);
break;*/
default:
throw new IllegalArgumentException("Wrong element clicked");
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
dismissDialog(DIALOG_NO_ACCOUNT);
if (resultCode == RESULT_CANCELED) {
finish();
}
Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);
if (accounts.length == 0) {
showDialog(DIALOG_NO_ACCOUNT);
} else {
// there is no need for checking for is there more then one
// account at this point
// since account setup can set only one account at time
mAccount = accounts[0];
populateDirectoryList();
}
}
}
private void populateDirectoryList() {
setContentView(R.layout.uploader_layout);
String full_path = "";
for (String a : mParents)
full_path += a + "/";
Log.d(TAG, "Populating view with content of : " + full_path);
mFile = mStorageManager.getFileByPath(full_path);
if (mFile != null) {
Vector<OCFile> files = mStorageManager.getDirectoryContent(mFile);
List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
for (OCFile f : files) {
HashMap<String, Object> h = new HashMap<String, Object>();
if (f.isDirectory()) {
h.put("dirname", f.getFileName());
data.add(h);
}
}
SimpleAdapter sa = new SimpleAdapter(this,
data,
R.layout.uploader_list_item_layout,
new String[] {"dirname"},
new int[] {R.id.textView1});
setListAdapter(sa);
Button btn = (Button) findViewById(R.id.uploader_choose_folder);
btn.setOnClickListener(this);
getListView().setOnItemClickListener(this);
}
}
private boolean prepareStreamsToUpload() {
if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
mStreamsToUpload = new ArrayList<Parcelable>();
mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
} else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
}
return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null);
}
public void uploadFiles() {
try {
WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext());
// create last directory in path if necessary
if (mCreateDir) {
wdc.createDirectory(mUploadPath);
}
String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];
for (int i = 0; i < mStreamsToUpload.size(); ++i) {
Uri uri = (Uri) mStreamsToUpload.get(i);
if (uri.getScheme().equals("content")) {
Cursor c = getContentResolver().query((Uri) mStreamsToUpload.get(i),
CONTENT_PROJECTION,
null,
null,
null);
if (!c.moveToFirst())
continue;
final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
data = c.getString(c.getColumnIndex(Media.DATA));
local[i] = data;
remote[i] = mUploadPath + display_name;
} else if (uri.getScheme().equals("file")) {
final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));
local[i] = file.getAbsolutePath();
remote[i] = mUploadPath + file.getName();
}
}
Intent intent = new Intent(getApplicationContext(), FileUploader.class);
intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
intent.putExtra(FileUploader.KEY_LOCAL_FILE, local);
intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote);
intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
startService(intent);
finish();
} catch (SecurityException e) {
String message = String.format(getString(R.string.uploader_error_forbidden_content), getString(R.string.app_name));
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
}
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.Vector;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.network.OwnCloudClientUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.owncloud.android.R;
import eu.alefzero.webdav.WebdavClient;
/**
* This can be used to upload things to an ownCloud instance.
*
* @author Bartek Przybylski
*
*/
public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
private static final String TAG = "ownCloudUploader";
private Account mAccount;
private AccountManager mAccountManager;
private Stack<String> mParents;
private ArrayList<Parcelable> mStreamsToUpload;
private boolean mCreateDir;
private String mUploadPath;
private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
private DataStorageManager mStorageManager;
private OCFile mFile;
private final static int DIALOG_NO_ACCOUNT = 0;
private final static int DIALOG_WAITING = 1;
private final static int DIALOG_NO_STREAM = 2;
private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
//private final static int DIALOG_GET_DIRNAME = 4;
private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mParents = new Stack<String>();
mParents.add("");
/*if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
prepareStreamsToUpload();*/
if (prepareStreamsToUpload()) {
mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
if (accounts.length == 0) {
Log_OC.i(TAG, "No ownCloud account is available");
showDialog(DIALOG_NO_ACCOUNT);
} else if (accounts.length > 1) {
Log_OC.i(TAG, "More then one ownCloud is available");
showDialog(DIALOG_MULTIPLE_ACCOUNT);
} else {
mAccount = accounts[0];
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
populateDirectoryList();
}
} else {
showDialog(DIALOG_NO_STREAM);
}
}
@Override
protected Dialog onCreateDialog(final int id) {
final AlertDialog.Builder builder = new Builder(this);
switch (id) {
case DIALOG_WAITING:
ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
return pDialog;
case DIALOG_NO_ACCOUNT:
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.uploader_wrn_no_account_title);
builder.setMessage(String.format(getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
builder.setCancelable(false);
builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
// using string value since in API7 this
// constatn is not defined
// in API7 < this constatant is defined in
// Settings.ADD_ACCOUNT_SETTINGS
// and Settings.EXTRA_AUTHORITIES
Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
} else {
// since in API7 there is no direct call for
// account setup, so we need to
// show our own AccountSetupAcricity, get
// desired results and setup
// everything for ourself
Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
}
}
});
builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
return builder.create();
/*case DIALOG_GET_DIRNAME:
final EditText dirName = new EditText(getBaseContext());
builder.setView(dirName);
builder.setTitle(R.string.uploader_info_dirname);
String pathToUpload;
if (mParents.empty()) {
pathToUpload = "/";
} else {
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), null,
null, null, null);
mCursor.moveToFirst();
pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))
+ mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20"); // TODO don't make this ; use WebdavUtils.encode in the right moment
}
a a = new a(pathToUpload, dirName);
builder.setPositiveButton(R.string.common_ok, a);
builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
return builder.create();*/
case DIALOG_MULTIPLE_ACCOUNT:
CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
for (int i = 0; i < ac.length; ++i) {
ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;
}
builder.setTitle(R.string.common_choose_account);
builder.setItems(ac, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
populateDirectoryList();
}
});
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.cancel();
finish();
}
});
return builder.create();
case DIALOG_NO_STREAM:
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.uploader_wrn_no_content_title);
builder.setMessage(R.string.uploader_wrn_no_content_text);
builder.setCancelable(false);
builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
return builder.create();
default:
throw new IllegalArgumentException("Unknown dialog id: " + id);
}
}
class a implements OnClickListener {
String mPath;
EditText mDirname;
public a(String path, EditText dirname) {
mPath = path;
mDirname = dirname;
}
@Override
public void onClick(DialogInterface dialog, int which) {
Uploader.this.mUploadPath = mPath + mDirname.getText().toString();
Uploader.this.mCreateDir = true;
uploadFiles();
}
}
@Override
public void onBackPressed() {
if (mParents.size() <= 1) {
super.onBackPressed();
return;
} else {
mParents.pop();
populateDirectoryList();
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// click on folder in the list
Log_OC.d(TAG, "on item click");
Vector<OCFile> tmpfiles = mStorageManager.getDirectoryContent(mFile);
if (tmpfiles.size() <= 0) return;
// filter on dirtype
Vector<OCFile> files = new Vector<OCFile>();
for (OCFile f : tmpfiles)
if (f.isDirectory())
files.add(f);
if (files.size() < position) {
throw new IndexOutOfBoundsException("Incorrect item selected");
}
mParents.push(files.get(position).getFileName());
populateDirectoryList();
}
@Override
public void onClick(View v) {
// click on button
switch (v.getId()) {
case R.id.uploader_choose_folder:
mUploadPath = ""; // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
for (String p : mParents)
mUploadPath += p + OCFile.PATH_SEPARATOR;
Log_OC.d(TAG, "Uploading file to dir " + mUploadPath);
uploadFiles();
break;
/*case android.R.id.button1: // dynamic action for create aditional dir
showDialog(DIALOG_GET_DIRNAME);
break;*/
default:
throw new IllegalArgumentException("Wrong element clicked");
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log_OC.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
dismissDialog(DIALOG_NO_ACCOUNT);
if (resultCode == RESULT_CANCELED) {
finish();
}
Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);
if (accounts.length == 0) {
showDialog(DIALOG_NO_ACCOUNT);
} else {
// there is no need for checking for is there more then one
// account at this point
// since account setup can set only one account at time
mAccount = accounts[0];
populateDirectoryList();
}
}
}
private void populateDirectoryList() {
setContentView(R.layout.uploader_layout);
String full_path = "";
for (String a : mParents)
full_path += a + "/";
Log_OC.d(TAG, "Populating view with content of : " + full_path);
mFile = mStorageManager.getFileByPath(full_path);
if (mFile != null) {
Vector<OCFile> files = mStorageManager.getDirectoryContent(mFile);
List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
for (OCFile f : files) {
HashMap<String, Object> h = new HashMap<String, Object>();
if (f.isDirectory()) {
h.put("dirname", f.getFileName());
data.add(h);
}
}
SimpleAdapter sa = new SimpleAdapter(this,
data,
R.layout.uploader_list_item_layout,
new String[] {"dirname"},
new int[] {R.id.textView1});
setListAdapter(sa);
Button btn = (Button) findViewById(R.id.uploader_choose_folder);
btn.setOnClickListener(this);
getListView().setOnItemClickListener(this);
}
}
private boolean prepareStreamsToUpload() {
if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
mStreamsToUpload = new ArrayList<Parcelable>();
mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
} else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
}
return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null);
}
public void uploadFiles() {
try {
WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext());
// create last directory in path if necessary
if (mCreateDir) {
wdc.createDirectory(mUploadPath);
}
String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];
for (int i = 0; i < mStreamsToUpload.size(); ++i) {
Uri uri = (Uri) mStreamsToUpload.get(i);
if (uri.getScheme().equals("content")) {
Cursor c = getContentResolver().query((Uri) mStreamsToUpload.get(i),
CONTENT_PROJECTION,
null,
null,
null);
if (!c.moveToFirst())
continue;
final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
data = c.getString(c.getColumnIndex(Media.DATA));
local[i] = data;
remote[i] = mUploadPath + display_name;
} else if (uri.getScheme().equals("file")) {
final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));
local[i] = file.getAbsolutePath();
remote[i] = mUploadPath + file.getName();
}
}
Intent intent = new Intent(getApplicationContext(), FileUploader.class);
intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
intent.putExtra(FileUploader.KEY_LOCAL_FILE, local);
intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote);
intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
startService(intent);
finish();
} catch (SecurityException e) {
String message = String.format(getString(R.string.uploader_error_forbidden_content), getString(R.string.app_name));
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
}

View file

@ -1,282 +1,283 @@
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.authenticator;
import com.owncloud.android.ui.activity.AuthenticatorActivity;
import android.accounts.*;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class AccountAuthenticator extends AbstractAccountAuthenticator {
/**
* Is used by android system to assign accounts to authenticators. Should be
* used by application and all extensions.
*/
public static final String ACCOUNT_TYPE = "owncloud";
public static final String AUTH_TOKEN_TYPE = "org.owncloud";
public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
public static final String KEY_LOGIN_OPTIONS = "loginOptions";
public static final String KEY_ACCOUNT = "account";
/**
* Value under this key should handle path to webdav php script. Will be
* removed and usage should be replaced by combining
* {@link com.owncloud.android.authenticator.AuthenticatorActivity.KEY_OC_BASE_URL} and
* {@link com.owncloud.android.utils.OwnCloudVersion}
*
* @deprecated
*/
public static final String KEY_OC_URL = "oc_url";
/**
* Version should be 3 numbers separated by dot so it can be parsed by
* {@link com.owncloud.android.utils.OwnCloudVersion}
*/
public static final String KEY_OC_VERSION = "oc_version";
/**
* Base url should point to owncloud installation without trailing / ie:
* http://server/path or https://owncloud.server
*/
public static final String KEY_OC_BASE_URL = "oc_base_url";
private static final String TAG = "AccountAuthenticator";
private Context mContext;
public AccountAuthenticator(Context context) {
super(context);
mContext = context;
}
/**
* {@inheritDoc}
*/
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType, String authTokenType,
String[] requiredFeatures, Bundle options)
throws NetworkErrorException {
Log.i(TAG, "Adding account with type " + accountType
+ " and auth token " + authTokenType);
try {
validateAccountType(accountType);
} catch (AuthenticatorException e) {
Log.e(TAG, "Failed to validate account type " + accountType + ": "
+ e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
/**
* {@inheritDoc}
*/
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options) throws NetworkErrorException {
try {
validateAccountType(account.type);
} catch (AuthenticatorException e) {
Log.e(TAG, "Failed to validate account type " + account.type + ": "
+ e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
Bundle resultBundle = new Bundle();
resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
return resultBundle;
}
@Override
public Bundle editProperties(AccountAuthenticatorResponse response,
String accountType) {
return null;
}
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
try {
validateAccountType(account.type);
validateAuthTokenType(authTokenType);
} catch (AuthenticatorException e) {
Log.e(TAG, "Failed to validate account type " + account.type + ": "
+ e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
final AccountManager am = AccountManager.get(mContext);
final String password = am.getPassword(account);
if (password != null) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
result.putString(AccountManager.KEY_AUTHTOKEN, password);
return result;
}
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public String getAuthTokenLabel(String authTokenType) {
return null;
}
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException {
final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
return result;
}
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public Bundle getAccountRemovalAllowed(
AccountAuthenticatorResponse response, Account account)
throws NetworkErrorException {
return super.getAccountRemovalAllowed(response, account);
}
private void setIntentFlags(Intent intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
}
private void validateAccountType(String type)
throws UnsupportedAccountTypeException {
if (!type.equals(ACCOUNT_TYPE)) {
throw new UnsupportedAccountTypeException();
}
}
private void validateAuthTokenType(String authTokenType)
throws UnsupportedAuthTokenTypeException {
if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
throw new UnsupportedAuthTokenTypeException();
}
}
public static class AuthenticatorException extends Exception {
private static final long serialVersionUID = 1L;
private Bundle mFailureBundle;
public AuthenticatorException(int code, String errorMsg) {
mFailureBundle = new Bundle();
mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
mFailureBundle
.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
}
public Bundle getFailureBundle() {
return mFailureBundle;
}
}
public static class UnsupportedAccountTypeException extends
AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAccountTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported account type");
}
}
public static class UnsupportedAuthTokenTypeException extends
AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAuthTokenTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported auth token type");
}
}
public static class UnsupportedFeaturesException extends
AuthenticatorException {
public static final long serialVersionUID = 1L;
public UnsupportedFeaturesException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported features");
}
}
public static class AccessDeniedException extends AuthenticatorException {
public AccessDeniedException(int code, String errorMsg) {
super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
}
private static final long serialVersionUID = 1L;
}
}
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.authenticator;
import com.owncloud.android.Log_OC;
import com.owncloud.android.ui.activity.AuthenticatorActivity;
import android.accounts.*;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class AccountAuthenticator extends AbstractAccountAuthenticator {
/**
* Is used by android system to assign accounts to authenticators. Should be
* used by application and all extensions.
*/
public static final String ACCOUNT_TYPE = "owncloud";
public static final String AUTH_TOKEN_TYPE = "org.owncloud";
public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
public static final String KEY_LOGIN_OPTIONS = "loginOptions";
public static final String KEY_ACCOUNT = "account";
/**
* Value under this key should handle path to webdav php script. Will be
* removed and usage should be replaced by combining
* {@link com.owncloud.android.authenticator.AuthenticatorActivity.KEY_OC_BASE_URL} and
* {@link com.owncloud.android.utils.OwnCloudVersion}
*
* @deprecated
*/
public static final String KEY_OC_URL = "oc_url";
/**
* Version should be 3 numbers separated by dot so it can be parsed by
* {@link com.owncloud.android.utils.OwnCloudVersion}
*/
public static final String KEY_OC_VERSION = "oc_version";
/**
* Base url should point to owncloud installation without trailing / ie:
* http://server/path or https://owncloud.server
*/
public static final String KEY_OC_BASE_URL = "oc_base_url";
private static final String TAG = "AccountAuthenticator";
private Context mContext;
public AccountAuthenticator(Context context) {
super(context);
mContext = context;
}
/**
* {@inheritDoc}
*/
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType, String authTokenType,
String[] requiredFeatures, Bundle options)
throws NetworkErrorException {
Log_OC.i(TAG, "Adding account with type " + accountType
+ " and auth token " + authTokenType);
try {
validateAccountType(accountType);
} catch (AuthenticatorException e) {
Log_OC.e(TAG, "Failed to validate account type " + accountType + ": "
+ e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
/**
* {@inheritDoc}
*/
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options) throws NetworkErrorException {
try {
validateAccountType(account.type);
} catch (AuthenticatorException e) {
Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "
+ e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
Bundle resultBundle = new Bundle();
resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
return resultBundle;
}
@Override
public Bundle editProperties(AccountAuthenticatorResponse response,
String accountType) {
return null;
}
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
try {
validateAccountType(account.type);
validateAuthTokenType(authTokenType);
} catch (AuthenticatorException e) {
Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "
+ e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
final AccountManager am = AccountManager.get(mContext);
final String password = am.getPassword(account);
if (password != null) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
result.putString(AccountManager.KEY_AUTHTOKEN, password);
return result;
}
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public String getAuthTokenLabel(String authTokenType) {
return null;
}
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException {
final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
return result;
}
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public Bundle getAccountRemovalAllowed(
AccountAuthenticatorResponse response, Account account)
throws NetworkErrorException {
return super.getAccountRemovalAllowed(response, account);
}
private void setIntentFlags(Intent intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
}
private void validateAccountType(String type)
throws UnsupportedAccountTypeException {
if (!type.equals(ACCOUNT_TYPE)) {
throw new UnsupportedAccountTypeException();
}
}
private void validateAuthTokenType(String authTokenType)
throws UnsupportedAuthTokenTypeException {
if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
throw new UnsupportedAuthTokenTypeException();
}
}
public static class AuthenticatorException extends Exception {
private static final long serialVersionUID = 1L;
private Bundle mFailureBundle;
public AuthenticatorException(int code, String errorMsg) {
mFailureBundle = new Bundle();
mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
mFailureBundle
.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
}
public Bundle getFailureBundle() {
return mFailureBundle;
}
}
public static class UnsupportedAccountTypeException extends
AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAccountTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported account type");
}
}
public static class UnsupportedAuthTokenTypeException extends
AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAuthTokenTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported auth token type");
}
}
public static class UnsupportedFeaturesException extends
AuthenticatorException {
public static final long serialVersionUID = 1L;
public UnsupportedFeaturesException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported features");
}
}
public static class AccessDeniedException extends AuthenticatorException {
public AccessDeniedException(int code, String errorMsg) {
super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
}
private static final long serialVersionUID = 1L;
}
}

View file

@ -26,6 +26,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import com.owncloud.android.Log_OC;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import com.owncloud.android.utils.FileStorageUtils;
@ -156,7 +157,7 @@ public class FileDataStorageManager implements DataStorageManager {
cv, ProviderTableMeta._ID + "=?",
new String[] { String.valueOf(file.getFileId()) });
} catch (RemoteException e) {
Log.e(TAG,
Log_OC.e(TAG,
"Fail to insert insert file to database "
+ e.getMessage());
}
@ -171,7 +172,7 @@ public class FileDataStorageManager implements DataStorageManager {
result_uri = getContentProvider().insert(
ProviderTableMeta.CONTENT_URI_FILE, cv);
} catch (RemoteException e) {
Log.e(TAG,
Log_OC.e(TAG,
"Fail to insert insert file to database "
+ e.getMessage());
}
@ -256,10 +257,10 @@ public class FileDataStorageManager implements DataStorageManager {
}
} catch (OperationApplicationException e) {
Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
} catch (RemoteException e) {
Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
}
// update new id in file objects for insertions
@ -269,7 +270,7 @@ public class FileDataStorageManager implements DataStorageManager {
if (results[i].uri != null) {
newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
files.get(i).setFileId(newId);
//Log.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
//Log_OC.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
}
}
}
@ -321,7 +322,7 @@ public class FileDataStorageManager implements DataStorageManager {
ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[] { mAccount.name }, null);
} catch (RemoteException e) {
Log.e(TAG, e.getMessage());
Log_OC.e(TAG, e.getMessage());
return ret;
}
} else {
@ -364,7 +365,7 @@ public class FileDataStorageManager implements DataStorageManager {
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[] { value, mAccount.name }, null);
} catch (RemoteException e) {
Log.e(TAG,
Log_OC.e(TAG,
"Couldn't determine file existance, assuming non existance: "
+ e.getMessage());
return false;
@ -394,7 +395,7 @@ public class FileDataStorageManager implements DataStorageManager {
+ "=?", new String[] { value, mAccount.name },
null);
} catch (RemoteException e) {
Log.e(TAG, "Could not get file details: " + e.getMessage());
Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
c = null;
}
}
@ -517,7 +518,7 @@ public class FileDataStorageManager implements DataStorageManager {
ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ?",
new String[] { mAccount.name, dir.getRemotePath() + "%" }, null);
} catch (RemoteException e) {
Log.e(TAG, e.getMessage());
Log_OC.e(TAG, e.getMessage());
}
} else {
c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
@ -558,10 +559,10 @@ public class FileDataStorageManager implements DataStorageManager {
}
} catch (OperationApplicationException e) {
Log.e(TAG, "Fail to update descendants of " + dir.getFileId() + " in database", e);
Log_OC.e(TAG, "Fail to update descendants of " + dir.getFileId() + " in database", e);
} catch (RemoteException e) {
Log.e(TAG, "Fail to update desendants of " + dir.getFileId() + " in database", e);
Log_OC.e(TAG, "Fail to update desendants of " + dir.getFileId() + " in database", e);
}
}

View file

@ -21,11 +21,10 @@ package com.owncloud.android.datamodel;
import java.io.File;
import android.content.Intent;
import android.net.Uri;
import com.owncloud.android.Log_OC;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import android.webkit.MimeTypeMap;
public class OCFile implements Parcelable, Comparable<OCFile> {
@ -265,7 +264,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
* Does nothing if the new name is null, empty or includes "/" ; or if the file is the root directory
*/
public void setFileName(String name) {
Log.d(TAG, "OCFile name changin from " + mRemotePath);
Log_OC.d(TAG, "OCFile name changin from " + mRemotePath);
if (name != null && name.length() > 0 && !name.contains(PATH_SEPARATOR) && !mRemotePath.equals(PATH_SEPARATOR)) {
String parent = (new File(getRemotePath())).getParent();
parent = (parent.endsWith(PATH_SEPARATOR)) ? parent : parent + PATH_SEPARATOR;
@ -273,7 +272,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
if (isDirectory()) {
mRemotePath += PATH_SEPARATOR;
}
Log.d(TAG, "OCFile name changed to " + mRemotePath);
Log_OC.d(TAG, "OCFile name changed to " + mRemotePath);
}
}

View file

@ -17,6 +17,8 @@
*/
package com.owncloud.android.db;
import com.owncloud.android.Log_OC;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@ -57,7 +59,7 @@ public class DbHandler {
cv.put("attempt", UPLOAD_STATUS_UPLOAD_LATER);
cv.put("message", message);
long result = mDB.insert(TABLE_INSTANT_UPLOAD, null, cv);
Log.d(TABLE_INSTANT_UPLOAD, "putFileForLater returns with: " + result + " for file: " + filepath);
Log_OC.d(TABLE_INSTANT_UPLOAD, "putFileForLater returns with: " + result + " for file: " + filepath);
return result != -1;
}
@ -66,7 +68,7 @@ public class DbHandler {
cv.put("attempt", status);
cv.put("message", message);
int result = mDB.update(TABLE_INSTANT_UPLOAD, cv, "path=?", new String[] { filepath });
Log.d(TABLE_INSTANT_UPLOAD, "updateFileState returns with: " + result + " for file: " + filepath);
Log_OC.d(TABLE_INSTANT_UPLOAD, "updateFileState returns with: " + result + " for file: " + filepath);
return result;
}
@ -89,7 +91,7 @@ public class DbHandler {
*/
public boolean removeIUPendingFile(String localPath) {
long result = mDB.delete(TABLE_INSTANT_UPLOAD, "path = ?", new String[] { localPath });
Log.d(TABLE_INSTANT_UPLOAD, "delete returns with: " + result + " for file: " + localPath);
Log_OC.d(TABLE_INSTANT_UPLOAD, "delete returns with: " + result + " for file: " + localPath);
return result != 0;
}

View file

@ -19,6 +19,7 @@
package com.owncloud.android.extensions;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import android.content.Intent;
import android.os.Bundle;
@ -62,7 +63,7 @@ public class ExtensionsAvailableDialog extends DialogFragment implements
getActivity().finish();
break;
default:
Log.e("EAD", "Button with unknown id clicked " + v.getId());
Log_OC.e("EAD", "Button with unknown id clicked " + v.getId());
}
}

View file

@ -28,6 +28,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.owncloud.android.Log_OC;
import com.owncloud.android.utils.OwnCloudVersion;
@ -81,7 +82,7 @@ public class ExtensionsListActivity extends ListActivity {
final JSONArray ar;
try {
hc.executeMethod(gm);
Log.e("ASD", gm.getResponseBodyAsString() + "");
Log_OC.e("ASD", gm.getResponseBodyAsString() + "");
ar = new JSONObject(gm.getResponseBodyAsString())
.getJSONArray("apps");
} catch (Exception e) {

View file

@ -19,6 +19,7 @@
package com.owncloud.android.files;
import com.owncloud.android.Log_OC;
import com.owncloud.android.files.services.FileObserverService;
import android.content.BroadcastReceiver;
@ -33,15 +34,15 @@ public class BootupBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.wtf(TAG, "Incorrect action sent " + intent.getAction());
Log_OC.wtf(TAG, "Incorrect action sent " + intent.getAction());
return;
}
Log.d(TAG, "Starting file observer service...");
Log_OC.d(TAG, "Starting file observer service...");
Intent i = new Intent(context, FileObserverService.class);
i.putExtra(FileObserverService.KEY_FILE_CMD,
FileObserverService.CMD_INIT_OBSERVED_LIST);
context.startService(i);
Log.d(TAG, "DONE");
Log_OC.d(TAG, "DONE");
}
}

View file

@ -35,6 +35,7 @@ import android.util.Log;
import android.webkit.MimeTypeMap;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.db.DbHandler;
import com.owncloud.android.files.services.FileUploader;
@ -48,7 +49,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Received: " + intent.getAction());
Log_OC.d(TAG, "Received: " + intent.getAction());
if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {
handleConnectivityAction(context, intent);
} else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
@ -56,7 +57,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
} else if (intent.getAction().equals(FileUploader.UPLOAD_FINISH_MESSAGE)) {
handleUploadFinished(context, intent);
} else {
Log.e(TAG, "Incorrect intent sent: " + intent.getAction());
Log_OC.e(TAG, "Incorrect intent sent: " + intent.getAction());
}
}
@ -66,7 +67,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
DbHandler db = new DbHandler(context);
String localPath = intent.getStringExtra(FileUploader.EXTRA_OLD_FILE_PATH);
if (!db.removeIUPendingFile(localPath)) {
Log.w(TAG, "Tried to remove non existing instant upload file " + localPath);
Log_OC.w(TAG, "Tried to remove non existing instant upload file " + localPath);
}
db.close();
}
@ -74,20 +75,20 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
private void handleNewPhotoAction(Context context, Intent intent) {
if (!instantUploadEnabled(context)) {
Log.d(TAG, "Instant upload disabled, abording uploading");
Log_OC.d(TAG, "Instant upload disabled, abording uploading");
return;
}
Account account = AccountUtils.getCurrentOwnCloudAccount(context);
if (account == null) {
Log.w(TAG, "No owncloud account found for instant upload, aborting");
Log_OC.w(TAG, "No owncloud account found for instant upload, aborting");
return;
}
Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
if (!c.moveToFirst()) {
Log.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
Log_OC.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
return;
}
@ -96,7 +97,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE));
c.close();
Log.e(TAG, file_path + "");
Log_OC.e(TAG, file_path + "");
// same always temporally the picture to upload
DbHandler db = new DbHandler(context);
@ -131,7 +132,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
private void handleConnectivityAction(Context context, Intent intent) {
if (!instantUploadEnabled(context)) {
Log.d(TAG, "Instant upload disabled, abording uploading");
Log_OC.d(TAG, "Instant upload disabled, abording uploading");
return;
}
@ -156,7 +157,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
f.getName().substring(f.getName().lastIndexOf('.') + 1));
} catch (Throwable e) {
Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
}
if (mimeType == null)
mimeType = "application/octet-stream";
@ -170,7 +171,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
context.startService(i);
} else {
Log.w(TAG, "Instant upload file " + f.getAbsolutePath() + " dont exist anymore");
Log_OC.w(TAG, "Instant upload file " + f.getAbsolutePath() + " dont exist anymore");
}
} while (c.moveToNext());
}

View file

@ -21,6 +21,7 @@ package com.owncloud.android.files;
import java.io.File;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.network.OwnCloudClientUtils;
@ -71,9 +72,9 @@ public class OwnCloudFileObserver extends FileObserver {
@Override
public void onEvent(int event, String path) {
Log.d(TAG, "Got file modified with event " + event + " and path " + mPath + ((path != null) ? File.separator + path : ""));
Log_OC.d(TAG, "Got file modified with event " + event + " and path " + mPath + ((path != null) ? File.separator + path : ""));
if ((event & mMask) == 0) {
Log.wtf(TAG, "Incorrect event " + event + " sent for file " + mPath + ((path != null) ? File.separator + path : "") +
Log_OC.wtf(TAG, "Incorrect event " + event + " sent for file " + mPath + ((path != null) ? File.separator + path : "") +
" with registered for " + mMask + " and original path " +
mPath);
return;

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
@ -83,7 +84,7 @@ public class FileObserverService extends Service {
super.onDestroy();
unregisterReceiver(mDownloadReceiver);
mObserversMap = null; // TODO study carefully the life cycle of Services to grant the best possible observance
Log.d(TAG, "Bye, bye");
Log_OC.d(TAG, "Bye, bye");
}
@ -102,7 +103,7 @@ public class FileObserverService extends Service {
}
if (!intent.hasExtra(KEY_FILE_CMD)) {
Log.e(TAG, "No KEY_FILE_CMD argument given");
Log_OC.e(TAG, "No KEY_FILE_CMD argument given");
return Service.START_STICKY;
}
@ -119,7 +120,7 @@ public class FileObserverService extends Service {
(Account)intent.getParcelableExtra(KEY_CMD_ARG_ACCOUNT));
break;
default:
Log.wtf(TAG, "Incorrect key given");
Log_OC.wtf(TAG, "Incorrect key given");
}
return Service.START_STICKY;
@ -166,7 +167,7 @@ public class FileObserverService extends Service {
mObserversMap.put(path, observer);
if (new File(path).exists()) {
observer.startWatching();
Log.d(TAG, "Started watching file " + path);
Log_OC.d(TAG, "Started watching file " + path);
}
} while (c.moveToNext());
@ -189,7 +190,7 @@ public class FileObserverService extends Service {
*/
private void addObservedFile(OCFile file, Account account) {
if (file == null) {
Log.e(TAG, "Trying to add a NULL file to observer");
Log_OC.e(TAG, "Trying to add a NULL file to observer");
return;
}
String localPath = file.getStoragePath();
@ -204,11 +205,11 @@ public class FileObserverService extends Service {
getApplicationContext(),
OwnCloudFileObserver.CHANGES_ONLY);
mObserversMap.put(localPath, observer);
Log.d(TAG, "Observer added for path " + localPath);
Log_OC.d(TAG, "Observer added for path " + localPath);
if (file.isDown()) {
observer.startWatching();
Log.d(TAG, "Started watching " + localPath);
Log_OC.d(TAG, "Started watching " + localPath);
} // else - the observance can't be started on a file not already down; mDownloadReceiver will get noticed when the download of the file finishes
}
@ -229,7 +230,7 @@ public class FileObserverService extends Service {
*/
private void removeObservedFile(OCFile file, Account account) {
if (file == null) {
Log.e(TAG, "Trying to remove a NULL file");
Log_OC.e(TAG, "Trying to remove a NULL file");
return;
}
String localPath = file.getStoragePath();
@ -241,7 +242,7 @@ public class FileObserverService extends Service {
if (observer != null) {
observer.stopWatching();
mObserversMap.remove(observer);
Log.d(TAG, "Stopped watching " + localPath);
Log_OC.d(TAG, "Stopped watching " + localPath);
}
}
@ -263,11 +264,11 @@ public class FileObserverService extends Service {
if (intent.getAction().equals(FileDownloader.DOWNLOAD_FINISH_MESSAGE) &&
new File(downloadPath).exists()) { // the download could be successful, or not; in both cases, the file could be down, due to a former download or upload
observer.startWatching();
Log.d(TAG, "Watching again " + downloadPath);
Log_OC.d(TAG, "Watching again " + downloadPath);
} else if (intent.getAction().equals(FileDownloader.DOWNLOAD_ADDED_MESSAGE)) {
observer.stopWatching();
Log.d(TAG, "Disabling observance of " + downloadPath);
Log_OC.d(TAG, "Disabling observance of " + downloadPath);
}
}
}

View file

@ -51,6 +51,7 @@ import android.webkit.MimeTypeMap;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.datamodel.FileDataStorageManager;
@ -151,7 +152,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
@ -171,12 +172,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
public int onStartCommand(Intent intent, int flags, int startId) {
if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_UPLOAD_TYPE)
|| !(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) {
Log.e(TAG, "Not enough information provided in intent");
Log_OC.e(TAG, "Not enough information provided in intent");
return Service.START_NOT_STICKY;
}
int uploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
if (uploadType == -1) {
Log.e(TAG, "Incorrect upload type provided");
Log_OC.e(TAG, "Incorrect upload type provided");
return Service.START_NOT_STICKY;
}
Account account = intent.getParcelableExtra(KEY_ACCOUNT);
@ -227,20 +228,20 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
}
if (intent.hasExtra(KEY_FILE) && files == null) {
Log.e(TAG, "Incorrect array for OCFiles provided in upload intent");
Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
return Service.START_NOT_STICKY;
} else if (!intent.hasExtra(KEY_FILE)) {
if (localPaths == null) {
Log.e(TAG, "Incorrect array for local paths provided in upload intent");
Log_OC.e(TAG, "Incorrect array for local paths provided in upload intent");
return Service.START_NOT_STICKY;
}
if (remotePaths == null) {
Log.e(TAG, "Incorrect array for remote paths provided in upload intent");
Log_OC.e(TAG, "Incorrect array for remote paths provided in upload intent");
return Service.START_NOT_STICKY;
}
if (localPaths.length != remotePaths.length) {
Log.e(TAG, "Different number of remote paths and local paths!");
Log_OC.e(TAG, "Different number of remote paths and local paths!");
return Service.START_NOT_STICKY;
}
@ -280,15 +281,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
}
} catch (IllegalArgumentException e) {
Log.e(TAG, "Not enough information provided in intent: " + e.getMessage());
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
return START_NOT_STICKY;
} catch (IllegalStateException e) {
Log.e(TAG, "Bad information provided in intent: " + e.getMessage());
Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
return START_NOT_STICKY;
} catch (Exception e) {
Log.e(TAG, "Unexpected exception while processing upload intent", e);
Log_OC.e(TAG, "Unexpected exception while processing upload intent", e);
return START_NOT_STICKY;
}
@ -299,7 +300,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
msg.obj = requestedUploads;
mServiceHandler.sendMessage(msg);
}
Log.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
return Service.START_NOT_STICKY;
}
@ -516,7 +517,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
} finally {
synchronized (mPendingUploads) {
mPendingUploads.remove(uploadKey);
Log.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
}
}
@ -562,12 +563,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
}
result = new RemoteOperationResult(isMultiStatus, status);
Log.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": "
Log_OC.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": "
+ result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": "
Log_OC.e(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": "
+ result.getLogMessage(), e);
} finally {
@ -642,7 +643,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
remotePath.substring(remotePath.lastIndexOf('.') + 1));
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Trying to find out MIME type of a file without extension: " + remotePath);
Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + remotePath);
}
}
if (mimeType == null) {
@ -736,7 +737,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
* @param upload Finished upload operation
*/
private void notifyUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
Log.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
if (uploadResult.isCancelled()) {
// / cancelled operation -> silent removal of progress notification
mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
@ -817,7 +818,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
try {
db = new DbHandler(this.getBaseContext());
String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode();
Log.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
message = getString(R.string.failed_upload_quota_exceeded_text);
}

View file

@ -23,16 +23,16 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import com.owncloud.android.Log_OC;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.network.OwnCloudClientUtils;
import eu.alefzero.webdav.WebdavClient;
import android.accounts.Account;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.utils.FileStorageUtils;
import eu.alefzero.webdav.WebdavClient;
public class InstantUploadService extends Service {
@ -57,7 +57,7 @@ public class InstantUploadService extends Service {
if (intent == null || !intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_DISPLAY_NAME)
|| !intent.hasExtra(KEY_FILE_PATH) || !intent.hasExtra(KEY_FILE_SIZE)
|| !intent.hasExtra(KEY_MIME_TYPE)) {
Log.w(TAG, "Not all required information was provided, abording");
Log_OC.w(TAG, "Not all required information was provided, abording");
return Service.START_NOT_STICKY;
}
@ -75,7 +75,7 @@ public class InstantUploadService extends Service {
// starting new thread for new download doesnt seems like a good idea
// maybe some thread pool or single background thread would be better
Log.d(TAG, "Starting instant upload thread");
Log_OC.d(TAG, "Starting instant upload thread");
new Thread(mUploaderRunnable).start();
return Service.START_STICKY;

View file

@ -18,6 +18,8 @@
*/
package com.owncloud.android.location;
import com.owncloud.android.Log_OC;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.BroadcastReceiver;
@ -60,10 +62,10 @@ public class LocationServiceLauncherReciever extends BroadcastReceiver {
deviceTrackingIntent
.setAction("com.owncloud.android.location.LocationUpdateService");
if (!isDeviceTrackingServiceRunning(context) && trackDevice) {
Log.d(TAG, "Starting device tracker service");
Log_OC.d(TAG, "Starting device tracker service");
context.startService(deviceTrackingIntent);
} else if (isDeviceTrackingServiceRunning(context) && !trackDevice) {
Log.d(TAG, "Stopping device tracker service");
Log_OC.d(TAG, "Stopping device tracker service");
context.stopService(deviceTrackingIntent);
}
}

View file

@ -31,6 +31,7 @@ import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
public class LocationUpdateService extends IntentService implements
@ -76,7 +77,7 @@ public class LocationUpdateService extends IntentService implements
// If we do shall track the device -> Stop
if (!trackDevice) {
Log.d(TAG, "Devicetracking is disabled");
Log_OC.d(TAG, "Devicetracking is disabled");
stopSelf();
return;
}
@ -87,7 +88,7 @@ public class LocationUpdateService extends IntentService implements
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Location changed: " + location);
Log_OC.d(TAG, "Location changed: " + location);
}

View file

@ -34,11 +34,11 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.ui.activity.FileDetailActivity;
@ -218,7 +218,7 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
*/
@Override
public void onCreate() {
Log.d(TAG, "Creating ownCloud media service");
Log_OC.d(TAG, "Creating ownCloud media service");
mWifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE)).
createWifiLock(WifiManager.WIFI_MODE_FULL, MEDIA_WIFI_LOCK_TAG);
@ -466,22 +466,22 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
}
} catch (SecurityException e) {
Log.e(TAG, "SecurityException playing " + mAccount.name + mFile.getRemotePath(), e);
Log_OC.e(TAG, "SecurityException playing " + mAccount.name + mFile.getRemotePath(), e);
Toast.makeText(this, String.format(getString(R.string.media_err_security_ex), mFile.getFileName()), Toast.LENGTH_LONG).show();
processStopRequest(true);
} catch (IOException e) {
Log.e(TAG, "IOException playing " + mAccount.name + mFile.getRemotePath(), e);
Log_OC.e(TAG, "IOException playing " + mAccount.name + mFile.getRemotePath(), e);
Toast.makeText(this, String.format(getString(R.string.media_err_io_ex), mFile.getFileName()), Toast.LENGTH_LONG).show();
processStopRequest(true);
} catch (IllegalStateException e) {
Log.e(TAG, "IllegalStateException " + mAccount.name + mFile.getRemotePath(), e);
Log_OC.e(TAG, "IllegalStateException " + mAccount.name + mFile.getRemotePath(), e);
Toast.makeText(this, String.format(getString(R.string.media_err_unexpected), mFile.getFileName()), Toast.LENGTH_LONG).show();
processStopRequest(true);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException " + mAccount.name + mFile.getRemotePath(), e);
Log_OC.e(TAG, "IllegalArgumentException " + mAccount.name + mFile.getRemotePath(), e);
Toast.makeText(this, String.format(getString(R.string.media_err_unexpected), mFile.getFileName()), Toast.LENGTH_LONG).show();
processStopRequest(true);
}
@ -593,7 +593,7 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
* Warns the user about the error and resets the media player.
*/
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(TAG, "Error in audio playback, what = " + what + ", extra = " + extra);
Log_OC.e(TAG, "Error in audio playback, what = " + what + ", extra = " + extra);
String message = getMessageForMediaError(this, what, extra);
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();

View file

@ -19,6 +19,7 @@
package com.owncloud.android.media;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.media.MediaService.State;
@ -26,7 +27,6 @@ import android.accounts.Account;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.util.Log;
import android.widget.MediaController;
@ -129,13 +129,13 @@ public class MediaServiceBinder extends Binder implements MediaController.MediaP
@Override
public void pause() {
Log.d(TAG, "Pausing through binder...");
Log_OC.d(TAG, "Pausing through binder...");
mService.processPauseRequest();
}
@Override
public void seekTo(int pos) {
Log.d(TAG, "Seeking " + pos + " through binder...");
Log_OC.d(TAG, "Seeking " + pos + " through binder...");
MediaPlayer currentPlayer = mService.getPlayer();
MediaService.State currentState = mService.getState();
if (currentPlayer != null && currentState != State.PREPARING && currentState != State.STOPPED) {
@ -145,12 +145,12 @@ public class MediaServiceBinder extends Binder implements MediaController.MediaP
@Override
public void start() {
Log.d(TAG, "Starting through binder...");
Log_OC.d(TAG, "Starting through binder...");
mService.processPlayRequest(); // this will finish the service if there is no file preloaded to play
}
public void start(Account account, OCFile file, boolean playImmediately, int position) {
Log.d(TAG, "Loading and starting through binder...");
Log_OC.d(TAG, "Loading and starting through binder...");
Intent i = new Intent(mService, MediaService.class);
i.putExtra(MediaService.EXTRA_ACCOUNT, account);
i.putExtra(MediaService.EXTRA_FILE, file);

View file

@ -40,6 +40,8 @@ import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import com.owncloud.android.Log_OC;
import android.util.Log;
/**
@ -104,13 +106,13 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
final InetAddress localAddress, final int localPort,
final HttpConnectionParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
Log.d(TAG, "Creating SSL Socket with remote " + host + ":" + port + ", local " + localAddress + ":" + localPort + ", params: " + params);
Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port + ", local " + localAddress + ":" + localPort + ", params: " + params);
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = mSslContext.getSocketFactory();
Log.d(TAG, " ... with connection timeout " + timeout + " and socket timeout " + params.getSoTimeout());
Log_OC.d(TAG, " ... with connection timeout " + timeout + " and socket timeout " + params.getSoTimeout());
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
@ -126,7 +128,7 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
*/
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
Log.d(TAG, "Creating SSL Socket with remote " + host + ":" + port);
Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port);
Socket socket = mSslContext.getSocketFactory().createSocket(host, port);
verifyPeerIdentity(host, port, socket);
return socket;

View file

@ -32,6 +32,8 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import com.owncloud.android.Log_OC;
import android.util.Log;
/**
@ -139,7 +141,7 @@ public class AdvancedX509TrustManager implements X509TrustManager {
try {
return (mKnownServersKeyStore.getCertificateAlias(cert) != null);
} catch (KeyStoreException e) {
Log.d(TAG, "Fail while checking certificate in the known-servers store");
Log_OC.d(TAG, "Fail while checking certificate in the known-servers store");
return false;
}
}

View file

@ -38,6 +38,7 @@ import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import eu.alefzero.webdav.WebdavClient;
@ -75,7 +76,7 @@ public class OwnCloudClientUtils {
* @return A WebdavClient object ready to be used
*/
public static WebdavClient createOwnCloudClient (Account account, Context context) {
Log.d(TAG, "Creating WebdavClient associated to " + account.name);
Log_OC.d(TAG, "Creating WebdavClient associated to " + account.name);
Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(context, account));
WebdavClient client = createOwnCloudClient(uri, context);
@ -100,7 +101,7 @@ public class OwnCloudClientUtils {
* @return A WebdavClient object ready to be used
*/
public static WebdavClient createOwnCloudClient(Uri uri, String username, String password, Context context) {
Log.d(TAG, "Creating WebdavClient for " + username + "@" + uri);
Log_OC.d(TAG, "Creating WebdavClient for " + username + "@" + uri);
WebdavClient client = createOwnCloudClient(uri, context);
@ -118,16 +119,16 @@ public class OwnCloudClientUtils {
* @return A WebdavClient object ready to be used
*/
public static WebdavClient createOwnCloudClient(Uri uri, Context context) {
Log.d(TAG, "Creating WebdavClient for " + uri);
Log_OC.d(TAG, "Creating WebdavClient for " + uri);
//allowSelfsignedCertificates(true);
try {
registerAdvancedSslContext(true, context);
} catch (GeneralSecurityException e) {
Log.e(TAG, "Advanced SSL Context could not be loaded. Default SSL management in the system will be used for HTTPS connections", e);
Log_OC.e(TAG, "Advanced SSL Context could not be loaded. Default SSL management in the system will be used for HTTPS connections", e);
} catch (IOException e) {
Log.e(TAG, "The local server truststore could not be read. Default SSL management in the system will be used for HTTPS connections", e);
Log_OC.e(TAG, "The local server truststore could not be read. Default SSL management in the system will be used for HTTPS connections", e);
}
WebdavClient client = new WebdavClient(getMultiThreadedConnManager());
@ -205,7 +206,7 @@ public class OwnCloudClientUtils {
//mKnownServersStore = KeyStore.getInstance("BKS");
mKnownServersStore = KeyStore.getInstance(KeyStore.getDefaultType());
File localTrustStoreFile = new File(context.getFilesDir(), LOCAL_TRUSTSTORE_FILENAME);
Log.d(TAG, "Searching known-servers store at " + localTrustStoreFile.getAbsolutePath());
Log_OC.d(TAG, "Searching known-servers store at " + localTrustStoreFile.getAbsolutePath());
if (localTrustStoreFile.exists()) {
InputStream in = new FileInputStream(localTrustStoreFile);
try {

View file

@ -28,6 +28,7 @@ import java.util.Random;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PutMethod;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.network.ProgressiveDataTransferer;
@ -75,7 +76,7 @@ public class ChunkedUploadFileOperation extends UploadFileOperation {
mPutMethod.setRequestEntity(mEntity);
status = client.executeMethod(mPutMethod);
client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
Log.d(TAG, "Upload of " + getStoragePath() + " to " + getRemotePath() + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
Log_OC.d(TAG, "Upload of " + getStoragePath() + " to " + getRemotePath() + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
if (!isSuccess(status))
break;
}

View file

@ -24,6 +24,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.utils.OwnCloudVersion;
import eu.alefzero.webdav.WebdavClient;
@ -96,13 +97,13 @@ public class ConnectionCheckOperation extends RemoteOperation {
}
if (mLatestResult.isSuccess()) {
Log.i(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
Log_OC.i(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
} else if (mLatestResult.getException() != null) {
Log.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage(), mLatestResult.getException());
Log_OC.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage(), mLatestResult.getException());
} else {
Log.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
Log_OC.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
}
return retval;
@ -127,7 +128,7 @@ public class ConnectionCheckOperation extends RemoteOperation {
client.setBaseUri(Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH));
boolean httpsSuccess = tryConnection(client, "https://" + mUrl + AccountUtils.STATUS_PATH);
if (!httpsSuccess && !mLatestResult.isSslRecoverableException()) {
Log.d(TAG, "establishing secure connection failed, trying non secure connection");
Log_OC.d(TAG, "establishing secure connection failed, trying non secure connection");
client.setBaseUri(Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH));
tryConnection(client, "http://" + mUrl + AccountUtils.STATUS_PATH);
}

View file

@ -33,6 +33,7 @@ import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
@ -104,7 +105,7 @@ public class DownloadFileOperation extends RemoteOperation {
.getMimeTypeFromExtension(
mFile.getRemotePath().substring(mFile.getRemotePath().lastIndexOf('.') + 1));
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Trying to find out MIME type of a file without extension: " + mFile.getRemotePath());
Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + mFile.getRemotePath());
}
}
if (mimeType == null) {
@ -156,11 +157,11 @@ public class DownloadFileOperation extends RemoteOperation {
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED);
else
result = new RemoteOperationResult(isSuccess(status), status);
Log.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage());
Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage(), e);
Log_OC.e(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage(), e);
}
return result;

View file

@ -35,6 +35,7 @@ import org.apache.jackrabbit.webdav.DavException;
import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.network.CertificateCombinedException;
/**
@ -91,7 +92,7 @@ public class RemoteOperationResult implements Serializable {
break;
default:
mCode = ResultCode.UNHANDLED_HTTP_CODE;
Log.d(TAG, "RemoteOperationResult has prcessed UNHANDLED_HTTP_CODE: " + httpCode);
Log_OC.d(TAG, "RemoteOperationResult has prcessed UNHANDLED_HTTP_CODE: " + httpCode);
}
}
}

View file

@ -23,6 +23,7 @@ import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.OCFile;
@ -91,11 +92,11 @@ public class RemoveFileOperation extends RemoteOperation {
}
delete.getResponseBodyAsString(); // exhaust the response, although not interesting
result = new RemoteOperationResult((delete.succeeded() || status == HttpStatus.SC_NOT_FOUND), status);
Log.i(TAG, "Remove " + mFileToRemove.getRemotePath() + ": " + result.getLogMessage());
Log_OC.i(TAG, "Remove " + mFileToRemove.getRemotePath() + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Remove " + mFileToRemove.getRemotePath() + ": " + result.getLogMessage(), e);
Log_OC.e(TAG, "Remove " + mFileToRemove.getRemotePath() + ": " + result.getLogMessage(), e);
} finally {
if (delete != null)

View file

@ -27,6 +27,7 @@ import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
import android.accounts.Account;
import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
@ -138,11 +139,11 @@ public class RenameFileOperation extends RemoteOperation {
move.getResponseBodyAsString(); // exhaust response, although not interesting
result = new RemoteOperationResult(move.succeeded(), status);
Log.i(TAG, "Rename " + mFile.getRemotePath() + " to " + mNewRemotePath + ": " + result.getLogMessage());
Log_OC.i(TAG, "Rename " + mFile.getRemotePath() + " to " + mNewRemotePath + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + result.getLogMessage(), e);
Log_OC.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + result.getLogMessage(), e);
} finally {
if (move != null)
@ -206,7 +207,7 @@ public class RenameFileOperation extends RemoteOperation {
try {
testFile.createNewFile(); // return value is ignored; it could be 'false' because the file already existed, that doesn't invalidate the name
} catch (IOException e) {
Log.i(TAG, "Test for validity of name " + mNewName + " in the file system failed");
Log_OC.i(TAG, "Test for validity of name " + mNewName + " in the file system failed");
return false;
}
boolean result = (testFile.exists() && testFile.isFile());

View file

@ -28,6 +28,7 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
@ -158,11 +159,11 @@ public class SynchronizeFileOperation extends RemoteOperation {
}
Log.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage());
Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Synchronizing " + mAccount.name + ", file " + (mLocalFile != null ? mLocalFile.getRemotePath() : "NULL") + ": " + result.getLogMessage(), result.getException());
Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", file " + (mLocalFile != null ? mLocalFile.getRemotePath() : "NULL") + ": " + result.getLogMessage(), result.getException());
} finally {
if (propfind != null)

View file

@ -37,6 +37,7 @@ import android.accounts.Account;
import android.content.Context;
import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
@ -132,7 +133,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
// code before in FileSyncAdapter.fetchData
PropFindMethod query = null;
try {
Log.d(TAG, "Synchronizing " + mAccount.name + ", fetching files in " + mRemotePath);
Log_OC.d(TAG, "Synchronizing " + mAccount.name + ", fetching files in " + mRemotePath);
// remote request
query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
@ -209,9 +210,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
} else {
mFailsInFavouritesFound++;
if (contentsResult.getException() != null) {
Log.d(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage(), contentsResult.getException());
Log_OC.d(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage(), contentsResult.getException());
} else {
Log.d(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage());
Log_OC.d(TAG, "Error while synchronizing favourites : " + contentsResult.getLogMessage());
}
}
} // won't let these fails break the synchronization process
@ -225,7 +226,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
for (int i=0; i < mChildren.size(); ) {
file = mChildren.get(i);
if (file.getLastSyncDateForProperties() != mCurrentSyncTime) {
Log.d(TAG, "removing file: " + file);
Log_OC.d(TAG, "removing file: " + file);
mStorageManager.removeFile(file, (file.isDown() && file.getStoragePath().startsWith(currentSavePath)));
mChildren.remove(i);
} else {
@ -248,12 +249,12 @@ public class SynchronizeFolderOperation extends RemoteOperation {
} else {
result = new RemoteOperationResult(false, status);
}
Log.i(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage());
Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage(), result.getException());
Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage(), result.getException());
} finally {
if (query != null)
@ -329,7 +330,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
file.setStoragePath(expectedPath);
} catch (Exception e) {
Log.e(TAG, "Exception while copying foreign file " + expectedPath, e);
Log_OC.e(TAG, "Exception while copying foreign file " + expectedPath, e);
mForgottenLocalFiles.put(file.getRemotePath(), storagePath);
file.setStoragePath(null);
@ -337,12 +338,12 @@ public class SynchronizeFolderOperation extends RemoteOperation {
try {
if (in != null) in.close();
} catch (Exception e) {
Log.d(TAG, "Weird exception while closing input stream for " + storagePath + " (ignoring)", e);
Log_OC.d(TAG, "Weird exception while closing input stream for " + storagePath + " (ignoring)", e);
}
try {
if (out != null) out.close();
} catch (Exception e) {
Log.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
Log_OC.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
}
}
}

View file

@ -29,6 +29,7 @@ import android.content.Context;
import android.util.Log;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.utils.OwnCloudVersion;
@ -76,11 +77,11 @@ public class UpdateOCVersionOperation extends RemoteOperation {
OwnCloudVersion ocver = new OwnCloudVersion(json.getString("version"));
if (ocver.isVersionValid()) {
accountMngr.setUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION, ocver.toString());
Log.d(TAG, "Got new OC version " + ocver.toString());
Log_OC.d(TAG, "Got new OC version " + ocver.toString());
result = new RemoteOperationResult(ResultCode.OK);
} else {
Log.w(TAG, "Invalid version number received from server: " + json.getString("version"));
Log_OC.w(TAG, "Invalid version number received from server: " + json.getString("version"));
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.BAD_OC_VERSION);
}
}
@ -89,15 +90,15 @@ public class UpdateOCVersionOperation extends RemoteOperation {
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
}
}
Log.i(TAG, "Check for update of ownCloud server version at " + client.getBaseUri() + ": " + result.getLogMessage());
Log_OC.i(TAG, "Check for update of ownCloud server version at " + client.getBaseUri() + ": " + result.getLogMessage());
} catch (JSONException e) {
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
Log.e(TAG, "Check for update of ownCloud server version at " + client.getBaseUri() + ": " + result.getLogMessage(), e);
Log_OC.e(TAG, "Check for update of ownCloud server version at " + client.getBaseUri() + ": " + result.getLogMessage(), e);
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Check for update of ownCloud server version at " + client.getBaseUri() + ": " + result.getLogMessage(), e);
Log_OC.e(TAG, "Check for update of ownCloud server version at " + client.getBaseUri() + ": " + result.getLogMessage(), e);
} finally {
if (get != null)

View file

@ -33,8 +33,8 @@ import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.http.HttpStatus;
import com.owncloud.android.Log_OC;
import android.accounts.Account;
import android.util.Log;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
@ -246,15 +246,13 @@ public class UploadFileOperation extends RemoteOperation {
if (in != null)
in.close();
} catch (Exception e) {
Log.d(TAG, "Weird exception while closing input stream for " + mOriginalStoragePath
+ " (ignoring)", e);
Log_OC.d(TAG, "Weird exception while closing input stream for " + mOriginalStoragePath + " (ignoring)", e);
}
try {
if (out != null)
out.close();
} catch (Exception e) {
Log.d(TAG, "Weird exception while closing output stream for " + expectedPath
+ " (ignoring)", e);
Log_OC.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
}
}
}
@ -322,8 +320,7 @@ public class UploadFileOperation extends RemoteOperation {
temporalFile.delete();
}
if (result.isSuccess()) {
Log.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
} else {
if (result.getException() != null) {
String complement = "";
@ -333,12 +330,9 @@ public class UploadFileOperation extends RemoteOperation {
complement = " (while copying local file to " + FileStorageUtils.getSavePath(mAccount.name)
+ ")";
}
Log.e(TAG,
"Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage()
+ complement, result.getException());
Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage() + complement, result.getException());
} else {
Log.e(TAG,
"Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
}
}
}

View file

@ -1,289 +1,290 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.providers;
import java.util.HashMap;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
/**
* The ContentProvider for the ownCloud App.
*
* @author Bartek Przybylski
*
*/
public class FileContentProvider extends ContentProvider {
private DataBaseHelper mDbHelper;
private static HashMap<String, String> mProjectionMap;
static {
mProjectionMap = new HashMap<String, String>();
mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
ProviderTableMeta.FILE_PARENT);
mProjectionMap.put(ProviderTableMeta.FILE_PATH,
ProviderTableMeta.FILE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_NAME,
ProviderTableMeta.FILE_NAME);
mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
ProviderTableMeta.FILE_CREATION);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
ProviderTableMeta.FILE_MODIFIED);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
ProviderTableMeta.FILE_CONTENT_LENGTH);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
ProviderTableMeta.FILE_CONTENT_TYPE);
mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
ProviderTableMeta.FILE_STORAGE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,
ProviderTableMeta.FILE_LAST_SYNC_DATE);
mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA);
mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,
ProviderTableMeta.FILE_KEEP_IN_SYNC);
mProjectionMap.put(ProviderTableMeta.FILE_ACCOUNT_OWNER,
ProviderTableMeta.FILE_ACCOUNT_OWNER);
}
private static final int SINGLE_FILE = 1;
private static final int DIRECTORY = 2;
private static final int ROOT_DIRECTORY = 3;
private static final UriMatcher mUriMatcher;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int count = 0;
switch (mUriMatcher.match(uri)) {
case SINGLE_FILE:
count = db.delete(ProviderTableMeta.DB_NAME,
ProviderTableMeta._ID
+ "="
+ uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(where) ? " AND (" + where
+ ")" : ""), whereArgs);
break;
case ROOT_DIRECTORY:
count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown uri: " + uri.toString());
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
return ProviderTableMeta.CONTENT_TYPE;
case SINGLE_FILE:
return ProviderTableMeta.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown Uri id."
+ uri.toString());
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (mUriMatcher.match(uri) != SINGLE_FILE &&
mUriMatcher.match(uri) != ROOT_DIRECTORY) {
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
SQLiteDatabase db = mDbHelper.getWritableDatabase();
long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);
if (rowId > 0) {
Uri insertedFileUri = ContentUris.withAppendedId(
ProviderTableMeta.CONTENT_URI_FILE, rowId);
getContext().getContentResolver().notifyChange(insertedFileUri,
null);
return insertedFileUri;
}
throw new SQLException("ERROR " + uri);
}
@Override
public boolean onCreate() {
mDbHelper = new DataBaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
sqlQuery.setTables(ProviderTableMeta.DB_NAME);
sqlQuery.setProjectionMap(mProjectionMap);
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
break;
case DIRECTORY:
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
+ uri.getPathSegments().get(1));
break;
case SINGLE_FILE:
if (uri.getPathSegments().size() > 1) {
sqlQuery.appendWhere(ProviderTableMeta._ID + "="
+ uri.getPathSegments().get(1));
}
break;
default:
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
String order;
if (TextUtils.isEmpty(sortOrder)) {
order = ProviderTableMeta.DEFAULT_SORT_ORDER;
} else {
order = sortOrder;
}
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,
null, null, order);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return mDbHelper.getWritableDatabase().update(
ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
}
class DataBaseHelper extends SQLiteOpenHelper {
public DataBaseHelper(Context context) {
super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// files table
Log.i("SQL", "Entering in onCreate");
db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("
+ ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
+ ProviderTableMeta.FILE_NAME + " TEXT, "
+ ProviderTableMeta.FILE_PATH + " TEXT, "
+ ProviderTableMeta.FILE_PARENT + " INTEGER, "
+ ProviderTableMeta.FILE_CREATION + " INTEGER, "
+ ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
+ ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
+ ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
+ ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
+ ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
+ ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER, "
+ ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER, "
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER );"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("SQL", "Entering in onUpgrade");
boolean upgraded = false;
if (oldVersion == 1 && newVersion >= 2) {
Log.i("SQL", "Entering in the #1 ADD in onUpgrade");
db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
" DEFAULT 0");
upgraded = true;
}
if (oldVersion < 3 && newVersion >= 3) {
Log.i("SQL", "Entering in the #2 ADD in onUpgrade");
db.beginTransaction();
try {
db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER " +
" DEFAULT 0");
// assume there are not local changes pending to upload
db.execSQL("UPDATE " + ProviderTableMeta.DB_NAME +
" SET " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " = " + System.currentTimeMillis() +
" WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
upgraded = true;
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
if (oldVersion < 4 && newVersion >= 4) {
Log.i("SQL", "Entering in the #3 ADD in onUpgrade");
db.beginTransaction();
try {
db .execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER " +
" DEFAULT 0");
db.execSQL("UPDATE " + ProviderTableMeta.DB_NAME +
" SET " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " = " + ProviderTableMeta.FILE_MODIFIED +
" WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
upgraded = true;
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
if (!upgraded)
Log.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);
}
}
}
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.providers;
import java.util.HashMap;
import com.owncloud.android.Log_OC;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
/**
* The ContentProvider for the ownCloud App.
*
* @author Bartek Przybylski
*
*/
public class FileContentProvider extends ContentProvider {
private DataBaseHelper mDbHelper;
private static HashMap<String, String> mProjectionMap;
static {
mProjectionMap = new HashMap<String, String>();
mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
ProviderTableMeta.FILE_PARENT);
mProjectionMap.put(ProviderTableMeta.FILE_PATH,
ProviderTableMeta.FILE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_NAME,
ProviderTableMeta.FILE_NAME);
mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
ProviderTableMeta.FILE_CREATION);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
ProviderTableMeta.FILE_MODIFIED);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
ProviderTableMeta.FILE_CONTENT_LENGTH);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
ProviderTableMeta.FILE_CONTENT_TYPE);
mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
ProviderTableMeta.FILE_STORAGE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,
ProviderTableMeta.FILE_LAST_SYNC_DATE);
mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA);
mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,
ProviderTableMeta.FILE_KEEP_IN_SYNC);
mProjectionMap.put(ProviderTableMeta.FILE_ACCOUNT_OWNER,
ProviderTableMeta.FILE_ACCOUNT_OWNER);
}
private static final int SINGLE_FILE = 1;
private static final int DIRECTORY = 2;
private static final int ROOT_DIRECTORY = 3;
private static final UriMatcher mUriMatcher;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int count = 0;
switch (mUriMatcher.match(uri)) {
case SINGLE_FILE:
count = db.delete(ProviderTableMeta.DB_NAME,
ProviderTableMeta._ID
+ "="
+ uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(where) ? " AND (" + where
+ ")" : ""), whereArgs);
break;
case ROOT_DIRECTORY:
count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown uri: " + uri.toString());
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
return ProviderTableMeta.CONTENT_TYPE;
case SINGLE_FILE:
return ProviderTableMeta.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown Uri id."
+ uri.toString());
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (mUriMatcher.match(uri) != SINGLE_FILE &&
mUriMatcher.match(uri) != ROOT_DIRECTORY) {
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
SQLiteDatabase db = mDbHelper.getWritableDatabase();
long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);
if (rowId > 0) {
Uri insertedFileUri = ContentUris.withAppendedId(
ProviderTableMeta.CONTENT_URI_FILE, rowId);
getContext().getContentResolver().notifyChange(insertedFileUri,
null);
return insertedFileUri;
}
throw new SQLException("ERROR " + uri);
}
@Override
public boolean onCreate() {
mDbHelper = new DataBaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
sqlQuery.setTables(ProviderTableMeta.DB_NAME);
sqlQuery.setProjectionMap(mProjectionMap);
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
break;
case DIRECTORY:
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
+ uri.getPathSegments().get(1));
break;
case SINGLE_FILE:
if (uri.getPathSegments().size() > 1) {
sqlQuery.appendWhere(ProviderTableMeta._ID + "="
+ uri.getPathSegments().get(1));
}
break;
default:
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
String order;
if (TextUtils.isEmpty(sortOrder)) {
order = ProviderTableMeta.DEFAULT_SORT_ORDER;
} else {
order = sortOrder;
}
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,
null, null, order);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return mDbHelper.getWritableDatabase().update(
ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
}
class DataBaseHelper extends SQLiteOpenHelper {
public DataBaseHelper(Context context) {
super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// files table
Log_OC.i("SQL", "Entering in onCreate");
db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("
+ ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
+ ProviderTableMeta.FILE_NAME + " TEXT, "
+ ProviderTableMeta.FILE_PATH + " TEXT, "
+ ProviderTableMeta.FILE_PARENT + " INTEGER, "
+ ProviderTableMeta.FILE_CREATION + " INTEGER, "
+ ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
+ ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
+ ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
+ ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
+ ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
+ ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER, "
+ ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER, "
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER );"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log_OC.i("SQL", "Entering in onUpgrade");
boolean upgraded = false;
if (oldVersion == 1 && newVersion >= 2) {
Log_OC.i("SQL", "Entering in the #1 ADD in onUpgrade");
db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
" DEFAULT 0");
upgraded = true;
}
if (oldVersion < 3 && newVersion >= 3) {
Log_OC.i("SQL", "Entering in the #2 ADD in onUpgrade");
db.beginTransaction();
try {
db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER " +
" DEFAULT 0");
// assume there are not local changes pending to upload
db.execSQL("UPDATE " + ProviderTableMeta.DB_NAME +
" SET " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " = " + System.currentTimeMillis() +
" WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
upgraded = true;
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
if (oldVersion < 4 && newVersion >= 4) {
Log_OC.i("SQL", "Entering in the #3 ADD in onUpgrade");
db.beginTransaction();
try {
db .execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER " +
" DEFAULT 0");
db.execSQL("UPDATE " + ProviderTableMeta.DB_NAME +
" SET " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " = " + ProviderTableMeta.FILE_MODIFIED +
" WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
upgraded = true;
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
if (!upgraded)
Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);
}
}
}

View file

@ -1,370 +1,371 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.syncadapter;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.jackrabbit.webdav.DavException;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.operations.SynchronizeFolderOperation;
import com.owncloud.android.operations.UpdateOCVersionOperation;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
import android.accounts.Account;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
import android.util.Log;
/**
* SyncAdapter implementation for syncing sample SyncAdapter contacts to the
* platform ContactOperations provider.
*
* @author Bartek Przybylski
*/
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
private final static String TAG = "FileSyncAdapter";
/**
* Maximum number of failed folder synchronizations that are supported before finishing the synchronization operation
*/
private static final int MAX_FAILED_RESULTS = 3;
private long mCurrentSyncTime;
private boolean mCancellation;
private boolean mIsManualSync;
private int mFailedResultsCounter;
private RemoteOperationResult mLastFailedResult;
private SyncResult mSyncResult;
private int mConflictsFound;
private int mFailsInFavouritesFound;
private Map<String, String> mForgottenLocalFiles;
public FileSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void onPerformSync(Account account, Bundle extras,
String authority, ContentProviderClient provider,
SyncResult syncResult) {
mCancellation = false;
mIsManualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
mFailedResultsCounter = 0;
mLastFailedResult = null;
mConflictsFound = 0;
mFailsInFavouritesFound = 0;
mForgottenLocalFiles = new HashMap<String, String>();
mSyncResult = syncResult;
mSyncResult.fullSyncRequested = false;
mSyncResult.delayUntil = 60*60*24; // sync after 24h
this.setAccount(account);
this.setContentProvider(provider);
this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));
try {
this.initClientForCurrentAccount();
} catch (UnknownHostException e) {
/// the account is unknown for the Synchronization Manager, or unreachable for this context; don't try this again
mSyncResult.tooManyRetries = true;
notifyFailedSynchronization();
return;
}
Log.d(TAG, "Synchronization of ownCloud account " + account.name + " starting");
sendStickyBroadcast(true, null, null); // message to signal the start of the synchronization to the UI
try {
updateOCVersion();
mCurrentSyncTime = System.currentTimeMillis();
if (!mCancellation) {
fetchData(OCFile.PATH_SEPARATOR, DataStorageManager.ROOT_PARENT_ID);
} else {
Log.d(TAG, "Leaving synchronization before any remote request due to cancellation was requested");
}
} finally {
// it's important making this although very unexpected errors occur; that's the reason for the finally
if (mFailedResultsCounter > 0 && mIsManualSync) {
/// don't let the system synchronization manager retries MANUAL synchronizations
// (be careful: "MANUAL" currently includes the synchronization requested when a new account is created and when the user changes the current account)
mSyncResult.tooManyRetries = true;
/// notify the user about the failure of MANUAL synchronization
notifyFailedSynchronization();
}
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
notifyFailsInFavourites();
}
if (mForgottenLocalFiles.size() > 0) {
notifyForgottenLocalFiles();
}
sendStickyBroadcast(false, null, mLastFailedResult); // message to signal the end to the UI
}
}
/**
* Called by system SyncManager when a synchronization is required to be cancelled.
*
* Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder
* fetched will be still saved in the database. See onPerformSync implementation.
*/
@Override
public void onSyncCanceled() {
Log.d(TAG, "Synchronization of " + getAccount().name + " has been requested to cancel");
mCancellation = true;
super.onSyncCanceled();
}
/**
* Updates the locally stored version value of the ownCloud server
*/
private void updateOCVersion() {
UpdateOCVersionOperation update = new UpdateOCVersionOperation(getAccount(), getContext());
RemoteOperationResult result = update.execute(getClient());
if (!result.isSuccess()) {
mLastFailedResult = result;
}
}
/**
* Synchronize the properties of files and folders contained in a remote folder given by remotePath.
*
* @param remotePath Remote path to the folder to synchronize.
* @param parentId Database Id of the folder to synchronize.
*/
private void fetchData(String remotePath, long parentId) {
if (mFailedResultsCounter > MAX_FAILED_RESULTS || isFinisher(mLastFailedResult))
return;
// perform folder synchronization
SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( remotePath,
mCurrentSyncTime,
parentId,
getStorageManager(),
getAccount(),
getContext()
);
RemoteOperationResult result = synchFolderOp.execute(getClient());
// synchronized folder -> notice to UI - ALWAYS, although !result.isSuccess
sendStickyBroadcast(true, remotePath, null);
if (result.isSuccess() || result.getCode() == ResultCode.SYNC_CONFLICT) {
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
mConflictsFound += synchFolderOp.getConflictsFound();
mFailsInFavouritesFound += synchFolderOp.getFailsInFavouritesFound();
}
if (synchFolderOp.getForgottenLocalFiles().size() > 0) {
mForgottenLocalFiles.putAll(synchFolderOp.getForgottenLocalFiles());
}
// synchronize children folders
List<OCFile> children = synchFolderOp.getChildren();
fetchChildren(children); // beware of the 'hidden' recursion here!
} else {
if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED) {
mSyncResult.stats.numAuthExceptions++;
} else if (result.getException() instanceof DavException) {
mSyncResult.stats.numParseExceptions++;
} else if (result.getException() instanceof IOException) {
mSyncResult.stats.numIoExceptions++;
}
mFailedResultsCounter++;
mLastFailedResult = result;
}
}
/**
* Checks if a failed result should terminate the synchronization process immediately, according to
* OUR OWN POLICY
*
* @param failedResult Remote operation result to check.
* @return 'True' if the result should immediately finish the synchronization
*/
private boolean isFinisher(RemoteOperationResult failedResult) {
if (failedResult != null) {
RemoteOperationResult.ResultCode code = failedResult.getCode();
return (code.equals(RemoteOperationResult.ResultCode.SSL_ERROR) ||
code.equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) ||
code.equals(RemoteOperationResult.ResultCode.BAD_OC_VERSION) ||
code.equals(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED));
}
return false;
}
/**
* Synchronize data of folders in the list of received files
*
* @param files Files to recursively fetch
*/
private void fetchChildren(List<OCFile> files) {
int i;
for (i=0; i < files.size() && !mCancellation; i++) {
OCFile newFile = files.get(i);
if (newFile.isDirectory()) {
fetchData(newFile.getRemotePath(), newFile.getFileId());
}
}
if (mCancellation && i <files.size()) Log.d(TAG, "Leaving synchronization before synchronizing " + files.get(i).getRemotePath() + " because cancelation request");
}
/**
* Sends a message to any application component interested in the progress of the synchronization.
*
* @param inProgress 'True' when the synchronization progress is not finished.
* @param dirRemotePath Remote path of a folder that was just synchronized (with or without success)
*/
private void sendStickyBroadcast(boolean inProgress, String dirRemotePath, RemoteOperationResult result) {
Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
i.putExtra(FileSyncService.IN_PROGRESS, inProgress);
i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);
if (dirRemotePath != null) {
i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);
}
if (result != null) {
i.putExtra(FileSyncService.SYNC_RESULT, result);
}
getContext().sendStickyBroadcast(i);
}
/**
* Notifies the user about a failed synchronization through the status notification bar
*/
private void notifyFailedSynchronization() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// TODO put something smart in the contentIntent below
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_fail_ticker),
String.format(getContext().getString(R.string.sync_fail_content), getAccount().name),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_ticker, notification);
}
/**
* Notifies the user about conflicts and strange fails when trying to synchronize the contents of kept-in-sync files.
*
* By now, we won't consider a failed synchronization.
*/
private void notifyFailsInFavourites() {
if (mFailedResultsCounter > 0) {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_in_favourites_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// TODO put something smart in the contentIntent below
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_fail_in_favourites_ticker),
String.format(getContext().getString(R.string.sync_fail_in_favourites_content), mFailedResultsCounter + mConflictsFound, mConflictsFound),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_in_favourites_ticker, notification);
} else {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_conflicts_in_favourites_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// TODO put something smart in the contentIntent below
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_conflicts_in_favourites_ticker),
String.format(getContext().getString(R.string.sync_conflicts_in_favourites_content), mConflictsFound),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_conflicts_in_favourites_ticker, notification);
}
}
/**
* Notifies the user about local copies of files out of the ownCloud local directory that were 'forgotten' because
* copying them inside the ownCloud local directory was not possible.
*
* We don't want links to files out of the ownCloud local directory (foreign files) anymore. It's easy to have
* synchronization problems if a local file is linked to more than one remote file.
*
* We won't consider a synchronization as failed when foreign files can not be copied to the ownCloud local directory.
*/
private void notifyForgottenLocalFiles() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_foreign_files_forgotten_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
/// includes a pending intent in the notification showing a more detailed explanation
Intent explanationIntent = new Intent(getContext(), ErrorsWhileCopyingHandlerActivity.class);
explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_ACCOUNT, getAccount());
ArrayList<String> remotePaths = new ArrayList<String>();
ArrayList<String> localPaths = new ArrayList<String>();
remotePaths.addAll(mForgottenLocalFiles.keySet());
localPaths.addAll(mForgottenLocalFiles.values());
explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_LOCAL_PATHS, localPaths);
explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_REMOTE_PATHS, remotePaths);
explanationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), explanationIntent, 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_foreign_files_forgotten_ticker),
String.format(getContext().getString(R.string.sync_foreign_files_forgotten_content), mForgottenLocalFiles.size(), getContext().getString(R.string.app_name)),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_foreign_files_forgotten_ticker, notification);
}
}
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.syncadapter;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.jackrabbit.webdav.DavException;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.operations.SynchronizeFolderOperation;
import com.owncloud.android.operations.UpdateOCVersionOperation;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
import android.accounts.Account;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
import android.util.Log;
/**
* SyncAdapter implementation for syncing sample SyncAdapter contacts to the
* platform ContactOperations provider.
*
* @author Bartek Przybylski
*/
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
private final static String TAG = "FileSyncAdapter";
/**
* Maximum number of failed folder synchronizations that are supported before finishing the synchronization operation
*/
private static final int MAX_FAILED_RESULTS = 3;
private long mCurrentSyncTime;
private boolean mCancellation;
private boolean mIsManualSync;
private int mFailedResultsCounter;
private RemoteOperationResult mLastFailedResult;
private SyncResult mSyncResult;
private int mConflictsFound;
private int mFailsInFavouritesFound;
private Map<String, String> mForgottenLocalFiles;
public FileSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void onPerformSync(Account account, Bundle extras,
String authority, ContentProviderClient provider,
SyncResult syncResult) {
mCancellation = false;
mIsManualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
mFailedResultsCounter = 0;
mLastFailedResult = null;
mConflictsFound = 0;
mFailsInFavouritesFound = 0;
mForgottenLocalFiles = new HashMap<String, String>();
mSyncResult = syncResult;
mSyncResult.fullSyncRequested = false;
mSyncResult.delayUntil = 60*60*24; // sync after 24h
this.setAccount(account);
this.setContentProvider(provider);
this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));
try {
this.initClientForCurrentAccount();
} catch (UnknownHostException e) {
/// the account is unknown for the Synchronization Manager, or unreachable for this context; don't try this again
mSyncResult.tooManyRetries = true;
notifyFailedSynchronization();
return;
}
Log_OC.d(TAG, "Synchronization of ownCloud account " + account.name + " starting");
sendStickyBroadcast(true, null, null); // message to signal the start of the synchronization to the UI
try {
updateOCVersion();
mCurrentSyncTime = System.currentTimeMillis();
if (!mCancellation) {
fetchData(OCFile.PATH_SEPARATOR, DataStorageManager.ROOT_PARENT_ID);
} else {
Log_OC.d(TAG, "Leaving synchronization before any remote request due to cancellation was requested");
}
} finally {
// it's important making this although very unexpected errors occur; that's the reason for the finally
if (mFailedResultsCounter > 0 && mIsManualSync) {
/// don't let the system synchronization manager retries MANUAL synchronizations
// (be careful: "MANUAL" currently includes the synchronization requested when a new account is created and when the user changes the current account)
mSyncResult.tooManyRetries = true;
/// notify the user about the failure of MANUAL synchronization
notifyFailedSynchronization();
}
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
notifyFailsInFavourites();
}
if (mForgottenLocalFiles.size() > 0) {
notifyForgottenLocalFiles();
}
sendStickyBroadcast(false, null, mLastFailedResult); // message to signal the end to the UI
}
}
/**
* Called by system SyncManager when a synchronization is required to be cancelled.
*
* Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder
* fetched will be still saved in the database. See onPerformSync implementation.
*/
@Override
public void onSyncCanceled() {
Log_OC.d(TAG, "Synchronization of " + getAccount().name + " has been requested to cancel");
mCancellation = true;
super.onSyncCanceled();
}
/**
* Updates the locally stored version value of the ownCloud server
*/
private void updateOCVersion() {
UpdateOCVersionOperation update = new UpdateOCVersionOperation(getAccount(), getContext());
RemoteOperationResult result = update.execute(getClient());
if (!result.isSuccess()) {
mLastFailedResult = result;
}
}
/**
* Synchronize the properties of files and folders contained in a remote folder given by remotePath.
*
* @param remotePath Remote path to the folder to synchronize.
* @param parentId Database Id of the folder to synchronize.
*/
private void fetchData(String remotePath, long parentId) {
if (mFailedResultsCounter > MAX_FAILED_RESULTS || isFinisher(mLastFailedResult))
return;
// perform folder synchronization
SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( remotePath,
mCurrentSyncTime,
parentId,
getStorageManager(),
getAccount(),
getContext()
);
RemoteOperationResult result = synchFolderOp.execute(getClient());
// synchronized folder -> notice to UI - ALWAYS, although !result.isSuccess
sendStickyBroadcast(true, remotePath, null);
if (result.isSuccess() || result.getCode() == ResultCode.SYNC_CONFLICT) {
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
mConflictsFound += synchFolderOp.getConflictsFound();
mFailsInFavouritesFound += synchFolderOp.getFailsInFavouritesFound();
}
if (synchFolderOp.getForgottenLocalFiles().size() > 0) {
mForgottenLocalFiles.putAll(synchFolderOp.getForgottenLocalFiles());
}
// synchronize children folders
List<OCFile> children = synchFolderOp.getChildren();
fetchChildren(children); // beware of the 'hidden' recursion here!
} else {
if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED) {
mSyncResult.stats.numAuthExceptions++;
} else if (result.getException() instanceof DavException) {
mSyncResult.stats.numParseExceptions++;
} else if (result.getException() instanceof IOException) {
mSyncResult.stats.numIoExceptions++;
}
mFailedResultsCounter++;
mLastFailedResult = result;
}
}
/**
* Checks if a failed result should terminate the synchronization process immediately, according to
* OUR OWN POLICY
*
* @param failedResult Remote operation result to check.
* @return 'True' if the result should immediately finish the synchronization
*/
private boolean isFinisher(RemoteOperationResult failedResult) {
if (failedResult != null) {
RemoteOperationResult.ResultCode code = failedResult.getCode();
return (code.equals(RemoteOperationResult.ResultCode.SSL_ERROR) ||
code.equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) ||
code.equals(RemoteOperationResult.ResultCode.BAD_OC_VERSION) ||
code.equals(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED));
}
return false;
}
/**
* Synchronize data of folders in the list of received files
*
* @param files Files to recursively fetch
*/
private void fetchChildren(List<OCFile> files) {
int i;
for (i=0; i < files.size() && !mCancellation; i++) {
OCFile newFile = files.get(i);
if (newFile.isDirectory()) {
fetchData(newFile.getRemotePath(), newFile.getFileId());
}
}
if (mCancellation && i <files.size()) Log_OC.d(TAG, "Leaving synchronization before synchronizing " + files.get(i).getRemotePath() + " because cancelation request");
}
/**
* Sends a message to any application component interested in the progress of the synchronization.
*
* @param inProgress 'True' when the synchronization progress is not finished.
* @param dirRemotePath Remote path of a folder that was just synchronized (with or without success)
*/
private void sendStickyBroadcast(boolean inProgress, String dirRemotePath, RemoteOperationResult result) {
Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
i.putExtra(FileSyncService.IN_PROGRESS, inProgress);
i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);
if (dirRemotePath != null) {
i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);
}
if (result != null) {
i.putExtra(FileSyncService.SYNC_RESULT, result);
}
getContext().sendStickyBroadcast(i);
}
/**
* Notifies the user about a failed synchronization through the status notification bar
*/
private void notifyFailedSynchronization() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// TODO put something smart in the contentIntent below
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_fail_ticker),
String.format(getContext().getString(R.string.sync_fail_content), getAccount().name),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_ticker, notification);
}
/**
* Notifies the user about conflicts and strange fails when trying to synchronize the contents of kept-in-sync files.
*
* By now, we won't consider a failed synchronization.
*/
private void notifyFailsInFavourites() {
if (mFailedResultsCounter > 0) {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_in_favourites_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// TODO put something smart in the contentIntent below
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_fail_in_favourites_ticker),
String.format(getContext().getString(R.string.sync_fail_in_favourites_content), mFailedResultsCounter + mConflictsFound, mConflictsFound),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_in_favourites_ticker, notification);
} else {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_conflicts_in_favourites_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// TODO put something smart in the contentIntent below
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_conflicts_in_favourites_ticker),
String.format(getContext().getString(R.string.sync_conflicts_in_favourites_content), mConflictsFound),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_conflicts_in_favourites_ticker, notification);
}
}
/**
* Notifies the user about local copies of files out of the ownCloud local directory that were 'forgotten' because
* copying them inside the ownCloud local directory was not possible.
*
* We don't want links to files out of the ownCloud local directory (foreign files) anymore. It's easy to have
* synchronization problems if a local file is linked to more than one remote file.
*
* We won't consider a synchronization as failed when foreign files can not be copied to the ownCloud local directory.
*/
private void notifyForgottenLocalFiles() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_foreign_files_forgotten_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
/// includes a pending intent in the notification showing a more detailed explanation
Intent explanationIntent = new Intent(getContext(), ErrorsWhileCopyingHandlerActivity.class);
explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_ACCOUNT, getAccount());
ArrayList<String> remotePaths = new ArrayList<String>();
ArrayList<String> localPaths = new ArrayList<String>();
remotePaths.addAll(mForgottenLocalFiles.keySet());
localPaths.addAll(mForgottenLocalFiles.values());
explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_LOCAL_PATHS, localPaths);
explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_REMOTE_PATHS, remotePaths);
explanationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), explanationIntent, 0);
notification.setLatestEventInfo(getContext().getApplicationContext(),
getContext().getString(R.string.sync_foreign_files_forgotten_ticker),
String.format(getContext().getString(R.string.sync_foreign_files_forgotten_content), mForgottenLocalFiles.size(), getContext().getString(R.string.app_name)),
notification.contentIntent);
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_foreign_files_forgotten_ticker, notification);
}
}

View file

@ -50,6 +50,7 @@ import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.R;
@ -153,7 +154,7 @@ public class AccountSelectActivity extends SherlockListActivity implements
try {
map = (HashMap<String, String>) getListAdapter().getItem(index);
} catch (ClassCastException e) {
Log.wtf(TAG, "getitem(index) from list adapter did not return hashmap, bailing out");
Log_OC.wtf(TAG, "getitem(index) from list adapter did not return hashmap, bailing out");
return false;
}

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@
package com.owncloud.android.ui.activity;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
@ -29,7 +30,6 @@ import com.owncloud.android.ui.dialog.ConflictsResolveDialog.OnConflictDecisionM
import android.accounts.Account;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
/**
* Wrapper activity which will be launched if keep-in-sync file will be modified by external
@ -79,7 +79,7 @@ public class ConflictsResolveActivity extends SherlockFragmentActivity implement
i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
break;
default:
Log.wtf(TAG, "Unhandled conflict decision " + decision);
Log_OC.wtf(TAG, "Unhandled conflict decision " + decision);
return;
}
i.putExtra(FileUploader.KEY_ACCOUNT, mOCAccount);

View file

@ -41,6 +41,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
@ -182,16 +183,16 @@ public class ErrorsWhileCopyingHandlerActivity extends SherlockFragmentActivity
public void onClick(View v) {
if (v.getId() == R.id.ok) {
/// perform movement operation in background thread
Log.d(TAG, "Clicked MOVE, start movement");
Log_OC.d(TAG, "Clicked MOVE, start movement");
new MoveFilesTask().execute();
} else if (v.getId() == R.id.cancel) {
/// just finish
Log.d(TAG, "Clicked CANCEL, bye");
Log_OC.d(TAG, "Clicked CANCEL, bye");
finish();
} else {
Log.e(TAG, "Clicked phantom button, id: " + v.getId());
Log_OC.e(TAG, "Clicked phantom button, id: " + v.getId());
}
}

View file

@ -1,395 +1,392 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.activity;
import android.accounts.Account;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.R;
/**
* This activity displays the details of a file like its name, its size and so
* on.
*
* @author Bartek Przybylski
* @author David A. Velasco
*/
public class FileDetailActivity extends SherlockFragmentActivity implements FileFragment.ContainerActivity {
public static final int DIALOG_SHORT_WAIT = 0;
public static final String TAG = FileDetailActivity.class.getSimpleName();
public static final String EXTRA_MODE = "MODE";
public static final int MODE_DETAILS = 0;
public static final int MODE_PREVIEW = 1;
public static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
private boolean mConfigurationChangedToLandscape = false;
private FileDownloaderBinder mDownloaderBinder = null;
private ServiceConnection mDownloadConnection, mUploadConnection = null;
private FileUploaderBinder mUploaderBinder = null;
private boolean mWaitingToPreview;
private OCFile mFile;
private Account mAccount;
private FileDataStorageManager mStorageManager;
private DownloadFinishReceiver mDownloadFinishReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFile = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
mAccount = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
// check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity
Configuration conf = getResources().getConfiguration();
mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE &&
(conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
);
if (!mConfigurationChangedToLandscape) {
setContentView(R.layout.file_activity_details);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
if (savedInstanceState == null) {
mWaitingToPreview = false;
createChildFragment();
} else {
mWaitingToPreview = savedInstanceState.getBoolean(KEY_WAITING_TO_PREVIEW);
}
mDownloadConnection = new DetailsServiceConnection();
bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
mUploadConnection = new DetailsServiceConnection();
bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
} else {
backToDisplayActivity(false); // the 'back' won't be effective until this.onStart() and this.onResume() are completed;
}
}
/**
* Creates the proper fragment depending upon the state of the handled {@link OCFile} and
* the requested {@link Intent}.
*/
private void createChildFragment() {
int mode = getIntent().getIntExtra(EXTRA_MODE, MODE_PREVIEW);
Fragment newFragment = null;
if (PreviewMediaFragment.canBePreviewed(mFile) && mode == MODE_PREVIEW) {
if (mFile.isDown()) {
newFragment = new PreviewMediaFragment(mFile, mAccount);
} else {
newFragment = new FileDetailFragment(mFile, mAccount);
mWaitingToPreview = true;
}
} else {
newFragment = new FileDetailFragment(mFile, mAccount);
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment, newFragment, FileDetailFragment.FTAG);
ft.commit();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
}
@Override
public void onPause() {
super.onPause();
if (mDownloadFinishReceiver != null) {
unregisterReceiver(mDownloadFinishReceiver);
mDownloadFinishReceiver = null;
}
}
@Override
public void onResume() {
super.onResume();
if (!mConfigurationChangedToLandscape) {
// TODO this is probably unnecessary
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
if (fragment != null && fragment instanceof FileDetailFragment) {
((FileDetailFragment) fragment).updateFileDetails(false, false);
}
}
// Listen for download messages
IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_ADDED_MESSAGE);
downloadIntentFilter.addAction(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
mDownloadFinishReceiver = new DownloadFinishReceiver();
registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
}
/** Defines callbacks for service binding, passed to bindService() */
private class DetailsServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
if (component.equals(new ComponentName(FileDetailActivity.this, FileDownloader.class))) {
Log.d(TAG, "Download service connected");
mDownloaderBinder = (FileDownloaderBinder) service;
if (mWaitingToPreview) {
requestForDownload();
}
} else if (component.equals(new ComponentName(FileDetailActivity.this, FileUploader.class))) {
Log.d(TAG, "Upload service connected");
mUploaderBinder = (FileUploaderBinder) service;
} else {
return;
}
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
FileDetailFragment detailsFragment = (fragment instanceof FileDetailFragment) ? (FileDetailFragment) fragment : null;
if (detailsFragment != null) {
detailsFragment.listenForTransferProgress();
detailsFragment.updateFileDetails(mWaitingToPreview, false); // let the fragment gets the mDownloadBinder through getDownloadBinder() (see FileDetailFragment#updateFileDetais())
}
}
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(FileDetailActivity.this, FileDownloader.class))) {
Log.d(TAG, "Download service disconnected");
mDownloaderBinder = null;
} else if (component.equals(new ComponentName(FileDetailActivity.this, FileUploader.class))) {
Log.d(TAG, "Upload service disconnected");
mUploaderBinder = null;
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
if (mDownloadConnection != null) {
unbindService(mDownloadConnection);
mDownloadConnection = null;
}
if (mUploadConnection != null) {
unbindService(mUploadConnection);
mUploadConnection = null;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean returnValue = false;
switch(item.getItemId()){
case android.R.id.home:
backToDisplayActivity(true);
returnValue = true;
break;
default:
returnValue = super.onOptionsItemSelected(item);
}
return returnValue;
}
private void backToDisplayActivity(boolean moveToParent) {
Intent intent = new Intent(this, FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
OCFile targetFile = null;
if (mFile != null) {
targetFile = moveToParent ? mStorageManager.getFileById(mFile.getParentId()) : mFile;
}
intent.putExtra(FileDetailFragment.EXTRA_FILE, targetFile);
intent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
startActivity(intent);
finish();
}
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case DIALOG_SHORT_WAIT: {
ProgressDialog working_dialog = new ProgressDialog(this);
working_dialog.setMessage(getResources().getString(
R.string.wait_a_moment));
working_dialog.setIndeterminate(true);
working_dialog.setCancelable(false);
dialog = working_dialog;
break;
}
default:
dialog = null;
}
return dialog;
}
/**
* {@inheritDoc}
*/
@Override
public void onFileStateChanged() {
// nothing to do here!
}
/**
* {@inheritDoc}
*/
@Override
public FileDownloaderBinder getFileDownloaderBinder() {
return mDownloaderBinder;
}
@Override
public FileUploaderBinder getFileUploaderBinder() {
return mUploaderBinder;
}
@Override
public void showFragmentWithDetails(OCFile file) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, new FileDetailFragment(file, mAccount), FileDetailFragment.FTAG);
transaction.commit();
}
private void requestForDownload() {
if (!mDownloaderBinder.isDownloading(mAccount, mFile)) {
Intent i = new Intent(this, FileDownloader.class);
i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
i.putExtra(FileDownloader.EXTRA_FILE, mFile);
startService(i);
}
}
/**
* Class waiting for broadcast events from the {@link FielDownloader} service.
*
* Updates the UI when a download is started or finished, provided that it is relevant for the
* current file.
*/
private class DownloadFinishReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
boolean sameAccount = isSameAccount(context, intent);
String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
boolean samePath = (mFile != null && mFile.getRemotePath().equals(downloadedRemotePath));
if (sameAccount && samePath) {
updateChildFragment(intent.getAction(), downloadedRemotePath, intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
}
removeStickyBroadcast(intent);
}
private boolean isSameAccount(Context context, Intent intent) {
String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
return (accountName != null && accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name));
}
}
public void updateChildFragment(String downloadEvent, String downloadedRemotePath, boolean success) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
if (fragment != null && fragment instanceof FileDetailFragment) {
FileDetailFragment detailsFragment = (FileDetailFragment) fragment;
OCFile fileInFragment = detailsFragment.getFile();
if (fileInFragment != null && !downloadedRemotePath.equals(fileInFragment.getRemotePath())) {
// this never should happen; fileInFragment should be always equals to mFile, that was compared to downloadedRemotePath in DownloadReceiver
mWaitingToPreview = false;
} else if (downloadEvent.equals(FileDownloader.DOWNLOAD_ADDED_MESSAGE)) {
// grants that the progress bar is updated
detailsFragment.listenForTransferProgress();
detailsFragment.updateFileDetails(true, false);
} else if (downloadEvent.equals(FileDownloader.DOWNLOAD_FINISH_MESSAGE)) {
// refresh the details fragment
if (success && mWaitingToPreview) {
mFile = mStorageManager.getFileById(mFile.getFileId()); // update the file from database, for the local storage path
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, new PreviewMediaFragment(mFile, mAccount), FileDetailFragment.FTAG);
transaction.commit();
mWaitingToPreview = false;
} else {
detailsFragment.updateFileDetails(false, (success));
// TODO error message if !success ¿?
}
}
} // TODO else if (fragment != null && fragment )
}
}
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.activity;
import android.accounts.Account;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
/**
* This activity displays the details of a file like its name, its size and so
* on.
*
* @author Bartek Przybylski
* @author David A. Velasco
*/
public class FileDetailActivity extends SherlockFragmentActivity implements FileFragment.ContainerActivity {
public static final int DIALOG_SHORT_WAIT = 0;
public static final String TAG = FileDetailActivity.class.getSimpleName();
public static final String EXTRA_MODE = "MODE";
public static final int MODE_DETAILS = 0;
public static final int MODE_PREVIEW = 1;
public static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
private boolean mConfigurationChangedToLandscape = false;
private FileDownloaderBinder mDownloaderBinder = null;
private ServiceConnection mDownloadConnection, mUploadConnection = null;
private FileUploaderBinder mUploaderBinder = null;
private boolean mWaitingToPreview;
private OCFile mFile;
private Account mAccount;
private FileDataStorageManager mStorageManager;
private DownloadFinishReceiver mDownloadFinishReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFile = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
mAccount = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
// check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity
Configuration conf = getResources().getConfiguration();
mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE &&
(conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
);
if (!mConfigurationChangedToLandscape) {
setContentView(R.layout.file_activity_details);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
if (savedInstanceState == null) {
mWaitingToPreview = false;
createChildFragment();
} else {
mWaitingToPreview = savedInstanceState.getBoolean(KEY_WAITING_TO_PREVIEW);
}
mDownloadConnection = new DetailsServiceConnection();
bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
mUploadConnection = new DetailsServiceConnection();
bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
} else {
backToDisplayActivity(false); // the 'back' won't be effective until this.onStart() and this.onResume() are completed;
}
}
/**
* Creates the proper fragment depending upon the state of the handled {@link OCFile} and
* the requested {@link Intent}.
*/
private void createChildFragment() {
int mode = getIntent().getIntExtra(EXTRA_MODE, MODE_PREVIEW);
Fragment newFragment = null;
if (PreviewMediaFragment.canBePreviewed(mFile) && mode == MODE_PREVIEW) {
if (mFile.isDown()) {
newFragment = new PreviewMediaFragment(mFile, mAccount);
} else {
newFragment = new FileDetailFragment(mFile, mAccount);
mWaitingToPreview = true;
}
} else {
newFragment = new FileDetailFragment(mFile, mAccount);
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment, newFragment, FileDetailFragment.FTAG);
ft.commit();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
}
@Override
public void onPause() {
super.onPause();
if (mDownloadFinishReceiver != null) {
unregisterReceiver(mDownloadFinishReceiver);
mDownloadFinishReceiver = null;
}
}
@Override
public void onResume() {
super.onResume();
if (!mConfigurationChangedToLandscape) {
// TODO this is probably unnecessary
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
if (fragment != null && fragment instanceof FileDetailFragment) {
((FileDetailFragment) fragment).updateFileDetails(false, false);
}
}
// Listen for download messages
IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_ADDED_MESSAGE);
downloadIntentFilter.addAction(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
mDownloadFinishReceiver = new DownloadFinishReceiver();
registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
}
/** Defines callbacks for service binding, passed to bindService() */
private class DetailsServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
if (component.equals(new ComponentName(FileDetailActivity.this, FileDownloader.class))) {
Log_OC.d(TAG, "Download service connected");
mDownloaderBinder = (FileDownloaderBinder) service;
if (mWaitingToPreview) {
requestForDownload();
}
} else if (component.equals(new ComponentName(FileDetailActivity.this, FileUploader.class))) {
Log_OC.d(TAG, "Upload service connected");
mUploaderBinder = (FileUploaderBinder) service;
} else {
return;
}
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
FileDetailFragment detailsFragment = (fragment instanceof FileDetailFragment) ? (FileDetailFragment) fragment : null;
if (detailsFragment != null) {
detailsFragment.listenForTransferProgress();
detailsFragment.updateFileDetails(mWaitingToPreview, false); // let the fragment gets the mDownloadBinder through getDownloadBinder() (see FileDetailFragment#updateFileDetais())
}
}
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(FileDetailActivity.this, FileDownloader.class))) {
Log_OC.d(TAG, "Download service disconnected");
mDownloaderBinder = null;
} else if (component.equals(new ComponentName(FileDetailActivity.this, FileUploader.class))) {
Log_OC.d(TAG, "Upload service disconnected");
mUploaderBinder = null;
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
if (mDownloadConnection != null) {
unbindService(mDownloadConnection);
mDownloadConnection = null;
}
if (mUploadConnection != null) {
unbindService(mUploadConnection);
mUploadConnection = null;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean returnValue = false;
switch(item.getItemId()){
case android.R.id.home:
backToDisplayActivity(true);
returnValue = true;
break;
default:
returnValue = super.onOptionsItemSelected(item);
}
return returnValue;
}
private void backToDisplayActivity(boolean moveToParent) {
Intent intent = new Intent(this, FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
OCFile targetFile = null;
if (mFile != null) {
targetFile = moveToParent ? mStorageManager.getFileById(mFile.getParentId()) : mFile;
}
intent.putExtra(FileDetailFragment.EXTRA_FILE, targetFile);
intent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
startActivity(intent);
finish();
}
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case DIALOG_SHORT_WAIT: {
ProgressDialog working_dialog = new ProgressDialog(this);
working_dialog.setMessage(getResources().getString(
R.string.wait_a_moment));
working_dialog.setIndeterminate(true);
working_dialog.setCancelable(false);
dialog = working_dialog;
break;
}
default:
dialog = null;
}
return dialog;
}
/**
* {@inheritDoc}
*/
@Override
public void onFileStateChanged() {
// nothing to do here!
}
/**
* {@inheritDoc}
*/
@Override
public FileDownloaderBinder getFileDownloaderBinder() {
return mDownloaderBinder;
}
@Override
public FileUploaderBinder getFileUploaderBinder() {
return mUploaderBinder;
}
@Override
public void showFragmentWithDetails(OCFile file) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, new FileDetailFragment(file, mAccount), FileDetailFragment.FTAG);
transaction.commit();
}
private void requestForDownload() {
if (!mDownloaderBinder.isDownloading(mAccount, mFile)) {
Intent i = new Intent(this, FileDownloader.class);
i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
i.putExtra(FileDownloader.EXTRA_FILE, mFile);
startService(i);
}
}
/**
* Class waiting for broadcast events from the {@link FielDownloader} service.
*
* Updates the UI when a download is started or finished, provided that it is relevant for the
* current file.
*/
private class DownloadFinishReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
boolean sameAccount = isSameAccount(context, intent);
String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
boolean samePath = (mFile != null && mFile.getRemotePath().equals(downloadedRemotePath));
if (sameAccount && samePath) {
updateChildFragment(intent.getAction(), downloadedRemotePath, intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
}
removeStickyBroadcast(intent);
}
private boolean isSameAccount(Context context, Intent intent) {
String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
return (accountName != null && accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name));
}
}
public void updateChildFragment(String downloadEvent, String downloadedRemotePath, boolean success) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
if (fragment != null && fragment instanceof FileDetailFragment) {
FileDetailFragment detailsFragment = (FileDetailFragment) fragment;
OCFile fileInFragment = detailsFragment.getFile();
if (fileInFragment != null && !downloadedRemotePath.equals(fileInFragment.getRemotePath())) {
// this never should happen; fileInFragment should be always equals to mFile, that was compared to downloadedRemotePath in DownloadReceiver
mWaitingToPreview = false;
} else if (downloadEvent.equals(FileDownloader.DOWNLOAD_ADDED_MESSAGE)) {
// grants that the progress bar is updated
detailsFragment.listenForTransferProgress();
detailsFragment.updateFileDetails(true, false);
} else if (downloadEvent.equals(FileDownloader.DOWNLOAD_FINISH_MESSAGE)) {
// refresh the details fragment
if (success && mWaitingToPreview) {
mFile = mStorageManager.getFileById(mFile.getFileId()); // update the file from database, for the local storage path
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, new PreviewMediaFragment(mFile, mAccount), FileDetailFragment.FTAG);
transaction.commit();
mWaitingToPreview = false;
} else {
detailsFragment.updateFileDetails(false, (success));
// TODO error message if !success ¿?
}
}
} // TODO else if (fragment != null && fragment )
}
}

View file

@ -38,11 +38,8 @@ import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@ -67,6 +64,8 @@ import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
@ -97,7 +96,6 @@ import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.R;
import eu.alefzero.webdav.WebdavClient;
/**
@ -130,7 +128,6 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
private static final int DIALOG_SETUP_ACCOUNT = 0;
private static final int DIALOG_CREATE_DIR = 1;
private static final int DIALOG_ABOUT_APP = 2;
public static final int DIALOG_SHORT_WAIT = 3;
private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 4;
private static final int DIALOG_SSL_VALIDATOR = 5;
@ -143,15 +140,12 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
private static final String TAG = "FileDisplayActivity";
private static int[] mMenuIdentifiersToPatch = {R.id.action_about_app};
private OCFile mWaitingToPreview;
private Handler mHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(getClass().toString(), "onCreate() start");
Log_OC.d(getClass().toString(), "onCreate() start");
super.onCreate(savedInstanceState);
/// Load of parameters from received intent
@ -244,7 +238,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
//showChangeLog();
mBackFromCreatingFirstAccount = false;
Log.d(getClass().toString(), "onCreate() end");
Log_OC.d(getClass().toString(), "onCreate() end");
}
@ -355,31 +349,9 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
MenuInflater inflater = getSherlock().getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
patchHiddenAccents(menu);
return true;
}
/**
* Workaround for this: <a href="http://code.google.com/p/android/issues/detail?id=3974">http://code.google.com/p/android/issues/detail?id=3974</a>
*
* @param menu Menu to patch
*/
private void patchHiddenAccents(Menu menu) {
for (int i = 0; i < mMenuIdentifiersToPatch.length ; i++) {
MenuItem aboutItem = menu.findItem(mMenuIdentifiersToPatch[i]);
if (aboutItem != null && aboutItem.getIcon() instanceof BitmapDrawable) {
// Clip off the bottom three (density independent) pixels of transparent padding
Bitmap original = ((BitmapDrawable) aboutItem.getIcon()).getBitmap();
float scale = getResources().getDisplayMetrics().density;
int clippedHeight = (int) (original.getHeight() - (3 * scale));
Bitmap scaled = Bitmap.createBitmap(original, 0, 0, original.getWidth(), clippedHeight);
aboutItem.setIcon(new BitmapDrawable(getResources(), scaled));
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean retval = true;
@ -402,10 +374,6 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
startActivity(settingsIntent);
break;
}
case R.id.action_about_app: {
showDialog(DIALOG_ABOUT_APP);
break;
}
case android.R.id.home: {
if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
onBackPressed();
@ -480,7 +448,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
startService(i);
} else {
Log.d("FileDisplay", "User clicked on 'Update' with no selection");
Log_OC.d("FileDisplay", "User clicked on 'Update' with no selection");
Toast t = Toast.makeText(this, getString(R.string.filedisplay_no_file_selected), Toast.LENGTH_LONG);
t.show();
return;
@ -502,12 +470,12 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
filepath = filemanagerstring;
} catch (Exception e) {
Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
Log_OC.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
e.printStackTrace();
} finally {
if (filepath == null) {
Log.e("FileDisplay", "Couldnt resolve path to file");
Log_OC.e("FileDisplay", "Couldnt resolve path to file");
Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
t.show();
return;
@ -563,7 +531,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
@Override
protected void onSaveInstanceState(Bundle outState) {
// responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
Log.d(getClass().toString(), "onSaveInstanceState() start");
Log_OC.d(getClass().toString(), "onSaveInstanceState() start");
super.onSaveInstanceState(outState);
outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);
if (mDualPane) {
@ -576,13 +544,13 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
}
}
outState.putParcelable(FileDetailActivity.KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
Log.d(getClass().toString(), "onSaveInstanceState() end");
Log_OC.d(getClass().toString(), "onSaveInstanceState() end");
}
@Override
public void onResume() {
Log.d(getClass().toString(), "onResume() start");
protected void onResume() {
Log_OC.d(getClass().toString(), "onResume() start");
super.onResume();
if (AccountUtils.accountsAreSetup(this)) {
@ -621,13 +589,13 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
showDialog(DIALOG_SETUP_ACCOUNT);
}
Log.d(getClass().toString(), "onResume() end");
Log_OC.d(getClass().toString(), "onResume() end");
}
@Override
public void onPause() {
Log.d(getClass().toString(), "onPause() start");
protected void onPause() {
Log_OC.d(getClass().toString(), "onPause() start");
super.onPause();
if (mSyncBroadcastReceiver != null) {
unregisterReceiver(mSyncBroadcastReceiver);
@ -645,7 +613,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
dismissDialog(DIALOG_SETUP_ACCOUNT);
}
Log.d(getClass().toString(), "onPause() end");
Log_OC.d(getClass().toString(), "onPause() end");
}
@ -684,22 +652,6 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
dialog = builder.create();
break;
}
case DIALOG_ABOUT_APP: {
builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.about_title));
PackageInfo pkg;
try {
pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
builder.setMessage(String.format(getString(R.string.about_message), getString(R.string.app_name), pkg.versionName));
builder.setIcon(android.R.drawable.ic_menu_info_details);
dialog = builder.create();
} catch (NameNotFoundException e) {
builder = null;
dialog = null;
Log.e(TAG, "Error while showing about dialog", e);
}
break;
}
case DIALOG_CREATE_DIR: {
builder = new Builder(this);
final EditText dirNameInput = new EditText(getBaseContext());
@ -909,7 +861,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
msg.show();
} catch (NotFoundException e) {
Log.e(TAG, "Error while trying to show fail message " , e);
Log_OC.e(TAG, "Error while trying to show fail message ", e);
}
}
});
@ -952,13 +904,10 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
*/
@Override
public void onReceive(Context context, Intent intent) {
boolean inProgress = intent.getBooleanExtra(
FileSyncService.IN_PROGRESS, false);
String accountName = intent
.getStringExtra(FileSyncService.ACCOUNT_NAME);
boolean inProgress = intent.getBooleanExtra(FileSyncService.IN_PROGRESS, false);
String accountName = intent.getStringExtra(FileSyncService.ACCOUNT_NAME);
Log.d("FileDisplay", "sync of account " + accountName
+ " is in_progress: " + inProgress);
Log_OC.d("FileDisplay", "sync of account " + accountName + " is in_progress: " + inProgress);
if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {
@ -1252,14 +1201,14 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
Log.d(TAG, "Download service connected");
Log_OC.d(TAG, "Download service connected");
mDownloaderBinder = (FileDownloaderBinder) service;
if (mWaitingToPreview != null) {
requestForDownload();
}
} else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
Log.d(TAG, "Upload service connected");
Log_OC.d(TAG, "Upload service connected");
mUploaderBinder = (FileUploaderBinder) service;
} else {
return;
@ -1280,10 +1229,10 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
Log.d(TAG, "Download service disconnected");
Log_OC.d(TAG, "Download service disconnected");
mDownloaderBinder = null;
} else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
Log.d(TAG, "Upload service disconnected");
Log_OC.d(TAG, "Upload service disconnected");
mUploaderBinder = null;
}
}

View file

@ -44,6 +44,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.db.DbHandler;
import com.owncloud.android.files.InstantUploadBroadcastReceiver;
@ -132,7 +133,7 @@ public class InstantUploadActivity extends Activity {
rowLayout.addView(getImageButton(imp_path, lastLoadImageIdx));
rowLayout.addView(getFileButton(imp_path, message, lastLoadImageIdx));
listView.addView(rowLayout);
Log.d(LOG_TAG, imp_path + " on idx: " + lastLoadImageIdx);
Log_OC.d(LOG_TAG, imp_path + " on idx: " + lastLoadImageIdx);
if (lastLoadImageIdx % MAX_LOAD_IMAGES == 0) {
break;
}
@ -183,12 +184,12 @@ public class InstantUploadActivity extends Activity {
private List<CheckBox> getCheckboxList() {
List<CheckBox> list = new ArrayList<CheckBox>();
for (int i = 0; i < listView.getChildCount(); i++) {
Log.d(LOG_TAG, "ListView has Childs: " + listView.getChildCount());
Log_OC.d(LOG_TAG, "ListView has Childs: " + listView.getChildCount());
View childView = listView.getChildAt(i);
if (childView != null && childView instanceof ViewGroup) {
View checkboxView = getChildViews((ViewGroup) childView);
if (checkboxView != null && checkboxView instanceof CheckBox) {
Log.d(LOG_TAG, "found Child: " + checkboxView.getId() + " " + checkboxView.getClass());
Log_OC.d(LOG_TAG, "found Child: " + checkboxView.getId() + " " + checkboxView.getClass());
list.add((CheckBox) checkboxView);
}
}
@ -251,12 +252,12 @@ public class InstantUploadActivity extends Activity {
for (CheckBox checkbox : list) {
boolean to_retry = checkbox.isChecked();
Log.d(LOG_TAG, "Checkbox for " + checkbox.getId() + " was checked: " + to_retry);
Log_OC.d(LOG_TAG, "Checkbox for " + checkbox.getId() + " was checked: " + to_retry);
String img_path = fileList.get(checkbox.getId());
if (to_retry) {
final String msg = "Image-Path " + checkbox.getId() + " was checked: " + img_path;
Log.d(LOG_TAG, msg);
Log_OC.d(LOG_TAG, msg);
startUpload(img_path);
}
@ -292,12 +293,12 @@ public class InstantUploadActivity extends Activity {
for (CheckBox checkbox : list) {
boolean to_be_delete = checkbox.isChecked();
Log.d(LOG_TAG, "Checkbox for " + checkbox.getId() + " was checked: " + to_be_delete);
Log_OC.d(LOG_TAG, "Checkbox for " + checkbox.getId() + " was checked: " + to_be_delete);
String img_path = fileList.get(checkbox.getId());
Log.d(LOG_TAG, "Image-Path " + checkbox.getId() + " was checked: " + img_path);
Log_OC.d(LOG_TAG, "Image-Path " + checkbox.getId() + " was checked: " + img_path);
if (to_be_delete) {
boolean deleted = dbh.removeIUPendingFile(img_path);
Log.d(LOG_TAG, "removing " + checkbox.getId() + " was : " + deleted);
Log_OC.d(LOG_TAG, "removing " + checkbox.getId() + " was : " + deleted);
}
@ -391,7 +392,7 @@ public class InstantUploadActivity extends Activity {
// scale and add a thumbnail to the imagebutton
int base_scale_size = 32;
if (img_path != null) {
Log.d(LOG_TAG, "add " + img_path + " to Image Button");
Log_OC.d(LOG_TAG, "add " + img_path + " to Image Button");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(img_path, options);
@ -406,16 +407,16 @@ public class InstantUploadActivity extends Activity {
scale++;
}
Log.d(LOG_TAG, "scale Imgae with: " + scale);
Log_OC.d(LOG_TAG, "scale Imgae with: " + scale);
BitmapFactory.Options options2 = new BitmapFactory.Options();
options2.inSampleSize = scale;
bitmap = BitmapFactory.decodeFile(img_path, options2);
if (bitmap != null) {
Log.d(LOG_TAG, "loaded Bitmap Bytes: " + bitmap.getRowBytes());
Log_OC.d(LOG_TAG, "loaded Bitmap Bytes: " + bitmap.getRowBytes());
imageButton.setImageBitmap(bitmap);
} else {
Log.d(LOG_TAG, "could not load imgage: " + img_path);
Log_OC.d(LOG_TAG, "could not load imgage: " + img_path);
}
}
return imageButton;
@ -459,7 +460,7 @@ public class InstantUploadActivity extends Activity {
i.putExtra(com.owncloud.android.files.services.FileUploader.KEY_INSTANT_UPLOAD, true);
final String msg = "try to upload file with name :" + filename;
Log.d(LOG_TAG, msg);
Log_OC.d(LOG_TAG, msg);
Toast toast = Toast.makeText(InstantUploadActivity.this, getString(R.string.failed_upload_retry_text)
+ filename, Toast.LENGTH_LONG);
toast.show();

View file

@ -0,0 +1,119 @@
/* ownCloud Android client application
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.activity;
import java.io.File;
import java.util.ArrayList;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.R;
import com.owncloud.android.ui.adapter.LogListAdapter;
import com.owncloud.android.utils.FileStorageUtils;
public class LogHistoryActivity extends SherlockPreferenceActivity implements OnPreferenceChangeListener {
String logpath = FileStorageUtils.getLogPath();
File logDIR = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.log_send_file);
setTitle("Log History");
ActionBar actionBar = getSherlock().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
ListView listView = (ListView) findViewById(android.R.id.list);
Button deleteHistoryButton = (Button) findViewById(R.id.deleteLogHistoryButton);
deleteHistoryButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
File dir = new File(logpath);
if (dir != null) {
File[] files = dir.listFiles();
if(files!=null) {
for(File f: files) {
f.delete();
}
}
dir.delete();
}
Intent intent = new Intent(getBaseContext(), Preferences.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
if(logpath != null){
logDIR = new File(logpath);
}
if(logDIR != null && logDIR.isDirectory()) {
File[] files = logDIR.listFiles();
if (files != null && files.length != 0) {
ArrayList<String> logfiles_name = new ArrayList<String>();
for (File file : files) {
logfiles_name.add(file.getName());
}
String[] logFiles2Array = logfiles_name.toArray(new String[logfiles_name.size()]);
LogListAdapter listadapter = new LogListAdapter(this,logFiles2Array);
listView.setAdapter(listadapter);
}
}
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
super.onMenuItemSelected(featureId, item);
Intent intent;
switch (item.getItemId()) {
case android.R.id.home:
intent = new Intent(getBaseContext(), Preferences.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
default:
return false;
}
return true;
}
@Override
public boolean onPreferenceChange(Preference arg0, Object arg1) {
return false;
}
}

View file

@ -1,237 +1,241 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.activity;
import java.util.Vector;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.OwnCloudSession;
import com.owncloud.android.db.DbHandler;
import com.owncloud.android.R;
/**
* An Activity that allows the user to change the application's settings.
*
* @author Bartek Przybylski
*
*/
public class Preferences extends SherlockPreferenceActivity implements
OnPreferenceChangeListener{
private static final String TAG = "OwnCloudPreferences";
private final int mNewSession = 47;
private final int mEditSession = 48;
private DbHandler mDbHandler;
private Vector<OwnCloudSession> mSessions;
//private Account[] mAccounts;
//private ListPreference mAccountList;
private ListPreference mTrackingUpdateInterval;
private CheckBoxPreference mDeviceTracking;
private CheckBoxPreference pCode;
private int mSelectedMenuItem;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbHandler = new DbHandler(getBaseContext());
mSessions = new Vector<OwnCloudSession>();
addPreferencesFromResource(R.xml.preferences);
//populateAccountList();
ActionBar actionBar = getSherlock().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
Preference p = findPreference("manage_account");
if (p != null)
p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent i = new Intent(getApplicationContext(), AccountSelectActivity.class);
startActivity(i);
return true;
}
});
pCode = (CheckBoxPreference) findPreference("set_pincode");
if (pCode != null){
pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "preferences");
i.putExtra(PinCodeActivity.EXTRA_NEW_STATE, newValue.toString());
startActivity(i);
return true;
}
});
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
SharedPreferences appPrefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
boolean state = appPrefs.getBoolean("set_pincode", false);
pCode.setChecked(state);
super.onResume();
}
/**
* Populates the account selector
*-/
private void populateAccountList() {
AccountManager accMan = AccountManager.get(this);
mAccounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
mAccountList = (ListPreference) findPreference("select_oc_account");
mAccountList.setOnPreferenceChangeListener(this);
// Display the name of the current account if there is any
Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);
if (defaultAccount != null) {
mAccountList.setSummary(defaultAccount.name);
}
// Transform accounts into array of string for preferences to use
String[] accNames = new String[mAccounts.length];
for (int i = 0; i < mAccounts.length; i++) {
Account account = mAccounts[i];
accNames[i] = account.name;
}
mAccountList.setEntries(accNames);
mAccountList.setEntryValues(accNames);
}*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//MenuInflater inflater = getSherlock().getMenuInflater();
//inflater.inflate(R.menu.prefs_menu, menu);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
super.onMenuItemSelected(featureId, item);
Intent intent;
switch (item.getItemId()) {
//case R.id.addSessionItem:
case 1:
intent = new Intent(this, PreferencesNewSession.class);
startActivityForResult(intent, mNewSession);
break;
case R.id.SessionContextEdit:
intent = new Intent(this, PreferencesNewSession.class);
intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem)
.getEntryId());
intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem)
.getName());
intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem)
.getUrl());
startActivityForResult(intent, mEditSession);
break;
case android.R.id.home:
intent = new Intent(getBaseContext(), FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
default:
Log.w(TAG, "Unknown menu item triggered");
return false;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
mDbHandler.close();
super.onDestroy();
}
@Override
/**
* Updates various summaries after updates. Also starts and stops
* the
*/
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Update current account summary
/*if (preference.equals(mAccountList)) {
mAccountList.setSummary(newValue.toString());
}
// Update tracking interval summary
else*/ if (preference.equals(mTrackingUpdateInterval)) {
String trackingSummary = getResources().getString(
R.string.prefs_trackmydevice_interval_summary);
trackingSummary = String.format(trackingSummary,
newValue.toString());
mTrackingUpdateInterval.setSummary(trackingSummary);
}
// Start or stop tracking service
else if (preference.equals(mDeviceTracking)) {
Intent locationServiceIntent = new Intent();
locationServiceIntent
.setAction("com.owncloud.android.location.LocationLauncher");
locationServiceIntent.putExtra("TRACKING_SETTING",
(Boolean) newValue);
sendBroadcast(locationServiceIntent);
}
return true;
}
}
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.activity;
import java.io.File;
import java.util.Vector;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Environment;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceManager;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.Log_OC;
import com.owncloud.android.OwnCloudSession;
import com.owncloud.android.R;
import com.owncloud.android.db.DbHandler;
/**
* An Activity that allows the user to change the application's settings.
*
* @author Bartek Przybylski
*
*/
public class Preferences extends SherlockPreferenceActivity implements OnPreferenceChangeListener {
private static final String TAG = "OwnCloudPreferences";
private final int mNewSession = 47;
private final int mEditSession = 48;
private DbHandler mDbHandler;
private Vector<OwnCloudSession> mSessions;
private ListPreference mTrackingUpdateInterval;
private CheckBoxPreference mDeviceTracking;
private CheckBoxPreference pCode;
private CheckBoxPreference pLogging;
private Preference pLoggingHistory;
private Preference pAboutApp;
private int mSelectedMenuItem;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbHandler = new DbHandler(getBaseContext());
mSessions = new Vector<OwnCloudSession>();
addPreferencesFromResource(R.xml.preferences);
//populateAccountList();
ActionBar actionBar = getSherlock().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
Preference p = findPreference("manage_account");
if (p != null)
p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent i = new Intent(getApplicationContext(), AccountSelectActivity.class);
startActivity(i);
return true;
}
});
pCode = (CheckBoxPreference) findPreference("set_pincode");
if (pCode != null){
pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "preferences");
i.putExtra(PinCodeActivity.EXTRA_NEW_STATE, newValue.toString());
startActivity(i);
return true;
}
});
/* About App */
pAboutApp = (Preference) findPreference("about_app");
if (pAboutApp != null) {
pAboutApp.setTitle(String.format(getString(R.string.about_android), getString(R.string.app_name)));
PackageInfo pkg;
try {
pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
pAboutApp.setSummary(String.format(getString(R.string.about_version), pkg.versionName));
} catch (NameNotFoundException e) {
Log_OC.e(TAG, "Error while showing about dialog", e);
}
}
pLogging = (CheckBoxPreference) findPreference("log_to_file");
if (pLogging != null) {
pLogging.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String logpath = Environment.getExternalStorageDirectory()+File.separator+"owncloud"+File.separator+"log";
if(!pLogging.isChecked()) {
Log_OC.d("Debug", "start logging");
Log_OC.v("PATH", logpath);
Log_OC.startLogging(logpath);
}
else {
Log_OC.d("Debug", "stop logging");
Log_OC.stopLogging();
}
return true;
}
});
}
pLoggingHistory = (Preference) findPreference("log_history");
if (pLoggingHistory != null) {
pLoggingHistory.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(getApplicationContext(),LogHistoryActivity.class);
startActivity(intent);
return true;
}
});
}
}
}
@Override
protected void onResume() {
SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean state = appPrefs.getBoolean("set_pincode", false);
pCode.setChecked(state);
super.onResume();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
super.onMenuItemSelected(featureId, item);
Intent intent;
switch (item.getItemId()) {
//case R.id.addSessionItem:
case 1:
intent = new Intent(this, PreferencesNewSession.class);
startActivityForResult(intent, mNewSession);
break;
case R.id.SessionContextEdit:
intent = new Intent(this, PreferencesNewSession.class);
intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem)
.getEntryId());
intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem)
.getName());
intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem)
.getUrl());
startActivityForResult(intent, mEditSession);
break;
case android.R.id.home:
intent = new Intent(getBaseContext(), FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
default:
Log_OC.w(TAG, "Unknown menu item triggered");
return false;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
mDbHandler.close();
super.onDestroy();
}
@Override
/**
* Updates various summaries after updates. Also starts and stops
* the
*/
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Update current account summary
/*if (preference.equals(mAccountList)) {
mAccountList.setSummary(newValue.toString());
}
// Update tracking interval summary
else*/ if (preference.equals(mTrackingUpdateInterval)) {
String trackingSummary = getResources().getString(
R.string.prefs_trackmydevice_interval_summary);
trackingSummary = String.format(trackingSummary,
newValue.toString());
mTrackingUpdateInterval.setSummary(trackingSummary);
}
// Start or stop tracking service
else if (preference.equals(mDeviceTracking)) {
Intent locationServiceIntent = new Intent();
locationServiceIntent
.setAction("com.owncloud.android.location.LocationLauncher");
locationServiceIntent.putExtra("TRACKING_SETTING",
(Boolean) newValue);
sendBroadcast(locationServiceIntent);
}
return true;
}
}

View file

@ -44,6 +44,7 @@ import com.owncloud.android.ui.fragment.LocalFileListFragment;
import com.owncloud.android.ui.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
/**
@ -78,7 +79,7 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate() start");
Log_OC.d(TAG, "onCreate() start");
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
@ -125,7 +126,7 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
mCurrentDialog = null;
}
Log.d(TAG, "onCreate() end");
Log_OC.d(TAG, "onCreate() end");
}
@ -181,10 +182,10 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
@Override
protected void onSaveInstanceState(Bundle outState) {
// responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
Log.d(TAG, "onSaveInstanceState() start");
Log_OC.d(TAG, "onSaveInstanceState() start");
super.onSaveInstanceState(outState);
outState.putString(UploadFilesActivity.KEY_DIRECTORY_PATH, mCurrentDir.getAbsolutePath());
Log.d(TAG, "onSaveInstanceState() end");
Log_OC.d(TAG, "onSaveInstanceState() end");
}
@ -354,7 +355,7 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
@Override
public void onConfirmation(String callerTag) {
Log.d(TAG, "Positive button in dialog was clicked; dialog tag is " + callerTag);
Log_OC.d(TAG, "Positive button in dialog was clicked; dialog tag is " + callerTag);
if (callerTag.equals(QUERY_TO_MOVE_DIALOG_TAG)) {
// return the list of selected files to the caller activity (success), signaling that they should be moved to the ownCloud folder, instead of copied
Intent data = new Intent();
@ -367,14 +368,14 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
@Override
public void onNeutral(String callerTag) {
Log.d(TAG, "Phantom neutral button in dialog was clicked; dialog tag is " + callerTag);
Log_OC.d(TAG, "Phantom neutral button in dialog was clicked; dialog tag is " + callerTag);
}
@Override
public void onCancel(String callerTag) {
/// nothing to do; don't finish, let the user change the selection
Log.d(TAG, "Negative button in dialog was clicked; dialog tag is " + callerTag);
Log_OC.d(TAG, "Negative button in dialog was clicked; dialog tag is " + callerTag);
}

View file

@ -0,0 +1,54 @@
package com.owncloud.android.ui.adapter;
import java.io.File;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.owncloud.android.R;
public class LogListAdapter extends ArrayAdapter<String> {
private Context context = null;
private String[] values;
private Uri fileUri = null;
public LogListAdapter(Context context, String[] values) {
super(context, R.layout.log_item, values);
this.context = context;
this.values = values;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.log_item, parent, false);
TextView listText = (TextView) rowView.findViewById(R.id.log_item_single);
listText.setText(values[position]);
listText.setTextSize(15);
fileUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+File.separator+"owncloud"+File.separator+"log"+File.separator+values[position]));
listText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/rtf");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "OwnCloud Logfile");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "This is a automatic E-mail send by owncloud/android");
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, fileUri);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
});
return rowView;
}
}

View file

@ -38,6 +38,7 @@ import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.network.CertificateCombinedException;
import com.owncloud.android.network.OwnCloudClientUtils;
@ -110,13 +111,13 @@ public class SslValidatorDialog extends Dialog {
if (mListener != null)
mListener.onSavedCertificate();
else
Log.d(TAG, "Nobody there to notify the certificate was saved");
Log_OC.d(TAG, "Nobody there to notify the certificate was saved");
} catch (Exception e) {
dismiss();
if (mListener != null)
mListener.onFailedSavingCertificate();
Log.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
Log_OC.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
}
}
});

View file

@ -26,6 +26,7 @@ import android.os.Bundle;
import android.util.Log;
import com.actionbarsherlock.app.SherlockDialogFragment;
import com.owncloud.android.Log_OC;
public class ConfirmationDialogFragment extends SherlockDialogFragment {
@ -75,7 +76,7 @@ public class ConfirmationDialogFragment extends SherlockDialogFragment {
int negBtn = getArguments().getInt(ARG_NEGATIVE_BTN_RES, -1);
if (confirmationTarget == null || resourceId == -1) {
Log.wtf(getTag(), "Calling confirmation dialog without resource or arguments");
Log_OC.wtf(getTag(), "Calling confirmation dialog without resource or arguments");
return null;
}

File diff suppressed because it is too large Load diff

View file

@ -35,6 +35,7 @@ import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
/**
@ -76,10 +77,10 @@ public class LocalFileListFragment extends FragmentListView {
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG, "onCreateView() start");
Log_OC.i(TAG, "onCreateView() start");
View v = super.onCreateView(inflater, container, savedInstanceState);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Log.i(TAG, "onCreateView() end");
Log_OC.i(TAG, "onCreateView() end");
return v;
}
@ -89,30 +90,30 @@ public class LocalFileListFragment extends FragmentListView {
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG, "onActivityCreated() start");
Log_OC.i(TAG, "onActivityCreated() start");
super.onCreate(savedInstanceState);
mAdapter = new LocalFileListAdapter(mContainerActivity.getInitialDirectory(), getActivity());
setListAdapter(mAdapter);
if (savedInstanceState != null) {
Log.i(TAG, "savedInstanceState is not null");
Log_OC.i(TAG, "savedInstanceState is not null");
int position = savedInstanceState.getInt(SAVED_LIST_POSITION);
setReferencePosition(position);
}
Log.i(TAG, "onActivityCreated() stop");
Log_OC.i(TAG, "onActivityCreated() stop");
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onSaveInstanceState() start");
Log_OC.i(TAG, "onSaveInstanceState() start");
savedInstanceState.putInt(SAVED_LIST_POSITION, getReferencePosition());
Log.i(TAG, "onSaveInstanceState() stop");
Log_OC.i(TAG, "onSaveInstanceState() stop");
}
@ -144,7 +145,7 @@ public class LocalFileListFragment extends FragmentListView {
}
} else {
Log.w(TAG, "Null object in ListAdapter!!");
Log_OC.w(TAG, "Null object in ListAdapter!!");
}
}
@ -203,7 +204,7 @@ public class LocalFileListFragment extends FragmentListView {
// if that's not a directory -> List its parent
if(!directory.isDirectory()){
Log.w(TAG, "You see, that is not a directory -> " + directory.toString());
Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
directory = directory.getParentFile();
}
@ -225,7 +226,7 @@ public class LocalFileListFragment extends FragmentListView {
String [] result = null;
SparseBooleanArray positions = mList.getCheckedItemPositions();
if (positions.size() > 0) {
Log.d(TAG, "Returning " + positions.size() + " selected files");
Log_OC.d(TAG, "Returning " + positions.size() + " selected files");
result = new String[positions.size()];
for (int i=0; i<positions.size(); i++) {
result[i] = ((File) mList.getItemAtPosition(positions.keyAt(i))).getAbsolutePath();

View file

@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.List;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.OCFile;
@ -100,14 +101,14 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG, "onActivityCreated() start");
Log_OC.i(TAG, "onActivityCreated() start");
super.onActivityCreated(savedInstanceState);
mAdapter = new FileListListAdapter(mContainerActivity.getInitialDirectory(), mContainerActivity.getStorageManager(), getActivity(), mContainerActivity);
setListAdapter(mAdapter);
if (savedInstanceState != null) {
Log.i(TAG, "savedInstanceState is not null");
Log_OC.i(TAG, "savedInstanceState is not null");
int position = savedInstanceState.getInt(SAVED_LIST_POSITION);
setReferencePosition(position);
}
@ -117,18 +118,18 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
mHandler = new Handler();
Log.i(TAG, "onActivityCreated() stop");
Log_OC.i(TAG, "onActivityCreated() stop");
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onSaveInstanceState() start");
Log_OC.i(TAG, "onSaveInstanceState() start");
savedInstanceState.putInt(SAVED_LIST_POSITION, getReferencePosition());
Log.i(TAG, "onSaveInstanceState() stop");
Log_OC.i(TAG, "onSaveInstanceState() stop");
}
@ -149,7 +150,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
}
} else {
Log.d(TAG, "Null object in ListAdapter!!");
Log_OC.d(TAG, "Null object in ListAdapter!!");
}
}
@ -276,7 +277,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
startActivity(i);
} catch (Throwable t) {
Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mTargetFile.getMimetype());
Log_OC.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mTargetFile.getMimetype());
boolean toastIt = true;
String mimeType = "";
try {
@ -295,13 +296,13 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
}
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
Log_OC.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
} catch (Throwable th) {
Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);
Log_OC.e(TAG, "Unexpected problem when opening: " + storagePath, th);
} finally {
if (toastIt) {
@ -404,7 +405,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
// If that's not a directory -> List its parent
if(!directory.isDirectory()){
Log.w(TAG, "You see, that is not a directory -> " + directory.toString());
Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
directory = storageManager.getFileById(directory.getParentId());
}
@ -477,7 +478,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
public void onDismiss(EditNameDialog dialog) {
if (dialog.getResult()) {
String newFilename = dialog.getNewFilename();
Log.d(TAG, "name edit dialog dismissed with new name " + newFilename);
Log_OC.d(TAG, "name edit dialog dismissed with new name " + newFilename);
RemoteOperation operation = new RenameFileOperation(mTargetFile,
AccountUtils.getCurrentOwnCloudAccount(getActivity()),
newFilename,
@ -522,7 +523,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
@Override
public void onCancel(String callerTag) {
Log.d(TAG, "REMOVAL CANCELED");
Log_OC.d(TAG, "REMOVAL CANCELED");
}

View file

@ -65,6 +65,10 @@ public class FileStorageUtils {
}
}
public static final String getLogPath() {
return Environment.getExternalStorageDirectory() + File.separator + "owncloud" + File.separator + "log";
}
// to ensure we will not add the slash twice between filename and
// folder-name

View file

@ -30,12 +30,11 @@ import java.util.Set;
import org.apache.commons.httpclient.methods.RequestEntity;
import com.owncloud.android.Log_OC;
import com.owncloud.android.network.ProgressiveDataTransferer;
import eu.alefzero.webdav.OnDatatransferProgressListener;
import android.util.Log;
/**
* A RequestEntity that represents a PIECE of a file.
@ -136,7 +135,7 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
}
} catch (IOException io) {
Log.e(TAG, io.getMessage());
Log_OC.e(TAG, io.getMessage());
throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);
}

View file

@ -32,12 +32,11 @@ import java.util.Set;
import org.apache.commons.httpclient.methods.RequestEntity;
import com.owncloud.android.Log_OC;
import com.owncloud.android.network.ProgressiveDataTransferer;
import eu.alefzero.webdav.OnDatatransferProgressListener;
import android.util.Log;
/**
* A RequestEntity that represents a File.
@ -123,7 +122,7 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
}
} catch (IOException io) {
Log.e("FileRequestException", io.getMessage());
Log_OC.e("FileRequestException", io.getMessage());
throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);
} finally {

View file

@ -1,341 +1,342 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package eu.alefzero.webdav;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpStatus;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.jackrabbit.webdav.client.methods.DavMethod;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import android.net.Uri;
import android.util.Log;
public class WebdavClient extends HttpClient {
private Uri mUri;
private Credentials mCredentials;
final private static String TAG = "WebdavClient";
private static final String USER_AGENT = "Android-ownCloud";
private OnDatatransferProgressListener mDataTransferListener;
static private byte[] sExhaustBuffer = new byte[1024];
/**
* Constructor
*/
public WebdavClient(HttpConnectionManager connectionMgr) {
super(connectionMgr);
Log.d(TAG, "Creating WebdavClient");
getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);
getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
}
public void setCredentials(String username, String password) {
getParams().setAuthenticationPreemptive(true);
getState().setCredentials(AuthScope.ANY,
getCredentials(username, password));
}
private Credentials getCredentials(String username, String password) {
if (mCredentials == null)
mCredentials = new UsernamePasswordCredentials(username, password);
return mCredentials;
}
/**
* Downloads a file in remoteFilepath to the local targetPath.
*
* @param remoteFilepath Path to the file in the remote server, URL DECODED.
* @param targetFile Local path to save the downloaded file.
* @return 'True' when the file is successfully downloaded.
*/
public boolean downloadFile(String remoteFilePath, File targetFile) {
boolean ret = false;
GetMethod get = new GetMethod(mUri.toString() + WebdavUtils.encodePath(remoteFilePath));
try {
int status = executeMethod(get);
if (status == HttpStatus.SC_OK) {
targetFile.createNewFile();
BufferedInputStream bis = new BufferedInputStream(
get.getResponseBodyAsStream());
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] bytes = new byte[4096];
int readResult;
while ((readResult = bis.read(bytes)) != -1) {
if (mDataTransferListener != null)
mDataTransferListener.onTransferProgress(readResult);
fos.write(bytes, 0, readResult);
}
fos.close();
ret = true;
} else {
exhaustResponse(get.getResponseBodyAsStream());
}
Log.e(TAG, "Download of " + remoteFilePath + " to " + targetFile + " finished with HTTP status " + status + (!ret?"(FAIL)":""));
} catch (Exception e) {
logException(e, "dowloading " + remoteFilePath);
} finally {
if (!ret && targetFile.exists()) {
targetFile.delete();
}
get.releaseConnection(); // let the connection available for other methods
}
return ret;
}
/**
* Deletes a remote file via webdav
* @param remoteFilePath Remote file path of the file to delete, in URL DECODED format.
* @return
*/
public boolean deleteFile(String remoteFilePath) {
boolean ret = false;
DavMethod delete = new DeleteMethod(mUri.toString() + WebdavUtils.encodePath(remoteFilePath));
try {
int status = executeMethod(delete);
ret = (status == HttpStatus.SC_OK || status == HttpStatus.SC_ACCEPTED || status == HttpStatus.SC_NO_CONTENT);
exhaustResponse(delete.getResponseBodyAsStream());
Log.e(TAG, "DELETE of " + remoteFilePath + " finished with HTTP status " + status + (!ret?"(FAIL)":""));
} catch (Exception e) {
logException(e, "deleting " + remoteFilePath);
} finally {
delete.releaseConnection(); // let the connection available for other methods
}
return ret;
}
public void setDataTransferProgressListener(OnDatatransferProgressListener listener) {
mDataTransferListener = listener;
}
/**
* Creates or update a file in the remote server with the contents of a local file.
*
* @param localFile Path to the local file to upload.
* @param remoteTarget Remote path to the file to create or update, URL DECODED
* @param contentType MIME type of the file.
* @return Status HTTP code returned by the server.
* @throws IOException When a transport error that could not be recovered occurred while uploading the file to the server.
* @throws HttpException When a violation of the HTTP protocol occurred.
*/
public int putFile(String localFile, String remoteTarget, String contentType) throws HttpException, IOException {
int status = -1;
PutMethod put = new PutMethod(mUri.toString() + WebdavUtils.encodePath(remoteTarget));
try {
File f = new File(localFile);
FileRequestEntity entity = new FileRequestEntity(f, contentType);
entity.addDatatransferProgressListener(mDataTransferListener);
put.setRequestEntity(entity);
status = executeMethod(put);
exhaustResponse(put.getResponseBodyAsStream());
} finally {
put.releaseConnection(); // let the connection available for other methods
}
return status;
}
/**
* Tries to log in to the current URI, with the current credentials
*
* @return A {@link HttpStatus}-Code of the result. SC_OK is good.
*/
public int tryToLogin() {
int status = 0;
HeadMethod head = new HeadMethod(mUri.toString());
try {
status = executeMethod(head);
boolean result = status == HttpStatus.SC_OK;
Log.d(TAG, "HEAD for " + mUri + " finished with HTTP status " + status + (!result?"(FAIL)":""));
exhaustResponse(head.getResponseBodyAsStream());
} catch (Exception e) {
logException(e, "trying to login at " + mUri.toString());
} finally {
head.releaseConnection();
}
return status;
}
/**
* Creates a remote directory with the received path.
*
* @param path Path of the directory to create, URL DECODED
* @return 'True' when the directory is successfully created
*/
public boolean createDirectory(String path) {
boolean result = false;
int status = -1;
MkColMethod mkcol = new MkColMethod(mUri.toString() + WebdavUtils.encodePath(path));
try {
Log.d(TAG, "Creating directory " + path);
status = executeMethod(mkcol);
Log.d(TAG, "Status returned: " + status);
result = mkcol.succeeded();
Log.d(TAG, "MKCOL to " + path + " finished with HTTP status " + status + (!result?"(FAIL)":""));
exhaustResponse(mkcol.getResponseBodyAsStream());
} catch (Exception e) {
logException(e, "creating directory " + path);
} finally {
mkcol.releaseConnection(); // let the connection available for other methods
}
return result;
}
/**
* Check if a file exists in the OC server
*
* @return 'true' if the file exists; 'false' it doesn't exist
* @throws Exception When the existence could not be determined
*/
public boolean existsFile(String path) throws IOException, HttpException {
HeadMethod head = new HeadMethod(mUri.toString() + WebdavUtils.encodePath(path));
try {
int status = executeMethod(head);
Log.d(TAG, "HEAD to " + path + " finished with HTTP status " + status + ((status != HttpStatus.SC_OK)?"(FAIL)":""));
exhaustResponse(head.getResponseBodyAsStream());
return (status == HttpStatus.SC_OK);
} finally {
head.releaseConnection(); // let the connection available for other methods
}
}
/**
* Requests the received method with the received timeout (milliseconds).
*
* Executes the method through the inherited HttpClient.executedMethod(method).
*
* Sets the socket and connection timeouts only for the method received.
*
* The timeouts are both in milliseconds; 0 means 'infinite'; < 0 means 'do not change the default'
*
* @param method HTTP method request.
* @param readTimeout Timeout to set for data reception
* @param conntionTimout Timeout to set for connection establishment
*/
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws HttpException, IOException {
int oldSoTimeout = getParams().getSoTimeout();
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
try {
if (readTimeout >= 0) {
method.getParams().setSoTimeout(readTimeout); // this should be enough...
getParams().setSoTimeout(readTimeout); // ... but this looks like necessary for HTTPS
}
if (connectionTimeout >= 0) {
getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
}
return executeMethod(method);
} finally {
getParams().setSoTimeout(oldSoTimeout);
getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout);
}
}
/**
* Exhausts a not interesting HTTP response. Encouraged by HttpClient documentation.
*
* @param responseBodyAsStream InputStream with the HTTP response to exhaust.
*/
public void exhaustResponse(InputStream responseBodyAsStream) {
if (responseBodyAsStream != null) {
try {
while (responseBodyAsStream.read(sExhaustBuffer) >= 0);
responseBodyAsStream.close();
} catch (IOException io) {
Log.e(TAG, "Unexpected exception while exhausting not interesting HTTP response; will be IGNORED", io);
}
}
}
/**
* Logs an exception triggered in a HTTP request.
*
* @param e Caught exception.
* @param doing Suffix to add at the end of the logged message.
*/
private void logException(Exception e, String doing) {
if (e instanceof HttpException) {
Log.e(TAG, "HTTP violation while " + doing, e);
} else if (e instanceof IOException) {
Log.e(TAG, "Unrecovered transport exception while " + doing, e);
} else {
Log.e(TAG, "Unexpected exception while " + doing, e);
}
}
/**
* Sets the connection and wait-for-data timeouts to be applied by default to the methods performed by this client.
*/
public void setDefaultTimeouts(int defaultDataTimeout, int defaultConnectionTimeout) {
getParams().setSoTimeout(defaultDataTimeout);
getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout);
}
/**
* Sets the base URI for the helper methods that receive paths as parameters, instead of full URLs
* @param uri
*/
public void setBaseUri(Uri uri) {
mUri = uri;
}
public Uri getBaseUri() {
return mUri;
}
}
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package eu.alefzero.webdav;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpStatus;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.jackrabbit.webdav.client.methods.DavMethod;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import com.owncloud.android.Log_OC;
import android.net.Uri;
import android.util.Log;
public class WebdavClient extends HttpClient {
private Uri mUri;
private Credentials mCredentials;
final private static String TAG = "WebdavClient";
private static final String USER_AGENT = "Android-ownCloud";
private OnDatatransferProgressListener mDataTransferListener;
static private byte[] sExhaustBuffer = new byte[1024];
/**
* Constructor
*/
public WebdavClient(HttpConnectionManager connectionMgr) {
super(connectionMgr);
Log_OC.d(TAG, "Creating WebdavClient");
getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);
getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
}
public void setCredentials(String username, String password) {
getParams().setAuthenticationPreemptive(true);
getState().setCredentials(AuthScope.ANY,
getCredentials(username, password));
}
private Credentials getCredentials(String username, String password) {
if (mCredentials == null)
mCredentials = new UsernamePasswordCredentials(username, password);
return mCredentials;
}
/**
* Downloads a file in remoteFilepath to the local targetPath.
*
* @param remoteFilepath Path to the file in the remote server, URL DECODED.
* @param targetFile Local path to save the downloaded file.
* @return 'True' when the file is successfully downloaded.
*/
public boolean downloadFile(String remoteFilePath, File targetFile) {
boolean ret = false;
GetMethod get = new GetMethod(mUri.toString() + WebdavUtils.encodePath(remoteFilePath));
try {
int status = executeMethod(get);
if (status == HttpStatus.SC_OK) {
targetFile.createNewFile();
BufferedInputStream bis = new BufferedInputStream(
get.getResponseBodyAsStream());
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] bytes = new byte[4096];
int readResult;
while ((readResult = bis.read(bytes)) != -1) {
if (mDataTransferListener != null)
mDataTransferListener.onTransferProgress(readResult);
fos.write(bytes, 0, readResult);
}
fos.close();
ret = true;
} else {
exhaustResponse(get.getResponseBodyAsStream());
}
Log_OC.e(TAG, "Download of " + remoteFilePath + " to " + targetFile + " finished with HTTP status " + status + (!ret?"(FAIL)":""));
} catch (Exception e) {
logException(e, "dowloading " + remoteFilePath);
} finally {
if (!ret && targetFile.exists()) {
targetFile.delete();
}
get.releaseConnection(); // let the connection available for other methods
}
return ret;
}
/**
* Deletes a remote file via webdav
* @param remoteFilePath Remote file path of the file to delete, in URL DECODED format.
* @return
*/
public boolean deleteFile(String remoteFilePath) {
boolean ret = false;
DavMethod delete = new DeleteMethod(mUri.toString() + WebdavUtils.encodePath(remoteFilePath));
try {
int status = executeMethod(delete);
ret = (status == HttpStatus.SC_OK || status == HttpStatus.SC_ACCEPTED || status == HttpStatus.SC_NO_CONTENT);
exhaustResponse(delete.getResponseBodyAsStream());
Log_OC.e(TAG, "DELETE of " + remoteFilePath + " finished with HTTP status " + status + (!ret?"(FAIL)":""));
} catch (Exception e) {
logException(e, "deleting " + remoteFilePath);
} finally {
delete.releaseConnection(); // let the connection available for other methods
}
return ret;
}
public void setDataTransferProgressListener(OnDatatransferProgressListener listener) {
mDataTransferListener = listener;
}
/**
* Creates or update a file in the remote server with the contents of a local file.
*
* @param localFile Path to the local file to upload.
* @param remoteTarget Remote path to the file to create or update, URL DECODED
* @param contentType MIME type of the file.
* @return Status HTTP code returned by the server.
* @throws IOException When a transport error that could not be recovered occurred while uploading the file to the server.
* @throws HttpException When a violation of the HTTP protocol occurred.
*/
public int putFile(String localFile, String remoteTarget, String contentType) throws HttpException, IOException {
int status = -1;
PutMethod put = new PutMethod(mUri.toString() + WebdavUtils.encodePath(remoteTarget));
try {
File f = new File(localFile);
FileRequestEntity entity = new FileRequestEntity(f, contentType);
entity.addDatatransferProgressListener(mDataTransferListener);
put.setRequestEntity(entity);
status = executeMethod(put);
exhaustResponse(put.getResponseBodyAsStream());
} finally {
put.releaseConnection(); // let the connection available for other methods
}
return status;
}
/**
* Tries to log in to the current URI, with the current credentials
*
* @return A {@link HttpStatus}-Code of the result. SC_OK is good.
*/
public int tryToLogin() {
int status = 0;
HeadMethod head = new HeadMethod(mUri.toString());
try {
status = executeMethod(head);
boolean result = status == HttpStatus.SC_OK;
Log_OC.d(TAG, "HEAD for " + mUri + " finished with HTTP status " + status + (!result?"(FAIL)":""));
exhaustResponse(head.getResponseBodyAsStream());
} catch (Exception e) {
logException(e, "trying to login at " + mUri.toString());
} finally {
head.releaseConnection();
}
return status;
}
/**
* Creates a remote directory with the received path.
*
* @param path Path of the directory to create, URL DECODED
* @return 'True' when the directory is successfully created
*/
public boolean createDirectory(String path) {
boolean result = false;
int status = -1;
MkColMethod mkcol = new MkColMethod(mUri.toString() + WebdavUtils.encodePath(path));
try {
Log_OC.d(TAG, "Creating directory " + path);
status = executeMethod(mkcol);
Log_OC.d(TAG, "Status returned: " + status);
result = mkcol.succeeded();
Log_OC.d(TAG, "MKCOL to " + path + " finished with HTTP status " + status + (!result?"(FAIL)":""));
exhaustResponse(mkcol.getResponseBodyAsStream());
} catch (Exception e) {
logException(e, "creating directory " + path);
} finally {
mkcol.releaseConnection(); // let the connection available for other methods
}
return result;
}
/**
* Check if a file exists in the OC server
*
* @return 'true' if the file exists; 'false' it doesn't exist
* @throws Exception When the existence could not be determined
*/
public boolean existsFile(String path) throws IOException, HttpException {
HeadMethod head = new HeadMethod(mUri.toString() + WebdavUtils.encodePath(path));
try {
int status = executeMethod(head);
Log_OC.d(TAG, "HEAD to " + path + " finished with HTTP status " + status + ((status != HttpStatus.SC_OK)?"(FAIL)":""));
exhaustResponse(head.getResponseBodyAsStream());
return (status == HttpStatus.SC_OK);
} finally {
head.releaseConnection(); // let the connection available for other methods
}
}
/**
* Requests the received method with the received timeout (milliseconds).
*
* Executes the method through the inherited HttpClient.executedMethod(method).
*
* Sets the socket and connection timeouts only for the method received.
*
* The timeouts are both in milliseconds; 0 means 'infinite'; < 0 means 'do not change the default'
*
* @param method HTTP method request.
* @param readTimeout Timeout to set for data reception
* @param conntionTimout Timeout to set for connection establishment
*/
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws HttpException, IOException {
int oldSoTimeout = getParams().getSoTimeout();
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
try {
if (readTimeout >= 0) {
method.getParams().setSoTimeout(readTimeout); // this should be enough...
getParams().setSoTimeout(readTimeout); // ... but this looks like necessary for HTTPS
}
if (connectionTimeout >= 0) {
getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
}
return executeMethod(method);
} finally {
getParams().setSoTimeout(oldSoTimeout);
getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout);
}
}
/**
* Exhausts a not interesting HTTP response. Encouraged by HttpClient documentation.
*
* @param responseBodyAsStream InputStream with the HTTP response to exhaust.
*/
public void exhaustResponse(InputStream responseBodyAsStream) {
if (responseBodyAsStream != null) {
try {
while (responseBodyAsStream.read(sExhaustBuffer) >= 0);
responseBodyAsStream.close();
} catch (IOException io) {
Log_OC.e(TAG, "Unexpected exception while exhausting not interesting HTTP response; will be IGNORED", io);
}
}
}
/**
* Logs an exception triggered in a HTTP request.
*
* @param e Caught exception.
* @param doing Suffix to add at the end of the logged message.
*/
private void logException(Exception e, String doing) {
if (e instanceof HttpException) {
Log_OC.e(TAG, "HTTP violation while " + doing, e);
} else if (e instanceof IOException) {
Log_OC.e(TAG, "Unrecovered transport exception while " + doing, e);
} else {
Log_OC.e(TAG, "Unexpected exception while " + doing, e);
}
}
/**
* Sets the connection and wait-for-data timeouts to be applied by default to the methods performed by this client.
*/
public void setDefaultTimeouts(int defaultDataTimeout, int defaultConnectionTimeout) {
getParams().setSoTimeout(defaultDataTimeout);
getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout);
}
/**
* Sets the base URI for the helper methods that receive paths as parameters, instead of full URLs
* @param uri
*/
public void setBaseUri(Uri uri) {
mUri = uri;
}
public Uri getBaseUri() {
return mUri;
}
}

View file

@ -24,6 +24,8 @@ import org.apache.jackrabbit.webdav.property.DavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import com.owncloud.android.Log_OC;
import android.net.Uri;
import android.util.Log;
@ -89,7 +91,7 @@ public class WebdavEntry {
}
} else {
Log.e("WebdavEntry",
Log_OC.e("WebdavEntry",
"General fuckup, no status for webdav response");
}
}