blob: ada890a10361ce6267f8f055d208184d952d7a3b [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.notification;
import static com.android.server.notification.NotificationManagerService.REPORT_REMOTE_VIEWS;
import android.os.ParcelFileDescriptor;
import android.service.notification.NotificationRemoteViewsProto;
import android.service.notification.PackageRemoteViewInfoProto;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class PulledStats {
static final String TAG = "PulledStats";
private final long mTimePeriodStartMs;
private long mTimePeriodEndMs;
private List<String> mUndecoratedPackageNames;
public PulledStats(long startMs) {
mTimePeriodEndMs = mTimePeriodStartMs = startMs;
mUndecoratedPackageNames = new ArrayList<>();
}
ParcelFileDescriptor toParcelFileDescriptor(int report)
throws IOException {
final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
switch(report) {
case REPORT_REMOTE_VIEWS:
Thread thr = new Thread("NotificationManager pulled metric output") {
public void run() {
try {
FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(
fds[1]);
final ProtoOutputStream proto = new ProtoOutputStream(fout);
writeToProto(report, proto);
proto.flush();
fout.close();
} catch (IOException e) {
Slog.w(TAG, "Failure writing pipe", e);
}
}
};
thr.start();
break;
default:
Slog.w(TAG, "Unknown pulled stats request: " + report);
break;
}
return fds[0];
}
/*
* @return the most recent timestamp in the report, as nanoseconds.
*/
public long endTimeMs() {
return mTimePeriodEndMs;
}
public void dump(int report, PrintWriter pw, NotificationManagerService.DumpFilter filter) {
switch(report) {
case REPORT_REMOTE_VIEWS:
pw.print(" Packages with undecordated notifications (");
pw.print(mTimePeriodStartMs);
pw.print(" - ");
pw.print(mTimePeriodEndMs);
pw.println("):");
if (mUndecoratedPackageNames.size() == 0) {
pw.println(" none");
} else {
for (String pkg : mUndecoratedPackageNames) {
if (!filter.filtered || pkg.equals(filter.pkgFilter)) {
pw.println(" " + pkg);
}
}
}
break;
default:
pw.println("Unknown pulled stats request: " + report);
break;
}
}
@VisibleForTesting
void writeToProto(int report, ProtoOutputStream proto) {
switch(report) {
case REPORT_REMOTE_VIEWS:
for (String pkg: mUndecoratedPackageNames) {
long token = proto.start(NotificationRemoteViewsProto.PACKAGE_REMOTE_VIEW_INFO);
proto.write(PackageRemoteViewInfoProto.PACKAGE_NAME, pkg);
proto.end(token);
}
break;
default:
Slog.w(TAG, "Unknown pulled stats request: " + report);
break;
}
}
public void addUndecoratedPackage(String packageName, long timestampMs) {
mUndecoratedPackageNames.add(packageName);
mTimePeriodEndMs = Math.max(mTimePeriodEndMs, timestampMs);
}
}