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

Commit 236a41d4 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Allow apps receiving onMediaButton() callback to start FGS from BG." into sc-dev

parents 2363bb81 eba0108f
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.SystemService;
import android.annotation.UserHandleAware;
import android.content.Context;
import android.content.Context;


import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
@@ -295,6 +296,11 @@ public class PowerExemptionManager {
     * @hide
     * @hide
     */
     */
    public static final int REASON_SHELL = 316;
    public static final int REASON_SHELL = 316;
    /**
     * Media session callbacks.
     * @hide
     */
    public static final int REASON_MEDIA_SESSION_CALLBACK = 317;


    /**
    /**
     * The list of BG-FGS-Launch and temp-allow-list reason code.
     * The list of BG-FGS-Launch and temp-allow-list reason code.
@@ -354,6 +360,7 @@ public class PowerExemptionManager {
            REASON_EVENT_SMS,
            REASON_EVENT_SMS,
            REASON_EVENT_MMS,
            REASON_EVENT_MMS,
            REASON_SHELL,
            REASON_SHELL,
            REASON_MEDIA_SESSION_CALLBACK,
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface ReasonCode {}
    public @interface ReasonCode {}
@@ -451,6 +458,7 @@ public class PowerExemptionManager {
     * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
     * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
     * @param reason a optional human readable reason string, could be null or empty string.
     * @param reason a optional human readable reason string, could be null or empty string.
     */
     */
    @UserHandleAware
    @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
    @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
    public void addToTemporaryAllowList(@NonNull String packageName, long durationMs,
    public void addToTemporaryAllowList(@NonNull String packageName, long durationMs,
            @ReasonCode int reasonCode, @Nullable String reason) {
            @ReasonCode int reasonCode, @Nullable String reason) {
@@ -474,6 +482,7 @@ public class PowerExemptionManager {
     *                    used for logging purposes. Could be null or empty string.
     *                    used for logging purposes. Could be null or empty string.
     * @return The duration (in milliseconds) that the app is allow-listed for
     * @return The duration (in milliseconds) that the app is allow-listed for
     */
     */
    @UserHandleAware
    @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
    @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
    public long addToTemporaryAllowListForEvent(@NonNull String packageName,
    public long addToTemporaryAllowListForEvent(@NonNull String packageName,
            @AllowListEvent int event, @ReasonCode int reasonCode, @Nullable String reason) {
            @AllowListEvent int event, @ReasonCode int reasonCode, @Nullable String reason) {
@@ -626,6 +635,8 @@ public class PowerExemptionManager {
                return "EVENT_MMS";
                return "EVENT_MMS";
            case REASON_SHELL:
            case REASON_SHELL:
                return "SHELL";
                return "SHELL";
            case REASON_MEDIA_SESSION_CALLBACK:
                return "MEDIA_SESSION_CALLBACK";
            default:
            default:
                return "(unknown:" + reasonCode + ")";
                return "(unknown:" + reasonCode + ")";
        }
        }
+2 −2
Original line number Original line Diff line number Diff line
@@ -2692,7 +2692,7 @@ public class DeviceIdleController extends SystemService
    void addPowerSaveTempAllowlistAppChecked(String packageName, long duration,
    void addPowerSaveTempAllowlistAppChecked(String packageName, long duration,
            int userId, @ReasonCode int reasonCode, @Nullable String reason)
            int userId, @ReasonCode int reasonCode, @Nullable String reason)
            throws RemoteException {
            throws RemoteException {
        getContext().enforceCallingPermission(
        getContext().enforceCallingOrSelfPermission(
                Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
                Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
                "No permission to change device idle whitelist");
                "No permission to change device idle whitelist");
        final int callingUid = Binder.getCallingUid();
        final int callingUid = Binder.getCallingUid();
@@ -2715,7 +2715,7 @@ public class DeviceIdleController extends SystemService


    void removePowerSaveTempAllowlistAppChecked(String packageName, int userId)
    void removePowerSaveTempAllowlistAppChecked(String packageName, int userId)
            throws RemoteException {
            throws RemoteException {
        getContext().enforceCallingPermission(
        getContext().enforceCallingOrSelfPermission(
                Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
                Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
                "No permission to change device idle whitelist");
                "No permission to change device idle whitelist");
        final int callingUid = Binder.getCallingUid();
        final int callingUid = Binder.getCallingUid();
+8 −0
Original line number Original line Diff line number Diff line
@@ -88,6 +88,14 @@ package com.android.server {


}
}


package com.android.server.am {

  public interface ActivityManagerLocal {
    method public boolean canStartForegroundService(int, int, @NonNull String);
  }

}

package com.android.server.role {
package com.android.server.role {


  public interface RoleServicePlatformHelper {
  public interface RoleServicePlatformHelper {
+8 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,14 @@ package com.android.server {


}
}


package com.android.server.am {

  public interface ActivityManagerLocal {
    method public boolean canStartForegroundService(int, int, @NonNull String);
  }

}

package com.android.server.role {
package com.android.server.role {


  public interface RoleServicePlatformHelper {
  public interface RoleServicePlatformHelper {
+51 −31
Original line number Original line Diff line number Diff line
@@ -5409,16 +5409,28 @@ public final class ActiveServices {
        }
        }
    }
    }


    boolean canStartForegroundServiceLocked(int callingPid, int callingUid, String callingPackage) {
        if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
            return true;
        }
        final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
                callingPackage, callingPid, callingUid, null /* serviceRecord */,
                false /* allowBackgroundActivityStarts */);
        final @ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundLocked(
                allowWhileInUse, callingPid, callingUid, callingPackage, null /* targetService */);
        return allowStartFgs != REASON_DENIED;
    }

    /**
    /**
     * Should allow while-in-use permissions in FGS or not.
     * Should allow while-in-use permissions in FGS or not.
     * A typical BG started FGS is not allowed to have while-in-use permissions.
     * A typical BG started FGS is not allowed to have while-in-use permissions.
     * @param callingPackage caller app's package name.
     * @param callingPackage caller app's package name.
     * @param callingUid caller app's uid.
     * @param callingUid caller app's uid.
     * @param r the service to start.
     * @param targetService the service to start.
     * @return {@link ReasonCode}
     * @return {@link ReasonCode}
     */
     */
    private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
    private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
            int callingPid, int callingUid, ServiceRecord r,
            int callingPid, int callingUid, @Nullable ServiceRecord targetService,
            boolean allowBackgroundActivityStarts) {
            boolean allowBackgroundActivityStarts) {
        int ret = REASON_DENIED;
        int ret = REASON_DENIED;


@@ -5480,8 +5492,8 @@ public final class ActiveServices {
        }
        }


        if (ret == REASON_DENIED) {
        if (ret == REASON_DENIED) {
            if (r.app != null) {
            if (targetService != null && targetService.app != null) {
                ActiveInstrumentation instr = r.app.getActiveInstrumentation();
                ActiveInstrumentation instr = targetService.app.getActiveInstrumentation();
                if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
                if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
                    ret = REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
                    ret = REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
                }
                }
@@ -5527,16 +5539,44 @@ public final class ActiveServices {
    private @ReasonCode int shouldAllowFgsStartForegroundLocked(
    private @ReasonCode int shouldAllowFgsStartForegroundLocked(
            @ReasonCode int allowWhileInUse, String callingPackage, int callingPid,
            @ReasonCode int allowWhileInUse, String callingPackage, int callingPid,
            int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) {
            int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) {
        int ret = allowWhileInUse;
        FgsStartTempAllowList.TempFgsAllowListEntry tempAllowListReason =
        FgsStartTempAllowList.TempFgsAllowListEntry tempAllowListReason =
                r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid);
                r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid);
        int ret = shouldAllowFgsStartForegroundLocked(allowWhileInUse, callingPid, callingUid,
                callingPackage, r);


        final StringBuilder sb = new StringBuilder(64);
        final int uidState = mAm.getUidStateLocked(callingUid);
        final int uidState = mAm.getUidStateLocked(callingUid);
        final String debugInfo =
                "[callingPackage: " + callingPackage
                        + "; callingUid: " + callingUid
                        + "; uidState: " + ProcessList.makeProcStateString(uidState)
                        + "; intent: " + intent
                        + "; code:" + reasonCodeToString(ret)
                        + "; tempAllowListReason:<"
                        + (tempAllowListReason == null ? null :
                                (tempAllowListReason.mReason
                                        + ",reasonCode:"
                                        + reasonCodeToString(tempAllowListReason.mReasonCode)
                                        + ",duration:" + tempAllowListReason.mDuration
                                        + ",callingUid:" + tempAllowListReason.mCallingUid))
                        + ">"
                        + "; targetSdkVersion:" + r.appInfo.targetSdkVersion
                        + "]";
        if (!debugInfo.equals(r.mInfoAllowStartForeground)) {
            r.mLoggedInfoAllowStartForeground = false;
            r.mInfoAllowStartForeground = debugInfo;
        }
        return ret;
    }

    private @ReasonCode int shouldAllowFgsStartForegroundLocked(@ReasonCode int allowWhileInUse,
            int callingPid, int callingUid, String callingPackage,
            @Nullable ServiceRecord targetService) {
        int ret = allowWhileInUse;

        if (ret == REASON_DENIED) {
        if (ret == REASON_DENIED) {
            final int uidState = mAm.getUidStateLocked(callingUid);
            // Is the calling UID at PROCESS_STATE_TOP or above?
            // Is the calling UID at PROCESS_STATE_TOP or above?
            if (uidState <= PROCESS_STATE_TOP) {
            if (uidState <= PROCESS_STATE_TOP) {
                sb.append("uidState=").append(uidState);
                ret = getReasonCodeFromProcState(uidState);
                ret = getReasonCodeFromProcState(uidState);
            }
            }
        }
        }
@@ -5608,8 +5648,10 @@ public final class ActiveServices {


        // NOTE this should always be the last check.
        // NOTE this should always be the last check.
        if (ret == REASON_DENIED) {
        if (ret == REASON_DENIED) {
            if (isPackageExemptedFromFgsRestriction(r.appInfo.packageName, r.appInfo.uid)
            if (isPackageExemptedFromFgsRestriction(callingPackage, callingUid)) {
                    || isPackageExemptedFromFgsRestriction(callingPackage, callingUid)) {
                ret = REASON_EXEMPTED_PACKAGE;
            } else if (targetService != null && isPackageExemptedFromFgsRestriction(
                    targetService.appInfo.packageName, targetService.appInfo.uid)) {
                ret = REASON_EXEMPTED_PACKAGE;
                ret = REASON_EXEMPTED_PACKAGE;
            }
            }
        }
        }
@@ -5622,28 +5664,6 @@ public final class ActiveServices {
            }
            }
        }
        }


        final String debugInfo =
                "[callingPackage: " + callingPackage
                        + "; callingUid: " + callingUid
                        + "; uidState: " + ProcessList.makeProcStateString(uidState)
                        + "; intent: " + intent
                        + "; code:" + reasonCodeToString(ret)
                        + "; tempAllowListReason:<" +
                        (tempAllowListReason == null ? null :
                                (tempAllowListReason.mReason
                                + ",reasonCode:"
                                + reasonCodeToString(tempAllowListReason.mReasonCode)
                                + ",duration:" + tempAllowListReason.mDuration
                                + ",callingUid:" + tempAllowListReason.mCallingUid))
                        + ">"
                        + "; extra:" + sb.toString()
                        + "; targetSdkVersion:" + r.appInfo.targetSdkVersion
                        + "]";
        if (!debugInfo.equals(r.mInfoAllowStartForeground)) {
            r.mLoggedInfoAllowStartForeground = false;
            r.mInfoAllowStartForeground = debugInfo;
        }

        return ret;
        return ret;
    }
    }


Loading