2  *   ownCloud Android client application 
   4  *   Copyright (C) 2012  Bartek Przybylski 
   5  *   Copyright (C) 2015 ownCloud Inc. 
   7  *   This program is free software: you can redistribute it and/or modify 
   8  *   it under the terms of the GNU General Public License version 2, 
   9  *   as published by the Free Software Foundation. 
  11  *   This program is distributed in the hope that it will be useful, 
  12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  14  *   GNU General Public License for more details. 
  16  *   You should have received a copy of the GNU General Public License 
  17  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  21 package com
.owncloud
.android
.files
; 
  25 import com
.owncloud
.android
.MainApp
; 
  26 import com
.owncloud
.android
.authentication
.AccountUtils
; 
  27 import com
.owncloud
.android
.db
.DbHandler
; 
  28 import com
.owncloud
.android
.files
.services
.FileUploader
; 
  29 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
; 
  30 import com
.owncloud
.android
.utils
.FileStorageUtils
; 
  32 import android
.accounts
.Account
; 
  33 import android
.content
.BroadcastReceiver
; 
  34 import android
.content
.Context
; 
  35 import android
.content
.Intent
; 
  36 import android
.content
.IntentFilter
; 
  37 import android
.content
.SharedPreferences
; 
  38 import android
.database
.Cursor
; 
  39 import android
.net
.ConnectivityManager
; 
  40 import android
.net
.NetworkInfo
.State
; 
  41 import android
.os
.BatteryManager
; 
  42 import android
.preference
.PreferenceManager
; 
  43 import android
.provider
.MediaStore
.Images
; 
  44 import android
.provider
.MediaStore
.Video
; 
  45 import android
.webkit
.MimeTypeMap
; 
  48 public class InstantUploadBroadcastReceiver 
extends BroadcastReceiver 
{ 
  50     private static String TAG 
= InstantUploadBroadcastReceiver
.class.getName(); 
  52     // Unofficial action, works for most devices but not HTC. See: https://github.com/owncloud/android/issues/6 
  53     private static String NEW_PHOTO_ACTION_UNOFFICIAL 
= "com.android.camera.NEW_PICTURE"; 
  54     // Officially supported action since SDK 14: http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_PICTURE 
  55     private static String NEW_PHOTO_ACTION 
= "android.hardware.action.NEW_PICTURE"; 
  57     // Officially supported action since SDK 14: http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_VIDEO 
  58     private static String NEW_VIDEO_ACTION 
= "android.hardware.action.NEW_VIDEO"; 
  61     public void onReceive(Context context
, Intent intent
) { 
  62         Log_OC
.d(TAG
, "Received: " + intent
.getAction()); 
  63         if (intent
.getAction().equals(android
.net
.ConnectivityManager
.CONNECTIVITY_ACTION
) || intent
.getAction().equals(Intent
.ACTION_POWER_CONNECTED
)) { 
  64             handleConnectivityAction(context
, intent
); 
  65         }else if (intent
.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL
)) { 
  66             handleNewPictureAction(context
, intent
);  
  67             Log_OC
.d(TAG
, "UNOFFICIAL processed: com.android.camera.NEW_PICTURE"); 
  68         } else if (intent
.getAction().equals(NEW_PHOTO_ACTION
)) { 
  69             handleNewPictureAction(context
, intent
);  
  70             Log_OC
.d(TAG
, "OFFICIAL processed: android.hardware.action.NEW_PICTURE"); 
  71         } else if (intent
.getAction().equals(NEW_VIDEO_ACTION
)) { 
  72             Log_OC
.d(TAG
, "OFFICIAL processed: android.hardware.action.NEW_VIDEO"); 
  73             handleNewVideoAction(context
, intent
); 
  75             Log_OC
.e(TAG
, "Incorrect intent sent: " + intent
.getAction()); 
  79     private void handleNewPictureAction(Context context
, Intent intent
) { 
  81         String file_path 
= null
; 
  82         String file_name 
= null
; 
  83         String mime_type 
= null
; 
  85         Log_OC
.w(TAG
, "New photo received"); 
  87         if (!instantPictureUploadEnabled(context
)) { 
  88             Log_OC
.d(TAG
, "Instant picture upload disabled, ignoring new picture"); 
  92         Account account 
= AccountUtils
.getCurrentOwnCloudAccount(context
); 
  93         if (account 
== null
) { 
  94             Log_OC
.w(TAG
, "No ownCloud account found for instant upload, aborting"); 
  98         String
[] CONTENT_PROJECTION 
= { Images
.Media
.DATA
, Images
.Media
.DISPLAY_NAME
, Images
.Media
.MIME_TYPE
, Images
.Media
.SIZE 
}; 
  99         c 
= context
.getContentResolver().query(intent
.getData(), CONTENT_PROJECTION
, null
, null
, null
); 
 100         if (!c
.moveToFirst()) { 
 101             Log_OC
.e(TAG
, "Couldn't resolve given uri: " + intent
.getDataString()); 
 104         file_path 
= c
.getString(c
.getColumnIndex(Images
.Media
.DATA
)); 
 105         file_name 
= c
.getString(c
.getColumnIndex(Images
.Media
.DISPLAY_NAME
)); 
 106         mime_type 
= c
.getString(c
.getColumnIndex(Images
.Media
.MIME_TYPE
)); 
 108         Log_OC
.d(TAG
, file_path 
+ ""); 
 110         // save always temporally the picture to upload 
 111         DbHandler db 
= new DbHandler(context
); 
 112         db
.putFileForLater(file_path
, account
.name
, null
); 
 115         if (!isOnline(context
)  
 116                 || (instantPictureUploadViaWiFiOnly(context
) && !isConnectedViaWiFi(context
)) 
 117                 || (instantUploadWhenChargingOnly(context
) && !isCharging(context
)) 
 122         Intent i 
= new Intent(context
, FileUploader
.class); 
 123         i
.putExtra(FileUploader
.KEY_ACCOUNT
, account
); 
 124         i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, file_path
); 
 125         i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, FileStorageUtils
.getInstantUploadFilePath(context
, file_name
)); 
 126         i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_SINGLE_FILE
); 
 127         i
.putExtra(FileUploader
.KEY_MIME_TYPE
, mime_type
); 
 128         i
.putExtra(FileUploader
.KEY_INSTANT_UPLOAD
, true
); 
 130         // instant upload behaviour 
 131         SharedPreferences appPreferences 
= PreferenceManager
.getDefaultSharedPreferences(context
); 
 132         String behaviour 
= appPreferences
.getString("prefs_instant_behaviour", "NOTHING"); 
 134         if (behaviour
.equalsIgnoreCase("NOTHING")) { 
 135             Log_OC
.d(TAG
, "upload file and do nothing"); 
 136             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_FORGET
); 
 137         } else if (behaviour
.equalsIgnoreCase("COPY")) { 
 138             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_COPY
); 
 139             Log_OC
.d(TAG
, "upload file and copy file to oc folder"); 
 140         } else if (behaviour
.equalsIgnoreCase("MOVE")) { 
 141             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_MOVE
); 
 142             Log_OC
.d(TAG
, "upload file and move file to oc folder"); 
 143         } else if (behaviour
.equalsIgnoreCase("DELETE")){ 
 144             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_REMOVE
); 
 145             Log_OC
.d(TAG
, "upload file and delete file in original place"); 
 148         context
.startService(i
); 
 151     private void handleNewVideoAction(Context context
, Intent intent
) { 
 153         String file_path 
= null
; 
 154         String file_name 
= null
; 
 155         String mime_type 
= null
; 
 157         Log_OC
.w(TAG
, "New video received"); 
 159         if (!instantVideoUploadEnabled(context
)) { 
 160             Log_OC
.d(TAG
, "Instant video upload disabled, ignoring new video"); 
 164         Account account 
= AccountUtils
.getCurrentOwnCloudAccount(context
); 
 165         if (account 
== null
) { 
 166             Log_OC
.w(TAG
, "No owncloud account found for instant upload, aborting"); 
 170         String
[] CONTENT_PROJECTION 
= { Video
.Media
.DATA
, Video
.Media
.DISPLAY_NAME
, Video
.Media
.MIME_TYPE
, Video
.Media
.SIZE 
}; 
 171         c 
= context
.getContentResolver().query(intent
.getData(), CONTENT_PROJECTION
, null
, null
, null
); 
 172         if (!c
.moveToFirst()) { 
 173             Log_OC
.e(TAG
, "Couldn't resolve given uri: " + intent
.getDataString()); 
 176         file_path 
= c
.getString(c
.getColumnIndex(Video
.Media
.DATA
)); 
 177         file_name 
= c
.getString(c
.getColumnIndex(Video
.Media
.DISPLAY_NAME
)); 
 178         mime_type 
= c
.getString(c
.getColumnIndex(Video
.Media
.MIME_TYPE
)); 
 180         Log_OC
.d(TAG
, file_path 
+ ""); 
 182         // save always temporally the picture to upload 
 183         DbHandler db 
= new DbHandler(context
); 
 184         db
.putFileForLater(file_path
, account
.name
, null
); 
 187         if (!isOnline(context
)  
 188                 || (instantVideoUploadViaWiFiOnly(context
) && !isConnectedViaWiFi(context
)) 
 189                 || (instantVideoUploadWhenChargingOnly(context
) && !isCharging(context
)) 
 194         Intent i 
= new Intent(context
, FileUploader
.class); 
 195         i
.putExtra(FileUploader
.KEY_ACCOUNT
, account
); 
 196         i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, file_path
); 
 197         i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, FileStorageUtils
.getInstantVideoUploadFilePath(context
, file_name
)); 
 198         i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_SINGLE_FILE
); 
 199         i
.putExtra(FileUploader
.KEY_MIME_TYPE
, mime_type
); 
 200         i
.putExtra(FileUploader
.KEY_INSTANT_UPLOAD
, true
); 
 202         // instant upload behaviour 
 203         SharedPreferences appPreferences 
= PreferenceManager
.getDefaultSharedPreferences(context
); 
 204         String behaviour 
= appPreferences
.getString("prefs_instant_behaviour", "NOTHING"); 
 206         if (behaviour
.equalsIgnoreCase("NOTHING")) { 
 207             Log_OC
.d(TAG
, "upload file and do nothing"); 
 208             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_FORGET
); 
 209         } else if (behaviour
.equalsIgnoreCase("COPY")) { 
 210             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_COPY
); 
 211             Log_OC
.d(TAG
, "upload file and copy file to oc folder"); 
 212         } else if (behaviour
.equalsIgnoreCase("MOVE")) { 
 213             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_MOVE
); 
 214             Log_OC
.d(TAG
, "upload file and move file to oc folder"); 
 215         } else if (behaviour
.equalsIgnoreCase("DELETE")){ 
 216             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_REMOVE
); 
 217             Log_OC
.d(TAG
, "upload file and delete file in original place"); 
 220         context
.startService(i
); 
 224     private void handleConnectivityAction(Context context
, Intent intent
) { 
 225         if (!instantPictureUploadEnabled(context
) && !instantVideoUploadEnabled(context
)) { 
 226             Log_OC
.d(TAG
, "Instant upload disabled, don't upload anything"); 
 230         if (!intent
.hasExtra(ConnectivityManager
.EXTRA_NO_CONNECTIVITY
) 
 232                 && (!instantUploadWhenChargingOnly(context
) || (instantUploadWhenChargingOnly(context
) && isCharging(context
))) 
 233                 && (!instantVideoUploadWhenChargingOnly(context
) || (instantVideoUploadWhenChargingOnly(context
) && isCharging(context
))) 
 234                 && (!instantPictureUploadViaWiFiOnly(context
) || (instantPictureUploadViaWiFiOnly(context
) && isConnectedViaWiFi(context
))) 
 235                 && (!instantVideoUploadViaWiFiOnly(context
) || (instantVideoUploadViaWiFiOnly(context
) && isConnectedViaWiFi(context
))) 
 237             DbHandler db 
= new DbHandler(context
); 
 238             Cursor c 
= db
.getAwaitingFiles(); 
 239             if (c
.moveToFirst()) { 
 241                     String account_name 
= c
.getString(c
.getColumnIndex("account")); 
 242                     String file_path 
= c
.getString(c
.getColumnIndex("path")); 
 243                     File f 
= new File(file_path
); 
 245                         Account account 
= new Account(account_name
, MainApp
.getAccountType()); 
 247                         String mimeType 
= null
; 
 249                             mimeType 
= MimeTypeMap
.getSingleton().getMimeTypeFromExtension( 
 250                                     f
.getName().substring(f
.getName().lastIndexOf('.') + 1)); 
 252                         } catch (Throwable e
) { 
 253                             Log_OC
.e(TAG
, "Trying to find out MIME type of a file without extension: " + f
.getName()); 
 255                         if (mimeType 
== null
) 
 256                             mimeType 
= "application/octet-stream"; 
 258                         Intent i 
= new Intent(context
, FileUploader
.class); 
 259                         i
.putExtra(FileUploader
.KEY_ACCOUNT
, account
); 
 260                         i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, file_path
); 
 261                         i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, FileStorageUtils
.getInstantUploadFilePath(context
, f
.getName())); 
 262                         i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_SINGLE_FILE
); 
 263                         i
.putExtra(FileUploader
.KEY_INSTANT_UPLOAD
, true
); 
 265                         // instant upload behaviour 
 266                         SharedPreferences appPreferences 
= PreferenceManager
.getDefaultSharedPreferences(context
); 
 267                         String behaviour 
= appPreferences
.getString("prefs_instant_behaviour", "NOTHING"); 
 269                         if (behaviour
.equalsIgnoreCase("NOTHING")) { 
 270                             Log_OC
.d(TAG
, "upload file and do nothing"); 
 271                             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_FORGET
); 
 272                         } else if (behaviour
.equalsIgnoreCase("COPY")) { 
 273                             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_COPY
); 
 274                             Log_OC
.d(TAG
, "upload file and copy file to oc folder"); 
 275                         } else if (behaviour
.equalsIgnoreCase("MOVE")) { 
 276                             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_MOVE
); 
 277                             Log_OC
.d(TAG
, "upload file and move file to oc folder"); 
 278                         } else if (behaviour
.equalsIgnoreCase("DELETE")){ 
 279                             i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_REMOVE
); 
 280                             Log_OC
.d(TAG
, "upload file and delete file in original place"); 
 283                         context
.startService(i
); 
 286                         Log_OC
.w(TAG
, "Instant upload file " + f
.getAbsolutePath() + " dont exist anymore"); 
 288                 } while (c
.moveToNext()); 
 295     public static boolean isOnline(Context context
) { 
 296         ConnectivityManager cm 
= (ConnectivityManager
) context
.getSystemService(Context
.CONNECTIVITY_SERVICE
); 
 297         return cm
.getActiveNetworkInfo() != null 
&& cm
.getActiveNetworkInfo().isConnected(); 
 300     public static boolean isConnectedViaWiFi(Context context
) { 
 301         ConnectivityManager cm 
= (ConnectivityManager
) context
.getSystemService(Context
.CONNECTIVITY_SERVICE
); 
 302         return cm 
!= null 
&& cm
.getActiveNetworkInfo() != null
 
 303                 && cm
.getActiveNetworkInfo().getType() == ConnectivityManager
.TYPE_WIFI
 
 304                 && cm
.getActiveNetworkInfo().getState() == State
.CONNECTED
; 
 307     public static boolean isCharging(Context context
){ 
 308         IntentFilter ifilter 
= new IntentFilter(Intent
.ACTION_BATTERY_CHANGED
); 
 309         Intent batteryStatus 
= context
.registerReceiver(null
, ifilter
); 
 312         if (batteryStatus 
!= null
) { 
 313             status 
= batteryStatus
.getIntExtra(BatteryManager
.EXTRA_STATUS
, -1); 
 315         return status 
== BatteryManager
.BATTERY_STATUS_CHARGING 
|| 
 316                 status 
== BatteryManager
.BATTERY_STATUS_FULL
; 
 319     public static boolean instantPictureUploadEnabled(Context context
) { 
 320         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_uploading", false
); 
 323     public static boolean instantVideoUploadEnabled(Context context
) { 
 324         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_video_uploading", false
); 
 327     public static boolean instantPictureUploadViaWiFiOnly(Context context
) { 
 328         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_upload_on_wifi", false
); 
 331     public static boolean instantVideoUploadViaWiFiOnly(Context context
) { 
 332         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_video_upload_on_wifi", false
); 
 334     public static boolean instantUploadWhenChargingOnly(Context context
) { 
 335         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_upload_on_charging", false
); 
 337     public static boolean instantVideoUploadWhenChargingOnly(Context context
) { 
 338         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_video_upload_on_charging", false
);