Merge change 5171 into donut

* changes:
  Track native processes and airplane mode.
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index ce32754..4bac593 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -37,6 +37,7 @@
     void notePhoneOff();
     void notePhoneSignalStrength(in SignalStrength signalStrength);
     void notePhoneDataConnectionState(int dataType, boolean hasData);
+    void noteAirplaneMode(boolean isAirplaneMode);
     void noteWifiOn(int uid);
     void noteWifiOff(int uid);
     void noteWifiRunning();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 58a3a83..fc4a9c4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -191,6 +191,8 @@
     private final Map<String, KernelWakelockStats> mProcWakelockFileStats = 
             new HashMap<String, KernelWakelockStats>();
 
+    private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
+    
     // For debugging
     public BatteryStatsImpl() {
         mFile = mBackupFile = null;
@@ -714,6 +716,10 @@
             }
         }
 
+        boolean isRunningLocked() {
+            return mNesting > 0;
+        }
+
         void stopRunningLocked(BatteryStatsImpl stats) {
             // Ignore attempt to stop a timer that isn't running
             if (mNesting == 0) {
@@ -1048,7 +1054,24 @@
             mPhoneOnTimer.stopRunningLocked(this);
         }
     }
-    
+
+    public void noteAirplaneModeLocked(boolean isAirplaneMode) {
+        final int bin = mPhoneSignalStrengthBin;
+        if (bin >= 0) {
+            if (!isAirplaneMode) {
+                if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
+                    mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
+                }
+            } else {
+                for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
+                    while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
+                        mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
+                    }
+                }
+            }
+        }
+    }
+
     public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
         // Bin the strength.
         int bin;
@@ -2797,7 +2820,7 @@
     public void removeUidStatsLocked(int uid) {
         mUidStats.remove(uid);
     }
-    
+
     /**
      * Retrieve the statistics object for a particular process, creating
      * if needed.
@@ -2808,6 +2831,26 @@
     }
 
     /**
+     * Retrieve the statistics object for a particular process, given
+     * the name of the process.
+     * @param name process name
+     * @return the statistics object for the process
+     */
+    public Uid.Proc getProcessStatsLocked(String name) {
+        int uid;
+        if (mUidCache.containsKey(name)) {
+            uid = mUidCache.get(name);
+        } else {
+            // TODO: Find the actual uid from /proc/pid/status. For now use the hashcode of the
+            // process name
+            uid = name.hashCode();
+            mUidCache.put(name, uid);
+        }
+        Uid u = getUidStatsLocked(uid);
+        return u.getProcessStatsLocked(name);
+    }
+
+    /**
      * Retrieve the statistics object for a particular process, creating
      * if needed.
      */
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index a37bf6e..4a8d8b1 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -219,12 +219,12 @@
     public double getAveragePower(String type, int level) {
         if (sPowerMap.containsKey(type)) {
             Object data = sPowerMap.get(type);
-            if (data instanceof double[]) {
-                final double[] values = (double[]) data;
-                if (values.length > level) {
+            if (data instanceof Double[]) {
+                final Double[] values = (Double[]) data;
+                if (values.length > level && level >= 0) {
                     return values[level];
-                } else if (values.length < 0) {
-                    return values[0];
+                } else if (level < 0) {
+                    return 0;
                 } else {
                     return values[values.length - 1];
                 }
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index b601ece..9f2856c 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -462,6 +462,15 @@
     //
 
     private void broadcastServiceStateChanged(ServiceState state) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            mBatteryStats.noteAirplaneMode(state.getState() == ServiceState.STATE_POWER_OFF);
+        } catch (RemoteException re) {
+            // Can't do much
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+
         Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
         Bundle data = new Bundle();
         state.fillInNotifierBundle(data);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 16bb29d..62b4d5e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -61,6 +61,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -1517,7 +1518,9 @@
                 }
             }
             
-            synchronized(mBatteryStatsService.getActiveStatistics()) {
+            final BatteryStatsImpl bstats =
+                    (BatteryStatsImpl) mBatteryStatsService.getActiveStatistics();
+            synchronized(bstats) {
                 synchronized(mPidsSelfLocked) {
                     if (haveNewCpuStats) {
                         if (mBatteryStatsService.isOnBattery()) {
@@ -1529,12 +1532,18 @@
                                 if (pr != null) {
                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
+                                } else {
+                                    BatteryStatsImpl.Uid.Proc ps =
+                                            bstats.getProcessStatsLocked(st.name);
+                                    if (ps != null) {
+                                        ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
+                                    }
                                 }
                             }
                         }
                     }
                 }
-        
+
                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
                     mLastWriteTime = now;
                     mBatteryStatsService.getActiveStatistics().writeLocked();
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 9a4b642..39a1ee0 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -16,9 +16,6 @@
 
 package com.android.server.am;
 
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.os.BatteryStatsImpl;
-
 import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
@@ -26,8 +23,12 @@
 import android.os.Process;
 import android.os.ServiceManager;
 import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
 import android.util.Log;
 
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.os.BatteryStatsImpl;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
@@ -191,7 +192,14 @@
             mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
         }
     }
-    
+
+    public void noteAirplaneMode(boolean airplaneMode) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteAirplaneModeLocked(airplaneMode);
+        }
+    }
+
     public void noteWifiOn(int uid) {
         enforceCallingPermission();
         synchronized (mStats) {