Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/src/androidTest/java/com/owncloud/android/AbstractIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ public Connectivity getConnectivity() {
};

PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@Override
public boolean isIgnoringOptimization() {
return true;
}

@NonNull
@Override
public BatteryStatus getBattery() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ public Connectivity getConnectivity() {
};

PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@Override
public boolean isIgnoringOptimization() {
return true;
}

@NonNull
@Override
public BatteryStatus getBattery() {
Expand Down
10 changes: 10 additions & 0 deletions app/src/androidTest/java/com/owncloud/android/UploadIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public Connectivity getConnectivity() {
};

private PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@Override
public boolean isIgnoringOptimization() {
return true;
}

@Override
public boolean isPowerSavingEnabled() {
return false;
Expand Down Expand Up @@ -226,6 +231,11 @@ public void testUploadOnChargingOnlyButNotCharging() {
@Test
public void testUploadOnChargingOnlyAndCharging() {
PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@Override
public boolean isIgnoringOptimization() {
return true;
}

@Override
public boolean isPowerSavingEnabled() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ abstract class FileUploaderIT : AbstractOnServerIT() {
}

private val powerManagementServiceMock: PowerManagementService = object : PowerManagementService {
override val isIgnoringOptimization: Boolean
get() = true

override val isPowerSavingEnabled: Boolean
get() = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ interface PowerManagementService {
*/
val isPowerSavingEnabled: Boolean

/**
* Checks app is excluded from battery optimization or not
*/
val isIgnoringOptimization: Boolean

/**
* Checks current battery status using platform [android.os.BatteryManager]
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ internal class PowerManagementServiceImpl(
}
}

override val isIgnoringOptimization: Boolean
get() {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
return powerManager.isIgnoringBatteryOptimizations(context.packageName)
}

override val isPowerSavingEnabled: Boolean
get() {
return platformPowerManager.isPowerSaveMode
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

package com.nextcloud.ui.component

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.PowerManager
import android.view.View
import com.nextcloud.client.device.PowerManagementService
import com.nextcloud.utils.extensions.setVisibleIf
import com.owncloud.android.databinding.AutoUploadBatterySaverWarningBannerBinding
import com.owncloud.android.utils.theme.ViewThemeUtils

class AutoUploadWarningCardManager(
private val powerManagementService: PowerManagementService,
private val viewThemeUtils: ViewThemeUtils
) {
fun bind(binding: AutoUploadBatterySaverWarningBannerBinding) {
val isBatterySaver = powerManagementService.isPowerSavingEnabled
val isIgnoringOptimization = powerManagementService.isIgnoringOptimization

binding.root.setVisibleIf(isBatterySaver || isIgnoringOptimization)

if (isBatterySaver && isIgnoringOptimization) {
binding.title.visibility = View.VISIBLE
binding.batterySaverReason.visibility = View.VISIBLE
binding.batteryOptimizationReason.visibility = View.VISIBLE
} else if (isBatterySaver) {
binding.title.visibility = View.VISIBLE
binding.batterySaverReason.visibility = View.VISIBLE
} else if (isIgnoringOptimization) {
binding.title.visibility = View.VISIBLE
binding.batteryOptimizationReason.visibility = View.VISIBLE
}

viewThemeUtils.material.themeCardView(binding.root)
}

// region listen power mode changes
private var binding: AutoUploadBatterySaverWarningBannerBinding? = null

private val batterySaverReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == PowerManager.ACTION_POWER_SAVE_MODE_CHANGED) {
binding?.let { bind(it) }
}
}
}

fun register(context: Context, binding: AutoUploadBatterySaverWarningBannerBinding) {
this.binding = binding
bind(binding)
context.registerReceiver(batterySaverReceiver, IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED))
}

fun unregister(context: Context) {
context.unregisterReceiver(batterySaverReceiver)
binding = null
}
// endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.nextcloud.client.jobs.MediaFoldersDetectionWork
import com.nextcloud.client.jobs.NotificationWork
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.preferences.SubFolderRule
import com.nextcloud.ui.component.AutoUploadWarningCardManager
import com.nextcloud.utils.BatteryOptimizationHelper
import com.nextcloud.utils.extensions.getParcelableArgument
import com.nextcloud.utils.extensions.isDialogFragmentReady
Expand Down Expand Up @@ -152,6 +153,8 @@ class SyncedFoldersActivity :
@Inject
lateinit var appInfo: AppInfo

private var autoUploadWarningCardManager: AutoUploadWarningCardManager? = null

lateinit var binding: SyncedFoldersLayoutBinding
lateinit var adapter: SyncedFolderAdapter

Expand All @@ -163,6 +166,7 @@ class SyncedFoldersActivity :
super.onCreate(savedInstanceState)
binding = SyncedFoldersLayoutBinding.inflate(layoutInflater)
setContentView(binding.root)
autoUploadWarningCardManager = AutoUploadWarningCardManager(powerManagementService, viewThemeUtils)
if (intent != null && intent.extras != null) {
val accountName = intent.extras!!.getString(NotificationWork.KEY_NOTIFICATION_ACCOUNT)
val optionalUser = user
Expand Down Expand Up @@ -256,6 +260,9 @@ class SyncedFoldersActivity :
powerManagementService,
connectivityService
)
autoUploadWarningCardManager?.bind(binding.autoUploadBatterySaverWarningCard)
autoUploadWarningCardManager?.register(this, binding.autoUploadBatterySaverWarningCard)

binding.emptyList.emptyListIcon.setImageResource(R.drawable.nav_synced_folders)
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.emptyList.emptyListViewAction)
val lm = GridLayoutManager(this, gridWidth)
Expand All @@ -275,6 +282,11 @@ class SyncedFoldersActivity :
}
}

override fun onDestroy() {
super.onDestroy()
autoUploadWarningCardManager?.unregister(this)
}

/**
* loads all media/synced folders, adds them to the recycler view adapter and shows the list.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.nextcloud.client.jobs.upload.FileUploadEventBroadcaster
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.utils.UploadErrorNotificationManager
import com.nextcloud.client.utils.Throttler
import com.nextcloud.ui.component.AutoUploadWarningCardManager
import com.nextcloud.utils.extensions.webDavParentPath
import com.owncloud.android.R
import com.owncloud.android.databinding.UploadListLayoutBinding
Expand Down Expand Up @@ -72,6 +73,8 @@ class UploadListActivity :

@Inject lateinit var uploadFileOperationFactory: UploadFileOperationFactory

private var autoUploadWarningCardManager: AutoUploadWarningCardManager? = null

private var swipeListRefreshLayout: SwipeRefreshLayout? = null
private var binding: UploadListLayoutBinding? = null

Expand All @@ -87,6 +90,7 @@ class UploadListActivity :
binding = UploadListLayoutBinding.inflate(layoutInflater)
val binding = binding!!
setContentView(binding.getRoot())
autoUploadWarningCardManager = AutoUploadWarningCardManager(powerManagementService, viewThemeUtils)
swipeListRefreshLayout = binding.swipeContainingList

// this activity has no file really bound, it's for multiple accounts at the same time; should no inherit
Expand Down Expand Up @@ -117,6 +121,11 @@ class UploadListActivity :
adapterHelper
)

binding?.autoUploadBatterySaverWarningCard?.let {
autoUploadWarningCardManager?.register(this, it)
autoUploadWarningCardManager?.bind(it)
}

val lm = GridLayoutManager(this, 1)
uploadListAdapter.setLayoutManager(lm)

Expand Down Expand Up @@ -368,6 +377,11 @@ class UploadListActivity :
}
}

override fun onDestroy() {
super.onDestroy()
autoUploadWarningCardManager?.unregister(this)
}

companion object {
private val TAG: String = UploadListActivity::class.java.getSimpleName()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.client.core.Clock
import com.nextcloud.client.device.PowerManagementService
import com.nextcloud.client.network.ConnectivityService
import com.nextcloud.ui.component.AutoUploadWarningCardManager
import com.nextcloud.utils.extensions.calculateScanInterval
import com.nextcloud.utils.extensions.filterEnabledOrWithoutEnabledParent
import com.nextcloud.utils.extensions.hasEnabledParent
Expand Down Expand Up @@ -263,13 +264,6 @@ class SyncedFolderAdapter(
holder.binding.run {
headerContainer.visibility = View.VISIBLE

if (section == 0) {
autoUploadBatterySaverWarningCard.root.run {
setVisibleIf(powerManagementService.isPowerSavingEnabled)
viewThemeUtils.material.themeCardView(this)
}
}

val syncedFolder = filteredSyncFolderItems[section]

title.text = syncedFolder.folderName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ class UploadListAdapter(

bindHeaderTitle(headerViewHolder, group, section)
bindHeaderActionButton(headerViewHolder, group)
bindHeaderBatterySaverWarning(headerViewHolder)
bindHeaderActionClickListener(headerViewHolder, group)
}

Expand Down Expand Up @@ -130,12 +129,6 @@ class UploadListAdapter(
holder.binding.uploadListAction.setImageResource(iconRes)
}

private fun bindHeaderBatterySaverWarning(holder: HeaderViewHolder) {
holder.binding.autoUploadBatterySaverWarningCard.root
.setVisibleIf(powerManagementService.isPowerSavingEnabled)
viewThemeUtils.material.themeCardView(holder.binding.autoUploadBatterySaverWarningCard.root)
}

private fun bindHeaderActionClickListener(holder: HeaderViewHolder, group: UploadListSection) {
holder.binding.uploadListAction.setOnClickListener {
when (group.type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
~ SPDX-FileCopyrightText: 2025 Alper Ozturk <alper.ozturk@nextcloud.com>
~ SPDX-License-Identifier: AGPL-3.0-or-later
-->
<com.google.android.material.card.MaterialCardView
android:id="@+id/root"
<com.google.android.material.card.MaterialCardView android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_rect_8dp"
Expand All @@ -16,7 +15,8 @@
android:elevation="4dp"
android:padding="@dimen/standard_double_margin"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<LinearLayout
android:layout_width="match_parent"
Expand All @@ -28,17 +28,52 @@
<ImageView
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:contentDescription="@string/auto_upload_battery_saver_mode_warning"
android:contentDescription="@null"
android:src="@drawable/ic_warning"
app:tint="@color/log_level_warning" />

<com.google.android.material.textview.MaterialTextView
android:layout_width="0dp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:text="@string/auto_upload_battery_saver_mode_warning"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="@color/text_color" />
android:orientation="vertical">

<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:text="@string/auto_upload_battery_combined_warning"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="@color/text_color"
tools:visibility="visible"
android:visibility="gone"/>

<com.google.android.material.textview.MaterialTextView
android:id="@+id/battery_saver_reason"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:text="@string/auto_upload_battery_saver_reason"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="@color/text_color"
tools:visibility="visible"
android:visibility="gone"/>

<com.google.android.material.textview.MaterialTextView
android:id="@+id/battery_optimization_reason"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:text="@string/auto_upload_battery_optimization_reason"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="@color/text_color"
tools:visibility="visible"
android:visibility="gone"/>

</LinearLayout>

</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<ImageView
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:contentDescription="@string/auto_upload_battery_saver_mode_warning"
android:contentDescription="@null"
android:src="@drawable/ic_warning"
app:tint="@color/log_level_warning" />

Expand Down
Loading
Loading