From 730bf96884464e0bca6bec92ce3dead0518dcd59 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Thu, 16 Jan 2020 15:59:52 -0800 Subject: [PATCH] Migrate pullNotificationRemoteViews Test: atest NotificationStatsTest Test: adb shell cmd stats pull-source 10066 Change-Id: I8fd848b233920a2fe6bba1d87ec22eeed0bcaf91 --- .../server/stats/StatsCompanionService.java | 39 ------- .../src/external/StatsPullerManager.cpp | 4 - .../stats/pull/StatsPullAtomService.java | 109 +++++++++++++++++- 3 files changed, 105 insertions(+), 47 deletions(-) diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java index 1a4a2f1329360..bb65867e4204e 100644 --- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java @@ -773,39 +773,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private INotificationManager mNotificationManager = - INotificationManager.Stub.asInterface( - ServiceManager.getService(Context.NOTIFICATION_SERVICE)); - - private void pullNotificationStats(int reportId, int tagId, long elapsedNanos, - long wallClockNanos, - List pulledData) { - final long callingToken = Binder.clearCallingIdentity(); - try { - // determine last pull tine. Copy file trick from pullProcessStats? - long lastNotificationStatsNs = wallClockNanos - - TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS); - - List statsFiles = new ArrayList<>(); - long notificationStatsNs = mNotificationManager.pullStats( - lastNotificationStatsNs, reportId, true, statsFiles); - if (statsFiles.size() != 1) { - return; - } - unpackStreamedData(tagId, elapsedNanos, wallClockNanos, pulledData, statsFiles); - } catch (IOException e) { - Log.e(TAG, "Getting notistats failed: ", e); - - } catch (RemoteException e) { - Log.e(TAG, "Getting notistats failed: ", e); - } catch (SecurityException e) { - Log.e(TAG, "Getting notistats failed: ", e); - } finally { - Binder.restoreCallingIdentity(callingToken); - } - - } - static void unpackStreamedData(int tagId, long elapsedNanos, long wallClockNanos, List pulledData, List statsFiles) throws IOException { @@ -1346,12 +1313,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { break; } - case StatsLog.NOTIFICATION_REMOTE_VIEWS: { - pullNotificationStats(NotificationManagerService.REPORT_REMOTE_VIEWS, - tagId, elapsedNanos, wallClockNanos, ret); - break; - } - default: Slog.w(TAG, "No such tagId data as " + tagId); return null; diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index c62b435640308..b282693a24561 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -168,10 +168,6 @@ std::map StatsPullerManager::kAllPullAtomInfo = { {.additiveFields = {5, 6, 7, 8, 9, 10}, .puller = new CarStatsPuller(android::util::VMS_CLIENT_STATS)}}, - // NotiifcationRemoteViews. - {{.atomTag = android::util::NOTIFICATION_REMOTE_VIEWS}, - {.puller = new StatsCompanionServicePuller(android::util::NOTIFICATION_REMOTE_VIEWS)}}, - // PermissionStateSampled. {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE_SAMPLED}, {.puller = diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 6aa3021d0fb9d..1224260999385 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -201,6 +201,9 @@ public class StatsPullAtomService extends SystemService { private final Object mStoragedLock = new Object(); @GuardedBy("mStoragedLock") private IStoraged mStorageService; + private final Object mNotificationStatsLock = new Object(); + @GuardedBy("mNotificationStatsLock") + private INotificationManager mNotificationManagerService; private final Context mContext; private StatsManager mStatsManager; @@ -376,6 +379,28 @@ public class StatsPullAtomService extends SystemService { return mStorageService; } + private INotificationManager getINotificationManagerService() { + synchronized (mNotificationStatsLock) { + if (mNotificationManagerService == null) { + mNotificationManagerService = INotificationManager.Stub.asInterface( + ServiceManager.getService(Context.NOTIFICATION_SERVICE)); + } + if (mNotificationManagerService != null) { + try { + mNotificationManagerService.asBinder().linkToDeath(() -> { + synchronized (mNotificationStatsLock) { + mNotificationManagerService = null; + } + }, /* flags */ 0); + } catch (RemoteException e) { + Slog.e(TAG, "linkToDeath with notificationManager failed", e); + mNotificationManagerService = null; + } + } + } + return mNotificationManagerService; + } + private void registerWifiBytesTransfer() { int tagId = StatsLog.WIFI_BYTES_TRANSFER; PullAtomMetadata metadata = new PullAtomMetadata.Builder() @@ -2167,12 +2192,88 @@ public class StatsPullAtomService extends SystemService { // No op. } - private void registerNotificationRemoteViews() { - // No op. + static void unpackStreamedData(int atomTag, List pulledData, + List statsFiles) throws IOException { + InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0)); + int[] len = new int[1]; + byte[] stats = readFully(stream, len); + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(atomTag) + .writeByteArray(Arrays.copyOf(stats, len[0])) + .build(); + pulledData.add(e); } - private void pullNotificationRemoteViews() { - // No op. + static byte[] readFully(InputStream stream, int[] outLen) throws IOException { + int pos = 0; + final int initialAvail = stream.available(); + byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384]; + while (true) { + int amt = stream.read(data, pos, data.length - pos); + if (DEBUG) { + Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length); + } + if (amt < 0) { + if (DEBUG) { + Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length); + } + outLen[0] = pos; + return data; + } + pos += amt; + if (pos >= data.length) { + byte[] newData = new byte[pos + 16384]; + if (DEBUG) { + Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length); + } + System.arraycopy(data, 0, newData, 0, pos); + data = newData; + } + } + } + + private void registerNotificationRemoteViews() { + int tagId = StatsLog.NOTIFICATION_REMOTE_VIEWS; + mStatsManager.registerPullAtomCallback( + tagId, + null, // use default PullAtomMetadata values + (atomTag, data) -> pullNotificationRemoteViews(atomTag, data), + BackgroundThread.getExecutor() + ); + } + + private int pullNotificationRemoteViews(int atomTag, List pulledData) { + INotificationManager notificationManagerService = getINotificationManagerService(); + if (notificationManagerService == null) { + return StatsManager.PULL_SKIP; + } + final long callingToken = Binder.clearCallingIdentity(); + try { + // determine last pull tine. Copy file trick from pullProcessStats? + long wallClockNanos = SystemClock.currentTimeMicro() * 1000L; + long lastNotificationStatsNs = wallClockNanos - + TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS); + + List statsFiles = new ArrayList<>(); + notificationManagerService.pullStats(lastNotificationStatsNs, + NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles); + if (statsFiles.size() != 1) { + return StatsManager.PULL_SKIP; + } + unpackStreamedData(atomTag, pulledData, statsFiles); + } catch (IOException e) { + Slog.e(TAG, "Getting notistats failed: ", e); + return StatsManager.PULL_SKIP; + } catch (RemoteException e) { + Slog.e(TAG, "Getting notistats failed: ", e); + return StatsManager.PULL_SKIP; + } catch (SecurityException e) { + Slog.e(TAG, "Getting notistats failed: ", e); + return StatsManager.PULL_SKIP; + } finally { + Binder.restoreCallingIdentity(callingToken); + } + return StatsManager.PULL_SUCCESS; } private void registerDangerousPermissionStateSampled() {