Migrate PowerUtils calls to PowerManagementService

Signed-off-by: Chris Narkiewicz <hello@ezaquarii.com>
This commit is contained in:
Chris Narkiewicz 2019-05-29 21:00:02 +01:00
parent c9f11d4c2d
commit 49d858ea9f
No known key found for this signature in database
GPG key ID: 30D28CA4CCC665C6
17 changed files with 221 additions and 220 deletions

View file

@ -35,7 +35,6 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'checkstyle'
apply plugin: 'pmd'
apply plugin: 'jacoco-android'
@ -263,7 +262,6 @@ dependencies {
implementation 'com.github.tobiaskaminsky:android-job:v1.2.6.1' // 'com.github.evernote:android-job:v1.2.5'
implementation 'com.jakewharton:butterknife:10.1.0'
kapt 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.5'
implementation 'org.lukhnos:nnio:0.2'

View file

@ -4,6 +4,7 @@ import android.content.ContentResolver;
import com.evernote.android.job.JobRequest;
import com.nextcloud.client.account.CurrentAccountProvider;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.datamodel.UploadsStorageManager;
@ -48,6 +49,23 @@ public class UploadIT extends AbstractIT {
}
};
private PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@Override
public boolean isPowerSavingEnabled() {
return false;
}
@Override
public boolean isPowerSavingExclusionAvailable() {
return false;
}
@Override
public boolean isBatteryCharging() {
return false;
}
};
@Before
public void setUp() {
final ContentResolver contentResolver = targetContext.getContentResolver();
@ -98,6 +116,7 @@ public class UploadIT extends AbstractIT {
UploadFileOperation newUpload = new UploadFileOperation(
storageManager,
connectivityServiceMock,
powerManagementServiceMock,
account,
null,
ocUpload,
@ -123,6 +142,7 @@ public class UploadIT extends AbstractIT {
UploadFileOperation newUpload = new UploadFileOperation(
storageManager,
connectivityServiceMock,
powerManagementServiceMock,
account,
null,
ocUpload,

View file

@ -26,6 +26,7 @@ import com.owncloud.android.authentication.DeepLinkLoginActivity;
import com.owncloud.android.files.BootupBroadcastReceiver;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.jobs.NContentObserverJob;
import com.owncloud.android.jobs.NotificationJob;
import com.owncloud.android.providers.DiskLruImageCacheFileProvider;
import com.owncloud.android.providers.DocumentsStorageProvider;
@ -147,4 +148,5 @@ abstract class ComponentsModule {
@ContributesAndroidInjector abstract AccountManagerService accountManagerService();
@ContributesAndroidInjector abstract OperationsService operationsService();
@ContributesAndroidInjector abstract NContentObserverJob contentObserverJob();
}

View file

@ -46,6 +46,7 @@ import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.appinfo.AppInfo;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.di.ActivityInjector;
import com.nextcloud.client.di.DaggerAppComponent;
import com.nextcloud.client.network.ConnectivityService;
@ -106,9 +107,8 @@ import static com.owncloud.android.ui.activity.ContactsPreferenceActivity.PREFER
/**
* Main Application of the project
*
* Contains methods to build the "static" strings. These strings were before constants in different
* classes
* <p>
* Contains methods to build the "static" strings. These strings were before constants in different classes
*/
public class MainApp extends MultiDexApplication implements
HasActivityInjector,
@ -161,6 +161,8 @@ public class MainApp extends MultiDexApplication implements
@Inject
ConnectivityService connectivityService;
@Inject PowerManagementService powerManagementService;
private PassCodeManager passCodeManager;
@SuppressWarnings("unused")
@ -202,7 +204,8 @@ public class MainApp extends MultiDexApplication implements
accountManager,
preferences,
uploadsStorageManager,
connectivityService
connectivityService,
powerManagementService
)
);
@ -235,22 +238,22 @@ public class MainApp extends MultiDexApplication implements
}
}
initSyncOperations(uploadsStorageManager, accountManager, connectivityService);
initSyncOperations(uploadsStorageManager, accountManager, connectivityService, powerManagementService);
initContactsBackup(accountManager);
notificationChannels();
new JobRequest.Builder(MediaFoldersDetectionJob.TAG)
.setPeriodic(TimeUnit.MINUTES.toMillis(15), TimeUnit.MINUTES.toMillis(5))
.setUpdateCurrent(true)
.build()
.schedule();
.setPeriodic(TimeUnit.MINUTES.toMillis(15), TimeUnit.MINUTES.toMillis(5))
.setUpdateCurrent(true)
.build()
.schedule();
new JobRequest.Builder(MediaFoldersDetectionJob.TAG)
.startNow()
.setUpdateCurrent(false)
.build()
.schedule();
.startNow()
.setUpdateCurrent(false)
.build()
.schedule();
// register global protection with pass code
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@ -324,7 +327,7 @@ public class MainApp extends MultiDexApplication implements
boolean set = false;
for (StoragePoint storagePoint : storagePoints) {
if (storagePoint.getStorageType() == StoragePoint.StorageType.INTERNAL &&
storagePoint.getPrivacyType() == StoragePoint.PrivacyType.PUBLIC) {
storagePoint.getPrivacyType() == StoragePoint.PrivacyType.PUBLIC) {
preferences.setStoragePath(storagePoint.getPath());
preferences.removeKeysMigrationPreference();
set = true;
@ -362,7 +365,8 @@ public class MainApp extends MultiDexApplication implements
public static void initSyncOperations(
final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService
) {
updateToAutoUpload();
cleanOldEntries();
@ -370,7 +374,7 @@ public class MainApp extends MultiDexApplication implements
if (getAppContext() != null) {
if (PermissionUtil.checkSelfPermission(getAppContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
splitOutAutoUploadEntries();
} else {
AppPreferences preferences = AppPreferencesImpl.fromContext(getAppContext());
@ -381,17 +385,30 @@ public class MainApp extends MultiDexApplication implements
initiateExistingAutoUploadEntries();
FilesSyncHelper.scheduleFilesSyncIfNeeded(mContext);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, accountManager, connectivityService);
FilesSyncHelper.restartJobsIfNeeded(
uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
FilesSyncHelper.scheduleOfflineSyncIfNeeded();
ReceiversHelper.registerNetworkChangeReceiver(uploadsStorageManager, accountManager, connectivityService);
ReceiversHelper.registerNetworkChangeReceiver(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
ReceiversHelper.registerPowerChangeReceiver(uploadsStorageManager, accountManager, connectivityService);
ReceiversHelper.registerPowerChangeReceiver(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ReceiversHelper.registerPowerSaveReceiver(uploadsStorageManager, accountManager, connectivityService);
ReceiversHelper.registerPowerSaveReceiver(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
}
}
@ -399,36 +416,36 @@ public class MainApp extends MultiDexApplication implements
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && getAppContext() != null) {
Context context = getAppContext();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
context.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_DOWNLOAD,
R.string.notification_channel_download_name,
R.string.notification_channel_download_description, context);
R.string.notification_channel_download_name,
R.string.notification_channel_download_description, context);
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_UPLOAD,
R.string.notification_channel_upload_name,
R.string.notification_channel_upload_description, context);
R.string.notification_channel_upload_name,
R.string.notification_channel_upload_description, context);
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_MEDIA,
R.string.notification_channel_media_name,
R.string.notification_channel_media_description, context);
R.string.notification_channel_media_name,
R.string.notification_channel_media_description, context);
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_FILE_SYNC,
R.string.notification_channel_file_sync_name,
R.string.notification_channel_file_sync_description, context);
R.string.notification_channel_file_sync_name,
R.string.notification_channel_file_sync_description, context);
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_FILE_OBSERVER,
R.string.notification_channel_file_observer_name, R.string
.notification_channel_file_observer_description, context);
R.string.notification_channel_file_observer_name, R.string
.notification_channel_file_observer_description, context);
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_PUSH,
R.string.notification_channel_push_name, R.string
.notification_channel_push_description, context, NotificationManager.IMPORTANCE_DEFAULT);
R.string.notification_channel_push_name, R.string
.notification_channel_push_description, context, NotificationManager.IMPORTANCE_DEFAULT);
createChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_GENERAL, R.string
.notification_channel_general_name, R.string.notification_channel_general_description,
context, NotificationManager.IMPORTANCE_DEFAULT);
.notification_channel_general_name, R.string.notification_channel_general_description,
context, NotificationManager.IMPORTANCE_DEFAULT);
} else {
Log_OC.e(TAG, "Notification manager is null");
}
@ -440,15 +457,15 @@ public class MainApp extends MultiDexApplication implements
String channelId, int channelName,
int channelDescription, Context context) {
createChannel(notificationManager, channelId, channelName, channelDescription, context,
NotificationManager.IMPORTANCE_LOW);
NotificationManager.IMPORTANCE_LOW);
}
private static void createChannel(NotificationManager notificationManager,
String channelId, int channelName,
int channelDescription, Context context, int importance) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O
&& getAppContext() != null
&& notificationManager.getNotificationChannel(channelId) == null) {
&& getAppContext() != null
&& notificationManager.getNotificationChannel(channelId) == null) {
CharSequence name = context.getString(channelName);
String description = context.getString(channelDescription);
NotificationChannel channel = new NotificationChannel(channelId, name, importance);
@ -547,29 +564,29 @@ public class MainApp extends MultiDexApplication implements
}
private static void updateToAutoUpload() {
Context context = getAppContext();
AppPreferences preferences = AppPreferencesImpl.fromContext(context);
if (preferences.instantPictureUploadEnabled() || preferences.instantVideoUploadEnabled()){
preferences.removeLegacyPreferences();
Context context = getAppContext();
AppPreferences preferences = AppPreferencesImpl.fromContext(context);
if (preferences.instantPictureUploadEnabled() || preferences.instantVideoUploadEnabled()) {
preferences.removeLegacyPreferences();
// show info pop-up
try {
new AlertDialog.Builder(context, R.style.Theme_ownCloud_Dialog)
.setTitle(R.string.drawer_synced_folders)
.setMessage(R.string.synced_folders_new_info)
.setPositiveButton(R.string.drawer_open, (dialog, which) -> {
// show Auto Upload
Intent folderSyncIntent = new Intent(context, SyncedFoldersActivity.class);
dialog.dismiss();
context.startActivity(folderSyncIntent);
})
.setNegativeButton(R.string.drawer_close, (dialog, which) -> dialog.dismiss())
.setIcon(R.drawable.nav_synced_folders)
.show();
} catch (WindowManager.BadTokenException e) {
Log_OC.i(TAG, "Error showing Auto Upload Update dialog, so skipping it: " + e.getMessage());
}
// show info pop-up
try {
new AlertDialog.Builder(context, R.style.Theme_ownCloud_Dialog)
.setTitle(R.string.drawer_synced_folders)
.setMessage(R.string.synced_folders_new_info)
.setPositiveButton(R.string.drawer_open, (dialog, which) -> {
// show Auto Upload
Intent folderSyncIntent = new Intent(context, SyncedFoldersActivity.class);
dialog.dismiss();
context.startActivity(folderSyncIntent);
})
.setNegativeButton(R.string.drawer_close, (dialog, which) -> dialog.dismiss())
.setIcon(R.drawable.nav_synced_folders)
.show();
} catch (WindowManager.BadTokenException e) {
Log_OC.i(TAG, "Error showing Auto Upload Update dialog, so skipping it: " + e.getMessage());
}
}
}
private static void updateAutoUploadEntries() {
@ -578,7 +595,7 @@ public class MainApp extends MultiDexApplication implements
AppPreferences preferences = AppPreferencesImpl.fromContext(context);
if (!preferences.isAutoUploadPathsUpdateEnabled()) {
SyncedFolderProvider syncedFolderProvider =
new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences);
new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences);
syncedFolderProvider.updateAutoUploadPaths(mContext);
}
}
@ -604,7 +621,7 @@ public class MainApp extends MultiDexApplication implements
for (SyncedFolder syncedFolder : syncedFolders) {
idsToDelete.add(syncedFolder.getId());
Log_OC.i(TAG, "Migration check for synced_folders record: "
+ syncedFolder.getId() + " - " + syncedFolder.getLocalPath());
+ syncedFolder.getId() + " - " + syncedFolder.getLocalPath());
for (MediaFolder imageMediaFolder : imageMediaFolders) {
if (imageMediaFolder.absolutePath.equals(syncedFolder.getLocalPath())) {
@ -612,7 +629,7 @@ public class MainApp extends MultiDexApplication implements
newSyncedFolder.setType(MediaFolderType.IMAGE);
primaryKey = syncedFolderProvider.storeSyncedFolder(newSyncedFolder);
Log_OC.i(TAG, "Migrated image synced_folders record: "
+ primaryKey + " - " + newSyncedFolder.getLocalPath());
+ primaryKey + " - " + newSyncedFolder.getLocalPath());
break;
}
}
@ -623,7 +640,7 @@ public class MainApp extends MultiDexApplication implements
newSyncedFolder.setType(MediaFolderType.VIDEO);
primaryKey = syncedFolderProvider.storeSyncedFolder(newSyncedFolder);
Log_OC.i(TAG, "Migrated video synced_folders record: "
+ primaryKey + " - " + newSyncedFolder.getLocalPath());
+ primaryKey + " - " + newSyncedFolder.getLocalPath());
break;
}
}
@ -643,7 +660,7 @@ public class MainApp extends MultiDexApplication implements
AppPreferences preferences = AppPreferencesImpl.fromContext(getAppContext());
if (!preferences.isAutoUploadInitialized()) {
SyncedFolderProvider syncedFolderProvider =
new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences);
new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences);
for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) {
if (syncedFolder.isEnabled()) {
@ -666,7 +683,7 @@ public class MainApp extends MultiDexApplication implements
if (!preferences.isLegacyClean()) {
SyncedFolderProvider syncedFolderProvider =
new SyncedFolderProvider(context.getContentResolver(), preferences);
new SyncedFolderProvider(context.getContentResolver(), preferences);
List<SyncedFolder> syncedFolderList = syncedFolderProvider.getSyncedFolders();
Map<Pair<String, String>, Long> syncedFolders = new HashMap<>();
@ -686,7 +703,7 @@ public class MainApp extends MultiDexApplication implements
if (ids.size() > 0) {
int deletedCount = syncedFolderProvider.deleteSyncedFoldersNotInList(ids);
if(deletedCount > 0) {
if (deletedCount > 0) {
preferences.setLegacyClean(true);
}
} else {

View file

@ -28,6 +28,7 @@ import android.content.Context;
import android.content.Intent;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.UploadsStorageManager;
@ -49,6 +50,7 @@ public class BootupBroadcastReceiver extends BroadcastReceiver {
@Inject UserAccountManager accountManager;
@Inject UploadsStorageManager uploadsStorageManager;
@Inject ConnectivityService connectivityService;
@Inject PowerManagementService powerManagementService;
/**
* Receives broadcast intent reporting that the system was just boot up.
@ -61,7 +63,10 @@ public class BootupBroadcastReceiver extends BroadcastReceiver {
AndroidInjection.inject(this, context);
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
MainApp.initSyncOperations(uploadsStorageManager, accountManager, connectivityService);
MainApp.initSyncOperations(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
MainApp.initContactsBackup(accountManager);
} else {
Log_OC.d(TAG, "Getting wrong intent: " + intent.getAction());

View file

@ -49,10 +49,10 @@ import android.util.Pair;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.Device;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
@ -74,7 +74,6 @@ import com.owncloud.android.ui.activity.FileActivity;
import com.owncloud.android.ui.activity.UploadListActivity;
import com.owncloud.android.ui.notifications.NotificationUtils;
import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.PowerUtils;
import com.owncloud.android.utils.ThemeUtils;
import org.jetbrains.annotations.NotNull;
@ -186,6 +185,7 @@ public class FileUploader extends Service
//since there can be only one instance of an Android service, there also just one db connection.
@Inject UploadsStorageManager mUploadsStorageManager;
@Inject ConnectivityService connectivityService;
@Inject PowerManagementService powerManagementService;
private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<>();
@ -399,6 +399,7 @@ public class FileUploader extends Service
@NotNull final UploadsStorageManager uploadsStorageManager,
@NotNull final ConnectivityService connectivityService,
@NotNull final UserAccountManager accountManager,
@NotNull final PowerManagementService powerManagementService,
@Nullable final UploadResult uploadResult
) {
OCUpload[] failedUploads = uploadsStorageManager.getFailedUploads();
@ -410,7 +411,7 @@ public class FileUploader extends Service
!connectivityService.isInternetWalled();
boolean gotWifi = gotNetwork && Device.getNetworkType(context).equals(JobRequest.NetworkType.UNMETERED);
boolean charging = Device.getBatteryStatus(context).isCharging();
boolean isPowerSaving = PowerUtils.isPowerSaveMode(context);
boolean isPowerSaving = powerManagementService.isPowerSavingEnabled();
for ( OCUpload failedUpload: failedUploads) {
accountMatch = account == null || account.name.equals(failedUpload.getAccountName());
@ -641,6 +642,7 @@ public class FileUploader extends Service
newUpload = new UploadFileOperation(
mUploadsStorageManager,
connectivityService,
powerManagementService,
account,
file,
ocUpload,
@ -701,6 +703,7 @@ public class FileUploader extends Service
UploadFileOperation newUpload = new UploadFileOperation(
mUploadsStorageManager,
connectivityService,
powerManagementService,
account,
null,
upload,
@ -986,7 +989,7 @@ public class FileUploader extends Service
cancel(mCurrentUpload.getAccount().name, mCurrentUpload.getFile().getRemotePath()
, ResultCode.DELAYED_FOR_CHARGING);
} else if (!mCurrentUpload.isIgnoringPowerSaveMode() &&
PowerUtils.isPowerSaveMode(MainApp.getAppContext())) {
powerManagementService.isPowerSavingEnabled()) {
cancel(mCurrentUpload.getAccount().name, mCurrentUpload.getFile().getRemotePath()
, ResultCode.DELAYED_IN_POWER_SAVE_MODE);
}

View file

@ -34,6 +34,7 @@ import android.text.TextUtils;
import com.evernote.android.job.Job;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.MainApp;
@ -52,7 +53,6 @@ import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.FilesSyncHelper;
import com.owncloud.android.utils.MimeType;
import com.owncloud.android.utils.MimeTypeUtil;
import com.owncloud.android.utils.PowerUtils;
import java.io.File;
import java.text.ParsePosition;
@ -74,7 +74,7 @@ import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR;
*/
public class FilesSyncJob extends Job {
public static final String TAG = "FilesSyncJob";
public static final String SKIP_CUSTOM = "skipCustom";
static final String SKIP_CUSTOM = "skipCustom";
public static final String OVERRIDE_POWER_SAVING = "overridePowerSaving";
private static final String WAKELOCK_TAG_SEPARATION = ":";
@ -82,17 +82,18 @@ public class FilesSyncJob extends Job {
private AppPreferences preferences;
private UploadsStorageManager uploadsStorageManager;
private ConnectivityService connectivityService;
private PowerManagementService powerManagementService;
public FilesSyncJob(
final UserAccountManager userAccountManager,
final AppPreferences preferences,
final UploadsStorageManager uploadsStorageManager,
final ConnectivityService connectivityService
) {
FilesSyncJob(final UserAccountManager userAccountManager,
final AppPreferences preferences,
final UploadsStorageManager uploadsStorageManager,
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService) {
this.userAccountManager = userAccountManager;
this.preferences = preferences;
this.uploadsStorageManager = uploadsStorageManager;
this.connectivityService = connectivityService;
this.powerManagementService = powerManagementService;
}
@NonNull
@ -112,8 +113,10 @@ public class FilesSyncJob extends Job {
final boolean overridePowerSaving = bundle.getBoolean(OVERRIDE_POWER_SAVING, false);
// If we are in power save mode, better to postpone upload
if (PowerUtils.isPowerSaveMode(context) && !overridePowerSaving) {
wakeLock.release();
if (powerManagementService.isPowerSavingEnabled() && !overridePowerSaving) {
if (wakeLock != null) {
wakeLock.release();
}
return Result.SUCCESS;
}
@ -121,7 +124,10 @@ public class FilesSyncJob extends Job {
boolean lightVersion = resources.getBoolean(R.bool.syncedFolder_light);
final boolean skipCustom = bundle.getBoolean(SKIP_CUSTOM, false);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, userAccountManager, connectivityService);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager,
userAccountManager,
connectivityService,
powerManagementService);
FilesSyncHelper.insertAllDBEntries(preferences, skipCustom);
// Create all the providers we'll need

View file

@ -29,6 +29,7 @@ import android.content.Context;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.datamodel.UploadsStorageManager;
@ -46,19 +47,22 @@ public class NCJobCreator implements JobCreator {
private final AppPreferences preferences;
private final UploadsStorageManager uploadsStorageManager;
private final ConnectivityService connectivityService;
private final PowerManagementService powerManagementService;
public NCJobCreator(
Context context,
UserAccountManager accountManager,
AppPreferences preferences,
UploadsStorageManager uploadsStorageManager,
ConnectivityService connectivityServices
ConnectivityService connectivityServices,
PowerManagementService powerManagementService
) {
this.context = context;
this.accountManager = accountManager;
this.preferences = preferences;
this.uploadsStorageManager = uploadsStorageManager;
this.connectivityService = connectivityServices;
this.powerManagementService = powerManagementService;
}
@Override
@ -71,9 +75,13 @@ public class NCJobCreator implements JobCreator {
case AccountRemovalJob.TAG:
return new AccountRemovalJob(uploadsStorageManager, accountManager);
case FilesSyncJob.TAG:
return new FilesSyncJob(accountManager, preferences, uploadsStorageManager, connectivityService);
return new FilesSyncJob(accountManager,
preferences,
uploadsStorageManager,
connectivityService,
powerManagementService);
case OfflineSyncJob.TAG:
return new OfflineSyncJob(accountManager, connectivityService);
return new OfflineSyncJob(accountManager, connectivityService, powerManagementService);
case NotificationJob.TAG:
return new NotificationJob(context, accountManager);
case MediaFoldersDetectionJob.TAG:

View file

@ -27,12 +27,15 @@ import android.os.Build;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.nextcloud.client.preferences.AppPreferencesImpl;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.datamodel.SyncedFolderProvider;
import com.owncloud.android.utils.FilesSyncHelper;
import com.owncloud.android.utils.PowerUtils;
import javax.inject.Inject;
import androidx.annotation.RequiresApi;
import dagger.android.AndroidInjection;
/*
Job that triggers new FilesSyncJob in case new photo or video were detected
@ -40,6 +43,16 @@ import androidx.annotation.RequiresApi;
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class NContentObserverJob extends JobService {
@Inject PowerManagementService powerManagementService;
@Inject AppPreferences preferences;
@Override
public void onCreate() {
super.onCreate();
AndroidInjection.inject(this);
}
@Override
public boolean onStartJob(JobParameters params) {
@ -65,9 +78,8 @@ public class NContentObserverJob extends JobService {
}
private void checkAndStartFileSyncJob() {
if (!PowerUtils.isPowerSaveMode(getApplicationContext()) &&
new SyncedFolderProvider(getContentResolver(),
AppPreferencesImpl.fromContext(getApplicationContext())).countEnabledSyncedFolders() > 0) {
if (!powerManagementService.isPowerSavingEnabled() &&
new SyncedFolderProvider(getContentResolver(), preferences).countEnabledSyncedFolders() > 0) {
PersistableBundleCompat persistableBundleCompat = new PersistableBundleCompat();
persistableBundleCompat.putBoolean(FilesSyncJob.SKIP_CUSTOM, true);

View file

@ -30,6 +30,7 @@ import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.FileDataStorageManager;
@ -39,7 +40,6 @@ import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.files.CheckEtagRemoteOperation;
import com.owncloud.android.operations.SynchronizeFileOperation;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.PowerUtils;
import java.io.File;
import java.util.Set;
@ -55,10 +55,12 @@ public class OfflineSyncJob extends Job {
private static final String WAKELOCK_TAG_SEPARATION = ":";
private final UserAccountManager userAccountManager;
private final ConnectivityService connectivityService;
private final PowerManagementService powerManagementService;
public OfflineSyncJob(UserAccountManager userAccountManager, ConnectivityService connectivityService) {
OfflineSyncJob(UserAccountManager userAccountManager, ConnectivityService connectivityService, PowerManagementService powerManagementService) {
this.userAccountManager = userAccountManager;
this.connectivityService = connectivityService;
this.powerManagementService = powerManagementService;
}
@NonNull
@ -67,7 +69,7 @@ public class OfflineSyncJob extends Job {
final Context context = getContext();
PowerManager.WakeLock wakeLock = null;
if (!PowerUtils.isPowerSaveMode(context) &&
if (!powerManagementService.isPowerSavingEnabled() &&
connectivityService.getActiveNetworkType() == JobRequest.NetworkType.UNMETERED &&
!connectivityService.isInternetWalled()) {
Set<Job> jobs = JobManager.instance().getAllJobsForTag(TAG);

View file

@ -32,6 +32,7 @@ import android.util.Log;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.Device;
import com.google.gson.reflect.TypeToken;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.DecryptedFolderMetadata;
@ -65,7 +66,6 @@ import com.owncloud.android.utils.EncryptionUtils;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.MimeType;
import com.owncloud.android.utils.MimeTypeUtil;
import com.owncloud.android.utils.PowerUtils;
import com.owncloud.android.utils.UriUtils;
import org.apache.commons.httpclient.HttpStatus;
@ -147,6 +147,7 @@ public class UploadFileOperation extends SyncOperation {
final private OCUpload mUpload;
final private UploadsStorageManager uploadsStorageManager;
final private ConnectivityService connectivityService;
final private PowerManagementService powerManagementService;
private boolean encryptedAncestor;
@ -178,6 +179,7 @@ public class UploadFileOperation extends SyncOperation {
public UploadFileOperation(UploadsStorageManager uploadsStorageManager,
ConnectivityService connectivityService,
PowerManagementService powerManagementService,
Account account,
OCFile file,
OCUpload upload,
@ -201,6 +203,7 @@ public class UploadFileOperation extends SyncOperation {
this.uploadsStorageManager = uploadsStorageManager;
this.connectivityService = connectivityService;
this.powerManagementService = powerManagementService;
mAccount = account;
mUpload = upload;
if (file == null) {
@ -742,7 +745,7 @@ public class UploadFileOperation extends SyncOperation {
}
// check that device is not in power save mode
if (!mIgnoringPowerSaveMode && PowerUtils.isPowerSaveMode(mContext)) {
if (!mIgnoringPowerSaveMode && powerManagementService.isPowerSavingEnabled()) {
Log_OC.d(TAG, "Upload delayed because device is in power save mode: " + getRemotePath());
remoteOperationResult = new RemoteOperationResult(ResultCode.DELAYED_IN_POWER_SAVE_MODE);
}

View file

@ -45,6 +45,7 @@ import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.UploadsStorageManager;
@ -117,6 +118,9 @@ public class UploadListActivity extends FileActivity {
@Inject
ConnectivityService connectivityService;
@Inject
PowerManagementService powerManagementService;
@Override
public void showFiles(boolean onDeviceOnly) {
super.showFiles(onDeviceOnly);
@ -180,7 +184,8 @@ public class UploadListActivity extends FileActivity {
uploadListAdapter = new UploadListAdapter(this,
uploadsStorageManager,
userAccountManager,
connectivityService);
connectivityService,
powerManagementService);
final GridLayoutManager lm = new GridLayoutManager(this, 1);
uploadListAdapter.setLayoutManager(lm);
@ -229,6 +234,7 @@ public class UploadListActivity extends FileActivity {
uploadsStorageManager,
connectivityService,
userAccountManager,
powerManagementService,
null)).start();
// update UI
@ -301,7 +307,10 @@ public class UploadListActivity extends FileActivity {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FileActivity.REQUEST_CODE__UPDATE_CREDENTIALS && resultCode == RESULT_OK) {
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, userAccountManager, connectivityService);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager,
userAccountManager,
connectivityService,
powerManagementService);
}
}
@ -321,7 +330,10 @@ public class UploadListActivity extends FileActivity {
} else {
// already updated -> just retry!
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, userAccountManager, connectivityService);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager,
userAccountManager,
connectivityService,
powerManagementService);
}
} else {

View file

@ -41,6 +41,7 @@ import android.widget.TextView;
import com.afollestad.sectionedrecyclerview.SectionedRecyclerViewAdapter;
import com.afollestad.sectionedrecyclerview.SectionedViewHolder;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
@ -74,6 +75,7 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
private FileActivity parentActivity;
private UploadsStorageManager uploadsStorageManager;
private ConnectivityService connectivityService;
private PowerManagementService powerManagementService;
private UserAccountManager accountManager;
private UploadGroup[] uploadGroups;
@ -133,6 +135,7 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
uploadsStorageManager,
connectivityService,
accountManager,
powerManagementService,
null))
.start();
break;
@ -154,12 +157,14 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
public UploadListAdapter(final FileActivity fileActivity,
final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService) {
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService) {
Log_OC.d(TAG, "UploadListAdapter");
this.parentActivity = fileActivity;
this.uploadsStorageManager = uploadsStorageManager;
this.accountManager = accountManager;
this.connectivityService = connectivityService;
this.powerManagementService = powerManagementService;
uploadGroups = new UploadGroup[3];
shouldShowHeadersForEmptySections(false);

View file

@ -39,6 +39,7 @@ import android.util.Log;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.MainApp;
@ -218,7 +219,8 @@ public final class FilesSyncHelper {
public static void restartJobsIfNeeded(final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService) {
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService) {
final Context context = MainApp.getAppContext();
FileUploader.UploadRequester uploadRequester = new FileUploader.UploadRequester();
@ -251,6 +253,7 @@ public final class FilesSyncHelper {
uploadsStorageManager,
connectivityService,
accountManager,
powerManagementService,
null);
}
}).start();

View file

@ -1,28 +0,0 @@
package com.owncloud.android.utils;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.PowerManager;
public final class PowerUtils {
private PowerUtils() {
// utility class -> private constructor
}
/**
* Checks if device is in power save mode. For older devices that do not support this API, returns false.
* @return true if it is, false otherwise.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static boolean isPowerSaveMode(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return powerManager != null && powerManager.isPowerSaveMode();
}
// For older versions, we just say that device is not in power save mode
return false;
}
}

View file

@ -30,6 +30,7 @@ import android.content.IntentFilter;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.Device;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.UploadsStorageManager;
@ -43,11 +44,10 @@ public final class ReceiversHelper {
// utility class -> private constructor
}
public static void registerNetworkChangeReceiver(
final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService
) {
public static void registerNetworkChangeReceiver(final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService) {
Context context = MainApp.getAppContext();
IntentFilter intentFilter = new IntentFilter();
@ -58,7 +58,10 @@ public final class ReceiversHelper {
@Override
public void onReceive(Context context, Intent intent) {
if (!Device.getNetworkType(context).equals(JobRequest.NetworkType.ANY)) {
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, accountManager, connectivityService);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
}
}
};
@ -69,7 +72,8 @@ public final class ReceiversHelper {
public static void registerPowerChangeReceiver(
final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService
) {
Context context = MainApp.getAppContext();
@ -81,7 +85,10 @@ public final class ReceiversHelper {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())) {
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, accountManager, connectivityService);
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
}
}
};
@ -92,8 +99,9 @@ public final class ReceiversHelper {
public static void registerPowerSaveReceiver(
final UploadsStorageManager uploadsStorageManager,
final UserAccountManager accountManager,
final ConnectivityService connectivityService
) {
final ConnectivityService connectivityService,
final PowerManagementService powerManagementService
) {
Context context = MainApp.getAppContext();
IntentFilter intentFilter = new IntentFilter();
@ -102,8 +110,11 @@ public final class ReceiversHelper {
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!PowerUtils.isPowerSaveMode(context)) {
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager, accountManager, connectivityService);
if (!powerManagementService.isPowerSavingEnabled()) {
FilesSyncHelper.restartJobsIfNeeded(uploadsStorageManager,
accountManager,
connectivityService,
powerManagementService);
}
}
};

View file

@ -1,78 +0,0 @@
/*
* Nextcloud Android client application
*
* @author Edvard Holst
* Copyright (C) 2019 Edvard Holst
* Copyright (C) 2019 Nextcloud GmbH
*
* 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 3 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 <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.utils;
import android.content.Context;
import android.os.Build;
import android.os.PowerManager;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
public class PowerUtilsTest {
@Mock
private Context mContext;
@Mock
private PowerManager mPowerManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
private static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
@Test
public void isPowerSaveMode_assertCorrectlyReportsTrue() throws Exception {
setFinalStatic(Build.VERSION.class.getField("SDK_INT"), Build.VERSION_CODES.O);
when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
when(mPowerManager.isPowerSaveMode()).thenReturn(true);
assertTrue("Incorrectly reported power saving mode on",
PowerUtils.isPowerSaveMode(mContext));
}
@Test
public void isPowerSaveMode_assertCorrectlyReportsFalse() throws Exception {
setFinalStatic(Build.VERSION.class.getField("SDK_INT"), Build.VERSION_CODES.O);
when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
when(mPowerManager.isPowerSaveMode()).thenReturn(false);
assertFalse("Incorrectly reported power saving mode off",
PowerUtils.isPowerSaveMode(mContext));
}
}