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

Commit fb72b990 authored by Hui Yu's avatar Hui Yu
Browse files

Add API Service.getForegroundServiceType()

To return current foregroundServiceType if the service has become a
foreground service.

If service become foreground service by calling Service.startForeground(int,
Notification, int type), the returned type is the type specified.

If the no-type version Service.startForeground(int, Notification) is called.
the returned type is foregroundServiceType specified in manifest.

If no foregroundServiceType specified in manifest, the returned type is
zero.

If the service is not a foreground service, the returned type is zero.

Bug: 124517685
Test: atest cts/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java#testFgsLocation

Change-Id: Ibcc4431429a90aab92a5533e296fb104b4add9e6
parent c7e26f7f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6169,6 +6169,7 @@ package android.app {
    ctor public Service();
    method protected void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
    method public final android.app.Application getApplication();
    method public final int getForegroundServiceType();
    method @Nullable public abstract android.os.IBinder onBind(android.content.Intent);
    method public void onConfigurationChanged(android.content.res.Configuration);
    method public void onCreate();
+1 −0
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ interface IActivityManager {
    void setProcessImportant(in IBinder token, int pid, boolean isForeground, String reason);
    void setServiceForeground(in ComponentName className, in IBinder token,
            int id, in Notification notification, int flags, int foregroundServiceType);
    int getForegroundServiceType(in ComponentName className, in IBinder token);
    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);
    void getMemoryInfo(out ActivityManager.MemoryInfo outInfo);
    List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
+26 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.content.pm.ServiceInfo.ForegroundServiceType;
import android.content.res.Configuration;
import android.os.Build;
@@ -733,7 +734,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
   * {@link android.R.attr#foregroundServiceType} flags.
   * @throws IllegalArgumentException if param foregroundServiceType is not subset of manifest
   *     attribute {@link android.R.attr#foregroundServiceType}.
   * @see {@link android.content.pm.ServiceInfo} for the set of FOREGROUND_SERVICE_TYPE flags.
   * @see android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST
   */
    public final void startForeground(int id, @NonNull Notification notification,
            @ForegroundServiceType int foregroundServiceType) {
@@ -774,6 +775,30 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
        }
    }

    /**
     * If the service has become a foreground service by calling
     * {@link #startForeground(int, Notification)}
     * or {@link #startForeground(int, Notification, int)}, {@link #getForegroundServiceType()}
     * returns the current foreground service type.
     *
     * <p>If there is no foregroundServiceType specified
     * in manifest, {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE} is returned. </p>
     *
     * <p>If the service is not a foreground service,
     * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE} is returned.</p>
     *
     * @return current foreground service type flags.
     */
    public final @ForegroundServiceType int getForegroundServiceType() {
        int ret = ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE;
        try {
            ret = mActivityManager.getForegroundServiceType(
                    new ComponentName(this, mClassName), mToken);
        } catch (RemoteException ex) {
        }
        return ret;
    }

    /**
     * Print the Service's state into the given stream.  This gets invoked if
     * you run "adb shell dumpsys activity service &lt;yourservicename&gt;"
+26 −4
Original line number Diff line number Diff line
@@ -933,6 +933,27 @@ public final class ActiveServices {
        }
    }

    /**
     * Return the current foregroundServiceType of the ServiceRecord.
     * @param className ComponentName of the Service class.
     * @param token IBinder token.
     * @return current foreground service type.
     */
    public int getForegroundServiceTypeLocked(ComponentName className, IBinder token) {
        final int userId = UserHandle.getCallingUserId();
        final long origId = Binder.clearCallingIdentity();
        int ret = ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE;
        try {
            ServiceRecord r = findServiceLocked(className, token, userId);
            if (r != null) {
                ret = r.foregroundServiceType;
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return ret;
    }

    boolean foregroundAppShownEnoughLocked(ActiveForegroundApp aa, long nowElapsed) {
        if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Shown enough: pkg=" + aa.mPackageName + ", uid="
                + aa.mUid);
@@ -1260,10 +1281,11 @@ public final class ActiveServices {
                // Check the passed in foreground service type flags is a subset of manifest
                // foreground service type flags.
                if ((foregroundServiceType & manifestType) != foregroundServiceType) {
                    // STOPSHIP(b/120611119): replace log message with IllegalArgumentException.
                    Slog.w(TAG, "foregroundServiceType must be a subset of "
                            + "foregroundServiceType attribute in "
                            + "service element of manifest file");
                    throw new IllegalArgumentException("foregroundServiceType "
                        + String.format("0x%08X", foregroundServiceType)
                        + " is not a subset of foregroundServiceType attribute "
                        +  String.format("0x%08X", manifestType)
                        + " in service element of manifest file");
                }
            }
            boolean alreadyStartedOp = false;
+7 −0
Original line number Diff line number Diff line
@@ -13571,6 +13571,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    @Override
    public int getForegroundServiceType(ComponentName className, IBinder token) {
        synchronized (this) {
            return mServices.getForegroundServiceTypeLocked(className, token);
        }
    }
    @Override
    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
            boolean requireFull, String name, String callerPackage) {