Add better service reporting.

This will be used elsewhere.

Change-Id: Id561fa7fed5eb65446312cb697813483903d33a6
diff --git a/api/current.xml b/api/current.xml
index b052a61..7bb99e4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -17373,6 +17373,21 @@
  visibility="public"
 >
 </method>
+<method name="getRunningServiceControlPanel"
+ return="android.app.PendingIntent"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="service" type="android.content.ComponentName">
+</parameter>
+<exception name="SecurityException" type="java.lang.SecurityException">
+</exception>
+</method>
 <method name="getRunningServices"
  return="java.util.List&lt;android.app.ActivityManager.RunningServiceInfo&gt;"
  abstract="false"
@@ -17942,6 +17957,39 @@
  visibility="public"
 >
 </field>
+<field name="REASON_PROVIDER_IN_USE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="REASON_SERVICE_IN_USE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="REASON_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="importance"
  type="int"
  transient="false"
@@ -17952,6 +18000,36 @@
  visibility="public"
 >
 </field>
+<field name="importanceReasonCode"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="importanceReasonComponent"
+ type="android.content.ComponentName"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="importanceReasonPid"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="lru"
  type="int"
  transient="false"
@@ -18125,6 +18203,26 @@
  visibility="public"
 >
 </field>
+<field name="clientLabel"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="clientPackage"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="crashCount"
  type="int"
  transient="false"
@@ -112103,6 +112201,17 @@
  visibility="public"
 >
 </constructor>
+<field name="ACTION_ACCESSIBILITY_SETTINGS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.settings.ACCESSIBILITY_SETTINGS&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ACTION_AIRPLANE_MODE_SETTINGS"
  type="java.lang.String"
  transient="false"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index ad06fa9..af73112 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -366,6 +366,19 @@
          */
         public int flags;
         
+        /**
+         * For special services that are bound to by system code, this is
+         * the package that holds the binding.
+         */
+        public String clientPackage;
+        
+        /**
+         * For special services that are bound to by system code, this is
+         * a string resource providing a user-visible label for who the
+         * client is.
+         */
+        public int clientLabel;
+        
         public RunningServiceInfo() {
         }
 
@@ -386,6 +399,8 @@
             dest.writeLong(lastActivityTime);
             dest.writeLong(restarting);
             dest.writeInt(this.flags);
+            dest.writeString(clientPackage);
+            dest.writeInt(clientLabel);
         }
 
         public void readFromParcel(Parcel source) {
@@ -401,6 +416,8 @@
             lastActivityTime = source.readLong();
             restarting = source.readLong();
             flags = source.readInt();
+            clientPackage = source.readString();
+            clientLabel = source.readInt();
         }
         
         public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() {
@@ -439,6 +456,22 @@
     }
     
     /**
+     * Returns a PendingIntent you can start to show a control panel for the
+     * given running service.  If the service does not have a control panel,
+     * null is returned.
+     */
+    public PendingIntent getRunningServiceControlPanel(ComponentName service)
+            throws SecurityException {
+        try {
+            return ActivityManagerNative.getDefault()
+                    .getRunningServiceControlPanel(service);
+        } catch (RemoteException e) {
+            // System dead, we will be dead too soon!
+            return null;
+        }
+    }
+    
+    /**
      * Information you can retrieve about the available memory through
      * {@link ActivityManager#getMemoryInfo}.
      */
@@ -704,8 +737,51 @@
          */
         public int lru;
         
+        /**
+         * Constant for {@link #importanceReasonCode}: nothing special has
+         * been specified for the reason for this level.
+         */
+        public static final int REASON_UNKNOWN = 0;
+        
+        /**
+         * Constant for {@link #importanceReasonCode}: one of the application's
+         * content providers is being used by another process.  The pid of
+         * the client process is in {@link #importanceReasonPid} and the
+         * target provider in this process is in
+         * {@link #importanceReasonComponent}.
+         */
+        public static final int REASON_PROVIDER_IN_USE = 1;
+        
+        /**
+         * Constant for {@link #importanceReasonCode}: one of the application's
+         * content providers is being used by another process.  The pid of
+         * the client process is in {@link #importanceReasonPid} and the
+         * target provider in this process is in
+         * {@link #importanceReasonComponent}.
+         */
+        public static final int REASON_SERVICE_IN_USE = 2;
+        
+        /**
+         * The reason for {@link #importance}, if any.
+         */
+        public int importanceReasonCode;
+        
+        /**
+         * For the specified values of {@link #importanceReasonCode}, this
+         * is the process ID of the other process that is a client of this
+         * process.  This will be 0 if no other process is using this one.
+         */
+        public int importanceReasonPid;
+        
+        /**
+         * For the specified values of {@link #importanceReasonCode}, this
+         * is the name of the component that is being used in this process.
+         */
+        public ComponentName importanceReasonComponent;
+        
         public RunningAppProcessInfo() {
             importance = IMPORTANCE_FOREGROUND;
+            importanceReasonCode = REASON_UNKNOWN;
         }
         
         public RunningAppProcessInfo(String pProcessName, int pPid, String pArr[]) {
@@ -724,6 +800,9 @@
             dest.writeStringArray(pkgList);
             dest.writeInt(importance);
             dest.writeInt(lru);
+            dest.writeInt(importanceReasonCode);
+            dest.writeInt(importanceReasonPid);
+            ComponentName.writeToParcel(importanceReasonComponent, dest);
         }
 
         public void readFromParcel(Parcel source) {
@@ -732,6 +811,9 @@
             pkgList = source.readStringArray();
             importance = source.readInt();
             lru = source.readInt();
+            importanceReasonCode = source.readInt();
+            importanceReasonPid = source.readInt();
+            importanceReasonComponent = ComponentName.readFromParcel(source);
         }
 
         public static final Creator<RunningAppProcessInfo> CREATOR = 
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 213f26e..4ed152e 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -510,6 +510,15 @@
             return true;
         }
         
+        case GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            ComponentName comp = ComponentName.CREATOR.createFromParcel(data);
+            PendingIntent pi = getRunningServiceControlPanel(comp);
+            reply.writeNoException();
+            PendingIntent.writePendingIntentOrNullToParcel(pi, reply);
+            return true;
+        }
+
         case START_SERVICE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
@@ -1634,6 +1643,21 @@
         reply.recycle();
     }
     
+    public PendingIntent getRunningServiceControlPanel(ComponentName service)
+            throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        service.writeToParcel(data, 0);
+        mRemote.transact(GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION, data, reply, 0);
+        reply.readException();
+        PendingIntent res = PendingIntent.readPendingIntentOrNullFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+    
     public ComponentName startService(IApplicationThread caller, Intent service,
             String resolvedType) throws RemoteException
     {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index a7bef54..a937c11 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -126,13 +126,15 @@
     public void finishOtherInstances(IBinder token, ComponentName className) throws RemoteException;
     /* oneway */
     public void reportThumbnail(IBinder token,
-                                Bitmap thumbnail, CharSequence description) throws RemoteException;
+            Bitmap thumbnail, CharSequence description) throws RemoteException;
     public ContentProviderHolder getContentProvider(IApplicationThread caller,
-                                                    String name) throws RemoteException;
+            String name) throws RemoteException;
     public void removeContentProvider(IApplicationThread caller,
-        String name) throws RemoteException;
+            String name) throws RemoteException;
     public void publishContentProviders(IApplicationThread caller,
-                                        List<ContentProviderHolder> providers) throws RemoteException;
+            List<ContentProviderHolder> providers) throws RemoteException;
+    public PendingIntent getRunningServiceControlPanel(ComponentName service)
+            throws RemoteException;
     public ComponentName startService(IApplicationThread caller, Intent service,
             String resolvedType) throws RemoteException;
     public int stopService(IApplicationThread caller, Intent service,
@@ -367,7 +369,7 @@
     int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
     int SET_PERSISTENT_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;
     int STOP_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+34;
     int BIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+35;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 87a8f39..1d1161e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2044,6 +2044,24 @@
     public static final String EXTRA_CHANGED_COMPONENT_NAME =
             "android.intent.extra.changed_component_name";
 
+    /**
+     * @hide
+     * Magic extra system code can use when binding, to give a label for
+     * who it is that has bound to a service.  This is an integer giving
+     * a framework string resource that can be displayed to the user.
+     */
+    public static final String EXTRA_CLIENT_LABEL =
+            "android.intent.extra.client_label";
+
+    /**
+     * @hide
+     * Magic extra system code can use when binding, to give a PendingIntent object
+     * that can be launched for the user to disable the system's use of this
+     * service.
+     */
+    public static final String EXTRA_CLIENT_INTENT =
+            "android.intent.extra.client_intent";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 5ffe962..6d27bc7 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1064,6 +1064,10 @@
             Intent intent = new Intent();
             intent.setAction("android.content.SyncAdapter");
             intent.setComponent(info.componentName);
+            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
+                    com.android.internal.R.string.sync_binding_label);
+            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+                    mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
             return mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
         }
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 125ed0b..64e47eb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -119,6 +119,20 @@
             "android.settings.AIRPLANE_MODE_SETTINGS";
 
     /**
+     * Activity Action: Show settings for accessibility modules.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ACCESSIBILITY_SETTINGS =
+            "android.settings.ACCESSIBILITY_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of security and
      * location privacy.
      * <p>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 70c9385..3333915 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1943,25 +1943,34 @@
     <string-array translatable="false" name="carrier_properties">
     </string-array>
 
-     <!-- Title for the selected state of a CompoundButton. -->
-     <string name="accessibility_compound_button_selected">checked</string>
+    <!-- Title for the selected state of a CompoundButton. -->
+    <string name="accessibility_compound_button_selected">checked</string>
 
-     <!-- Title for the unselected state of a CompoundButton. -->
-     <string name="accessibility_compound_button_unselected">not checked</string>
+    <!-- Title for the unselected state of a CompoundButton. -->
+    <string name="accessibility_compound_button_unselected">not checked</string>
 
-     <string name="grant_credentials_permission_message_desc">The
-     listed applications are requesting permission to access the login credentials for account <xliff:g id="account" example="foo@gmail.com">%1$s</xliff:g> from
-     <xliff:g id="application" example="Google Apps">%2$s</xliff:g>. Do you wish to grant this permission? If so, your answer will be remembered and you will not be prompted
-     again.</string>
+    <string name="grant_credentials_permission_message_desc">The
+    listed applications are requesting permission to access the login credentials for account <xliff:g id="account" example="foo@gmail.com">%1$s</xliff:g> from
+    <xliff:g id="application" example="Google Apps">%2$s</xliff:g>. Do you wish to grant this permission? If so, your answer will be remembered and you will not be prompted
+    again.</string>
 
-     <string name="grant_credentials_permission_message_with_authtokenlabel_desc">The
-     listed applications are requesting permission to access the <xliff:g id="type" example="Contacts">%1$s</xliff:g> login credentials for account <xliff:g id="account" example="foo@gmail.com">%2$s</xliff:g> from
-     <xliff:g id="application" example="Google Apps">%3$s</xliff:g>. Do you wish to grant this permission? If so, your answer will be remembered and you will not be prompted
-     again.</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc">The
+    listed applications are requesting permission to access the <xliff:g id="type" example="Contacts">%1$s</xliff:g> login credentials for account <xliff:g id="account" example="foo@gmail.com">%2$s</xliff:g> from
+    <xliff:g id="application" example="Google Apps">%3$s</xliff:g>. Do you wish to grant this permission? If so, your answer will be remembered and you will not be prompted
+    again.</string>
 
-     <string name="allow">Allow</string>
-     <string name="deny">Deny</string>
-     <string name="permission_request_notification_title">Permission Requested</string>
-     <string name="permission_request_notification_subtitle">for account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g></string>
+    <string name="allow">Allow</string>
+    <string name="deny">Deny</string>
+    <string name="permission_request_notification_title">Permission Requested</string>
+    <string name="permission_request_notification_subtitle">for account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g></string>
 
+    <!-- Label to show for a service that is running because it is an input method. -->
+    <string name="input_method_binding_label">Input method</string>
+    <!-- Label to show for a service that is running because it is a sync adapter. -->
+    <string name="sync_binding_label">Sync</string>
+    <!-- Label to show for a service that is running because it is an accessibility module. -->
+    <string name="accessibility_binding_label">Accessibility</string>
+    <!-- Label to show for a service that is running because it is a wallpaper. -->
+    <string name="wallpaper_binding_label">Wallpaper</string>
+    
 </resources>
diff --git a/services/java/com/android/server/AccessibilityManagerService.java b/services/java/com/android/server/AccessibilityManagerService.java
index 55007ba..f67a7ae 100644
--- a/services/java/com/android/server/AccessibilityManagerService.java
+++ b/services/java/com/android/server/AccessibilityManagerService.java
@@ -25,6 +25,7 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.accessibilityservice.IEventListener;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -615,6 +616,10 @@
             mId = sIdCounter++;
             mComponentName = componentName;
             mIntent = new Intent().setComponent(mComponentName);
+            mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
+                    com.android.internal.R.string.accessibility_binding_label);
+            mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+                    mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
         }
 
         /**
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 558a024..1da2b47 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -32,6 +32,7 @@
 
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
+import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -765,6 +766,10 @@
         
         mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE);
         mCurIntent.setComponent(info.getComponent());
+        mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
+                com.android.internal.R.string.input_method_binding_label);
+        mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+                mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
         if (mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE)) {
             mLastBindTime = SystemClock.uptimeMillis();
             mHaveConnection = true;
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index c101463..cc977b0 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -21,6 +21,7 @@
 
 import android.app.IWallpaperManager;
 import android.app.IWallpaperManagerCallback;
+import android.app.PendingIntent;
 import android.backup.BackupManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -40,6 +41,7 @@
 import android.os.RemoteCallbackList;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.service.wallpaper.IWallpaperConnection;
 import android.service.wallpaper.IWallpaperEngine;
 import android.service.wallpaper.IWallpaperService;
@@ -376,6 +378,10 @@
             // Bind the service!
             WallpaperConnection newConn = new WallpaperConnection();
             intent.setComponent(realName);
+            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
+                    com.android.internal.R.string.wallpaper_binding_label);
+            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+                    mContext, 0, new Intent(Intent.ACTION_SET_WALLPAPER), 0));
             if (!mContext.bindService(intent, newConn,
                     Context.BIND_AUTO_CREATE)) {
                 throw new IllegalArgumentException("Unable to bind service: "
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 03ebf0c..9554a22 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8866,6 +8866,16 @@
                     } else {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
                     }
+                    currApp.importanceReasonCode = app.adjTypeCode;
+                    if (app.adjSource instanceof ProcessRecord) {
+                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
+                    } else if (app.adjSource instanceof HistoryRecord) {
+                        HistoryRecord r = (HistoryRecord)app.adjSource;
+                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
+                    }
+                    if (app.adjTarget instanceof ComponentName) {
+                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
+                    }
                     //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
                     //        + " lru=" + currApp.lru);
                     if (runList == null) {
@@ -9888,6 +9898,13 @@
         if (r.app != null && r.app.persistent) {
             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
         }
+        for (ConnectionRecord conn : r.connections.values()) {
+            if (conn.clientLabel != 0) {
+                info.clientPackage = conn.binding.client.info.packageName;
+                info.clientLabel = conn.clientLabel;
+                break;
+            }
+        }
         return info;
     }
     
@@ -9916,6 +9933,20 @@
         }
     }
 
+    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
+        synchronized (this) {
+            ServiceRecord r = mServices.get(name);
+            if (r != null) {
+                for (ConnectionRecord conn : r.connections.values()) {
+                    if (conn.clientIntent != null) {
+                        return conn.clientIntent;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+    
     private final ServiceRecord findServiceLocked(ComponentName name,
             IBinder token) {
         ServiceRecord r = mServices.get(name);
@@ -10783,6 +10814,29 @@
                 activity = (HistoryRecord)mHistory.get(aindex);
             }
 
+            int clientLabel = 0;
+            PendingIntent clientIntent = null;
+            
+            if (callerApp.info.uid == Process.SYSTEM_UID) {
+                // Hacky kind of thing -- allow system stuff to tell us
+                // what they are, so we can report this elsewhere for
+                // others to know why certain services are running.
+                try {
+                    clientIntent = (PendingIntent)service.getParcelableExtra(
+                            Intent.EXTRA_CLIENT_INTENT);
+                } catch (RuntimeException e) {
+                }
+                if (clientIntent != null) {
+                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
+                    if (clientLabel != 0) {
+                        // There are no useful extras in the intent, trash them.
+                        // System code calling with this stuff just needs to know
+                        // this will happen.
+                        service = service.cloneFilter();
+                    }
+                }
+            }
+            
             ServiceLookupResult res =
                 retrieveServiceLocked(service, resolvedType,
                         Binder.getCallingPid(), Binder.getCallingUid());
@@ -10803,7 +10857,7 @@
 
             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
             ConnectionRecord c = new ConnectionRecord(b, activity,
-                    connection, flags);
+                    connection, flags, clientLabel, clientIntent);
 
             IBinder binder = connection.asBinder();
             s.connections.put(binder, c);
@@ -12776,6 +12830,7 @@
             return (app.curAdj=app.maxAdj);
        }
         
+        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
         app.adjSource = null;
         app.adjTarget = null;
 
@@ -12909,6 +12964,8 @@
                                 adj = clientAdj > VISIBLE_APP_ADJ
                                         ? clientAdj : VISIBLE_APP_ADJ;
                                 app.adjType = "service";
+                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+                                        .REASON_SERVICE_IN_USE;
                                 app.adjSource = cr.binding.client;
                                 app.adjTarget = s.serviceInfo.name;
                             }
@@ -12922,6 +12979,8 @@
                                  || a.state == ActivityState.PAUSING)) {
                             adj = FOREGROUND_APP_ADJ;
                             app.adjType = "service";
+                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+                                    .REASON_SERVICE_IN_USE;
                             app.adjSource = a;
                             app.adjTarget = s.serviceInfo.name;
                         }
@@ -12964,6 +13023,8 @@
                             adj = clientAdj > FOREGROUND_APP_ADJ
                                     ? clientAdj : FOREGROUND_APP_ADJ;
                             app.adjType = "provider";
+                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+                                    .REASON_PROVIDER_IN_USE;
                             app.adjSource = client;
                             app.adjTarget = cpr.info.name;
                         }
diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/java/com/android/server/am/ConnectionRecord.java
index b3343dd..f613b00 100644
--- a/services/java/com/android/server/am/ConnectionRecord.java
+++ b/services/java/com/android/server/am/ConnectionRecord.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import android.app.IServiceConnection;
+import android.app.PendingIntent;
 
 import java.io.PrintWriter;
 
@@ -28,6 +29,8 @@
     final HistoryRecord activity;   // If non-null, the owning activity.
     final IServiceConnection conn;  // The client connection.
     final int flags;                // Binding options.
+    final int clientLabel;          // String resource labeling this client.
+    final PendingIntent clientIntent; // How to launch the client.
     String stringName;              // Caching of toString.
     
     void dump(PrintWriter pw, String prefix) {
@@ -40,11 +43,14 @@
     }
     
     ConnectionRecord(AppBindRecord _binding, HistoryRecord _activity,
-               IServiceConnection _conn, int _flags) {
+               IServiceConnection _conn, int _flags,
+               int _clientLabel, PendingIntent _clientIntent) {
         binding = _binding;
         activity = _activity;
         conn = _conn;
         flags = _flags;
+        clientLabel = _clientLabel;
+        clientIntent = _clientIntent;
     }
 
     public String toString() {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 76fdf09..d05b44b 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -75,6 +75,7 @@
     boolean reportLowMemory;    // Set to true when waiting to report low mem
     int lastPss;                // Last pss size reported by app.
     String adjType;             // Debugging: primary thing impacting oom_adj.
+    int adjTypeCode;            // Debugging: adj code to report to app.
     Object adjSource;           // Debugging: option dependent object.
     Object adjTarget;           // Debugging: target component impacting oom_adj.