Loading apex/statsd/aidl/android/os/IStatsCompanionService.aidl +0 −7 Original line number Diff line number Diff line Loading @@ -67,11 +67,4 @@ interface IStatsCompanionService { /** Tells StatsCompaionService to grab the uid map snapshot and send it to statsd. */ oneway void triggerUidSnapshot(); /** Tells StatsCompanionService to tell statsd to register a puller for the given atom id */ oneway void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, in int[] additiveFields, IPullAtomCallback pullerCallback); /** Tells StatsCompanionService to tell statsd to unregister a puller for the given atom id */ oneway void unregisterPullAtomCallback(int atomTag); } apex/statsd/aidl/android/os/IStatsManagerService.aidl +9 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.os; import android.app.PendingIntent; import android.os.IPullAtomCallback; /** * Binder interface to communicate with the Java-based statistics service helper. Loading Loading @@ -125,4 +126,11 @@ interface IStatsManagerService { * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS. */ void removeConfiguration(in long configId, in String packageName); /** Tell StatsManagerService to register a puller for the given atom tag with statsd. */ oneway void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, in int[] additiveFields, IPullAtomCallback pullerCallback); /** Tell StatsManagerService to unregister the pulller for the given atom tag from statsd. */ oneway void unregisterPullAtomCallback(int atomTag); } apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +0 −130 Original line number Diff line number Diff line Loading @@ -75,7 +75,6 @@ import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.IPullAtomCallback; import android.os.IStatsCompanionService; import android.os.IStatsd; import android.os.IStoraged; Loading Loading @@ -263,71 +262,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private StatsManagerService mStatsManagerService; private static final class PullerKey { private final int mUid; private final int mAtomTag; PullerKey(int uid, int atom) { mUid = uid; mAtomTag = atom; } public int getUid() { return mUid; } public int getAtom() { return mAtomTag; } @Override public int hashCode() { return Objects.hash(mUid, mAtomTag); } @Override public boolean equals(Object obj) { if (obj instanceof PullerKey) { PullerKey other = (PullerKey) obj; return this.mUid == other.getUid() && this.mAtomTag == other.getAtom(); } return false; } } private static final class PullerValue { private final long mCoolDownNs; private final long mTimeoutNs; private int[] mAdditiveFields; private IPullAtomCallback mCallback; PullerValue(long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback callback) { mCoolDownNs = coolDownNs; mTimeoutNs = timeoutNs; mAdditiveFields = additiveFields; mCallback = callback; } public long getCoolDownNs() { return mCoolDownNs; } public long getTimeoutNs() { return mTimeoutNs; } public int[] getAdditiveFields() { return mAdditiveFields; } public IPullAtomCallback getCallback() { return mCallback; } } private final HashMap<PullerKey, PullerValue> mPullers = new HashMap<>(); private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); private WifiManager mWifiManager = null; Loading Loading @@ -2634,57 +2568,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } @Override public void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback pullerCallback) { synchronized (sStatsdLock) { // Always cache the puller in SCS. // If statsd is down, we will register it when it comes back up. int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); PullerValue val = new PullerValue( coolDownNs, timeoutNs, additiveFields, pullerCallback); mPullers.put(key, val); if (sStatsd == null) { Slog.w(TAG, "Could not access statsd for registering puller for atom " + atomTag); return; } try { sStatsd.registerPullAtomCallback( callingUid, atomTag, coolDownNs, timeoutNs, additiveFields, pullerCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to register puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } } @Override public void unregisterPullAtomCallback(int atomTag) { synchronized (sStatsdLock) { // Always remove the puller in SCS. // If statsd is down, we will not register it when it comes back up. int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); mPullers.remove(key); if (sStatsd == null) { Slog.w(TAG, "Could not access statsd for registering puller for atom " + atomTag); return; } try { sStatsd.unregisterPullAtomCallback(callingUid, atomTag); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to register puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } } // Statsd related code Loading Loading @@ -2763,8 +2646,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Pull the latest state of UID->app name, version mapping when // statsd starts. informAllUidsLocked(mContext); // Register all pullers. If SCS has just started, this should be empty. registerAllPullersLocked(); } finally { restoreCallingIdentity(token); } Loading @@ -2776,17 +2657,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } @GuardedBy("sStatsdLock") private void registerAllPullersLocked() throws RemoteException { // TODO: pass in one call, using a file descriptor (similar to uidmap). for (Map.Entry<PullerKey, PullerValue> entry : mPullers.entrySet()) { PullerKey key = entry.getKey(); PullerValue val = entry.getValue(); sStatsd.registerPullAtomCallback(key.getUid(), key.getAtom(), val.getCoolDownNs(), val.getTimeoutNs(), val.getAdditiveFields(), val.getCallback()); } } private class StatsdDeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Loading apex/statsd/service/java/com/android/server/stats/StatsManagerService.java +193 −34 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.Context; import android.os.Binder; import android.os.IPullAtomCallback; import android.os.IStatsManagerService; import android.os.IStatsd; import android.os.Process; Loading Loading @@ -60,8 +61,7 @@ public class StatsManagerService extends IStatsManagerService.Stub { @GuardedBy("mLock") private ArrayMap<ConfigKey, PendingIntentRef> mDataFetchPirMap = new ArrayMap<>(); @GuardedBy("mLock") private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>(); private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>(); @GuardedBy("mLock") private ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> mBroadcastSubscriberPirMap = new ArrayMap<>(); Loading @@ -72,8 +72,8 @@ public class StatsManagerService extends IStatsManagerService.Stub { } private static class ConfigKey { private int mUid; private long mConfigId; private final int mUid; private final long mConfigId; ConfigKey(int uid, long configId) { mUid = uid; Loading Loading @@ -103,6 +103,126 @@ public class StatsManagerService extends IStatsManagerService.Stub { } } private static class PullerKey { private final int mUid; private final int mAtomTag; PullerKey(int uid, int atom) { mUid = uid; mAtomTag = atom; } public int getUid() { return mUid; } public int getAtom() { return mAtomTag; } @Override public int hashCode() { return Objects.hash(mUid, mAtomTag); } @Override public boolean equals(Object obj) { if (obj instanceof PullerKey) { PullerKey other = (PullerKey) obj; return this.mUid == other.getUid() && this.mAtomTag == other.getAtom(); } return false; } } private static class PullerValue { private final long mCoolDownNs; private final long mTimeoutNs; private final int[] mAdditiveFields; private final IPullAtomCallback mCallback; PullerValue(long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback callback) { mCoolDownNs = coolDownNs; mTimeoutNs = timeoutNs; mAdditiveFields = additiveFields; mCallback = callback; } public long getCoolDownNs() { return mCoolDownNs; } public long getTimeoutNs() { return mTimeoutNs; } public int[] getAdditiveFields() { return mAdditiveFields; } public IPullAtomCallback getCallback() { return mCallback; } } private final ArrayMap<PullerKey, PullerValue> mPullers = new ArrayMap<>(); @Override public void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback pullerCallback) { int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); PullerValue val = new PullerValue(coolDownNs, timeoutNs, additiveFields, pullerCallback); // Always cache the puller in StatsManagerService. If statsd is down, we will register the // puller when statsd comes back up. synchronized (mLock) { mPullers.put(key, val); } IStatsd statsd = getStatsdNonblocking(); if (statsd == null) { return; } try { statsd.registerPullAtomCallback( callingUid, atomTag, coolDownNs, timeoutNs, additiveFields, pullerCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to register puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } @Override public void unregisterPullAtomCallback(int atomTag) { int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); // Always remove the puller from StatsManagerService even if statsd is down. When statsd // comes back up, we will not re-register the removed puller. synchronized (mLock) { mPullers.remove(key); } IStatsd statsd = getStatsdNonblocking(); if (statsd == null) { return; } try { statsd.unregisterPullAtomCallback(callingUid, atomTag); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to unregister puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } @Override public void setDataFetchOperation(long configId, PendingIntent pendingIntent, String packageName) { Loading Loading @@ -441,46 +561,85 @@ public class StatsManagerService extends IStatsManagerService.Stub { if (statsd == null) { return; } // Since we do not want to make an IPC with the a lock held, we first create local deep // copies of the data with the lock held before iterating through the maps. final long token = Binder.clearCallingIdentity(); try { registerAllPullers(statsd); registerAllDataFetchOperations(statsd); registerAllActiveConfigsChangedOperations(statsd); registerAllBroadcastSubscribers(statsd); } catch (RemoteException e) { Slog.e(TAG, "StatsManager failed to (re-)register data with statsd"); } finally { Binder.restoreCallingIdentity(token); } } // Pre-condition: the Binder calling identity has already been cleared private void registerAllPullers(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a copy of the // data with the lock held before iterating through the map. ArrayMap<PullerKey, PullerValue> pullersCopy; synchronized (mLock) { pullersCopy = new ArrayMap<>(mPullers); } for (Map.Entry<PullerKey, PullerValue> entry : pullersCopy.entrySet()) { PullerKey key = entry.getKey(); PullerValue value = entry.getValue(); statsd.registerPullAtomCallback(key.getUid(), key.getAtom(), value.getCoolDownNs(), value.getTimeoutNs(), value.getAdditiveFields(), value.getCallback()); } } // Pre-condition: the Binder calling identity has already been cleared private void registerAllDataFetchOperations(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a copy of the // data with the lock held before iterating through the map. ArrayMap<ConfigKey, PendingIntentRef> dataFetchCopy; ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy; ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy; synchronized (mLock) { dataFetchCopy = new ArrayMap<>(mDataFetchPirMap); activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap); broadcastSubscriberCopy = new ArrayMap<>(); for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : mBroadcastSubscriberPirMap.entrySet()) { broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap<>(entry.getValue())); } } for (Map.Entry<ConfigKey, PendingIntentRef> entry : dataFetchCopy.entrySet()) { ConfigKey key = entry.getKey(); try { statsd.setDataFetchOperation(key.getConfigId(), entry.getValue(), key.getUid()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setDataFetchOperation from pirMap"); } } for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) { try { // Pre-condition: the Binder calling identity has already been cleared private void registerAllActiveConfigsChangedOperations(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a copy of the // data with the lock held before iterating through the map. ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy; synchronized (mLock) { activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap); } for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) { statsd.setActiveConfigsChangedOperation(entry.getValue(), entry.getKey()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setActiveConfigsChangedOperation from pirMap"); } } for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : broadcastSubscriberCopy.entrySet()) { for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) { // Pre-condition: the Binder calling identity has already been cleared private void registerAllBroadcastSubscribers(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a deep copy of // the data with the lock held before iterating through the map. ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy = new ArrayMap<>(); synchronized (mLock) { for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : mBroadcastSubscriberPirMap.entrySet()) { broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap(entry.getValue())); } } for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : mBroadcastSubscriberPirMap.entrySet()) { ConfigKey configKey = entry.getKey(); try { for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) { statsd.setBroadcastSubscriber(configKey.getConfigId(), subscriberEntry.getKey(), subscriberEntry.getValue(), configKey.getUid()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setBroadcastSubscriber from pirMap"); } } } } Loading core/java/android/app/StatsManager.java +2 −16 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.content.Context; import android.os.IBinder; import android.os.IPullAtomCallback; import android.os.IPullAtomResultReceiver; import android.os.IStatsCompanionService; import android.os.IStatsManagerService; import android.os.IStatsPullerCallback; import android.os.IStatsd; Loading Loading @@ -60,9 +59,6 @@ public final class StatsManager { @GuardedBy("sLock") private IStatsd mService; @GuardedBy("sLock") private IStatsCompanionService mStatsCompanion; @GuardedBy("sLock") private IStatsManagerService mStatsManagerService; Loading Loading @@ -538,7 +534,7 @@ public final class StatsManager { } synchronized (sLock) { try { IStatsCompanionService service = getIStatsCompanionServiceLocked(); IStatsManagerService service = getIStatsManagerServiceLocked(); PullAtomCallbackInternal rec = new PullAtomCallbackInternal(atomTag, callback, executor); service.registerPullAtomCallback(atomTag, coolDownNs, timeoutNs, additiveFields, Loading @@ -560,7 +556,7 @@ public final class StatsManager { public void unregisterPullAtomCallback(int atomTag) { synchronized (sLock) { try { IStatsCompanionService service = getIStatsCompanionServiceLocked(); IStatsManagerService service = getIStatsManagerServiceLocked(); service.unregisterPullAtomCallback(atomTag); } catch (RemoteException e) { throw new RuntimeException("Unable to unregister pull atom callback"); Loading Loading @@ -745,16 +741,6 @@ public final class StatsManager { return mService; } @GuardedBy("sLock") private IStatsCompanionService getIStatsCompanionServiceLocked() { if (mStatsCompanion != null) { return mStatsCompanion; } mStatsCompanion = IStatsCompanionService.Stub.asInterface( ServiceManager.getService("statscompanion")); return mStatsCompanion; } @GuardedBy("sLock") private IStatsManagerService getIStatsManagerServiceLocked() { if (mStatsManagerService != null) { Loading Loading
apex/statsd/aidl/android/os/IStatsCompanionService.aidl +0 −7 Original line number Diff line number Diff line Loading @@ -67,11 +67,4 @@ interface IStatsCompanionService { /** Tells StatsCompaionService to grab the uid map snapshot and send it to statsd. */ oneway void triggerUidSnapshot(); /** Tells StatsCompanionService to tell statsd to register a puller for the given atom id */ oneway void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, in int[] additiveFields, IPullAtomCallback pullerCallback); /** Tells StatsCompanionService to tell statsd to unregister a puller for the given atom id */ oneway void unregisterPullAtomCallback(int atomTag); }
apex/statsd/aidl/android/os/IStatsManagerService.aidl +9 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.os; import android.app.PendingIntent; import android.os.IPullAtomCallback; /** * Binder interface to communicate with the Java-based statistics service helper. Loading Loading @@ -125,4 +126,11 @@ interface IStatsManagerService { * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS. */ void removeConfiguration(in long configId, in String packageName); /** Tell StatsManagerService to register a puller for the given atom tag with statsd. */ oneway void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, in int[] additiveFields, IPullAtomCallback pullerCallback); /** Tell StatsManagerService to unregister the pulller for the given atom tag from statsd. */ oneway void unregisterPullAtomCallback(int atomTag); }
apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +0 −130 Original line number Diff line number Diff line Loading @@ -75,7 +75,6 @@ import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.IPullAtomCallback; import android.os.IStatsCompanionService; import android.os.IStatsd; import android.os.IStoraged; Loading Loading @@ -263,71 +262,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private StatsManagerService mStatsManagerService; private static final class PullerKey { private final int mUid; private final int mAtomTag; PullerKey(int uid, int atom) { mUid = uid; mAtomTag = atom; } public int getUid() { return mUid; } public int getAtom() { return mAtomTag; } @Override public int hashCode() { return Objects.hash(mUid, mAtomTag); } @Override public boolean equals(Object obj) { if (obj instanceof PullerKey) { PullerKey other = (PullerKey) obj; return this.mUid == other.getUid() && this.mAtomTag == other.getAtom(); } return false; } } private static final class PullerValue { private final long mCoolDownNs; private final long mTimeoutNs; private int[] mAdditiveFields; private IPullAtomCallback mCallback; PullerValue(long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback callback) { mCoolDownNs = coolDownNs; mTimeoutNs = timeoutNs; mAdditiveFields = additiveFields; mCallback = callback; } public long getCoolDownNs() { return mCoolDownNs; } public long getTimeoutNs() { return mTimeoutNs; } public int[] getAdditiveFields() { return mAdditiveFields; } public IPullAtomCallback getCallback() { return mCallback; } } private final HashMap<PullerKey, PullerValue> mPullers = new HashMap<>(); private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); private WifiManager mWifiManager = null; Loading Loading @@ -2634,57 +2568,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } @Override public void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback pullerCallback) { synchronized (sStatsdLock) { // Always cache the puller in SCS. // If statsd is down, we will register it when it comes back up. int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); PullerValue val = new PullerValue( coolDownNs, timeoutNs, additiveFields, pullerCallback); mPullers.put(key, val); if (sStatsd == null) { Slog.w(TAG, "Could not access statsd for registering puller for atom " + atomTag); return; } try { sStatsd.registerPullAtomCallback( callingUid, atomTag, coolDownNs, timeoutNs, additiveFields, pullerCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to register puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } } @Override public void unregisterPullAtomCallback(int atomTag) { synchronized (sStatsdLock) { // Always remove the puller in SCS. // If statsd is down, we will not register it when it comes back up. int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); mPullers.remove(key); if (sStatsd == null) { Slog.w(TAG, "Could not access statsd for registering puller for atom " + atomTag); return; } try { sStatsd.unregisterPullAtomCallback(callingUid, atomTag); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to register puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } } // Statsd related code Loading Loading @@ -2763,8 +2646,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Pull the latest state of UID->app name, version mapping when // statsd starts. informAllUidsLocked(mContext); // Register all pullers. If SCS has just started, this should be empty. registerAllPullersLocked(); } finally { restoreCallingIdentity(token); } Loading @@ -2776,17 +2657,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } @GuardedBy("sStatsdLock") private void registerAllPullersLocked() throws RemoteException { // TODO: pass in one call, using a file descriptor (similar to uidmap). for (Map.Entry<PullerKey, PullerValue> entry : mPullers.entrySet()) { PullerKey key = entry.getKey(); PullerValue val = entry.getValue(); sStatsd.registerPullAtomCallback(key.getUid(), key.getAtom(), val.getCoolDownNs(), val.getTimeoutNs(), val.getAdditiveFields(), val.getCallback()); } } private class StatsdDeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Loading
apex/statsd/service/java/com/android/server/stats/StatsManagerService.java +193 −34 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.Context; import android.os.Binder; import android.os.IPullAtomCallback; import android.os.IStatsManagerService; import android.os.IStatsd; import android.os.Process; Loading Loading @@ -60,8 +61,7 @@ public class StatsManagerService extends IStatsManagerService.Stub { @GuardedBy("mLock") private ArrayMap<ConfigKey, PendingIntentRef> mDataFetchPirMap = new ArrayMap<>(); @GuardedBy("mLock") private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>(); private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>(); @GuardedBy("mLock") private ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> mBroadcastSubscriberPirMap = new ArrayMap<>(); Loading @@ -72,8 +72,8 @@ public class StatsManagerService extends IStatsManagerService.Stub { } private static class ConfigKey { private int mUid; private long mConfigId; private final int mUid; private final long mConfigId; ConfigKey(int uid, long configId) { mUid = uid; Loading Loading @@ -103,6 +103,126 @@ public class StatsManagerService extends IStatsManagerService.Stub { } } private static class PullerKey { private final int mUid; private final int mAtomTag; PullerKey(int uid, int atom) { mUid = uid; mAtomTag = atom; } public int getUid() { return mUid; } public int getAtom() { return mAtomTag; } @Override public int hashCode() { return Objects.hash(mUid, mAtomTag); } @Override public boolean equals(Object obj) { if (obj instanceof PullerKey) { PullerKey other = (PullerKey) obj; return this.mUid == other.getUid() && this.mAtomTag == other.getAtom(); } return false; } } private static class PullerValue { private final long mCoolDownNs; private final long mTimeoutNs; private final int[] mAdditiveFields; private final IPullAtomCallback mCallback; PullerValue(long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback callback) { mCoolDownNs = coolDownNs; mTimeoutNs = timeoutNs; mAdditiveFields = additiveFields; mCallback = callback; } public long getCoolDownNs() { return mCoolDownNs; } public long getTimeoutNs() { return mTimeoutNs; } public int[] getAdditiveFields() { return mAdditiveFields; } public IPullAtomCallback getCallback() { return mCallback; } } private final ArrayMap<PullerKey, PullerValue> mPullers = new ArrayMap<>(); @Override public void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs, int[] additiveFields, IPullAtomCallback pullerCallback) { int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); PullerValue val = new PullerValue(coolDownNs, timeoutNs, additiveFields, pullerCallback); // Always cache the puller in StatsManagerService. If statsd is down, we will register the // puller when statsd comes back up. synchronized (mLock) { mPullers.put(key, val); } IStatsd statsd = getStatsdNonblocking(); if (statsd == null) { return; } try { statsd.registerPullAtomCallback( callingUid, atomTag, coolDownNs, timeoutNs, additiveFields, pullerCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to register puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } @Override public void unregisterPullAtomCallback(int atomTag) { int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); PullerKey key = new PullerKey(callingUid, atomTag); // Always remove the puller from StatsManagerService even if statsd is down. When statsd // comes back up, we will not re-register the removed puller. synchronized (mLock) { mPullers.remove(key); } IStatsd statsd = getStatsdNonblocking(); if (statsd == null) { return; } try { statsd.unregisterPullAtomCallback(callingUid, atomTag); } catch (RemoteException e) { Slog.e(TAG, "Failed to access statsd to unregister puller for atom " + atomTag); } finally { Binder.restoreCallingIdentity(token); } } @Override public void setDataFetchOperation(long configId, PendingIntent pendingIntent, String packageName) { Loading Loading @@ -441,46 +561,85 @@ public class StatsManagerService extends IStatsManagerService.Stub { if (statsd == null) { return; } // Since we do not want to make an IPC with the a lock held, we first create local deep // copies of the data with the lock held before iterating through the maps. final long token = Binder.clearCallingIdentity(); try { registerAllPullers(statsd); registerAllDataFetchOperations(statsd); registerAllActiveConfigsChangedOperations(statsd); registerAllBroadcastSubscribers(statsd); } catch (RemoteException e) { Slog.e(TAG, "StatsManager failed to (re-)register data with statsd"); } finally { Binder.restoreCallingIdentity(token); } } // Pre-condition: the Binder calling identity has already been cleared private void registerAllPullers(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a copy of the // data with the lock held before iterating through the map. ArrayMap<PullerKey, PullerValue> pullersCopy; synchronized (mLock) { pullersCopy = new ArrayMap<>(mPullers); } for (Map.Entry<PullerKey, PullerValue> entry : pullersCopy.entrySet()) { PullerKey key = entry.getKey(); PullerValue value = entry.getValue(); statsd.registerPullAtomCallback(key.getUid(), key.getAtom(), value.getCoolDownNs(), value.getTimeoutNs(), value.getAdditiveFields(), value.getCallback()); } } // Pre-condition: the Binder calling identity has already been cleared private void registerAllDataFetchOperations(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a copy of the // data with the lock held before iterating through the map. ArrayMap<ConfigKey, PendingIntentRef> dataFetchCopy; ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy; ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy; synchronized (mLock) { dataFetchCopy = new ArrayMap<>(mDataFetchPirMap); activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap); broadcastSubscriberCopy = new ArrayMap<>(); for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : mBroadcastSubscriberPirMap.entrySet()) { broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap<>(entry.getValue())); } } for (Map.Entry<ConfigKey, PendingIntentRef> entry : dataFetchCopy.entrySet()) { ConfigKey key = entry.getKey(); try { statsd.setDataFetchOperation(key.getConfigId(), entry.getValue(), key.getUid()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setDataFetchOperation from pirMap"); } } for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) { try { // Pre-condition: the Binder calling identity has already been cleared private void registerAllActiveConfigsChangedOperations(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a copy of the // data with the lock held before iterating through the map. ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy; synchronized (mLock) { activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap); } for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) { statsd.setActiveConfigsChangedOperation(entry.getValue(), entry.getKey()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setActiveConfigsChangedOperation from pirMap"); } } for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : broadcastSubscriberCopy.entrySet()) { for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) { // Pre-condition: the Binder calling identity has already been cleared private void registerAllBroadcastSubscribers(IStatsd statsd) throws RemoteException { // Since we do not want to make an IPC with the lock held, we first create a deep copy of // the data with the lock held before iterating through the map. ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy = new ArrayMap<>(); synchronized (mLock) { for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : mBroadcastSubscriberPirMap.entrySet()) { broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap(entry.getValue())); } } for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry : mBroadcastSubscriberPirMap.entrySet()) { ConfigKey configKey = entry.getKey(); try { for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) { statsd.setBroadcastSubscriber(configKey.getConfigId(), subscriberEntry.getKey(), subscriberEntry.getValue(), configKey.getUid()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setBroadcastSubscriber from pirMap"); } } } } Loading
core/java/android/app/StatsManager.java +2 −16 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.content.Context; import android.os.IBinder; import android.os.IPullAtomCallback; import android.os.IPullAtomResultReceiver; import android.os.IStatsCompanionService; import android.os.IStatsManagerService; import android.os.IStatsPullerCallback; import android.os.IStatsd; Loading Loading @@ -60,9 +59,6 @@ public final class StatsManager { @GuardedBy("sLock") private IStatsd mService; @GuardedBy("sLock") private IStatsCompanionService mStatsCompanion; @GuardedBy("sLock") private IStatsManagerService mStatsManagerService; Loading Loading @@ -538,7 +534,7 @@ public final class StatsManager { } synchronized (sLock) { try { IStatsCompanionService service = getIStatsCompanionServiceLocked(); IStatsManagerService service = getIStatsManagerServiceLocked(); PullAtomCallbackInternal rec = new PullAtomCallbackInternal(atomTag, callback, executor); service.registerPullAtomCallback(atomTag, coolDownNs, timeoutNs, additiveFields, Loading @@ -560,7 +556,7 @@ public final class StatsManager { public void unregisterPullAtomCallback(int atomTag) { synchronized (sLock) { try { IStatsCompanionService service = getIStatsCompanionServiceLocked(); IStatsManagerService service = getIStatsManagerServiceLocked(); service.unregisterPullAtomCallback(atomTag); } catch (RemoteException e) { throw new RuntimeException("Unable to unregister pull atom callback"); Loading Loading @@ -745,16 +741,6 @@ public final class StatsManager { return mService; } @GuardedBy("sLock") private IStatsCompanionService getIStatsCompanionServiceLocked() { if (mStatsCompanion != null) { return mStatsCompanion; } mStatsCompanion = IStatsCompanionService.Stub.asInterface( ServiceManager.getService("statscompanion")); return mStatsCompanion; } @GuardedBy("sLock") private IStatsManagerService getIStatsManagerServiceLocked() { if (mStatsManagerService != null) { Loading