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

Commit b60a625f authored by Jing Ji's avatar Jing Ji Committed by Android (Google) Code Review
Browse files

Merge "Exclude the bg battery usage for apps with access to fine location"

parents 66b601d8 4838c7ca
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -5778,4 +5778,15 @@
         show the prompt to user, False - we'll not show it.
    -->
    <bool name="config_bg_prompt_fgs_with_noti_to_bg_restricted">false</bool>

    <!-- The types of state where we'll exempt its battery usage during that state.
         The state here must be one or a combination of STATE_TYPE_* in BaseAppStateTracker.
    -->
    <integer name="config_bg_current_drain_exempted_types">9</integer>

    <!-- The behavior when an app has the permission ACCESS_BACKGROUND_LOCATION granted,
         whether or not the system will use a higher threshold towards its background battery usage
         because of it.
    -->
    <bool name="config_bg_current_drain_high_threshold_by_bg_location">false</bool>
</resources>
+2 −0
Original line number Diff line number Diff line
@@ -4748,4 +4748,6 @@
  <java-symbol type="integer" name="config_bg_current_drain_media_playback_min_duration" />
  <java-symbol type="integer" name="config_bg_current_drain_location_min_duration" />
  <java-symbol type="bool" name="config_bg_prompt_fgs_with_noti_to_bg_restricted" />
  <java-symbol type="integer" name="config_bg_current_drain_exempted_types" />
  <java-symbol type="bool" name="config_bg_current_drain_high_threshold_by_bg_location" />
</resources>
+21 −27
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.AppBatteryTracker.BATTERY_USAGE_NONE;
import static com.android.server.am.AppRestrictionController.DEVICE_CONFIG_SUBNAMESPACE_PREFIX;
import static com.android.server.am.BaseAppStateDurationsTracker.EVENT_NUM;
import static com.android.server.am.BaseAppStateTracker.STATE_TYPE_NUM;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -36,9 +36,9 @@ import com.android.server.am.AppBatteryExemptionTracker.UidBatteryStates;
import com.android.server.am.AppBatteryTracker.AppBatteryPolicy;
import com.android.server.am.AppBatteryTracker.BatteryUsage;
import com.android.server.am.AppBatteryTracker.ImmutableBatteryUsage;
import com.android.server.am.BaseAppStateDurationsTracker.EventListener;
import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent;
import com.android.server.am.BaseAppStateTracker.Injector;
import com.android.server.am.BaseAppStateTracker.StateListener;

import java.io.PrintWriter;
import java.lang.reflect.Constructor;
@@ -57,13 +57,13 @@ import java.util.LinkedList;
 */
final class AppBatteryExemptionTracker
        extends BaseAppStateDurationsTracker<AppBatteryExemptionPolicy, UidBatteryStates>
        implements BaseAppStateEvents.Factory<UidBatteryStates>, EventListener {
        implements BaseAppStateEvents.Factory<UidBatteryStates>, StateListener {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppBatteryExemptionTracker" : TAG_AM;

    private static final boolean DEBUG_BACKGROUND_BATTERY_EXEMPTION_TRACKER = false;

    // As it's a UID-based tracker, anywhere which requires a package name, use this default name.
    private static final String DEFAULT_NAME = "";
    static final String DEFAULT_NAME = "";

    AppBatteryExemptionTracker(Context context, AppRestrictionController controller) {
        this(context, controller, null, null);
@@ -80,9 +80,7 @@ final class AppBatteryExemptionTracker
    void onSystemReady() {
        super.onSystemReady();
        mAppRestrictionController.forEachTracker(tracker -> {
            if (tracker instanceof BaseAppStateDurationsTracker) {
                ((BaseAppStateDurationsTracker) tracker).registerEventListener(this);
            }
            tracker.registerStateListener(this);
        });
    }

@@ -97,19 +95,20 @@ final class AppBatteryExemptionTracker
    }

    @Override
    public void onNewEvent(int uid, String packageName, boolean start, long now, int eventType) {
    public void onStateChange(int uid, String packageName, boolean start, long now, int stateType) {
        if (!mInjector.getPolicy().isEnabled()) {
            return;
        }
        final ImmutableBatteryUsage batteryUsage = mAppRestrictionController
                .getUidBatteryUsage(uid);
        final int stateTypeIndex = stateTypeToIndex(stateType);
        synchronized (mLock) {
            UidBatteryStates pkg = mPkgEvents.get(uid, DEFAULT_NAME);
            if (pkg == null) {
                pkg = createAppStateEvents(uid, DEFAULT_NAME);
                mPkgEvents.put(uid, DEFAULT_NAME, pkg);
            }
            pkg.addEvent(start, now, batteryUsage, eventType);
            pkg.addEvent(start, now, batteryUsage, stateTypeIndex);
        }
    }

@@ -125,7 +124,8 @@ final class AppBatteryExemptionTracker
     * @return The to-be-exempted battery usage of the given UID in the given duration; it could
     *         be considered as "exempted" due to various use cases, i.e. media playback.
     */
    ImmutableBatteryUsage getUidBatteryExemptedUsageSince(int uid, long since, long now) {
    ImmutableBatteryUsage getUidBatteryExemptedUsageSince(int uid, long since, long now,
            int types) {
        if (!mInjector.getPolicy().isEnabled()) {
            return BATTERY_USAGE_NONE;
        }
@@ -135,7 +135,7 @@ final class AppBatteryExemptionTracker
            if (pkg == null) {
                return BATTERY_USAGE_NONE;
            }
            result = pkg.getBatteryUsageSince(since, now);
            result = pkg.getBatteryUsageSince(since, now, types);
        }
        if (!result.second.isEmpty()) {
            // We have an open event (just start, no stop), get the battery usage till now.
@@ -149,7 +149,7 @@ final class AppBatteryExemptionTracker
    static final class UidBatteryStates extends BaseAppStateDurations<UidStateEventWithBattery> {
        UidBatteryStates(int uid, @NonNull String tag,
                @NonNull MaxTrackingDurationConfig maxTrackingDurationConfig) {
            super(uid, DEFAULT_NAME, EVENT_NUM, tag, maxTrackingDurationConfig);
            super(uid, DEFAULT_NAME, STATE_TYPE_NUM, tag, maxTrackingDurationConfig);
        }

        UidBatteryStates(@NonNull UidBatteryStates other) {
@@ -160,7 +160,7 @@ final class AppBatteryExemptionTracker
         * @param start {@code true} if it's a start event.
         * @param now   The timestamp when this event occurred.
         * @param batteryUsage The background current drain since the system boots.
         * @param eventType One of EVENT_TYPE_* defined in the class BaseAppStateDurationsTracker.
         * @param eventType One of STATE_TYPE_INDEX_* defined in the class BaseAppStateTracker.
         */
        void addEvent(boolean start, long now, ImmutableBatteryUsage batteryUsage, int eventType) {
            if (start) {
@@ -184,17 +184,6 @@ final class AppBatteryExemptionTracker
            return mEvents[eventType] != null ? mEvents[eventType].peekLast() : null;
        }

        /**
         * @return The pair of bg battery usage of given duration; the first value in the pair
         *         is the aggregated battery usage of all event pairs in this duration; while
         *         the second value is the battery usage since the system boots, if there is
         *         an open event(just start, no stop) at the end of the duration.
         */
        Pair<ImmutableBatteryUsage, ImmutableBatteryUsage> getBatteryUsageSince(long since,
                long now, int eventType) {
            return getBatteryUsageSince(since, now, mEvents[eventType]);
        }

        private Pair<ImmutableBatteryUsage, ImmutableBatteryUsage> getBatteryUsageSince(long since,
                long now, LinkedList<UidStateEventWithBattery> events) {
            if (events == null || events.size() == 0) {
@@ -217,14 +206,19 @@ final class AppBatteryExemptionTracker
        }

        /**
         * @return The aggregated battery usage amongst all the event types we're tracking.
         * @return The pair of bg battery usage of given duration; the first value in the pair
         *         is the aggregated battery usage of selected events in this duration; while
         *         the second value is the battery usage since the system boots, if there is
         *         an open event(just start, no stop) at the end of the duration.
         */
        Pair<ImmutableBatteryUsage, ImmutableBatteryUsage> getBatteryUsageSince(long since,
                long now) {
                long now, int types) {
            LinkedList<UidStateEventWithBattery> result = new LinkedList<>();
            for (int i = 0; i < mEvents.length; i++) {
                if ((types & stateIndexToType(i)) != 0) {
                    result = add(result, mEvents[i]);
                }
            }
            return getBatteryUsageSince(since, now, result);
        }

+70 −2
Original line number Diff line number Diff line
@@ -325,7 +325,8 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                final int uid = uidConsumers.keyAt(i);
                final ImmutableBatteryUsage actualUsage = uidConsumers.valueAt(i);
                final ImmutableBatteryUsage exemptedUsage = mAppRestrictionController
                        .getUidBatteryExemptedUsageSince(uid, since, now);
                        .getUidBatteryExemptedUsageSince(uid, since, now,
                                bgPolicy.mBgCurrentDrainExemptedTypes);
                // It's possible the exemptedUsage could be larger than actualUsage,
                // as the former one is an approximate value.
                final BatteryUsage bgUsage = actualUsage.mutate()
@@ -656,7 +657,8 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                    final BatteryUsage bgUsage = uidConsumers.valueAt(i)
                            .calcPercentage(uid, bgPolicy);
                    final BatteryUsage exemptedUsage = mAppRestrictionController
                            .getUidBatteryExemptedUsageSince(uid, since, now)
                            .getUidBatteryExemptedUsageSince(uid, since, now,
                                    bgPolicy.mBgCurrentDrainExemptedTypes)
                            .calcPercentage(uid, bgPolicy);
                    final BatteryUsage reportedUsage = new BatteryUsage(bgUsage)
                            .subtract(exemptedUsage)
@@ -1026,6 +1028,21 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
        static final String KEY_BG_CURRENT_DRAIN_POWER_COMPONENTS =
                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_power_components";

        /**
         * The types of state where we'll exempt its battery usage when it's in that state.
         * The state here must be one or a combination of STATE_TYPE_* in BaseAppStateTracker.
         */
        static final String KEY_BG_CURRENT_DRAIN_EXEMPTED_TYPES =
                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_exempted_types";

        /**
         * The behavior when an app has the permission ACCESS_BACKGROUND_LOCATION granted,
         * whether or not the system will use a higher threshold towards its background battery
         * usage because of it.
         */
        static final String KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION =
                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_high_threshold_by_bg_location";

        /**
         * Default value to the {@link #INDEX_REGULAR_CURRENT_DRAIN_THRESHOLD} of
         * the {@link #mBgCurrentDrainRestrictedBucketThreshold}.
@@ -1088,6 +1105,16 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>

        final int mDefaultBgCurrentDrainPowerComponent;

        /**
         * Default value to {@link #mBgCurrentDrainExmptedTypes}.
         **/
        final int mDefaultBgCurrentDrainExemptedTypes;

        /**
         * Default value to {@link #mBgCurrentDrainHighThresholdByBgLocation}.
         */
        final boolean mDefaultBgCurrentDrainHighThresholdByBgLocation;

        /**
         * The index to {@link #mBgCurrentDrainRestrictedBucketThreshold}
         * and {@link #mBgCurrentDrainBgRestrictedThreshold}.
@@ -1145,6 +1172,16 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>

        volatile Dimensions[] mBatteryDimensions;

        /**
         * @see #KEY_BG_CURRENT_DRAIN_EXEMPTED_TYPES.
         */
        volatile int mBgCurrentDrainExemptedTypes;

        /**
         * @see #KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION.
         */
        volatile boolean mBgCurrentDrainHighThresholdByBgLocation;

        /**
         * The capacity of the battery when fully charged in mAh.
         */
@@ -1201,6 +1238,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                    R.integer.config_bg_current_drain_types_to_bg_restricted);
            mDefaultBgCurrentDrainPowerComponent = resources.getInteger(
                    R.integer.config_bg_current_drain_power_components);
            mDefaultBgCurrentDrainExemptedTypes = resources.getInteger(
                    R.integer.config_bg_current_drain_exempted_types);
            mDefaultBgCurrentDrainHighThresholdByBgLocation = resources.getBoolean(
                    R.bool.config_bg_current_drain_high_threshold_by_bg_location);
            mBgCurrentDrainRestrictedBucketThreshold[0] =
                    mDefaultBgCurrentDrainRestrictedBucket;
            mBgCurrentDrainRestrictedBucketThreshold[1] =
@@ -1230,6 +1271,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
            switch (name) {
                case KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET:
                case KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_BG_RESTRICTED:
                case KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION:
                case KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_TO_RESTRICTED_BUCKET:
                case KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_TO_BG_RESTRICTED:
                case KEY_BG_CURRENT_DRAIN_TYPES_TO_RESTRICTED_BUCKET:
@@ -1249,6 +1291,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                case KEY_BG_CURRENT_DRAIN_EVENT_DURATION_BASED_THRESHOLD_ENABLED:
                    updateCurrentDrainEventDurationBasedThresholdEnabled();
                    break;
                case KEY_BG_CURRENT_DRAIN_EXEMPTED_TYPES:
                    updateCurrentDrainExemptedTypes();
                    break;
                default:
                    super.onPropertiesChanged(name);
                    break;
@@ -1305,6 +1350,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                    mBatteryDimensions[i] = new Dimensions(mBgCurrentDrainPowerComponents, i);
                }
            }
            mBgCurrentDrainHighThresholdByBgLocation =
                    DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                    KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION,
                    mDefaultBgCurrentDrainHighThresholdByBgLocation);
        }

        private void updateCurrentDrainWindow() {
@@ -1335,6 +1384,13 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                    mDefaultBgCurrentDrainEventDurationBasedThresholdEnabled);
        }

        private void updateCurrentDrainExemptedTypes() {
            mBgCurrentDrainExemptedTypes = DeviceConfig.getInt(
                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                    KEY_BG_CURRENT_DRAIN_EXEMPTED_TYPES,
                    mDefaultBgCurrentDrainExemptedTypes);
        }

        @Override
        public void onSystemReady() {
            mBatteryFullChargeMah =
@@ -1345,6 +1401,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
            updateCurrentDrainMediaPlaybackMinDuration();
            updateCurrentDrainLocationMinDuration();
            updateCurrentDrainEventDurationBasedThresholdEnabled();
            updateCurrentDrainExemptedTypes();
        }

        @Override
@@ -1507,6 +1564,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
        }

        private boolean hasLocation(int uid, long now, long window) {
            if (!mBgCurrentDrainHighThresholdByBgLocation) {
                return false;
            }
            final AppRestrictionController controller = mTracker.mAppRestrictionController;
            if (mInjector.getPermissionManagerServiceInternal().checkUidPermission(
                    uid, ACCESS_BACKGROUND_LOCATION) == PERMISSION_GRANTED) {
@@ -1620,6 +1680,14 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                pw.print(KEY_BG_CURRENT_DRAIN_POWER_COMPONENTS);
                pw.print('=');
                pw.println(mBgCurrentDrainPowerComponents);
                pw.print(prefix);
                pw.print(KEY_BG_CURRENT_DRAIN_EXEMPTED_TYPES);
                pw.print('=');
                pw.println(BaseAppStateTracker.stateTypesToString(mBgCurrentDrainExemptedTypes));
                pw.print(prefix);
                pw.print(KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION);
                pw.print('=');
                pw.println(mBgCurrentDrainHighThresholdByBgLocation);

                pw.print(prefix);
                pw.println("Excessive current drain detected:");
+8 −8
Original line number Diff line number Diff line
@@ -541,7 +541,7 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
                    }
                    if (isActive(i)) {
                        mEvents[i].add(new BaseTimeEvent(now));
                        notifyListenersOnEventIfNecessary(false, now,
                        notifyListenersOnStateChangeIfNecessary(false, now,
                                indexToForegroundServiceType(i));
                    }
                }
@@ -567,13 +567,13 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
                    }
                    if (!isActive(i)) {
                        mEvents[i].add(new BaseTimeEvent(now));
                        notifyListenersOnEventIfNecessary(true, now, serviceType);
                        notifyListenersOnStateChangeIfNecessary(true, now, serviceType);
                    }
                } else {
                    // Stop this type.
                    if (mEvents[i] != null && isActive(i)) {
                        mEvents[i].add(new BaseTimeEvent(now));
                        notifyListenersOnEventIfNecessary(false, now, serviceType);
                        notifyListenersOnStateChangeIfNecessary(false, now, serviceType);
                    }
                }
                changes &= ~serviceType;
@@ -582,20 +582,20 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac
            mForegroundServiceTypes = serviceTypes;
        }

        private void notifyListenersOnEventIfNecessary(boolean start, long now,
        private void notifyListenersOnStateChangeIfNecessary(boolean start, long now,
                @ForegroundServiceType int serviceType) {
            int eventType;
            int stateType;
            switch (serviceType) {
                case FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK:
                    eventType = BaseAppStateDurationsTracker.EVENT_TYPE_FGS_MEDIA_PLAYBACK;
                    stateType = BaseAppStateDurationsTracker.STATE_TYPE_FGS_MEDIA_PLAYBACK;
                    break;
                case FOREGROUND_SERVICE_TYPE_LOCATION:
                    eventType = BaseAppStateDurationsTracker.EVENT_TYPE_FGS_LOCATION;
                    stateType = BaseAppStateDurationsTracker.STATE_TYPE_FGS_LOCATION;
                    break;
                default:
                    return;
            }
            mTracker.notifyListenersOnEvent(mUid, mPackageName, start, now, eventType);
            mTracker.notifyListenersOnStateChange(mUid, mPackageName, start, now, stateType);
        }

        void setIsLongRunning(boolean isLongRunning) {
Loading