blob: 8162699a74c68b79e32e5553932978ca5b81cf05 [file] [log] [blame]
Tony Mak5a5f0d52019-01-08 11:07:23 +00001/*
2 * Copyright (C) 2018 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 */
16package android.view.textclassifier;
17
Tony Mak5a5f0d52019-01-08 11:07:23 +000018import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXTCLASSIFIER_MODEL;
Tony Mak03a1d032019-01-24 15:12:00 +000019import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_FIRST_ENTITY_TYPE;
20import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_SCORE;
21import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_SECOND_ENTITY_TYPE;
22import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_SESSION_ID;
23import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_THIRD_ENTITY_TYPE;
24import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_WIDGET_TYPE;
25import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_WIDGET_VERSION;
Tony Mak5a5f0d52019-01-08 11:07:23 +000026
27import android.metrics.LogMaker;
28
29import com.android.internal.annotations.VisibleForTesting;
30import com.android.internal.logging.MetricsLogger;
31import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Daulet Zhanguzine1559472019-12-18 14:17:56 +000032import java.util.Objects;
Tony Mak5a5f0d52019-01-08 11:07:23 +000033
34
35/**
36 * Log {@link TextClassifierEvent} by using Tron, only support language detection and
37 * conversation actions.
38 *
39 * @hide
40 */
41public final class TextClassifierEventTronLogger {
42
43 private static final String TAG = "TCEventTronLogger";
Tony Mak5a5f0d52019-01-08 11:07:23 +000044
45 private final MetricsLogger mMetricsLogger;
46
47 public TextClassifierEventTronLogger() {
Abodunrinwa Toki520b2f82019-01-27 07:48:02 +000048 this(new MetricsLogger());
Tony Mak5a5f0d52019-01-08 11:07:23 +000049 }
50
51 @VisibleForTesting
52 public TextClassifierEventTronLogger(MetricsLogger metricsLogger) {
Daulet Zhanguzine1559472019-12-18 14:17:56 +000053 mMetricsLogger = Objects.requireNonNull(metricsLogger);
Tony Mak5a5f0d52019-01-08 11:07:23 +000054 }
55
56 /** Emits a text classifier event to the logs. */
57 public void writeEvent(TextClassifierEvent event) {
Daulet Zhanguzine1559472019-12-18 14:17:56 +000058 Objects.requireNonNull(event);
Abodunrinwa Toki520b2f82019-01-27 07:48:02 +000059
Tony Mak5a5f0d52019-01-08 11:07:23 +000060 int category = getCategory(event);
61 if (category == -1) {
62 Log.w(TAG, "Unknown category: " + event.getEventCategory());
63 return;
64 }
65 final LogMaker log = new LogMaker(category)
Tony Mak03a1d032019-01-24 15:12:00 +000066 .setSubtype(getLogType(event))
67 .addTaggedData(FIELD_TEXT_CLASSIFIER_SESSION_ID, event.getResultId())
Abodunrinwa Toki6d063372019-04-11 22:36:04 +010068 .addTaggedData(FIELD_TEXTCLASSIFIER_MODEL, getModelName(event));
69 if (event.getScores().length >= 1) {
70 log.addTaggedData(FIELD_TEXT_CLASSIFIER_SCORE, event.getScores()[0]);
71 }
Tony Mak03a1d032019-01-24 15:12:00 +000072 String[] entityTypes = event.getEntityTypes();
Abodunrinwa Toki520b2f82019-01-27 07:48:02 +000073 // The old logger does not support a field of list type, and thus workaround by store them
74 // in three separate fields. This is not an issue with the new logger.
Tony Mak03a1d032019-01-24 15:12:00 +000075 if (entityTypes.length >= 1) {
76 log.addTaggedData(FIELD_TEXT_CLASSIFIER_FIRST_ENTITY_TYPE, entityTypes[0]);
77 }
78 if (entityTypes.length >= 2) {
79 log.addTaggedData(FIELD_TEXT_CLASSIFIER_SECOND_ENTITY_TYPE, entityTypes[1]);
80 }
81 if (entityTypes.length >= 3) {
82 log.addTaggedData(FIELD_TEXT_CLASSIFIER_THIRD_ENTITY_TYPE, entityTypes[2]);
83 }
Tony Mak5a5f0d52019-01-08 11:07:23 +000084 TextClassificationContext eventContext = event.getEventContext();
85 if (eventContext != null) {
Tony Mak03a1d032019-01-24 15:12:00 +000086 log.addTaggedData(FIELD_TEXT_CLASSIFIER_WIDGET_TYPE, eventContext.getWidgetType());
87 log.addTaggedData(FIELD_TEXT_CLASSIFIER_WIDGET_VERSION,
88 eventContext.getWidgetVersion());
Tony Mak5a5f0d52019-01-08 11:07:23 +000089 log.setPackageName(eventContext.getPackageName());
90 }
91 mMetricsLogger.write(log);
92 debugLog(log);
93 }
94
Abodunrinwa Toki520b2f82019-01-27 07:48:02 +000095 private static String getModelName(TextClassifierEvent event) {
96 if (event.getModelName() != null) {
97 return event.getModelName();
98 }
99 return SelectionSessionLogger.SignatureParser.getModelName(event.getResultId());
100 }
101
Tony Mak5a5f0d52019-01-08 11:07:23 +0000102 private static int getCategory(TextClassifierEvent event) {
103 switch (event.getEventCategory()) {
104 case TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS:
105 return MetricsEvent.CONVERSATION_ACTIONS;
106 case TextClassifierEvent.CATEGORY_LANGUAGE_DETECTION:
107 return MetricsEvent.LANGUAGE_DETECTION;
108 }
109 return -1;
110 }
111
112 private static int getLogType(TextClassifierEvent event) {
113 switch (event.getEventType()) {
114 case TextClassifierEvent.TYPE_SMART_ACTION:
115 return MetricsEvent.ACTION_TEXT_SELECTION_SMART_SHARE;
116 case TextClassifierEvent.TYPE_ACTIONS_SHOWN:
117 return MetricsEvent.ACTION_TEXT_CLASSIFIER_ACTIONS_SHOWN;
118 case TextClassifierEvent.TYPE_MANUAL_REPLY:
119 return MetricsEvent.ACTION_TEXT_CLASSIFIER_MANUAL_REPLY;
Tony Mak03a1d032019-01-24 15:12:00 +0000120 case TextClassifierEvent.TYPE_ACTIONS_GENERATED:
121 return MetricsEvent.ACTION_TEXT_CLASSIFIER_ACTIONS_GENERATED;
Tony Mak5a5f0d52019-01-08 11:07:23 +0000122 default:
123 return MetricsEvent.VIEW_UNKNOWN;
124 }
125 }
126
127 private String toCategoryName(int category) {
128 switch (category) {
129 case MetricsEvent.CONVERSATION_ACTIONS:
130 return "conversation_actions";
131 case MetricsEvent.LANGUAGE_DETECTION:
132 return "language_detection";
133 }
134 return "unknown";
135 }
136
137 private String toEventName(int logType) {
138 switch (logType) {
139 case MetricsEvent.ACTION_TEXT_SELECTION_SMART_SHARE:
140 return "smart_share";
141 case MetricsEvent.ACTION_TEXT_CLASSIFIER_ACTIONS_SHOWN:
142 return "actions_shown";
143 case MetricsEvent.ACTION_TEXT_CLASSIFIER_MANUAL_REPLY:
144 return "manual_reply";
145 case MetricsEvent.ACTION_TEXT_CLASSIFIER_ACTIONS_GENERATED:
146 return "actions_generated";
147 }
148 return "unknown";
149 }
150
151 private void debugLog(LogMaker log) {
Tony Makafd54672019-01-04 15:56:44 +0000152 if (!Log.ENABLE_FULL_LOGGING) {
Tony Mak5a5f0d52019-01-08 11:07:23 +0000153 return;
154 }
Tony Mak03a1d032019-01-24 15:12:00 +0000155 final String id = String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_SESSION_ID));
Tony Mak5a5f0d52019-01-08 11:07:23 +0000156 final String categoryName = toCategoryName(log.getCategory());
Tony Mak03a1d032019-01-24 15:12:00 +0000157 final String eventName = toEventName(log.getSubtype());
158 final String widgetType =
159 String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_WIDGET_TYPE));
Tony Mak5a5f0d52019-01-08 11:07:23 +0000160 final String widgetVersion =
Tony Mak03a1d032019-01-24 15:12:00 +0000161 String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_WIDGET_VERSION));
Tony Mak5a5f0d52019-01-08 11:07:23 +0000162 final String model = String.valueOf(log.getTaggedData(FIELD_TEXTCLASSIFIER_MODEL));
Tony Mak03a1d032019-01-24 15:12:00 +0000163 final String firstEntityType =
164 String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_FIRST_ENTITY_TYPE));
165 final String secondEntityType =
166 String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_SECOND_ENTITY_TYPE));
167 final String thirdEntityType =
168 String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_THIRD_ENTITY_TYPE));
169 final String score =
170 String.valueOf(log.getTaggedData(FIELD_TEXT_CLASSIFIER_SCORE));
Tony Mak5a5f0d52019-01-08 11:07:23 +0000171
172 StringBuilder builder = new StringBuilder();
173 builder.append("writeEvent: ");
174 builder.append("id=").append(id);
175 builder.append(", category=").append(categoryName);
176 builder.append(", eventName=").append(eventName);
177 builder.append(", widgetType=").append(widgetType);
178 builder.append(", widgetVersion=").append(widgetVersion);
179 builder.append(", model=").append(model);
Tony Mak03a1d032019-01-24 15:12:00 +0000180 builder.append(", firstEntityType=").append(firstEntityType);
181 builder.append(", secondEntityType=").append(secondEntityType);
182 builder.append(", thirdEntityType=").append(thirdEntityType);
183 builder.append(", score=").append(score);
Tony Mak5a5f0d52019-01-08 11:07:23 +0000184
Tony Makafd54672019-01-04 15:56:44 +0000185 Log.v(TAG, builder.toString());
Tony Mak5a5f0d52019-01-08 11:07:23 +0000186 }
187}