Fix (mostly) issue #5109947: Race condition between retrieving a...

...content provider and updating its oom adj

This introduces the concept of an "unstable" reference on a content
provider.  When holding such a reference (and no normal stable ref),
the content provider dying will not cause the client process to be
killed.

This is used in ContentResolver.query(), .openAssetFileDescriptor(),
and .openTypedAssetFileDescriptor() to first access the provider
with an unstable reference, and if at the point of calling into the
provider we find it is dead then acquiring a new stable reference
and doing the operation again.  Thus if the provider process dies
at any point until we get the result back, our own process will not
be killed and we can safely retry the operation.

Arguably there is still the potential for a race -- if somehow the
provider is killed way late by the OOM killer after the query or
open has returned -- but this should now be *extremely* unlikely.
We also continue to have the issue with the other calls, but these
are much less critical, and the same model can't be used there (we
wouldn't want to execute two insert operations for example).

The implementation of this required some significant changes to the
underlying plumbing of content providers, now keeping track of the
two different reference counts, and managing them appropriately.  To
facilitate this, the activity manager now has a formal connection
object for a client reference on a content provider, which hands to
the application when opening the provider.

These changes have allowed a lot of the code to be cleaned up and
subtle issues closed.  For example, when a process is crashing, we
now have a much better idea of the state of content provider clients
(olding a stable ref, unstable ref, or waiting for it to launch), so
that we can correctly handle each of these.

The client side code is also a fair amount cleaner, though in the
future there is more than should be done.  In particular, the two
ProviderClientRecord and ProviderRefCount classes should be combined
into one, part of which is exposed to the ContentResolver internal
API as a reference on a content provider with methods for updating
reference counts and such.  Some day we'll do that.

Change-Id: I87b10d1b67573ab899e09ca428f1b556fd669c8c
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cf304df..609a047 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -116,14 +116,16 @@
     public void reportThumbnail(IBinder token,
             Bitmap thumbnail, CharSequence description) throws RemoteException;
     public ContentProviderHolder getContentProvider(IApplicationThread caller,
-            String name) throws RemoteException;
+            String name, boolean stable) throws RemoteException;
     public ContentProviderHolder getContentProviderExternal(String name, IBinder token)
             throws RemoteException;
-    public void removeContentProvider(IApplicationThread caller,
-            String name) throws RemoteException;
+    public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException;
     public void removeContentProviderExternal(String name, IBinder token) throws RemoteException;
     public void publishContentProviders(IApplicationThread caller,
             List<ContentProviderHolder> providers) throws RemoteException;
+    public boolean refContentProvider(IBinder connection, int stableDelta, int unstableDelta)
+            throws RemoteException;
+    public void unstableProviderDied(IBinder connection) throws RemoteException;
     public PendingIntent getRunningServiceControlPanel(ComponentName service)
             throws RemoteException;
     public ComponentName startService(IApplicationThread caller, Intent service,
@@ -363,6 +365,7 @@
     public static class ContentProviderHolder implements Parcelable {
         public final ProviderInfo info;
         public IContentProvider provider;
+        public IBinder connection;
         public boolean noReleaseNeeded;
 
         public ContentProviderHolder(ProviderInfo _info) {
@@ -380,6 +383,7 @@
             } else {
                 dest.writeStrongBinder(null);
             }
+            dest.writeStrongBinder(connection);
             dest.writeInt(noReleaseNeeded ? 1:0);
         }
 
@@ -398,6 +402,7 @@
             info = ProviderInfo.CREATOR.createFromParcel(source);
             provider = ContentProviderNative.asInterface(
                 source.readStrongBinder());
+            connection = source.readStrongBinder();
             noReleaseNeeded = source.readInt() != 0;
         }
     }
@@ -476,7 +481,7 @@
     int REPORT_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
     int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
     int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
-    
+    int REF_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
     int FINISH_SUB_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
     int GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
     int START_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
@@ -597,4 +602,5 @@
     int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147;
     int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
     int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149;
+    int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150;
 }