1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.tracing; 18 19 import static com.android.systemui.tracing.nano.SystemUiTraceFileProto.MAGIC_NUMBER_H; 20 import static com.android.systemui.tracing.nano.SystemUiTraceFileProto.MAGIC_NUMBER_L; 21 22 import android.content.Context; 23 import android.os.SystemClock; 24 25 import androidx.annotation.NonNull; 26 27 import com.android.systemui.Dumpable; 28 import com.android.systemui.dump.DumpManager; 29 import com.android.systemui.shared.tracing.FrameProtoTracer; 30 import com.android.systemui.shared.tracing.FrameProtoTracer.ProtoTraceParams; 31 import com.android.systemui.shared.tracing.ProtoTraceable; 32 import com.android.systemui.tracing.nano.SystemUiTraceEntryProto; 33 import com.android.systemui.tracing.nano.SystemUiTraceFileProto; 34 import com.android.systemui.tracing.nano.SystemUiTraceProto; 35 36 import com.google.protobuf.nano.MessageNano; 37 38 import java.io.File; 39 import java.io.FileDescriptor; 40 import java.io.PrintWriter; 41 import java.util.ArrayList; 42 import java.util.Queue; 43 44 import javax.inject.Inject; 45 import javax.inject.Singleton; 46 47 /** 48 * Controller for coordinating winscope proto tracing. 49 */ 50 @Singleton 51 public class ProtoTracer implements Dumpable, ProtoTraceParams<MessageNano, SystemUiTraceFileProto, 52 SystemUiTraceEntryProto, SystemUiTraceProto> { 53 54 private static final String TAG = "ProtoTracer"; 55 private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L; 56 57 private final Context mContext; 58 private final FrameProtoTracer<MessageNano, SystemUiTraceFileProto, SystemUiTraceEntryProto, 59 SystemUiTraceProto> mProtoTracer; 60 61 @Inject ProtoTracer(Context context, DumpManager dumpManager)62 public ProtoTracer(Context context, DumpManager dumpManager) { 63 mContext = context; 64 mProtoTracer = new FrameProtoTracer<>(this); 65 dumpManager.registerDumpable(getClass().getName(), this); 66 } 67 68 @Override getTraceFile()69 public File getTraceFile() { 70 return new File(mContext.getFilesDir(), "sysui_trace.pb"); 71 } 72 73 @Override getEncapsulatingTraceProto()74 public SystemUiTraceFileProto getEncapsulatingTraceProto() { 75 return new SystemUiTraceFileProto(); 76 } 77 78 @Override updateBufferProto(SystemUiTraceEntryProto reuseObj, ArrayList<ProtoTraceable<SystemUiTraceProto>> traceables)79 public SystemUiTraceEntryProto updateBufferProto(SystemUiTraceEntryProto reuseObj, 80 ArrayList<ProtoTraceable<SystemUiTraceProto>> traceables) { 81 SystemUiTraceEntryProto proto = reuseObj != null 82 ? reuseObj 83 : new SystemUiTraceEntryProto(); 84 proto.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); 85 proto.systemUi = proto.systemUi != null ? proto.systemUi : new SystemUiTraceProto(); 86 for (ProtoTraceable t : traceables) { 87 t.writeToProto(proto.systemUi); 88 } 89 return proto; 90 } 91 92 @Override serializeEncapsulatingProto(SystemUiTraceFileProto encapsulatingProto, Queue<SystemUiTraceEntryProto> buffer)93 public byte[] serializeEncapsulatingProto(SystemUiTraceFileProto encapsulatingProto, 94 Queue<SystemUiTraceEntryProto> buffer) { 95 encapsulatingProto.magicNumber = MAGIC_NUMBER_VALUE; 96 encapsulatingProto.entry = buffer.toArray(new SystemUiTraceEntryProto[0]); 97 return MessageNano.toByteArray(encapsulatingProto); 98 } 99 100 @Override getProtoBytes(MessageNano proto)101 public byte[] getProtoBytes(MessageNano proto) { 102 return MessageNano.toByteArray(proto); 103 } 104 105 @Override getProtoSize(MessageNano proto)106 public int getProtoSize(MessageNano proto) { 107 return proto.getCachedSize(); 108 } 109 start()110 public void start() { 111 mProtoTracer.start(); 112 } 113 stop()114 public void stop() { 115 mProtoTracer.stop(); 116 } 117 isEnabled()118 public boolean isEnabled() { 119 return mProtoTracer.isEnabled(); 120 } 121 add(ProtoTraceable<SystemUiTraceProto> traceable)122 public void add(ProtoTraceable<SystemUiTraceProto> traceable) { 123 mProtoTracer.add(traceable); 124 } 125 remove(ProtoTraceable<SystemUiTraceProto> traceable)126 public void remove(ProtoTraceable<SystemUiTraceProto> traceable) { 127 mProtoTracer.remove(traceable); 128 } 129 scheduleFrameUpdate()130 public void scheduleFrameUpdate() { 131 mProtoTracer.scheduleFrameUpdate(); 132 } 133 update()134 public void update() { 135 mProtoTracer.update(); 136 } 137 138 @Override dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args)139 public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { 140 pw.println("ProtoTracer:"); 141 pw.print(" "); pw.println("enabled: " + mProtoTracer.isEnabled()); 142 pw.print(" "); pw.println("usagePct: " + mProtoTracer.getBufferUsagePct()); 143 pw.print(" "); pw.println("file: " + getTraceFile()); 144 } 145 } 146