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
diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java
index e9ee12c..b78389b 100644
--- a/services/java/com/android/server/IntentResolver.java
+++ b/services/java/com/android/server/IntentResolver.java
@@ -36,7 +36,6 @@
 import android.util.Printer;
 
 import android.util.Config;
-import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.IntentFilter;
 
@@ -326,6 +325,15 @@
         return true;
     }
 
+    /**
+     * Returns whether the object associated with the given filter is
+     * "stopped," that is whether it should not be included in the result
+     * if the intent requests to excluded stopped objects.
+     */
+    protected boolean isFilterStopped(F filter) {
+        return false;
+    }
+
     protected String packageForFilter(F filter) {
         return null;
     }
@@ -496,6 +504,8 @@
         final String action = intent.getAction();
         final Uri data = intent.getData();
 
+        final boolean excludingStopped = intent.isExcludingStopped();
+
         final int N = src != null ? src.size() : 0;
         boolean hasNonDefaults = false;
         int i;
@@ -504,6 +514,13 @@
             int match;
             if (debug) Slog.v(TAG, "Matching against filter " + filter);
 
+            if (excludingStopped && isFilterStopped(filter)) {
+                if (debug) {
+                    Slog.v(TAG, "  Filter's target is stopped; skipping");
+                }
+                continue;
+            }
+
             // Do we already have this one?
             if (!allowFilterResult(filter, dest)) {
                 if (debug) {