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

Commit e7f97212 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Implement issue #3426299: Introduce application "stopped" state

The package manager now keeps track of whether an application is
stopped.  There are new intent flags to control whether intent
filters in a stopped application will match the intent.  This is
currently used in one place, sending broadcasts, so that stopped
apps can not be launched due to background processes.

The package manager during first init makes sure no applications
are in the stopped state.  When new applications are installed,
that begin in the stopped state.  When the activity manager is
launching a component of an application, it ensures the application
is taken out of the stopped state.

The "force stop" button in manage applications will now put an
application back in to the stopped state; it can't go back out
of the stopped state until one of its components is launched by
the activity manager.

There will probably be a few more places where we need to filter
stopped applications out of intent matches, but doing this for
broadcast is a very big first step.

This also introduces a new broadcast that is sent to an application
after it is replaced with a new .apk.  But only if the app is not
in the stopped state.  This makes it a lot easier for developers to
implement code to get their application back in proper running shape
after an upgrade.

Finally another new broadcast is added that is sent to a package's
installer at the first time it is launched.  This allows the installer
to tell the package about it being installed only when it is first
actually used.

Change-Id: I589c53ff0e0ece868fe734ace4439c0d202dca2d
parent 56d93531
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -53165,6 +53165,17 @@
 visibility="public"
>
</field>
<field name="ACTION_MY_PACKAGE_REPLACED"
 type="java.lang.String"
 transient="false"
 volatile="false"
 value="&quot;android.intent.action.MY_PACKAGE_REPLACED&quot;"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ACTION_NEW_OUTGOING_CALL"
 type="java.lang.String"
 transient="false"
@@ -53209,6 +53220,17 @@
 visibility="public"
>
</field>
<field name="ACTION_PACKAGE_FIRST_LAUNCH"
 type="java.lang.String"
 transient="false"
 volatile="false"
 value="&quot;android.intent.action.PACKAGE_FIRST_LAUNCH&quot;"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ACTION_PACKAGE_INSTALL"
 type="java.lang.String"
 transient="false"
@@ -54484,6 +54506,17 @@
 visibility="public"
>
</field>
<field name="FLAG_EXCLUDE_STOPPED_PACKAGES"
 type="int"
 transient="false"
 volatile="false"
 value="16"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_FROM_BACKGROUND"
 type="int"
 transient="false"
@@ -54517,6 +54550,17 @@
 visibility="public"
>
</field>
<field name="FLAG_INCLUDE_STOPPED_PACKAGES"
 type="int"
 transient="false"
 volatile="false"
 value="32"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_RECEIVER_REGISTERED_ONLY"
 type="int"
 transient="false"
@@ -58332,6 +58376,17 @@
 visibility="public"
>
</field>
<field name="FLAG_STOPPED"
 type="int"
 transient="false"
 volatile="false"
 value="2097152"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_SUPPORTS_LARGE_SCREENS"
 type="int"
 transient="false"
+42 −0
Original line number Diff line number Diff line
@@ -1311,6 +1311,17 @@ public class Intent implements Parcelable, Cloneable {
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
    /**
     * Broadcast Action: A new version of your application has been installed
     * over an existing one.  This is only sent to the application that was
     * replaced.  It does not contain any additional data; to receive it, just
     * use an intent filter for this action.
     *
     * <p class="note">This is a protected intent that can only be sent
     * by the system.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED";
    /**
     * Broadcast Action: An existing application package has been removed from
     * the device.  The data contains the name of the package.  The package
@@ -1402,6 +1413,17 @@ public class Intent implements Parcelable, Cloneable {
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED";

    /**
     * Broadcast Action: Sent to the installer package of an application
     * when that application is first launched (that is the first time it
     * is moved out of the stopped state).  The data contains the name of the package.
     *
     * <p class="note">This is a protected intent that can only be sent
     * by the system.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";

    /**
     * Broadcast Action: Resources for a set of packages (which were
     * previously unavailable) are currently
@@ -2442,6 +2464,20 @@ public class Intent implements Parcelable, Cloneable {
     * been found to create the final resolved list.
     */
    public static final int FLAG_DEBUG_LOG_RESOLUTION = 0x00000008;
    /**
     * If set, this intent will not match any components in packages that
     * are currently stopped.  If this is not set, then the default behavior
     * is to include such applications in the result.
     */
    public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 0x00000010;
    /**
     * If set, this intent will always match any components in packages that
     * are currently stopped.  This is the default behavior when
     * {@link #FLAG_EXCLUDE_STOPPED_PACKAGES} is not set.  If both of these
     * flags are set, this one wins (it allows overriding of exclude for
     * places where the framework may automatically set the exclude flag).
     */
    public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020;

    /**
     * If set, the new activity is not kept in the history stack.  As soon as
@@ -3915,6 +3951,12 @@ public class Intent implements Parcelable, Cloneable {
        return mFlags;
    }

    /** @hide */
    public boolean isExcludingStopped() {
        return (mFlags&(FLAG_EXCLUDE_STOPPED_PACKAGES|FLAG_INCLUDE_STOPPED_PACKAGES))
                == FLAG_EXCLUDE_STOPPED_PACKAGES;
    }

    /**
     * Retrieve the application package name this Intent is limited to.  When
     * resolving an Intent, if non-null this limits the resolution to only
+6 −0
Original line number Diff line number Diff line
@@ -277,6 +277,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
     */
    public static final int FLAG_LARGE_HEAP = 1<<20;

    /**
     * Value for {@link #flags}: true if this application's package is in
     * the stopped state.
     */
    public static final int FLAG_STOPPED = 1<<21;

    /**
     * Value for {@link #flags}: Set to true if the application has been
     * installed using the forward lock option.
+6 −0
Original line number Diff line number Diff line
@@ -209,6 +209,12 @@ interface IPackageManager {
     */
    int getApplicationEnabledSetting(in String packageName);
    
    /**
     * Set whether the given package should be considered stopped, making
     * it not visible to implicit intents that filter out stopped packages.
     */
    void setPackageStoppedState(String packageName, boolean stopped);

    /**
     * Free storage by deleting LRU sorted list of cache files across
     * all applications. If the currently available free storage
+13 −0
Original line number Diff line number Diff line
@@ -2817,6 +2817,9 @@ public class PackageParser {
        // User set enabled state.
        public int mSetEnabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;

        // Whether the package has been stopped.
        public boolean mSetStopped = false;

        // Additional data supplied by callers.
        public Object mExtras;

@@ -3071,6 +3074,11 @@ public class PackageParser {
            if (!sCompatibilityModeEnabled) {
                p.applicationInfo.disableCompatibilityMode();
            }
            if (p.mSetStopped) {
                p.applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED;
            } else {
                p.applicationInfo.flags &= ~ApplicationInfo.FLAG_STOPPED;
            }
            return p.applicationInfo;
        }

@@ -3085,6 +3093,11 @@ public class PackageParser {
        if (!sCompatibilityModeEnabled) {
            ai.disableCompatibilityMode();
        }
        if (p.mSetStopped) {
            p.applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED;
        } else {
            p.applicationInfo.flags &= ~ApplicationInfo.FLAG_STOPPED;
        }
        if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
            ai.enabled = true;
        } else if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
Loading