Pārlūkot izejas kodu

Merge pull request #4086 from nextcloud/ezaquarii/remove-legacy-power-utils

Migrate PowerUtils calls to PowerManagementService
Andy Scherzinger 5 gadi atpakaļ
vecāks
revīzija
a4a0a28201

+ 0 - 2
build.gradle

@@ -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'

+ 20 - 0
src/androidTest/java/com/owncloud/android/UploadIT.java

@@ -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,

+ 2 - 0
src/main/java/com/nextcloud/client/di/ComponentsModule.java

@@ -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();
 }

+ 84 - 67
src/main/java/com/owncloud/android/MainApp.java

@@ -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();
-
-                // 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());
-                }
+        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());
             }
+        }
     }
 
     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 {

+ 6 - 1
src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java

@@ -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());

+ 7 - 4
src/main/java/com/owncloud/android/files/services/FileUploader.java

@@ -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);
                     }

+ 17 - 11
src/main/java/com/owncloud/android/jobs/FilesSyncJob.java

@@ -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

+ 11 - 3
src/main/java/com/owncloud/android/jobs/NCJobCreator.java

@@ -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:

+ 17 - 5
src/main/java/com/owncloud/android/jobs/NContentObserverJob.java

@@ -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);
 

+ 5 - 3
src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java

@@ -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);

+ 5 - 2
src/main/java/com/owncloud/android/operations/UploadFileOperation.java

@@ -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);
         }

+ 15 - 3
src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java

@@ -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 {

+ 6 - 1
src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java

@@ -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);

+ 4 - 1
src/main/java/com/owncloud/android/utils/FilesSyncHelper.java

@@ -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();

+ 0 - 28
src/main/java/com/owncloud/android/utils/PowerUtils.java

@@ -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;
-    }
-}

+ 23 - 12
src/main/java/com/owncloud/android/utils/ReceiversHelper.java

@@ -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);
                 }
             }
         };

+ 0 - 78
src/test/java/com/owncloud/android/utils/PowerUtilsTest.java

@@ -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));
-    }
-}