cmsdk: Rework the PerformanceManager
* Added a proper API for this thing * Pass objects around with necessary metadata, pre-filtered and sorted * Added event log and service dump * Simplified locking and adjusted for performance / correctness * Clarified/beautified code where possible * TODO: - Write profile descriptions - Finish the UI - Clean up javadocs - Do something with per-app profiles, maybe Change-Id: Ie2ef84031e81a18e95dcd62392c7e6939860d933
This commit is contained in:
@@ -775,11 +775,15 @@ package cyanogenmod.platform {
|
||||
package cyanogenmod.power {
|
||||
|
||||
public class PerformanceManager {
|
||||
method public cyanogenmod.power.PerformanceProfile getActivePowerProfile();
|
||||
method public static cyanogenmod.power.PerformanceManager getInstance(android.content.Context);
|
||||
method public int getNumberOfProfiles();
|
||||
method public int getPowerProfile();
|
||||
method public cyanogenmod.power.PerformanceProfile getPowerProfile(int);
|
||||
method public java.util.SortedSet<cyanogenmod.power.PerformanceProfile> getPowerProfiles();
|
||||
method public boolean getProfileHasAppProfiles(int);
|
||||
method public boolean setPowerProfile(int);
|
||||
method public boolean setPowerProfile(cyanogenmod.power.PerformanceProfile);
|
||||
field public static final java.lang.String POWER_PROFILE_CHANGED = "cyanogenmod.power.PROFILE_CHANGED";
|
||||
field public static final int PROFILE_BALANCED = 1; // 0x1
|
||||
field public static final int PROFILE_BIAS_PERFORMANCE = 4; // 0x4
|
||||
@@ -789,6 +793,19 @@ package cyanogenmod.power {
|
||||
field public static final java.lang.String TAG = "PerformanceManager";
|
||||
}
|
||||
|
||||
public class PerformanceProfile implements java.lang.Comparable android.os.Parcelable {
|
||||
ctor public PerformanceProfile(int, float, java.lang.String, java.lang.String, boolean);
|
||||
method public int compareTo(cyanogenmod.power.PerformanceProfile);
|
||||
method public int describeContents();
|
||||
method public java.lang.String getDescription();
|
||||
method public int getId();
|
||||
method public java.lang.String getName();
|
||||
method public float getWeight();
|
||||
method public boolean isBoostEnabled();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<cyanogenmod.power.PerformanceProfile> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package cyanogenmod.preference {
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
|
||||
package org.cyanogenmod.platform.internal;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -26,36 +32,53 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManagerInternal;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.ServiceThread;
|
||||
import com.android.server.SystemService;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cyanogenmod.app.CMContextConstants;
|
||||
import cyanogenmod.power.IPerformanceManager;
|
||||
import cyanogenmod.power.PerformanceManager;
|
||||
import cyanogenmod.power.PerformanceManagerInternal;
|
||||
import cyanogenmod.providers.CMSettings;
|
||||
import cyanogenmod.power.PerformanceProfile;
|
||||
|
||||
/** @hide */
|
||||
import static cyanogenmod.power.PerformanceManager.PROFILE_BALANCED;
|
||||
import static cyanogenmod.power.PerformanceManager.PROFILE_HIGH_PERFORMANCE;
|
||||
import static cyanogenmod.power.PerformanceManager.PROFILE_POWER_SAVE;
|
||||
import static cyanogenmod.providers.CMSettings.Secure.APP_PERFORMANCE_PROFILES_ENABLED;
|
||||
import static cyanogenmod.providers.CMSettings.Secure.PERFORMANCE_PROFILE;
|
||||
import static cyanogenmod.providers.CMSettings.Secure.getInt;
|
||||
import static cyanogenmod.providers.CMSettings.Secure.getUriFor;
|
||||
import static cyanogenmod.providers.CMSettings.Secure.putInt;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class PerformanceManagerService extends CMSystemService {
|
||||
|
||||
private static final String TAG = "PerformanceManager";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private Pattern[] mPatterns = null;
|
||||
private int[] mProfiles = null;
|
||||
private final LinkedHashMap<Pattern, Integer> mAppProfiles = new LinkedHashMap<>();
|
||||
private final ArrayMap<Integer, PerformanceProfile> mProfiles = new ArrayMap<>();
|
||||
|
||||
/** Active profile that based on low power mode, user and app rules */
|
||||
private int mCurrentProfile = -1;
|
||||
private int mNumProfiles = 0;
|
||||
|
||||
private final ServiceThread mHandlerThread;
|
||||
private final PerformanceManagerHandler mHandler;
|
||||
private final BoostHandler mHandler;
|
||||
|
||||
// keep in sync with hardware/libhardware/include/hardware/power.h
|
||||
private final int POWER_HINT_CPU_BOOST = 0x00000010;
|
||||
@@ -65,45 +88,110 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
private final int POWER_FEATURE_SUPPORTED_PROFILES = 0x00001000;
|
||||
|
||||
private PowerManagerInternal mPm;
|
||||
private boolean mLowPowerModeEnabled = false;
|
||||
private String mCurrentActivityName = null;
|
||||
|
||||
// Observes user-controlled settings
|
||||
private PerformanceSettingsObserver mObserver;
|
||||
|
||||
// Max time (microseconds) to allow a CPU boost for
|
||||
private static final int MAX_CPU_BOOST_TIME = 5000000;
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
// Standard weights
|
||||
private static final float WEIGHT_POWER_SAVE = 0.0f;
|
||||
private static final float WEIGHT_BALANCED = 0.5f;
|
||||
private static final float WEIGHT_HIGH_PERFORMANCE = 1.0f;
|
||||
|
||||
// Take lock when accessing mProfiles
|
||||
private final Object mLock = new Object();
|
||||
|
||||
// Manipulate state variables under lock
|
||||
private boolean mLowPowerModeEnabled = false;
|
||||
private boolean mSystemReady = false;
|
||||
private boolean mBoostEnabled = true;
|
||||
private int mUserProfile = -1;
|
||||
private int mActiveProfile = -1;
|
||||
private String mCurrentActivityName = null;
|
||||
|
||||
// Dumpable circular buffer for boost logging
|
||||
private final BoostLog mBoostLog = new BoostLog();
|
||||
|
||||
// Events on the handler
|
||||
private static final int MSG_CPU_BOOST = 1;
|
||||
private static final int MSG_LAUNCH_BOOST = 2;
|
||||
private static final int MSG_SET_PROFILE = 3;
|
||||
|
||||
public PerformanceManagerService(Context context) {
|
||||
super(context);
|
||||
|
||||
mContext = context;
|
||||
Resources res = context.getResources();
|
||||
|
||||
String[] activities = context.getResources().getStringArray(
|
||||
R.array.config_auto_perf_activities);
|
||||
String[] activities = res.getStringArray(R.array.config_auto_perf_activities);
|
||||
if (activities != null && activities.length > 0) {
|
||||
mPatterns = new Pattern[activities.length];
|
||||
mProfiles = new int[activities.length];
|
||||
for (int i = 0; i < activities.length; i++) {
|
||||
String[] info = activities[i].split(",");
|
||||
if (info.length == 2) {
|
||||
mPatterns[i] = Pattern.compile(info[0]);
|
||||
mProfiles[i] = Integer.valueOf(info[1]);
|
||||
mAppProfiles.put(Pattern.compile(info[0]), Integer.valueOf(info[1]));
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, String.format("App profile #%d: %s => %s",
|
||||
i, info[0], info[1]));
|
||||
i, info[0], info[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We need a high priority thread to handle these requests in front of
|
||||
// We need a higher priority thread to handle these requests in front of
|
||||
// everything else asynchronously
|
||||
mHandlerThread = new ServiceThread(TAG,
|
||||
Process.THREAD_PRIORITY_URGENT_DISPLAY + 1, false /*allowIo*/);
|
||||
Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
|
||||
mHandlerThread.start();
|
||||
|
||||
mHandler = new PerformanceManagerHandler(mHandlerThread.getLooper());
|
||||
mHandler = new BoostHandler(mHandlerThread.getLooper());
|
||||
}
|
||||
|
||||
private class PerformanceSettingsObserver extends ContentObserver {
|
||||
|
||||
private final Uri APP_PERFORMANCE_PROFILES_ENABLED_URI =
|
||||
getUriFor(APP_PERFORMANCE_PROFILES_ENABLED);
|
||||
|
||||
private final Uri PERFORMANCE_PROFILE_URI =
|
||||
getUriFor(PERFORMANCE_PROFILE);
|
||||
|
||||
private final ContentResolver mCR;
|
||||
|
||||
public PerformanceSettingsObserver(Context context, Handler handler) {
|
||||
super(handler);
|
||||
mCR = context.getContentResolver();
|
||||
}
|
||||
|
||||
public void observe(boolean enabled) {
|
||||
if (enabled) {
|
||||
mCR.registerContentObserver(APP_PERFORMANCE_PROFILES_ENABLED_URI, false, this);
|
||||
mCR.registerContentObserver(PERFORMANCE_PROFILE_URI, false, this);
|
||||
onChange(false);
|
||||
|
||||
} else {
|
||||
mCR.unregisterContentObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
int profile = getInt(mCR, PERFORMANCE_PROFILE, PROFILE_BALANCED);
|
||||
boolean boost = getInt(mCR, APP_PERFORMANCE_PROFILES_ENABLED, 1) == 1;
|
||||
|
||||
synchronized (mLock) {
|
||||
if (hasProfiles() && mProfiles.containsKey(profile)) {
|
||||
boost = boost && mProfiles.get(profile).isBoostEnabled();
|
||||
}
|
||||
|
||||
mBoostEnabled = boost;
|
||||
if (mUserProfile < 0) {
|
||||
mUserProfile = profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getFeatureDeclaration() {
|
||||
return CMContextConstants.Features.PERFORMANCE;
|
||||
@@ -115,85 +203,94 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
publishLocalService(PerformanceManagerInternal.class, new LocalService());
|
||||
}
|
||||
|
||||
private void populateProfilesLocked() {
|
||||
mProfiles.clear();
|
||||
|
||||
Resources res = mContext.getResources();
|
||||
String[] profileNames = res.getStringArray(R.array.perf_profile_entries);
|
||||
int[] profileIds = res.getIntArray(R.array.perf_profile_values);
|
||||
String[] profileWeights = res.getStringArray(R.array.perf_profile_weights);
|
||||
String[] profileDescs = res.getStringArray(R.array.perf_profile_summaries);
|
||||
|
||||
for (int i = 0; i < profileIds.length; i++) {
|
||||
if (profileIds[i] >= mNumProfiles) {
|
||||
continue;
|
||||
}
|
||||
float weight = Float.valueOf(profileWeights[i]);
|
||||
mProfiles.put(profileIds[i], new PerformanceProfile(profileIds[i],
|
||||
weight, profileNames[i], profileDescs[i], shouldUseOptimizations(weight)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == PHASE_SYSTEM_SERVICES_READY) {
|
||||
synchronized (this) {
|
||||
if (phase == PHASE_SYSTEM_SERVICES_READY && !mSystemReady) {
|
||||
synchronized (mLock) {
|
||||
mPm = getLocalService(PowerManagerInternal.class);
|
||||
mNumProfiles = mPm.getFeature(POWER_FEATURE_SUPPORTED_PROFILES);
|
||||
if (mNumProfiles > 0) {
|
||||
int profile = getUserProfile();
|
||||
if (profile == PerformanceManager.PROFILE_HIGH_PERFORMANCE) {
|
||||
Slog.i(TAG, String.format("Reverting profile %d to %d",
|
||||
profile, PerformanceManager.PROFILE_BALANCED));
|
||||
setPowerProfileInternal(
|
||||
PerformanceManager.PROFILE_BALANCED, true);
|
||||
|
||||
if (hasProfiles()) {
|
||||
populateProfilesLocked();
|
||||
|
||||
mObserver = new PerformanceSettingsObserver(mContext, mHandler);
|
||||
mObserver.observe(true);
|
||||
}
|
||||
|
||||
mSystemReady = true;
|
||||
|
||||
if (hasProfiles()) {
|
||||
if (mUserProfile == PROFILE_HIGH_PERFORMANCE) {
|
||||
Slog.w(TAG, "Reverting profile HIGH_PERFORMANCE to BALANCED");
|
||||
setPowerProfileLocked(PROFILE_BALANCED, true);
|
||||
} else {
|
||||
setPowerProfileInternal(profile, false);
|
||||
setPowerProfileLocked(mUserProfile, true);
|
||||
}
|
||||
|
||||
mPm.registerLowPowerModeObserver(mLowPowerModeListener);
|
||||
mContext.registerReceiver(mLocaleChangedReceiver,
|
||||
new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasProfiles() {
|
||||
return mNumProfiles > 0;
|
||||
}
|
||||
|
||||
private boolean hasAppProfiles() {
|
||||
return mNumProfiles > 0 && mPatterns != null &&
|
||||
(CMSettings.Secure.getInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.APP_PERFORMANCE_PROFILES_ENABLED, 1) == 1);
|
||||
}
|
||||
|
||||
private boolean getProfileHasAppProfilesInternal(int profile) {
|
||||
if (profile < 0 || profile > mNumProfiles) {
|
||||
Slog.e(TAG, "Invalid profile: " + profile);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (profile == PerformanceManager.PROFILE_BALANCED) {
|
||||
return mPatterns != null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the profile saved by the user
|
||||
*/
|
||||
private int getUserProfile() {
|
||||
return CMSettings.Secure.getInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE,
|
||||
PerformanceManager.PROFILE_BALANCED);
|
||||
return hasProfiles() && mBoostEnabled && mAppProfiles.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a power profile and persist if fromUser = true
|
||||
* <p>
|
||||
* Must call with lock held.
|
||||
*
|
||||
* @param profile power profile
|
||||
* @param fromUser true to persist the profile
|
||||
* @return true if the active profile changed
|
||||
* @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) {
|
||||
private boolean setPowerProfileLocked(int profile, boolean fromUser) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, String.format(
|
||||
"setPowerProfileInternal(profile=%d, fromUser=%b)",
|
||||
profile, fromUser));
|
||||
Slog.v(TAG, String.format("setPowerProfileL(%d, fromUser=%b)", profile, fromUser));
|
||||
}
|
||||
if (mPm == null) {
|
||||
|
||||
if (!mSystemReady) {
|
||||
Slog.e(TAG, "System is not ready, dropping profile request");
|
||||
return false;
|
||||
}
|
||||
if (profile < 0 || profile > mNumProfiles) {
|
||||
|
||||
if (!mProfiles.containsKey(profile)) {
|
||||
Slog.e(TAG, "Invalid profile: " + profile);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isProfileSame = profile == mCurrentProfile;
|
||||
boolean isProfileSame = profile == mActiveProfile;
|
||||
|
||||
if (!isProfileSame) {
|
||||
if (profile == PerformanceManager.PROFILE_POWER_SAVE) {
|
||||
// Handle the case where toggle power saver mode
|
||||
// failed
|
||||
if (profile == PROFILE_POWER_SAVE) {
|
||||
// Handle the case where toggle power saver mode failed
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if (!mPm.setPowerSaveMode(true)) {
|
||||
@@ -202,7 +299,7 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
} else if (mCurrentProfile == PerformanceManager.PROFILE_POWER_SAVE) {
|
||||
} else if (mActiveProfile == PROFILE_POWER_SAVE) {
|
||||
long token = Binder.clearCallingIdentity();
|
||||
mPm.setPowerSaveMode(false);
|
||||
Binder.restoreCallingIdentity(token);
|
||||
@@ -215,8 +312,8 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
* early if there is no work to be done.
|
||||
*/
|
||||
if (fromUser) {
|
||||
CMSettings.Secure.putInt(mContext.getContentResolver(),
|
||||
CMSettings.Secure.PERFORMANCE_PROFILE, profile);
|
||||
putInt(mContext.getContentResolver(), PERFORMANCE_PROFILE, profile);
|
||||
mUserProfile = profile;
|
||||
}
|
||||
|
||||
if (isProfileSame) {
|
||||
@@ -229,10 +326,10 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
|
||||
long token = Binder.clearCallingIdentity();
|
||||
|
||||
mCurrentProfile = profile;
|
||||
mActiveProfile = profile;
|
||||
|
||||
mHandler.obtainMessage(MSG_SET_PROFILE, profile,
|
||||
(fromUser ? 1 : 0)).sendToTarget();
|
||||
(fromUser ? 1 : 0)).sendToTarget();
|
||||
|
||||
Binder.restoreCallingIdentity(token);
|
||||
|
||||
@@ -240,69 +337,78 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
}
|
||||
|
||||
private int getProfileForActivity(String componentName) {
|
||||
int profile = -1;
|
||||
if (componentName != null) {
|
||||
for (int i = 0; i < mPatterns.length; i++) {
|
||||
if (mPatterns[i].matcher(componentName).matches()) {
|
||||
return mProfiles[i];
|
||||
for (Map.Entry<Pattern, Integer> entry : mAppProfiles.entrySet()) {
|
||||
if (entry.getKey().matcher(componentName).matches()) {
|
||||
profile = entry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PerformanceManager.PROFILE_BALANCED;
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "getProfileForActivity: activity=" + componentName + " profile=" + profile);
|
||||
}
|
||||
return profile < 0 ? mUserProfile : profile;
|
||||
}
|
||||
|
||||
private static boolean shouldUseOptimizations(float weight) {
|
||||
return weight >= (WEIGHT_BALANCED / 2) &&
|
||||
weight <= (WEIGHT_BALANCED + (WEIGHT_BALANCED / 2));
|
||||
}
|
||||
|
||||
private void cpuBoostInternal(int duration) {
|
||||
synchronized (PerformanceManagerService.this) {
|
||||
if (mPm == null) {
|
||||
Slog.e(TAG, "System is not ready, dropping cpu boost request");
|
||||
return;
|
||||
}
|
||||
if (!mSystemReady) {
|
||||
Slog.e(TAG, "System is not ready, dropping cpu boost request");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBoostEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (duration > 0 && duration <= MAX_CPU_BOOST_TIME) {
|
||||
// Don't send boosts if we're in another power profile
|
||||
if (mCurrentProfile == PerformanceManager.PROFILE_POWER_SAVE ||
|
||||
mCurrentProfile == PerformanceManager.PROFILE_HIGH_PERFORMANCE) {
|
||||
return;
|
||||
}
|
||||
mHandler.obtainMessage(MSG_CPU_BOOST, duration, 0).sendToTarget();
|
||||
} else {
|
||||
Slog.e(TAG, "Invalid boost duration: " + duration);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyProfile(boolean fromUser) {
|
||||
if (mNumProfiles < 1) {
|
||||
private void applyAppProfileLocked(boolean fromUser) {
|
||||
if (!hasProfiles()) {
|
||||
// don't have profiles, bail.
|
||||
return;
|
||||
}
|
||||
|
||||
int profile;
|
||||
final int profile;
|
||||
if (mLowPowerModeEnabled) {
|
||||
// LPM always wins
|
||||
profile = PerformanceManager.PROFILE_POWER_SAVE;
|
||||
} else if (fromUser && mCurrentProfile == PerformanceManager.PROFILE_POWER_SAVE) {
|
||||
profile = PerformanceManager.PROFILE_BALANCED;
|
||||
profile = PROFILE_POWER_SAVE;
|
||||
} else if (fromUser && mActiveProfile == PROFILE_POWER_SAVE) {
|
||||
// leaving LPM
|
||||
profile = PROFILE_BALANCED;
|
||||
} else if (hasAppProfiles()) {
|
||||
profile = getProfileForActivity(mCurrentActivityName);
|
||||
} else {
|
||||
profile = getUserProfile();
|
||||
// use app specific rules if profile is balanced
|
||||
if (hasAppProfiles() && getProfileHasAppProfilesInternal(profile)) {
|
||||
profile = getProfileForActivity(mCurrentActivityName);
|
||||
}
|
||||
profile = mUserProfile;
|
||||
}
|
||||
setPowerProfileInternal(profile, fromUser);
|
||||
|
||||
setPowerProfileLocked(profile, fromUser);
|
||||
}
|
||||
|
||||
private final IBinder mBinder = new IPerformanceManager.Stub() {
|
||||
|
||||
@Override
|
||||
public boolean setPowerProfile(int profile) {
|
||||
return setPowerProfileInternal(profile, true);
|
||||
synchronized (mLock) {
|
||||
return setPowerProfileLocked(profile, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Boost the CPU
|
||||
*
|
||||
* @param duration Duration to boost the CPU for, in milliseconds.
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public void cpuBoost(int duration) {
|
||||
@@ -311,7 +417,23 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
|
||||
@Override
|
||||
public int getPowerProfile() {
|
||||
return getUserProfile();
|
||||
synchronized (mLock) {
|
||||
return mUserProfile;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PerformanceProfile getPowerProfileById(int profile) {
|
||||
synchronized (mLock) {
|
||||
return mProfiles.get(profile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PerformanceProfile getActivePowerProfile() {
|
||||
synchronized (mLock) {
|
||||
return mProfiles.get(mUserProfile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -320,8 +442,45 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getProfileHasAppProfiles(int profile) {
|
||||
return getProfileHasAppProfilesInternal(profile);
|
||||
public PerformanceProfile[] getPowerProfiles() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return mProfiles.values().toArray(
|
||||
new PerformanceProfile[mProfiles.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
|
||||
|
||||
synchronized (mLock) {
|
||||
pw.println();
|
||||
pw.println("PerformanceManager Service State:");
|
||||
pw.println();
|
||||
pw.println(" Boost enabled: " + mBoostEnabled);
|
||||
|
||||
if (!hasProfiles()) {
|
||||
pw.println(" No profiles available.");
|
||||
} else {
|
||||
pw.println(" User-selected profile: " +
|
||||
Objects.toString(mProfiles.get(mUserProfile)));
|
||||
if (mUserProfile != mActiveProfile) {
|
||||
pw.println(" System-selected profile: " +
|
||||
Objects.toString(mProfiles.get(mActiveProfile)));
|
||||
}
|
||||
pw.println();
|
||||
pw.println(" Supported profiles:");
|
||||
for (Map.Entry<Integer, PerformanceProfile> profile : mProfiles.entrySet()) {
|
||||
pw.println(" " + profile.getKey() + ": " + profile.getValue().toString());
|
||||
}
|
||||
if (hasAppProfiles()) {
|
||||
pw.println();
|
||||
pw.println(" App trigger count: " + mAppProfiles.size());
|
||||
}
|
||||
pw.println();
|
||||
mBoostLog.dump(pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,15 +493,11 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
|
||||
@Override
|
||||
public void launchBoost(int pid, String packageName) {
|
||||
synchronized (PerformanceManagerService.this) {
|
||||
if (mPm == null) {
|
||||
Slog.e(TAG, "System is not ready, dropping launch boost request");
|
||||
return;
|
||||
}
|
||||
if (!mSystemReady) {
|
||||
Slog.e(TAG, "System is not ready, dropping launch boost request");
|
||||
return;
|
||||
}
|
||||
// Don't send boosts if we're in another power profile
|
||||
if (mCurrentProfile == PerformanceManager.PROFILE_POWER_SAVE ||
|
||||
mCurrentProfile == PerformanceManager.PROFILE_HIGH_PERFORMANCE) {
|
||||
if (!mBoostEnabled) {
|
||||
return;
|
||||
}
|
||||
mHandler.obtainMessage(MSG_LAUNCH_BOOST, pid, 0, packageName).sendToTarget();
|
||||
@@ -358,20 +513,65 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentActivityName = activityName;
|
||||
applyProfile(false);
|
||||
synchronized (mLock) {
|
||||
mCurrentActivityName = activityName;
|
||||
applyAppProfileLocked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int MSG_CPU_BOOST = 1;
|
||||
private static final int MSG_LAUNCH_BOOST = 2;
|
||||
private static final int MSG_SET_PROFILE = 3;
|
||||
private static class BoostLog {
|
||||
static final int APP_PROFILE = 0;
|
||||
static final int CPU_BOOST = 1;
|
||||
static final int LAUNCH_BOOST = 2;
|
||||
static final int USER_PROFILE = 3;
|
||||
|
||||
static final String[] EVENTS = new String[] {
|
||||
"APP_PROFILE", "CPU_BOOST", "LAUNCH_BOOST", "USER_PROFILE" };
|
||||
|
||||
private static final int LOG_BUF_SIZE = 25;
|
||||
|
||||
static class Entry {
|
||||
private final long timestamp;
|
||||
private final int event;
|
||||
private final String info;
|
||||
|
||||
Entry(long timestamp_, int event_, String info_) {
|
||||
timestamp = timestamp_;
|
||||
event = event_;
|
||||
info = info_;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayDeque<Entry> mBuffer = new ArrayDeque<>(LOG_BUF_SIZE);
|
||||
|
||||
void log(int event, String info) {
|
||||
synchronized (mBuffer) {
|
||||
mBuffer.add(new Entry(System.currentTimeMillis(), event, info));
|
||||
if (mBuffer.size() >= LOG_BUF_SIZE) {
|
||||
mBuffer.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump(PrintWriter pw) {
|
||||
synchronized (mBuffer) {
|
||||
pw.println(" Boost log:");
|
||||
for (Entry entry : mBuffer) {
|
||||
pw.println(String.format(" %1$tH:%1$tM:%1$tS.%1$tL: %2$14s %3$s",
|
||||
new Date(entry.timestamp), EVENTS[entry.event], entry.info));
|
||||
}
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for asynchronous operations performed by the performance manager.
|
||||
*/
|
||||
private final class PerformanceManagerHandler extends Handler {
|
||||
public PerformanceManagerHandler(Looper looper) {
|
||||
private final class BoostHandler extends Handler {
|
||||
|
||||
public BoostHandler(Looper looper) {
|
||||
super(looper, null, true /*async*/);
|
||||
}
|
||||
|
||||
@@ -380,6 +580,7 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
switch (msg.what) {
|
||||
case MSG_CPU_BOOST:
|
||||
mPm.powerHint(POWER_HINT_CPU_BOOST, msg.arg1);
|
||||
mBoostLog.log(BoostLog.CPU_BOOST, "duration=" + msg.arg1);
|
||||
break;
|
||||
case MSG_LAUNCH_BOOST:
|
||||
int pid = msg.arg1;
|
||||
@@ -387,9 +588,12 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
if (NativeHelper.isNativeLibraryAvailable() && packageName != null) {
|
||||
native_launchBoost(pid, packageName);
|
||||
}
|
||||
mBoostLog.log(BoostLog.LAUNCH_BOOST, "package=" + packageName);
|
||||
break;
|
||||
case MSG_SET_PROFILE:
|
||||
mPm.powerHint(POWER_HINT_SET_PROFILE, msg.arg1);
|
||||
mBoostLog.log((msg.arg2 == 1 ? BoostLog.USER_PROFILE : BoostLog.APP_PROFILE),
|
||||
"profile=" + msg.arg1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -400,16 +604,27 @@ public class PerformanceManagerService extends CMSystemService {
|
||||
|
||||
@Override
|
||||
public void onLowPowerModeChanged(boolean enabled) {
|
||||
if (enabled == mLowPowerModeEnabled) {
|
||||
return;
|
||||
synchronized (mLock) {
|
||||
if (enabled == mLowPowerModeEnabled) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "low power mode enabled: " + enabled);
|
||||
}
|
||||
mLowPowerModeEnabled = enabled;
|
||||
applyAppProfileLocked(true);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "low power mode enabled: " + enabled);
|
||||
}
|
||||
mLowPowerModeEnabled = enabled;
|
||||
applyProfile(true);
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mLocaleChangedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
synchronized (mLock) {
|
||||
populateProfilesLocked();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private native final void native_launchBoost(int pid, String packageName);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,26 @@
|
||||
<item>2</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Weights for each performance profile, 0 being lowest (powersave) and 1 being
|
||||
highest (performance). Used for sorting -->
|
||||
<string-array name="perf_profile_weights" translatable="false">
|
||||
<item>0.0</item>
|
||||
<item>0.25</item>
|
||||
<item>0.5</item>
|
||||
<item>0.75</item>
|
||||
<item>1.0</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Summary of each profile -->
|
||||
<string-array name="perf_profile_summaries" translatable="false">
|
||||
<item>@string/perf_profile_pwrsv_summary</item>
|
||||
<item>@string/perf_profile_bias_power_summary</item>
|
||||
<item>@string/perf_profile_bal_summary</item>
|
||||
<item>@string/perf_profile_bias_perf_summary</item>
|
||||
<item>@string/perf_profile_perf_summary</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<!-- LiveDisplay -->
|
||||
<string-array name="live_display_entries" translatable="false">
|
||||
<item>@string/live_display_auto</item>
|
||||
|
||||
@@ -107,6 +107,14 @@
|
||||
<string name="perf_profile_bias_power">Efficiency</string>
|
||||
<string name="perf_profile_bias_perf">Quick</string>
|
||||
|
||||
<!-- Performance profiles -->
|
||||
<string name="perf_profile_pwrsv_summary">Power save</string>
|
||||
<string name="perf_profile_bal_summary">Balanced</string>
|
||||
<string name="perf_profile_perf_summary">Performance</string>
|
||||
<string name="perf_profile_bias_power_summary">Efficiency</string>
|
||||
<string name="perf_profile_bias_perf_summary">Quick</string>
|
||||
|
||||
|
||||
<!-- LiveDisplay strings -->
|
||||
<string name="live_display_title" translatable="false">LiveDisplay</string>
|
||||
<string name="live_display_auto">Automatic</string>
|
||||
|
||||
@@ -30,11 +30,18 @@
|
||||
<!-- Performance Profiles -->
|
||||
<java-symbol type="array" name="perf_profile_entries" />
|
||||
<java-symbol type="array" name="perf_profile_values" />
|
||||
<java-symbol type="array" name="perf_profile_weights" />
|
||||
<java-symbol type="array" name="perf_profile_summaries" />
|
||||
<java-symbol type="string" name="perf_profile_pwrsv" />
|
||||
<java-symbol type="string" name="perf_profile_bal" />
|
||||
<java-symbol type="string" name="perf_profile_perf" />
|
||||
<java-symbol type="string" name="perf_profile_bias_power" />
|
||||
<java-symbol type="string" name="perf_profile_bias_perf" />
|
||||
<java-symbol type="string" name="perf_profile_pwrsv_summary" />
|
||||
<java-symbol type="string" name="perf_profile_bal_summary" />
|
||||
<java-symbol type="string" name="perf_profile_perf_summary" />
|
||||
<java-symbol type="string" name="perf_profile_bias_power_summary" />
|
||||
<java-symbol type="string" name="perf_profile_bias_perf_summary" />
|
||||
|
||||
<!-- Array of default activities with custom power management -->
|
||||
<java-symbol type="array" name="config_auto_perf_activities" />
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package cyanogenmod.power;
|
||||
|
||||
import cyanogenmod.power.PerformanceProfile;
|
||||
|
||||
/** @hide */
|
||||
interface IPerformanceManager {
|
||||
|
||||
@@ -27,5 +29,9 @@ interface IPerformanceManager {
|
||||
|
||||
int getNumberOfProfiles();
|
||||
|
||||
boolean getProfileHasAppProfiles(int profile);
|
||||
PerformanceProfile[] getPowerProfiles();
|
||||
|
||||
PerformanceProfile getPowerProfileById(int profile);
|
||||
|
||||
PerformanceProfile getActivePowerProfile();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import cyanogenmod.app.CMContextConstants;
|
||||
|
||||
/**
|
||||
@@ -177,10 +182,31 @@ public class PerformanceManager {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the system power profile
|
||||
*
|
||||
* @throws IllegalArgumentException if invalid
|
||||
*/
|
||||
public boolean setPowerProfile(PerformanceProfile profile) {
|
||||
if (mNumberOfProfiles < 1) {
|
||||
throw new IllegalArgumentException("Power profiles not enabled on this system!");
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
try {
|
||||
if (checkService()) {
|
||||
changed = sService.setPowerProfile(profile.getId());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current power profile
|
||||
*
|
||||
* Returns null if power profiles are not enabled
|
||||
* Returns -1 if power profiles are not enabled
|
||||
*/
|
||||
public int getPowerProfile() {
|
||||
int ret = -1;
|
||||
@@ -196,6 +222,43 @@ public class PerformanceManager {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified power profile
|
||||
*
|
||||
* Returns null if power profiles are not enabled or the profile was not found
|
||||
*/
|
||||
public PerformanceProfile getPowerProfile(int profile) {
|
||||
PerformanceProfile ret = null;
|
||||
if (mNumberOfProfiles > 0) {
|
||||
try {
|
||||
if (checkService()) {
|
||||
ret = sService.getPowerProfileById(profile);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently active performance profile
|
||||
*
|
||||
* Returns null if no profiles are available.
|
||||
*/
|
||||
public PerformanceProfile getActivePowerProfile() {
|
||||
PerformanceProfile ret = null;
|
||||
if (mNumberOfProfiles > 0) {
|
||||
try {
|
||||
if (checkService()) {
|
||||
ret = sService.getActivePowerProfile();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Check if profile has app-specific profiles
|
||||
*
|
||||
@@ -206,7 +269,7 @@ public class PerformanceManager {
|
||||
if (mNumberOfProfiles > 0) {
|
||||
try {
|
||||
if (checkService()) {
|
||||
ret = sService.getProfileHasAppProfiles(profile);
|
||||
ret = sService.getPowerProfileById(profile).isBoostEnabled();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// nothing
|
||||
@@ -214,4 +277,26 @@ public class PerformanceManager {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set, sorted by weight, of all supported power profiles
|
||||
*
|
||||
* Returns an empty set if power profiles are not enabled
|
||||
*/
|
||||
public SortedSet<PerformanceProfile> getPowerProfiles() {
|
||||
final SortedSet<PerformanceProfile> profiles = new TreeSet<PerformanceProfile>();
|
||||
if (mNumberOfProfiles > 0) {
|
||||
try {
|
||||
if (checkService()) {
|
||||
PerformanceProfile[] p = sService.getPowerProfiles();
|
||||
if (p != null) {
|
||||
profiles.addAll(Arrays.asList(p));
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSortedSet(profiles);
|
||||
}
|
||||
}
|
||||
|
||||
19
sdk/src/java/cyanogenmod/power/PerformanceProfile.aidl
Normal file
19
sdk/src/java/cyanogenmod/power/PerformanceProfile.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cyanogenmod.power;
|
||||
|
||||
parcelable PerformanceProfile;
|
||||
176
sdk/src/java/cyanogenmod/power/PerformanceProfile.java
Normal file
176
sdk/src/java/cyanogenmod/power/PerformanceProfile.java
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cyanogenmod.power;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import cyanogenmod.os.Build;
|
||||
import cyanogenmod.os.Concierge;
|
||||
|
||||
/**
|
||||
* Encapsulates information about an available system power/peformance profile, managed
|
||||
* by the PerformanceManager.
|
||||
*/
|
||||
public class PerformanceProfile implements Parcelable, Comparable<PerformanceProfile> {
|
||||
|
||||
private final int mId;
|
||||
|
||||
private final float mWeight;
|
||||
|
||||
private final String mName;
|
||||
|
||||
private final String mDescription;
|
||||
|
||||
private final boolean mBoostEnabled;
|
||||
|
||||
public PerformanceProfile(int id, float weight, String name, String description,
|
||||
boolean boostEnabled) {
|
||||
mId = id;
|
||||
mWeight = weight;
|
||||
mName = name;
|
||||
mDescription = description;
|
||||
mBoostEnabled = boostEnabled;
|
||||
}
|
||||
|
||||
private PerformanceProfile(Parcel in) {
|
||||
Concierge.ParcelInfo parcelInfo = Concierge.receiveParcel(in);
|
||||
int parcelableVersion = parcelInfo.getParcelVersion();
|
||||
|
||||
mId = in.readInt();
|
||||
mWeight = in.readFloat();
|
||||
mName = in.readString();
|
||||
mDescription = in.readString();
|
||||
mBoostEnabled = in.readInt() == 1;
|
||||
|
||||
if (parcelableVersion >= Build.CM_VERSION_CODES.GUAVA) {
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
parcelInfo.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this profile. Must match values used by the PowerHAL.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The profile's weight, from 0 to 1, with 0 being lowest (power save), 1 being
|
||||
* highest (performance), and 0.5 as the balanced default profile. Other
|
||||
* values may be seen, depending on the device. This value can be used for
|
||||
* sorting.
|
||||
*
|
||||
* @return weight
|
||||
*/
|
||||
public float getWeight() {
|
||||
return mWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* A localized name for the profile, suitable for display.
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A localized description of the profile, suitable for display.
|
||||
*
|
||||
* @return description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not per-app profiles and boosting will be used when this
|
||||
* profile is active. Far-end modes (powersave / high performance) do
|
||||
* not use boosting.
|
||||
*
|
||||
* @return true if boosting and per-app optimization will be used
|
||||
*/
|
||||
public boolean isBoostEnabled() {
|
||||
return mBoostEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
Concierge.ParcelInfo parcelInfo = Concierge.prepareParcel(dest);
|
||||
|
||||
dest.writeInt(mId);
|
||||
dest.writeFloat(mWeight);
|
||||
dest.writeString(mName);
|
||||
dest.writeString(mDescription);
|
||||
dest.writeInt(mBoostEnabled ? 1 : 0);
|
||||
|
||||
parcelInfo.complete();
|
||||
}
|
||||
|
||||
public static final Creator<PerformanceProfile> CREATOR = new Creator<PerformanceProfile>() {
|
||||
@Override
|
||||
public PerformanceProfile createFromParcel(Parcel in) {
|
||||
return new PerformanceProfile(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PerformanceProfile[] newArray(int size) {
|
||||
return new PerformanceProfile[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int compareTo(PerformanceProfile other) {
|
||||
return Float.compare(mWeight, other.mWeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (!getClass().equals(other.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PerformanceProfile o = (PerformanceProfile) other;
|
||||
return Objects.equals(mId, o.mId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("PerformanceProfile[id=%d, weight=%f, name=%s desc=%s " +
|
||||
"boostEnabled=%b]", mId, mWeight, mName, mDescription, mBoostEnabled);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import android.test.suitebuilder.annotation.SmallTest;
|
||||
import cyanogenmod.app.CMContextConstants;
|
||||
import cyanogenmod.power.IPerformanceManager;
|
||||
import cyanogenmod.power.PerformanceManager;
|
||||
import cyanogenmod.power.PerformanceProfile;
|
||||
|
||||
/**
|
||||
* Code coverage for public facing {@link PerformanceManager} interfaces.
|
||||
@@ -31,7 +32,7 @@ public class PerfomanceManagerTest extends AndroidTestCase {
|
||||
private static final String TAG = PerfomanceManagerTest.class.getSimpleName();
|
||||
private static final int IMPOSSIBLE_POWER_PROFILE = -1;
|
||||
private PerformanceManager mCMPerformanceManager;
|
||||
private int mSavedPerfProfile;
|
||||
private PerformanceProfile mSavedPerfProfile;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
@@ -41,7 +42,8 @@ public class PerfomanceManagerTest extends AndroidTestCase {
|
||||
CMContextConstants.Features.PERFORMANCE));
|
||||
mCMPerformanceManager = PerformanceManager.getInstance(mContext);
|
||||
// Save the perf profile for later restore.
|
||||
mSavedPerfProfile = mCMPerformanceManager.getPowerProfile();
|
||||
mSavedPerfProfile = mCMPerformanceManager.getPowerProfile(
|
||||
mCMPerformanceManager.getPowerProfile());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@@ -104,6 +106,6 @@ public class PerfomanceManagerTest extends AndroidTestCase {
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
// Reset
|
||||
mCMPerformanceManager.setPowerProfile(mSavedPerfProfile);
|
||||
mCMPerformanceManager.setPowerProfile(mSavedPerfProfile.getId());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user