Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41be9385 authored by Steve Kondik's avatar Steve Kondik
Browse files

power: Add CM performance manager



Squashed commit of:

power: Add CPU boosting interface

 * Boosts CPU using Power HAL for the given duration.
 * Duration is given in microseconds.
 * Power HAL must implement POWER_HINT_CPU_BOOST.

Add CPU boosting hooks

 * Send boost hint during scrolling
 * Still relevant on even high-end hardware

perf: Send a boost hint when a key on the navbar is pressed

 * A lot of stuff happens, especially when invoking recents.
 * Get ahead of the storm by sending a boost hint before
   kicking off the animations.

perf: Send boost hint during initial launch

perf: Per-app performance profiles

 * Performance Profiles is going to grow into a much more powerful
   feature which can apply advanced optimizations or power saving
   techniques depending on both the state of the hardware as well
   as the current applications in use.
 * Refactor the original code and move it into PowerManager so
   that it's managed from the same place.
 * Implement "automatic performance profiles". This feature will
   automatically select a profile when specific activities are
   running. Currently this list is static and engages performance
   mode for several benchmarks (trollface).
 * Added support for a new power hint, POWER_HINT_SET_PROFILE.
   Currently, these profiles are fired using a property trigger
   in init. This is easy, but the PowerHAL can do more.
 * Moved the setting to Settings.Secure and also wrapped calls
   to the service in the DEVICE_POWER permission. Nobody should
   mess with this stuff except the system.
 * Powersave profile will automatically activate Android's built-in
   low power mode.
 * Original patch by Jorge Ruesga

TODO:
 * Implement API for per-app configuration by user
 * Quicksettings tile

perf: Boost during animations

 * Reduce animation jank by preemptively boostin the CPUs.
 * Original idea taken from CodeAurora, modified for CM perf control.

systemui: Boost when expanding the notification shade

power: Add a new power hint for application launches

 * Some devices may prefer a different behavior when launching apps,
   particularly to avoid priority inversion issues. Add support
   for a new LAUNCH_BOOST hint which can be handled in the PowerHAL.

power: Boost improvements

 * Boost when opening the panelview
 * Adjust launch boost to handle relaunch correctly

PowerManager: change performance profile when disabling battery saver

We need to be sure to update the performance profile when the system
disables battery saver mode.

This fixes the perf tile becoming out of sync - changing it to low power
mode triggers power saver, but turning power saver off does not trigger
the tile.

Ref: CYNGNOS-1156

Signed-off-by: default avatarRoman Birg <roman@cyngn.com>

base: cache power profiles support

Signed-off-by: default avatarJorge Ruesga <jorge@ruesga.com>

perf: Add support for additional power profiles

 * Add support for bias power (efficiency) and bias performance (quick)
   modes if supported by a device.

Change-Id: Id3a53eaacdaf6ae93ee899835cfcb21279d35ad4
parent 2e724e9f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -68,4 +68,12 @@ interface IPowerManager
    void setKeyboardLight(boolean on, int key);

	void wakeUpWithProximityCheck(long time, String reason, String opPackageName);

    void cpuBoost(int duration);
    void launchBoost();

    boolean setPowerProfile(String profile);
    String getPowerProfile();

    void activityResumed(String componentName);
}
+150 −0
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ package android.os;

import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

/**
@@ -388,9 +391,35 @@ public final class PowerManager {
     */
    public static final String REBOOT_RECOVERY = "recovery";
    
    /**
     * Power save profile
     * @hide
     */
    public static final String PROFILE_POWER_SAVE = "0";

    /**
     * Balanced power profile
     * @hide
     */
    public static final String PROFILE_BALANCED = "1";

    /**
     * High-performance profile
     * @hide
     */
    public static final String PROFILE_HIGH_PERFORMANCE = "2";

    /**
     * Broadcast sent when profile is changed
     * @hide
     */
    public static final String POWER_PROFILE_CHANGED =
            "com.cyanogenmod.power.PROFILE_CHANGED";

    final Context mContext;
    final IPowerManager mService;
    final Handler mHandler;
    private final boolean mHasPowerProfilesSupport;

    IDeviceIdleController mIDeviceIdleController;

@@ -401,6 +430,10 @@ public final class PowerManager {
        mContext = context;
        mService = service;
        mHandler = handler;

        mHasPowerProfilesSupport = !TextUtils.isEmpty(getDefaultPowerProfile()) &&
                !TextUtils.isEmpty(mContext.getResources().getString(
                        com.android.internal.R.string.config_perf_profile_prop));
    }

    /**
@@ -950,6 +983,40 @@ public final class PowerManager {
        }
    }
    
    /**
     * Boost the CPU. Boosts the cpu for the given duration in microseconds.
     * Requires the {@link android.Manifest.permission#CPU_BOOST} permission.
     *
     * @param duration in microseconds to boost the CPU
     *
     * @hide
     */
    public void cpuBoost(int duration)
    {
        try {
            if (mService != null) {
                mService.cpuBoost(duration);
            }
        } catch (RemoteException e) {
        }
    }

    /**
     * Boost the CPU for an application launch.
     * Requires the {@link android.Manifest.permission#CPU_BOOST} permission.
     *
     * @hide
     */
    public void launchBoost()
    {
        try {
            if (mService != null) {
                mService.launchBoost();
            }
        } catch (RemoteException e) {
        }
    }

    /**
     * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes.
     * This broadcast is only sent to registered receivers.
@@ -1005,6 +1072,89 @@ public final class PowerManager {
    public static final String ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED
            = "android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED";

    /**
     * True if the system supports power profiles
     *
     * @hide
     */
    public boolean hasPowerProfiles() {
        return mHasPowerProfilesSupport;
    }

    /**
     * Gets the default power profile for the device.
     *
     * Returns null if not enabled.
     *
     * @hide
     */
    public String getDefaultPowerProfile() {
        return mContext.getResources().getString(
                com.android.internal.R.string.config_perf_profile_default_entry);
    }

    /**
     * Set the system power profile
     *
     * @throws IllegalArgumentException if invalid
     * @hide
     */
    public boolean setPowerProfile(String profile) {
        if (!hasPowerProfiles()) {
            throw new IllegalArgumentException("Power profiles not enabled on this system!");
        }

        boolean changed = false;
        try {
            if (mService != null) {
                changed = mService.setPowerProfile(profile);
            }
        } catch (RemoteException e) {
            throw new IllegalArgumentException(e);
        }
        return changed;
    }

    /**
     * Gets the current power profile
     *
     * Returns null if power profiles are not enabled
     * @hide
     */
    public String getPowerProfile() {
        String ret = null;
        if (hasPowerProfiles()) {
            try {
                if (mService != null) {
                    ret = mService.getPowerProfile();
                }
            } catch (RemoteException e) {
                // nothing
            }
        }
        return ret;
    }

    /**
     * Update profile for resumed app, called from ActivityStack
     * @hide
     */
    public void activityResumed(Intent intent) {
        String ret = null;
        if (hasPowerProfiles()) {
            try {
                if (intent != null && mService != null) {
                    ComponentName cn = intent.getComponent();
                    if (cn != null) {
                        mService.activityResumed(cn.flattenToString());
                    }
                }
            } catch (RemoteException e) {
                // nothing
            }
        }
    }

    /**
     * A wake lock is a mechanism to indicate that your application needs
     * to have the device stay on.
+13 −0
Original line number Diff line number Diff line
@@ -6595,6 +6595,19 @@ public final class Settings {
         */
        public static final String THEME_PREV_BOOT_API_LEVEL = "theme_prev_boot_api_level";

        /**
         * Performance profile
         * @see config_perf_profile_prop in frameworks/base/core/res/res/values/config.xml
         * @hide
         */
        public static final String PERFORMANCE_PROFILE = "performance_profile";

        /**
         * App-based performance profile selection
         * @hide
         */
        public static final String APP_PERFORMANCE_PROFILES_ENABLED = "app_perf_profiles_enabled";

        /**
         * This are the settings to be backed up.
         *
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.widget;

import android.content.Context;
import android.hardware.SensorManager;
import android.os.PowerManager;
import android.util.Log;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
@@ -599,6 +600,8 @@ public class OverScroller {
        private static final int CUBIC = 1;
        private static final int BALLISTIC = 2;

        private final PowerManager mPm;

        static {
            float x_min = 0.0f;
            float y_min = 0.0f;
@@ -643,6 +646,7 @@ public class OverScroller {
                    * 39.37f // inch/meter
                    * ppi
                    * 0.84f; // look and feel tuning
            mPm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        }

        void updateScroll(float q) {
@@ -760,6 +764,7 @@ public class OverScroller {
            if (velocity != 0) {
                mDuration = mSplineDuration = getSplineFlingDuration(velocity);
                totalDistance = getSplineFlingDistance(velocity);
                mPm.cpuBoost(mDuration * 1000);
            }

            mSplineDistance = (int) (totalDistance * Math.signum(velocity));
+7 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.widget;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.PowerManager;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -108,6 +109,8 @@ public class Scroller {
    private float mDeceleration;
    private final float mPpi;

    private final PowerManager mPm;

    // A context-specific coefficient adjusted to physical values.
    private float mPhysicalCoeff;

@@ -178,6 +181,8 @@ public class Scroller {
        mFlywheel = flywheel;

        mPhysicalCoeff = computeDeceleration(0.84f); // look and feel tuning

        mPm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    }

    /**
@@ -395,6 +400,8 @@ public class Scroller {
        mDeltaX = dx;
        mDeltaY = dy;
        mDurationReciprocal = 1.0f / (float) mDuration;

        mPm.cpuBoost(duration * 1000);
    }

    /**
Loading