blob: 5fa7998397898047ca00228b1f5b4bd38432bcda [file] [log] [blame]
/*
* Copyright 2020 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.media.metrics;
import android.content.Context;
import android.media.metrics.IPlaybackMetricsManager;
import android.media.metrics.NetworkEvent;
import android.media.metrics.PlaybackErrorEvent;
import android.media.metrics.PlaybackMetrics;
import android.media.metrics.PlaybackStateEvent;
import android.media.metrics.TrackChangeEvent;
import android.os.Binder;
import android.util.Base64;
import android.util.StatsEvent;
import android.util.StatsLog;
import com.android.server.SystemService;
import java.security.SecureRandom;
/**
* System service manages playback metrics.
*/
public final class PlaybackMetricsManagerService extends SystemService {
private final SecureRandom mSecureRandom;
/**
* Initializes the playback metrics manager service.
*
* @param context The system server context.
*/
public PlaybackMetricsManagerService(Context context) {
super(context);
mSecureRandom = new SecureRandom();
}
@Override
public void onStart() {
// TODO: make the service name a constant in Context.java
publishBinderService("playback_metrics", new BinderService());
}
private final class BinderService extends IPlaybackMetricsManager.Stub {
@Override
public void reportPlaybackMetrics(String sessionId, PlaybackMetrics metrics, int userId) {
StatsEvent statsEvent = StatsEvent.newBuilder()
.setAtomId(320)
.writeInt(Binder.getCallingUid())
.writeString(sessionId)
.writeLong(metrics.getMediaDurationMillis())
.writeInt(metrics.getStreamSource())
.writeInt(metrics.getStreamType())
.writeInt(metrics.getPlaybackType())
.writeInt(metrics.getDrmType())
.writeInt(metrics.getContentType())
.writeString(metrics.getPlayerName())
.writeString(metrics.getPlayerVersion())
.writeByteArray(new byte[0]) // TODO: write experiments proto
.writeInt(metrics.getVideoFramesPlayed())
.writeInt(metrics.getVideoFramesDropped())
.writeInt(metrics.getAudioUnderrunCount())
.writeLong(metrics.getNetworkBytesRead())
.writeLong(metrics.getLocalBytesRead())
.writeLong(metrics.getNetworkTransferDurationMillis())
.usePooledBuffer()
.build();
StatsLog.write(statsEvent);
}
@Override
public void reportPlaybackStateEvent(
String sessionId, PlaybackStateEvent event, int userId) {
// TODO: log it to statsd
}
@Override
public String getSessionId(int userId) {
byte[] byteId = new byte[16]; // 128 bits
mSecureRandom.nextBytes(byteId);
String id = Base64.encodeToString(byteId, Base64.DEFAULT);
return id;
}
@Override
public void reportPlaybackErrorEvent(
String sessionId, PlaybackErrorEvent event, int userId) {
StatsEvent statsEvent = StatsEvent.newBuilder()
.setAtomId(323)
.writeString(sessionId)
.writeString(event.getExceptionStack())
.writeInt(event.getErrorCode())
.writeInt(event.getSubErrorCode())
.writeLong(event.getTimeSincePlaybackCreatedMillis())
.usePooledBuffer()
.build();
StatsLog.write(statsEvent);
}
public void reportNetworkEvent(
String sessionId, NetworkEvent event, int userId) {
StatsEvent statsEvent = StatsEvent.newBuilder()
.setAtomId(321)
.writeString(sessionId)
.writeInt(event.getType())
.writeLong(event.getTimeSincePlaybackCreatedMillis())
.usePooledBuffer()
.build();
StatsLog.write(statsEvent);
}
@Override
public void reportTrackChangeEvent(
String sessionId, TrackChangeEvent event, int userId) {
StatsEvent statsEvent = StatsEvent.newBuilder()
.setAtomId(321)
.writeString(sessionId)
.writeInt(event.getTrackState())
.writeInt(event.getTrackChangeReason())
.writeString(event.getContainerMimeType())
.writeString(event.getSampleMimeType())
.writeString(event.getCodecName())
.writeInt(event.getBitrate())
.writeLong(event.getTimeSincePlaybackCreatedMillis())
.writeInt(event.getTrackType())
.writeString(event.getLanguage())
.writeString(event.getLanguageRegion())
.writeInt(event.getChannelCount())
.writeInt(event.getSampleRate())
.writeInt(event.getWidth())
.writeInt(event.getHeight())
.usePooledBuffer()
.build();
StatsLog.write(statsEvent);
}
}
}