Skip to content

Commit

Permalink
show on special vendors "disable power check" in auto upload menu
Browse files Browse the repository at this point in the history
- tint button
- change logic when to show battery warning

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
  • Loading branch information
tobiasKaminsky committed Aug 20, 2019
1 parent c8173c3 commit e72a789
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.nextcloud.client.device
package com.nextcloud.client.device;

import android.content.Context
import android.os.PowerManager
import dagger.Module
import dagger.Provides
import android.content.Context;
import android.os.PowerManager;

@Module
class DeviceModule {
import com.nextcloud.client.preferences.AppPreferences;

import dagger.Module;
import dagger.Provides;

@Module
public class DeviceModule {
@Provides
fun powerManagementService(context: Context): PowerManagementService {
val platformPowerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
return PowerManagementServiceImpl(
context = context,
powerManager = platformPowerManager,
deviceInfo = DeviceInfo()
)
PowerManagementService powerManagementService(Context context, AppPreferences preferences) {
PowerManager platformPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

return new PowerManagementServiceImpl(context, platformPowerManager, preferences, new DeviceInfo());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import android.os.PowerManager
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.client.preferences.AppPreferencesImpl

internal class PowerManagementServiceImpl(
private val context: Context,
private val powerManager: PowerManager,
private val preferences: AppPreferences,
private val deviceInfo: DeviceInfo = DeviceInfo()
) : PowerManagementService {

Expand All @@ -41,10 +44,22 @@ internal class PowerManagementServiceImpl(
* break application experience.
*/
val OVERLY_AGGRESSIVE_POWER_SAVING_VENDORS = setOf("samsung", "huawei", "xiaomi")

@JvmStatic
fun fromContext(context: Context): PowerManagementServiceImpl {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val preferences = AppPreferencesImpl.fromContext(context)

return PowerManagementServiceImpl(context, powerManager, preferences, DeviceInfo())
}
}

override val isPowerSavingEnabled: Boolean
get() {
if (preferences.isPowerCheckDisabled) {
return false
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
if (deviceInfo.apiLevel >= Build.VERSION_CODES.LOLLIPOP) {
return powerManager.isPowerSaveMode
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/nextcloud/client/di/ComponentsModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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.UsersAndGroupsSearchProvider;
Expand Down Expand Up @@ -154,4 +155,6 @@ abstract class ComponentsModule {

@ContributesAndroidInjector abstract AccountManagerService accountManagerService();
@ContributesAndroidInjector abstract OperationsService operationsService();

@ContributesAndroidInjector abstract NContentObserverJob nContentObserverJob();
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,8 @@ public interface AppPreferences {
void setPhotoSearchTimestamp(long timestamp);

long getPhotoSearchTimestamp();

boolean isPowerCheckDisabled();

void setPowerCheckDisabled(boolean value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public final class AppPreferencesImpl implements AppPreferences {
private static final String PREF__SELECTED_ACCOUNT_NAME = "select_oc_account";
private static final String PREF__MIGRATED_USER_ID = "migrated_user_id";
private static final String PREF__PHOTO_SEARCH_TIMESTAMP = "photo_search_timestamp";
private static final String PREF__POWER_CHECK_DISABLED = "power_check_disabled";

private final Context context;
private final SharedPreferences preferences;
Expand Down Expand Up @@ -534,4 +535,14 @@ private static String getKeyFromFolder(String preferenceName, OCFile folder) {

return preferenceName + "_" + folderIdString;
}

@Override
public boolean isPowerCheckDisabled() {
return preferences.getBoolean(PREF__POWER_CHECK_DISABLED, false);
}

@Override
public void setPowerCheckDisabled(boolean value) {
preferences.edit().putBoolean(PREF__POWER_CHECK_DISABLED, value).apply();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@


/**
* App-registered receiver catching the broadcast intent reporting that the system was
* App-registered receiver catching the broadcast intent reporting that the system was
* just boot up.
*/
public class BootupBroadcastReceiver extends BroadcastReceiver {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;

import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.BuildConfig;
Expand Down Expand Up @@ -96,7 +97,6 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA
SyncedFolderPreferencesDialogFragment.OnSyncedFolderPreferenceListener, Injectable {

private static final String[] PRIORITIZED_FOLDERS = new String[]{"Camera", "Screenshots"};
private static final List<String> SPECIAL_MANUFACTURER = Arrays.asList("Samsung", "Huawei", "Xiaomi");
public static final String EXTRA_SHOW_SIDEBAR = "SHOW_SIDEBAR";
private static final String SYNCED_FOLDER_PREFERENCES_DIALOG_TAG = "SYNCED_FOLDER_PREFERENCES_DIALOG";
private static final String TAG = SyncedFoldersActivity.class.getSimpleName();
Expand All @@ -112,6 +112,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA
private String path;
private int type;
@Inject AppPreferences preferences;
@Inject PowerManagementService powerManagementService;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -175,9 +176,42 @@ protected void onCreate(Bundle savedInstanceState) {
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.synced_folders_menu, menu);

if (powerManagementService.isPowerSavingExclusionAvailable()) {
MenuItem item = menu.findItem(R.id.action_disable_power_save_check);
item.setVisible(true);

item.setChecked(preferences.isPowerCheckDisabled());

item.setOnMenuItemClickListener(this::onDisablePowerSaveCheckClicked);
}

return true;
}

private boolean onDisablePowerSaveCheckClicked(MenuItem powerCheck) {
if (!powerCheck.isChecked()) {
showPowerCheckDialog();
}

preferences.setPowerCheckDisabled(!powerCheck.isChecked());
powerCheck.setChecked(!powerCheck.isChecked());

return true;
}

private void showPowerCheckDialog() {
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setView(findViewById(R.id.root_layout))
.setPositiveButton(R.string.common_ok, (dialog, which) -> dialog.dismiss())
.setTitle(ThemeUtils.getColoredTitle(getResources().getString(R.string.autoupload_disable_power_save_check),
ThemeUtils.primaryAccentColor(this)))
.setMessage(getString(R.string.power_save_check_dialog_message))
.show();

alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ThemeUtils.primaryAccentColor(this));
}

/**
* sets up the UI elements and loads all media/synced folders.
*/
Expand Down Expand Up @@ -691,10 +725,7 @@ protected void onResume() {
}

private void showBatteryOptimizationInfo() {

boolean isSpecialManufacturer = SPECIAL_MANUFACTURER.contains(Build.MANUFACTURER.toLowerCase(Locale.ROOT));

if (isSpecialManufacturer && checkIfBatteryOptimizationEnabled() || checkIfBatteryOptimizationEnabled()) {
if (powerManagementService.isPowerSavingExclusionAvailable() || checkIfBatteryOptimizationEnabled()) {
AlertDialog alertDialog = new AlertDialog.Builder(this, R.style.Theme_ownCloud_Dialog)
.setTitle(getString(R.string.battery_optimization_title))
.setMessage(getString(R.string.battery_optimization_message))
Expand Down
6 changes: 6 additions & 0 deletions src/main/res/menu/synced_folders_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@
<item
android:id="@+id/action_create_custom_folder"
android:title="@string/autoupload_custom_folder"/>

<item
android:id="@+id/action_disable_power_save_check"
android:title="@string/autoupload_disable_power_save_check"
android:visible="false"
android:checkable="true" />
</group>
</menu>
3 changes: 2 additions & 1 deletion src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,8 @@
<string name="copy_internal_link">Copy internal link</string>
<string name="copy_internal_link_subline">Only works for users with access to this folder</string>
<string name="failed_to_download">Failed to pass file to download manager</string>

<string name="autoupload_disable_power_save_check">Disable power save check</string>
<string name="power_save_check_dialog_message">Disabling power save check might result in uploading files when in low battery state!</string>
<string name="etm_title">Engineering Test Mode</string>
<string name="etm_preferences">Preferences</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import android.content.Intent
import android.os.BatteryManager
import android.os.Build
import android.os.PowerManager
import com.nextcloud.client.preferences.AppPreferences
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.anyOrNull
import com.nhaarman.mockitokotlin2.eq
Expand Down Expand Up @@ -61,13 +62,17 @@ class TestPowerManagementService {

internal lateinit var powerManagementService: PowerManagementServiceImpl

@Mock
lateinit var preferences: AppPreferences

@Before
fun setUpBase() {
MockitoAnnotations.initMocks(this)
powerManagementService = PowerManagementServiceImpl(
context = context,
powerManager = platformPowerManager,
deviceInfo = deviceInfo
context,
platformPowerManager,
preferences,
deviceInfo
)
}
}
Expand Down Expand Up @@ -120,6 +125,21 @@ class TestPowerManagementService {
whenever(deviceInfo.vendor).thenReturn("some_other_nice_vendor")
assertFalse(powerManagementService.isPowerSavingExclusionAvailable)
}

@Test
fun `power saving check is disabled`() {
// GIVEN
// a device which falsely returns power save mode enabled
// power check is overridden by user
whenever(preferences.isPowerCheckDisabled).thenReturn(true)
whenever(platformPowerManager.isPowerSaveMode).thenReturn(true)

// WHEN
// power save mode is checked
// THEN
// power saving is disabled
assertFalse(powerManagementService.isPowerSavingEnabled)
}
}

class BatteryCharging : Base() {
Expand Down

0 comments on commit e72a789

Please sign in to comment.