1 /* 2 * Copyright (C) 2024 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.internal.protolog; 18 19 import static com.android.internal.protolog.ProtoLog.REQUIRE_PROTOLOGTOOL; 20 21 import android.annotation.NonNull; 22 import android.ravenwood.annotation.RavenwoodKeepWholeClass; 23 import android.text.TextUtils; 24 import android.util.Log; 25 26 import com.android.internal.protolog.common.ILogger; 27 import com.android.internal.protolog.common.IProtoLog; 28 import com.android.internal.protolog.common.IProtoLogGroup; 29 import com.android.internal.protolog.common.LogLevel; 30 31 import java.util.Collections; 32 import java.util.List; 33 34 /** 35 * Class only created and used to serve temporarily for when there is source code pre-processing by 36 * the ProtoLog tool, when the tracing to Perfetto flag is off, and the static REQUIRE_PROTOLOGTOOL 37 * boolean is false. In which case we simply want to log protolog message to logcat. Note, that this 38 * means that in such cases there is no real advantage of using protolog over logcat. 39 * 40 * NOTE: Should not be used in real products as this mostly removes the benefits of protolog. This 41 * is just a temporary class to support a legacy behavior and tests running on the host-side. 42 */ 43 @RavenwoodKeepWholeClass 44 public class LogcatOnlyProtoLogImpl implements IProtoLog { 45 private static final String LOG_TAG = LogcatOnlyProtoLogImpl.class.getName(); 46 47 @Override log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask, Object[] args)48 public void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask, 49 Object[] args) { 50 throw new RuntimeException("Not supported when using LogcatOnlyProtoLogImpl"); 51 } 52 53 @Override log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object[] args)54 public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object[] args) { 55 if (REQUIRE_PROTOLOGTOOL && group.isLogToProto()) { 56 Log.w(LOG_TAG, "ProtoLog message not processed. Failed to log it to proto. " 57 + "Logging it below to logcat instead."); 58 } 59 60 if (group.isLogToLogcat() || group.isLogToProto()) { 61 String formattedString = TextUtils.formatSimple(messageString, args); 62 switch (logLevel) { 63 case VERBOSE -> Log.v(group.getTag(), formattedString); 64 case INFO -> Log.i(group.getTag(), formattedString); 65 case DEBUG -> Log.d(group.getTag(), formattedString); 66 case WARN -> Log.w(group.getTag(), formattedString); 67 case ERROR -> Log.e(group.getTag(), formattedString); 68 case WTF -> Log.wtf(group.getTag(), formattedString); 69 } 70 } 71 } 72 73 @Override isProtoEnabled()74 public boolean isProtoEnabled() { 75 return false; 76 } 77 78 @Override startLoggingToLogcat(String[] groups, ILogger logger)79 public int startLoggingToLogcat(String[] groups, ILogger logger) { 80 return 0; 81 } 82 83 @Override stopLoggingToLogcat(String[] groups, ILogger logger)84 public int stopLoggingToLogcat(String[] groups, ILogger logger) { 85 return 0; 86 } 87 88 @Override isEnabled(IProtoLogGroup group, LogLevel level)89 public boolean isEnabled(IProtoLogGroup group, LogLevel level) { 90 return true; 91 } 92 93 @Override 94 @NonNull getRegisteredGroups()95 public List<IProtoLogGroup> getRegisteredGroups() { 96 return Collections.emptyList(); 97 } 98 } 99