perf: fix perf profile change issues
Rework profile handling to address the following issues: - When app specific profiles are enabled, the perf service silently changes the profile to BALANCED when the user revisits settings. The service and Settings UI still show whatever pref the user had selected. The user is now unable to change the setting to BALANCED. The perf service ignores the change because the current profile (selected by app profiles) did not change. - When low power mode (battery saver) activates or deactivates, the user selected profile is overwritten. All runtime decisions regarding active profiles have been consolidated in to a single applyProfile() function that handles low power mode, user and app-specific profile rules. App specific profiles are applied only if the power profile is BALANCED. setPowerProfileInternal has been changed to save the user pref even if the active pref is unchanged. Fixes SAMBAR-1088 Change-Id: Iac658959130f08452f5e41ce3339fe4603ac474e
This commit is contained in:
parent
35fdbdab95
commit
37b590928f
|
@ -29,7 +29,6 @@ import android.os.Message;
|
|||
import android.os.Process;
|
||||
import android.os.SystemProperties;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.ServiceThread;
|
||||
|
@ -54,9 +53,8 @@ public class PerformanceManagerService extends SystemService {
|
|||
private Pattern[] mPatterns = null;
|
||||
private int[] mProfiles = null;
|
||||
|
||||
/** Active profile that based on low power mode, user and app rules */
|
||||
private int mCurrentProfile = -1;
|
||||
|
||||
private boolean mProfileSetByUser = false;
|
||||
private int mNumProfiles = 0;
|
||||
|
||||
private final ServiceThread mHandlerThread;
|
||||
|
@ -71,9 +69,11 @@ public class PerformanceManagerService extends SystemService {
|
|||
|
||||
private PowerManagerInternal mPm;
|
||||
private boolean mLowPowerModeEnabled = false;
|
||||
private String mCurrentActivityName = null;
|
||||
|
||||
// Max time (microseconds) to allow a CPU boost for
|
||||
private static final int MAX_CPU_BOOST_TIME = 5000000;
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public PerformanceManagerService(Context context) {
|
||||
super(context);
|
||||
|
@ -90,6 +90,10 @@ public class PerformanceManagerService extends SystemService {
|
|||
if (info.length == 2) {
|
||||
mPatterns[i] = Pattern.compile(info[0]);
|
||||
mProfiles[i] = Integer.valueOf(info[1]);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, String.format("App profile #%d: %s => %s",
|
||||
i, info[0], info[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,15 +119,17 @@ public class PerformanceManagerService extends SystemService {
|
|||
synchronized (this) {
|
||||
mPm = getLocalService(PowerManagerInternal.class);
|
||||
mNumProfiles = mPm.getFeature(POWER_FEATURE_SUPPORTED_PROFILES);
|
||||
Slog.d(TAG, "Supported profiles: " + mNumProfiles);
|
||||
if (mNumProfiles > 0) {
|
||||
int profile = CMSettings.Secure.getInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE,
|
||||
PerformanceManager.PROFILE_BALANCED);
|
||||
int profile = getUserProfile();
|
||||
if (profile == PerformanceManager.PROFILE_HIGH_PERFORMANCE) {
|
||||
profile = PerformanceManager.PROFILE_BALANCED;
|
||||
Slog.i(TAG, String.format("Reverting profile %d to %d",
|
||||
profile, PerformanceManager.PROFILE_BALANCED));
|
||||
setPowerProfileInternal(
|
||||
PerformanceManager.PROFILE_BALANCED, true);
|
||||
} else {
|
||||
setPowerProfileInternal(profile, false);
|
||||
}
|
||||
setPowerProfileInternal(profile, true);
|
||||
|
||||
mPm.registerLowPowerModeObserver(mLowPowerModeListener);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +142,44 @@ public class PerformanceManagerService extends SystemService {
|
|||
CMSettings.Secure.APP_PERFORMANCE_PROFILES_ENABLED, 1) == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the profile saved by the user
|
||||
*/
|
||||
private int getUserProfile() {
|
||||
return CMSettings.Secure.getInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE,
|
||||
PerformanceManager.PROFILE_BALANCED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a power profile and persist if fromUser = true
|
||||
*
|
||||
* @param profile power profile
|
||||
* @param fromUser true to persist the profile
|
||||
* @return true if the active profile changed
|
||||
*/
|
||||
private synchronized boolean setPowerProfileInternal(int profile, boolean fromUser) {
|
||||
if (profile == mCurrentProfile) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, String.format(
|
||||
"setPowerProfileInternal(profile=%d, fromUser=%b)",
|
||||
profile, fromUser));
|
||||
}
|
||||
if (profile < 0 || profile > mNumProfiles) {
|
||||
Slog.e(TAG, "Invalid profile: " + profile);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (profile < 0 || profile > mNumProfiles) {
|
||||
Slog.e(TAG, "Invalid profile: " + profile);
|
||||
/**
|
||||
* It's possible that mCurrrentProfile != getUserProfile() because of a
|
||||
* per-app profile. Store the user's profile preference and then bail
|
||||
* early if there is no work to be done.
|
||||
*/
|
||||
if (fromUser) {
|
||||
CMSettings.Secure.putInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE, profile);
|
||||
}
|
||||
|
||||
if (profile == mCurrentProfile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -150,11 +187,6 @@ public class PerformanceManagerService extends SystemService {
|
|||
|
||||
long token = Binder.clearCallingIdentity();
|
||||
|
||||
if (fromUser) {
|
||||
CMSettings.Secure.putInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE, profile);
|
||||
}
|
||||
|
||||
mCurrentProfile = profile;
|
||||
|
||||
mHandler.removeMessages(MSG_CPU_BOOST);
|
||||
|
@ -192,7 +224,29 @@ public class PerformanceManagerService extends SystemService {
|
|||
Slog.e(TAG, "Invalid boost duration: " + duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void applyProfile() {
|
||||
if (mNumProfiles < 1) {
|
||||
// don't have profiles, bail.
|
||||
return;
|
||||
}
|
||||
|
||||
int profile;
|
||||
if (mLowPowerModeEnabled) {
|
||||
// LPM always wins
|
||||
profile = PerformanceManager.PROFILE_POWER_SAVE;
|
||||
} else {
|
||||
profile = getUserProfile();
|
||||
// use app specific rules if profile is balanced
|
||||
if (hasAppProfiles() &&
|
||||
profile == PerformanceManager.PROFILE_BALANCED) {
|
||||
profile = getProfileForActivity(mCurrentActivityName);
|
||||
}
|
||||
}
|
||||
|
||||
setPowerProfileInternal(profile, false);
|
||||
}
|
||||
|
||||
private final IBinder mBinder = new IPerformanceManager.Stub() {
|
||||
|
||||
@Override
|
||||
|
@ -213,9 +267,7 @@ public class PerformanceManagerService extends SystemService {
|
|||
|
||||
@Override
|
||||
public int getPowerProfile() {
|
||||
return CMSettings.Secure.getInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE,
|
||||
PerformanceManager.PROFILE_BALANCED);
|
||||
return getUserProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -245,21 +297,16 @@ public class PerformanceManagerService extends SystemService {
|
|||
|
||||
@Override
|
||||
public void activityResumed(Intent intent) {
|
||||
if (!hasAppProfiles() || intent == null || mProfileSetByUser) {
|
||||
return;
|
||||
String activityName = null;
|
||||
if (intent != null) {
|
||||
final ComponentName cn = intent.getComponent();
|
||||
if (cn != null) {
|
||||
activityName = cn.flattenToString();
|
||||
}
|
||||
}
|
||||
|
||||
final ComponentName cn = intent.getComponent();
|
||||
if (cn == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int forApp = getProfileForActivity(cn.flattenToString());
|
||||
if (forApp == mCurrentProfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPowerProfileInternal(forApp, false);
|
||||
mCurrentActivityName = activityName;
|
||||
applyProfile();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,18 +343,14 @@ public class PerformanceManagerService extends SystemService {
|
|||
|
||||
@Override
|
||||
public void onLowPowerModeChanged(boolean enabled) {
|
||||
|
||||
if (mNumProfiles < 1) {
|
||||
return;
|
||||
}
|
||||
if (enabled == mLowPowerModeEnabled) {
|
||||
return;
|
||||
}
|
||||
if (enabled && mCurrentProfile != PerformanceManager.PROFILE_POWER_SAVE) {
|
||||
setPowerProfileInternal(PerformanceManager.PROFILE_POWER_SAVE, true);
|
||||
} else if (!enabled && mCurrentProfile == PerformanceManager.PROFILE_POWER_SAVE) {
|
||||
setPowerProfileInternal(PerformanceManager.PROFILE_BALANCED, true);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "low power mode enabled: " + enabled);
|
||||
}
|
||||
mLowPowerModeEnabled = enabled;
|
||||
applyProfile();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue