Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdea3b70 authored by Chris Wren's avatar Chris Wren
Browse files

track and report packages with undecorated remoteviews

print query results with:
  adb shell dumpsys notification --remote-view-stats

test the pulled atom with:
  make statsd_testdrive
  ./out/host/linux-x86/bin/statsd_testdrive 10066

Bug: 144855217
Test: atest PulledStatsTest
Change-Id: I773378fc7cfb47a9f9c7495404ddafa63f39cfaf
parent 3f9ba67f
Loading
Loading
Loading
Loading
+54 −8
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.app.AppOpsManager.HistoricalOps;
import android.app.AppOpsManager.HistoricalOpsRequest;
import android.app.AppOpsManager.HistoricalPackageOps;
import android.app.AppOpsManager.HistoricalUidOps;
import android.app.INotificationManager;
import android.app.ProcessMemoryState;
import android.app.StatsManager;
import android.bluetooth.BluetoothActivityEnergyInfo;
@@ -139,6 +140,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.am.MemoryStatUtil.MemoryStat;
import com.android.server.notification.NotificationManagerService;
import com.android.server.role.RoleManagerInternal;
import com.android.server.stats.IonMemoryUtil.IonAllocations;
import com.android.server.stats.ProcfsMemoryUtil.MemorySnapshot;
@@ -1750,14 +1752,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
                if (statsFiles.size() != 1) {
                    return;
                }
                InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
                        statsFiles.get(0));
                int[] len = new int[1];
                byte[] stats = readFully(stream, len);
                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
                        wallClockNanos);
                e.writeStorage(Arrays.copyOf(stats, len[0]));
                pulledData.add(e);
                unpackStreamedData(tagId, elapsedNanos, wallClockNanos, pulledData, statsFiles);
                new File(mBaseDir.getAbsolutePath() + "/" + section + "_"
                        + lastHighWaterMark).delete();
                new File(
@@ -1773,6 +1768,52 @@ 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<StatsLogEventWrapper> 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<ParcelFileDescriptor> 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<StatsLogEventWrapper> pulledData, List<ParcelFileDescriptor> statsFiles)
            throws IOException {
        InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
                statsFiles.get(0));
        int[] len = new int[1];
        byte[] stats = readFully(stream, len);
        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
                wallClockNanos);
        e.writeStorage(Arrays.copyOf(stats, len[0]));
        pulledData.add(e);
    }

    static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
        int pos = 0;
        final int initialAvail = stream.available();
@@ -2621,6 +2662,11 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
                pullAppOps(elapsedNanos, wallClockNanos, ret);
                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;
+20 −1
Original line number Diff line number Diff line
@@ -356,7 +356,7 @@ message Atom {
    }

    // Pulled events will start at field 10000.
    // Next: 10065
    // Next: 10067
    oneof pulled {
        WifiBytesTransfer wifi_bytes_transfer = 10000;
        WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -423,6 +423,7 @@ message Atom {
        SurfaceflingerStatsLayerInfo surfaceflinger_stats_layer_info = 10063;
        ProcessMemorySnapshot process_memory_snapshot = 10064;
        VmsClientStats vms_client_stats = 10065;
        NotificationRemoteViews notification_remote_views = 10066;
    }

    // DO NOT USE field numbers above 100,000 in AOSP.
@@ -4947,6 +4948,24 @@ message ProcStatsPkgProc {
    optional ProcessStatsSectionProto proc_stats_section = 1;
}

// Next Tag: 2
message PackageRemoteViewInfoProto {
    optional string package_name = 1;
    // add per-package additional info here (like channels)
}

// Next Tag: 2
message NotificationRemoteViewsProto {
    repeated PackageRemoteViewInfoProto package_remote_view_info = 1;
}

/**
 * Pulled from NotificationManagerService.java
 */
message NotificationRemoteViews {
    optional NotificationRemoteViewsProto notification_remote_views = 1;
}

message PowerProfileProto {
    optional double cpu_suspend = 1;

+3 −0
Original line number Diff line number Diff line
@@ -281,6 +281,9 @@ std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
        {{.atomTag = android::util::VMS_CLIENT_STATS},
         {.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)}},
};

StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
+2 −0
Original line number Diff line number Diff line
@@ -207,4 +207,6 @@ interface INotificationManager

    void setPrivateNotificationsAllowed(boolean allow);
    boolean getPrivateNotificationsAllowed();

    long pullStats(long startNs, int report, boolean doAgg, out List<ParcelFileDescriptor> stats);
}
+11 −0
Original line number Diff line number Diff line
@@ -264,3 +264,14 @@ message ZenPolicyProto {
    optional Sender priority_calls = 16;
    optional Sender priority_messages = 17;
}

// Next Tag: 2
message PackageRemoteViewInfoProto {
    optional string package_name = 1;
    // add per-package additional info here (like channels)
}

// Next Tag: 2
message NotificationRemoteViewsProto {
    repeated PackageRemoteViewInfoProto package_remote_view_info = 1;
}
 No newline at end of file
Loading