Optimize battery optimize page control flow

- Post the setup logic into background and setup once only when leaving
 this page, this can improve the performance since we won't setup
 every time when switching preference

Bug: 195306545
Bug: 199892006
Test: make SettingsRoboTests
Change-Id: I1c3ee4673cf5cdba0abe39f208dfb1412082c579
This commit is contained in:
Wesley.CW Wang
2021-10-28 16:20:55 +08:00
parent 9b325cd54f
commit 151b88f76f
11 changed files with 89 additions and 86 deletions

View File

@@ -282,6 +282,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
}
}
@Override
public void onPause() {
super.onPause();
if (mEnableTriState) {
Log.d(TAG, "Leave with mode: " + getSelectedPreference());
mBatteryOptimizeUtils.setAppUsageState(getSelectedPreference());
}
}
@Override
public void onDestroy() {
super.onDestroy();
@@ -490,6 +499,18 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
}
private int getSelectedPreference() {
if (mRestrictedPreference.isChecked()) {
return BatteryOptimizeUtils.MODE_RESTRICTED;
} else if (mUnrestrictedPreference.isChecked()) {
return BatteryOptimizeUtils.MODE_UNRESTRICTED;
} else if (mOptimizePreference.isChecked()) {
return BatteryOptimizeUtils.MODE_OPTIMIZED;
} else {
return BatteryOptimizeUtils.MODE_UNKNOWN;
}
}
private CharSequence getAppActiveTime(Bundle bundle) {
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);

View File

@@ -29,8 +29,8 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.os.Build;
import android.os.IDeviceIdleController;
import android.os.RemoteException;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
@@ -230,7 +230,7 @@ public final class BatteryBackupHelper implements BackupHelper {
mBatteryOptimizeUtils != null
? mBatteryOptimizeUtils /*testing only*/
: new BatteryOptimizeUtils(mContext, uid, packageName);
batteryOptimizeUtils.setAppOptimizationMode(mode);
batteryOptimizeUtils.setAppUsageState(mode);
Log.d(TAG, String.format("restore:%s mode=%d", packageName, mode));
}

View File

@@ -19,6 +19,7 @@ package com.android.settings.fuelgauge;
import android.annotation.IntDef;
import android.app.AppOpsManager;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -89,36 +90,28 @@ public class BatteryOptimizeUtils {
return getAppOptimizationMode(mMode, mAllowListed);
}
public void setAppOptimizationMode(@OptimizationMode int mode) {
try {
setAppUsageStateInternal(mode);
} catch (Exception e) {
Log.e(TAG, "setAppUsageState() is failed for " + mPackageName, e);
}
}
/** Sets the {@link OptimizationMode} for associated app. */
public void setAppUsageStateInternal(@OptimizationMode int mode) {
public void setAppUsageState(@OptimizationMode int mode) {
if (getAppOptimizationMode(mMode, mAllowListed) == mode) {
Log.w(TAG, "set the same optimization mode for: " + mPackageName);
return;
}
switch (mode) {
case MODE_RESTRICTED:
mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_IGNORED);
mPowerAllowListBackend.removeApp(mPackageName);
break;
case MODE_UNRESTRICTED:
mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_ALLOWED);
mPowerAllowListBackend.addApp(mPackageName);
break;
case MODE_OPTIMIZED:
mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_ALLOWED);
mPowerAllowListBackend.removeApp(mPackageName);
break;
default:
Log.d(TAG, "set unknown app optimization mode.");
}
AsyncTask.execute(() -> {
switch (mode) {
case MODE_RESTRICTED:
setAppOptimizationMode(AppOpsManager.MODE_IGNORED, /* allowListed */ false);
break;
case MODE_UNRESTRICTED:
setAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ true);
break;
case MODE_OPTIMIZED:
setAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ false);
break;
default:
Log.d(TAG, "set unknown app optimization mode.");
}
});
}
/**
@@ -142,6 +135,19 @@ public class BatteryOptimizeUtils {
return mPackageName == null ? UNKNOWN_PACKAGE : mPackageName;
}
private void setAppOptimizationMode(int appStandbyMode, boolean allowListed) {
try {
mBatteryUtils.setForceAppStandby(mUid, mPackageName, appStandbyMode);
if (allowListed) {
mPowerAllowListBackend.addApp(mPackageName);
} else {
mPowerAllowListBackend.removeApp(mPackageName);
}
} catch (Exception e) {
Log.e(TAG, "set OPTIMIZED failed for " + mPackageName, e);
}
}
private void refreshState() {
mPowerAllowListBackend.refreshList();
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);

View File

@@ -73,12 +73,6 @@ public class OptimizedPreferenceController extends AbstractPreferenceController
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!KEY_OPTIMIZED_PREF.equals(preference.getKey())) {
return false;
}
mBatteryOptimizeUtils.setAppOptimizationMode(BatteryOptimizeUtils.MODE_OPTIMIZED);
Log.d(TAG, "Set optimized");
return true;
return getPreferenceKey().equals(preference.getKey());
}
}

View File

@@ -76,12 +76,6 @@ public class RestrictedPreferenceController extends AbstractPreferenceController
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!KEY_RESTRICTED_PREF.equals(preference.getKey())) {
return false;
}
mBatteryOptimizeUtils.setAppOptimizationMode(BatteryOptimizeUtils.MODE_RESTRICTED);
Log.d(TAG, "Set restricted");
return true;
return getPreferenceKey().equals(preference.getKey());
}
}

View File

@@ -74,12 +74,6 @@ public class UnrestrictedPreferenceController extends AbstractPreferenceControll
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!KEY_UNRESTRICTED_PREF.equals(preference.getKey())) {
return false;
}
mBatteryOptimizeUtils.setAppOptimizationMode(BatteryOptimizeUtils.MODE_UNRESTRICTED);
Log.d(TAG, "Set unrestricted");
return true;
return getPreferenceKey().equals(preference.getKey());
}
}

View File

@@ -20,6 +20,7 @@ import static com.android.settings.fuelgauge.BatteryBackupHelper.DELIMITER;
import static com.android.settings.fuelgauge.BatteryBackupHelper.DELIMITER_MODE;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_RESTRICTED;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -33,7 +34,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.app.backup.BackupDataInputStream;
@@ -51,9 +51,6 @@ import android.os.UserManager;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -69,6 +66,10 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {BatteryBackupHelperTest.ShadowUserHandle.class})
public final class BatteryBackupHelperTest {
@@ -305,10 +306,11 @@ public final class BatteryBackupHelperTest {
PACKAGE_NAME2 + DELIMITER_MODE + invalidNumberFormat;
mBatteryBackupHelper.restoreOptimizationMode(packageModes.getBytes());
TimeUnit.SECONDS.sleep(1);
final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
inOrder.verify(mBatteryOptimizeUtils).setAppOptimizationMode(MODE_RESTRICTED);
inOrder.verify(mBatteryOptimizeUtils, never()).setAppOptimizationMode(anyInt());
inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(MODE_RESTRICTED);
inOrder.verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt());
}
@Test
@@ -319,11 +321,12 @@ public final class BatteryBackupHelperTest {
PACKAGE_NAME3 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER;
mBatteryBackupHelper.restoreOptimizationMode(packageModes.getBytes());
TimeUnit.SECONDS.sleep(1);
final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
inOrder.verify(mBatteryOptimizeUtils).setAppOptimizationMode(MODE_RESTRICTED);
inOrder.verify(mBatteryOptimizeUtils).setAppOptimizationMode(MODE_UNRESTRICTED);
inOrder.verify(mBatteryOptimizeUtils, never()).setAppOptimizationMode(MODE_RESTRICTED);
inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(MODE_RESTRICTED);
inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(MODE_UNRESTRICTED);
inOrder.verify(mBatteryOptimizeUtils, never()).setAppUsageState(MODE_RESTRICTED);
}
private void mockUid(int uid, String packageName) throws Exception {

View File

@@ -42,6 +42,8 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.concurrent.TimeUnit;
@RunWith(RobolectricTestRunner.class)
public class BatteryOptimizeUtilsTest {
@@ -125,12 +127,13 @@ public class BatteryOptimizeUtilsTest {
}
@Test
public void testSetAppOptimizationMode_Restricted_verifyAction() {
public void testSetAppUsageState_Restricted_verifyAction() throws Exception {
// Sets the current mode as MODE_UNRESTRICTED.
mBatteryOptimizeUtils.mAllowListed = false;
mBatteryOptimizeUtils.mMode = AppOpsManager.MODE_ALLOWED;
mBatteryOptimizeUtils.setAppOptimizationMode(MODE_RESTRICTED);
mBatteryOptimizeUtils.setAppUsageState(MODE_RESTRICTED);
TimeUnit.SECONDS.sleep(1);
verify(mMockBatteryUtils).setForceAppStandby(UID,
PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
@@ -138,8 +141,9 @@ public class BatteryOptimizeUtilsTest {
}
@Test
public void testSetAppOptimizationMode_Unrestricted_verifyAction() {
mBatteryOptimizeUtils.setAppOptimizationMode(MODE_UNRESTRICTED);
public void testSetAppUsageState_Unrestricted_verifyAction() throws Exception {
mBatteryOptimizeUtils.setAppUsageState(MODE_UNRESTRICTED);
TimeUnit.SECONDS.sleep(1);
verify(mMockBatteryUtils).setForceAppStandby(UID,
PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
@@ -147,8 +151,9 @@ public class BatteryOptimizeUtilsTest {
}
@Test
public void testSetAppOptimizationMode_Optimized_verifyAction() {
mBatteryOptimizeUtils.setAppOptimizationMode(MODE_OPTIMIZED);
public void testSetAppUsageState_Optimized_verifyAction() throws Exception {
mBatteryOptimizeUtils.setAppUsageState(MODE_OPTIMIZED);
TimeUnit.SECONDS.sleep(1);
verify(mMockBatteryUtils).setForceAppStandby(UID,
PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
@@ -156,12 +161,13 @@ public class BatteryOptimizeUtilsTest {
}
@Test
public void testSetAppOptimizationMode_sameUnrestrictedMode_verifyNoAction() {
public void testSetAppUsageState_sameUnrestrictedMode_verifyNoAction() throws Exception {
// Sets the current mode as MODE_UNRESTRICTED.
mBatteryOptimizeUtils.mAllowListed = true;
mBatteryOptimizeUtils.mMode = AppOpsManager.MODE_ALLOWED;
mBatteryOptimizeUtils.setAppOptimizationMode(MODE_UNRESTRICTED);
mBatteryOptimizeUtils.setAppUsageState(MODE_UNRESTRICTED);
TimeUnit.SECONDS.sleep(1);
verifyZeroInteractions(mMockBackend);
verifyZeroInteractions(mMockBatteryUtils);

View File

@@ -18,8 +18,6 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import com.android.settingslib.widget.RadioButtonPreference;
@@ -98,14 +96,11 @@ public class OptimizedPreferenceControllerTest {
mPreference.setKey(mController.KEY_OPTIMIZED_PREF);
mController.handlePreferenceTreeClick(mPreference);
verify(mockBatteryOptimizeUtils).setAppOptimizationMode(
BatteryOptimizeUtils.MODE_OPTIMIZED);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
}
@Test
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
mController.handlePreferenceTreeClick(mPreference);
verifyZeroInteractions(mockBatteryOptimizeUtils);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
}
}

View File

@@ -18,8 +18,6 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import com.android.settingslib.widget.RadioButtonPreference;
@@ -106,14 +104,11 @@ public class RestrictedPreferenceControllerTest {
mPreference.setKey(mController.KEY_RESTRICTED_PREF);
mController.handlePreferenceTreeClick(mPreference);
verify(mockBatteryOptimizeUtils).setAppOptimizationMode(
BatteryOptimizeUtils.MODE_RESTRICTED);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
}
@Test
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
mController.handlePreferenceTreeClick(mPreference);
verifyZeroInteractions(mockBatteryOptimizeUtils);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
}
}

View File

@@ -19,8 +19,6 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import com.android.settingslib.widget.RadioButtonPreference;
@@ -106,14 +104,11 @@ public class UnrestrictedPreferenceControllerTest {
mPreference.setKey(mController.KEY_UNRESTRICTED_PREF);
mController.handlePreferenceTreeClick(mPreference);
verify(mockBatteryOptimizeUtils).setAppOptimizationMode(
BatteryOptimizeUtils.MODE_UNRESTRICTED);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
}
@Test
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
mController.handlePreferenceTreeClick(mPreference);
verifyZeroInteractions(mockBatteryOptimizeUtils);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
}
}