1 /* 2 * Copyright (C) 2023 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.intentresolver.logging; 18 19 import android.annotation.Nullable; 20 import android.content.Intent; 21 import android.metrics.LogMaker; 22 import android.net.Uri; 23 import android.provider.MediaStore; 24 import android.util.HashedStringCache; 25 import android.util.Log; 26 27 import com.android.intentresolver.ChooserActivity; 28 import com.android.intentresolver.contentpreview.ContentPreviewType; 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.internal.logging.InstanceId; 31 import com.android.internal.logging.InstanceIdSequence; 32 import com.android.internal.logging.MetricsLogger; 33 import com.android.internal.logging.UiEvent; 34 import com.android.internal.logging.UiEventLogger; 35 import com.android.internal.logging.UiEventLoggerImpl; 36 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 37 import com.android.internal.util.FrameworkStatsLog; 38 39 /** 40 * Helper for writing Sharesheet atoms to statsd log. 41 * @hide 42 */ 43 public class EventLog { 44 private static final String TAG = "ChooserActivity"; 45 private static final boolean DEBUG = true; 46 47 public static final int SELECTION_TYPE_SERVICE = 1; 48 public static final int SELECTION_TYPE_APP = 2; 49 public static final int SELECTION_TYPE_STANDARD = 3; 50 public static final int SELECTION_TYPE_COPY = 4; 51 public static final int SELECTION_TYPE_NEARBY = 5; 52 public static final int SELECTION_TYPE_EDIT = 6; 53 public static final int SELECTION_TYPE_MODIFY_SHARE = 7; 54 public static final int SELECTION_TYPE_CUSTOM_ACTION = 8; 55 56 /** 57 * This shim is provided only for testing. In production, clients will only ever use a 58 * {@link DefaultFrameworkStatsLogger}. 59 */ 60 @VisibleForTesting 61 interface FrameworkStatsLogger { 62 /** Overload to use for logging {@code FrameworkStatsLog.SHARESHEET_STARTED}. */ write( int frameworkEventId, int appEventId, String packageName, int instanceId, String mimeType, int numAppProvidedDirectTargets, int numAppProvidedAppTargets, boolean isWorkProfile, int previewType, int intentType, int numCustomActions, boolean modifyShareActionProvided)63 void write( 64 int frameworkEventId, 65 int appEventId, 66 String packageName, 67 int instanceId, 68 String mimeType, 69 int numAppProvidedDirectTargets, 70 int numAppProvidedAppTargets, 71 boolean isWorkProfile, 72 int previewType, 73 int intentType, 74 int numCustomActions, 75 boolean modifyShareActionProvided); 76 77 /** Overload to use for logging {@code FrameworkStatsLog.RANKING_SELECTED}. */ write( int frameworkEventId, int appEventId, String packageName, int instanceId, int positionPicked, boolean isPinned)78 void write( 79 int frameworkEventId, 80 int appEventId, 81 String packageName, 82 int instanceId, 83 int positionPicked, 84 boolean isPinned); 85 } 86 87 private static final int SHARESHEET_INSTANCE_ID_MAX = (1 << 13); 88 89 // A small per-notification ID, used for statsd logging. 90 // TODO: consider precomputing and storing as final. 91 private static InstanceIdSequence sInstanceIdSequence; 92 private InstanceId mInstanceId; 93 94 private final UiEventLogger mUiEventLogger; 95 private final FrameworkStatsLogger mFrameworkStatsLogger; 96 private final MetricsLogger mMetricsLogger; 97 EventLog()98 public EventLog() { 99 this(new UiEventLoggerImpl(), new DefaultFrameworkStatsLogger(), new MetricsLogger()); 100 } 101 102 @VisibleForTesting EventLog( UiEventLogger uiEventLogger, FrameworkStatsLogger frameworkLogger, MetricsLogger metricsLogger)103 EventLog( 104 UiEventLogger uiEventLogger, 105 FrameworkStatsLogger frameworkLogger, 106 MetricsLogger metricsLogger) { 107 mUiEventLogger = uiEventLogger; 108 mFrameworkStatsLogger = frameworkLogger; 109 mMetricsLogger = metricsLogger; 110 } 111 112 /** Records metrics for the start time of the {@link ChooserActivity}. */ logChooserActivityShown( boolean isWorkProfile, String targetMimeType, long systemCost)113 public void logChooserActivityShown( 114 boolean isWorkProfile, String targetMimeType, long systemCost) { 115 mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN) 116 .setSubtype( 117 isWorkProfile ? MetricsEvent.MANAGED_PROFILE : MetricsEvent.PARENT_PROFILE) 118 .addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, targetMimeType) 119 .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost)); 120 } 121 122 /** Logs a UiEventReported event for the system sharesheet completing initial start-up. */ logShareStarted( String packageName, String mimeType, int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, String intent, int customActionCount, boolean modifyShareActionProvided)123 public void logShareStarted( 124 String packageName, 125 String mimeType, 126 int appProvidedDirect, 127 int appProvidedApp, 128 boolean isWorkprofile, 129 int previewType, 130 String intent, 131 int customActionCount, 132 boolean modifyShareActionProvided) { 133 mFrameworkStatsLogger.write(FrameworkStatsLog.SHARESHEET_STARTED, 134 /* event_id = 1 */ SharesheetStartedEvent.SHARE_STARTED.getId(), 135 /* package_name = 2 */ packageName, 136 /* instance_id = 3 */ getInstanceId().getId(), 137 /* mime_type = 4 */ mimeType, 138 /* num_app_provided_direct_targets = 5 */ appProvidedDirect, 139 /* num_app_provided_app_targets = 6 */ appProvidedApp, 140 /* is_workprofile = 7 */ isWorkprofile, 141 /* previewType = 8 */ typeFromPreviewInt(previewType), 142 /* intentType = 9 */ typeFromIntentString(intent), 143 /* num_provided_custom_actions = 10 */ customActionCount, 144 /* modify_share_action_provided = 11 */ modifyShareActionProvided); 145 } 146 147 /** 148 * Log that a custom action has been tapped by the user. 149 * 150 * @param positionPicked index of the custom action within the list of custom actions. 151 */ logCustomActionSelected(int positionPicked)152 public void logCustomActionSelected(int positionPicked) { 153 mFrameworkStatsLogger.write(FrameworkStatsLog.RANKING_SELECTED, 154 /* event_id = 1 */ 155 SharesheetTargetSelectedEvent.SHARESHEET_CUSTOM_ACTION_SELECTED.getId(), 156 /* package_name = 2 */ null, 157 /* instance_id = 3 */ getInstanceId().getId(), 158 /* position_picked = 4 */ positionPicked, 159 /* is_pinned = 5 */ false); 160 } 161 162 /** 163 * Logs a UiEventReported event for the system sharesheet when the user selects a target. 164 * TODO: document parameters and/or consider breaking up by targetType so we don't have to 165 * support an overly-generic signature. 166 */ logShareTargetSelected( int targetType, String packageName, int positionPicked, int directTargetAlsoRanked, int numCallerProvided, @Nullable HashedStringCache.HashResult directTargetHashed, boolean isPinned, boolean successfullySelected, long selectionCost)167 public void logShareTargetSelected( 168 int targetType, 169 String packageName, 170 int positionPicked, 171 int directTargetAlsoRanked, 172 int numCallerProvided, 173 @Nullable HashedStringCache.HashResult directTargetHashed, 174 boolean isPinned, 175 boolean successfullySelected, 176 long selectionCost) { 177 mFrameworkStatsLogger.write(FrameworkStatsLog.RANKING_SELECTED, 178 /* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), 179 /* package_name = 2 */ packageName, 180 /* instance_id = 3 */ getInstanceId().getId(), 181 /* position_picked = 4 */ positionPicked, 182 /* is_pinned = 5 */ isPinned); 183 184 int category = getTargetSelectionCategory(targetType); 185 if (category != 0) { 186 LogMaker targetLogMaker = new LogMaker(category).setSubtype(positionPicked); 187 if (directTargetHashed != null) { 188 targetLogMaker.addTaggedData( 189 MetricsEvent.FIELD_HASHED_TARGET_NAME, directTargetHashed.hashedString); 190 targetLogMaker.addTaggedData( 191 MetricsEvent.FIELD_HASHED_TARGET_SALT_GEN, 192 directTargetHashed.saltGeneration); 193 targetLogMaker.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, 194 directTargetAlsoRanked); 195 } 196 targetLogMaker.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, numCallerProvided); 197 mMetricsLogger.write(targetLogMaker); 198 } 199 200 if (successfullySelected) { 201 if (DEBUG) { 202 Log.d(TAG, "User Selection Time Cost is " + selectionCost); 203 Log.d(TAG, "position of selected app/service/caller is " + positionPicked); 204 } 205 MetricsLogger.histogram( 206 null, "user_selection_cost_for_smart_sharing", (int) selectionCost); 207 MetricsLogger.histogram(null, "app_position_for_smart_sharing", positionPicked); 208 } 209 } 210 211 /** Log when direct share targets were received. */ logDirectShareTargetReceived(int category, int latency)212 public void logDirectShareTargetReceived(int category, int latency) { 213 mMetricsLogger.write(new LogMaker(category).setSubtype(latency)); 214 } 215 216 /** 217 * Log when we display a preview UI of the specified {@code previewType} as part of our 218 * Sharesheet session. 219 */ logActionShareWithPreview(int previewType)220 public void logActionShareWithPreview(int previewType) { 221 mMetricsLogger.write( 222 new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW).setSubtype(previewType)); 223 } 224 225 /** Log when the user selects an action button with the specified {@code targetType}. */ logActionSelected(int targetType)226 public void logActionSelected(int targetType) { 227 if (targetType == SELECTION_TYPE_COPY) { 228 LogMaker targetLogMaker = new LogMaker( 229 MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET).setSubtype(1); 230 mMetricsLogger.write(targetLogMaker); 231 } 232 mFrameworkStatsLogger.write(FrameworkStatsLog.RANKING_SELECTED, 233 /* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), 234 /* package_name = 2 */ "", 235 /* instance_id = 3 */ getInstanceId().getId(), 236 /* position_picked = 4 */ -1, 237 /* is_pinned = 5 */ false); 238 } 239 240 /** Log a warning that we couldn't display the content preview from the supplied {@code uri}. */ logContentPreviewWarning(Uri uri)241 public void logContentPreviewWarning(Uri uri) { 242 // The ContentResolver already logs the exception. Log something more informative. 243 Log.w(TAG, "Could not load (" + uri.toString() + ") thumbnail/name for preview. If " 244 + "desired, consider using Intent#createChooser to launch the ChooserActivity, " 245 + "and set your Intent's clipData and flags in accordance with that method's " 246 + "documentation"); 247 248 } 249 250 /** Logs a UiEventReported event for the system sharesheet being triggered by the user. */ logSharesheetTriggered()251 public void logSharesheetTriggered() { 252 log(SharesheetStandardEvent.SHARESHEET_TRIGGERED, getInstanceId()); 253 } 254 255 /** Logs a UiEventReported event for the system sharesheet completing loading app targets. */ logSharesheetAppLoadComplete()256 public void logSharesheetAppLoadComplete() { 257 log(SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE, getInstanceId()); 258 } 259 260 /** 261 * Logs a UiEventReported event for the system sharesheet completing loading service targets. 262 */ logSharesheetDirectLoadComplete()263 public void logSharesheetDirectLoadComplete() { 264 log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_COMPLETE, getInstanceId()); 265 } 266 267 /** 268 * Logs a UiEventReported event for the system sharesheet timing out loading service targets. 269 */ logSharesheetDirectLoadTimeout()270 public void logSharesheetDirectLoadTimeout() { 271 log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_TIMEOUT, getInstanceId()); 272 } 273 274 /** 275 * Logs a UiEventReported event for the system sharesheet switching 276 * between work and main profile. 277 */ logSharesheetProfileChanged()278 public void logSharesheetProfileChanged() { 279 log(SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED, getInstanceId()); 280 } 281 282 /** Logs a UiEventReported event for the system sharesheet getting expanded or collapsed. */ logSharesheetExpansionChanged(boolean isCollapsed)283 public void logSharesheetExpansionChanged(boolean isCollapsed) { 284 log(isCollapsed ? SharesheetStandardEvent.SHARESHEET_COLLAPSED : 285 SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId()); 286 } 287 288 /** 289 * Logs a UiEventReported event for the system sharesheet app share ranking timing out. 290 */ logSharesheetAppShareRankingTimeout()291 public void logSharesheetAppShareRankingTimeout() { 292 log(SharesheetStandardEvent.SHARESHEET_APP_SHARE_RANKING_TIMEOUT, getInstanceId()); 293 } 294 295 /** 296 * Logs a UiEventReported event for the system sharesheet when direct share row is empty. 297 */ logSharesheetEmptyDirectShareRow()298 public void logSharesheetEmptyDirectShareRow() { 299 log(SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW, getInstanceId()); 300 } 301 302 /** 303 * Logs a UiEventReported event for a given share activity 304 * @param event 305 * @param instanceId 306 */ log(UiEventLogger.UiEventEnum event, InstanceId instanceId)307 private void log(UiEventLogger.UiEventEnum event, InstanceId instanceId) { 308 mUiEventLogger.logWithInstanceId( 309 event, 310 0, 311 null, 312 instanceId); 313 } 314 315 /** 316 * @return A unique {@link InstanceId} to join across events recorded by this logger instance. 317 */ getInstanceId()318 private InstanceId getInstanceId() { 319 if (mInstanceId == null) { 320 if (sInstanceIdSequence == null) { 321 sInstanceIdSequence = new InstanceIdSequence(SHARESHEET_INSTANCE_ID_MAX); 322 } 323 mInstanceId = sInstanceIdSequence.newInstanceId(); 324 } 325 return mInstanceId; 326 } 327 328 /** 329 * The UiEvent enums that this class can log. 330 */ 331 enum SharesheetStartedEvent implements UiEventLogger.UiEventEnum { 332 @UiEvent(doc = "Basic system Sharesheet has started and is visible.") 333 SHARE_STARTED(228); 334 335 private final int mId; SharesheetStartedEvent(int id)336 SharesheetStartedEvent(int id) { 337 mId = id; 338 } 339 @Override getId()340 public int getId() { 341 return mId; 342 } 343 } 344 345 /** 346 * The UiEvent enums that this class can log. 347 */ 348 enum SharesheetTargetSelectedEvent implements UiEventLogger.UiEventEnum { 349 INVALID(0), 350 @UiEvent(doc = "User selected a service target.") 351 SHARESHEET_SERVICE_TARGET_SELECTED(232), 352 @UiEvent(doc = "User selected an app target.") 353 SHARESHEET_APP_TARGET_SELECTED(233), 354 @UiEvent(doc = "User selected a standard target.") 355 SHARESHEET_STANDARD_TARGET_SELECTED(234), 356 @UiEvent(doc = "User selected the copy target.") 357 SHARESHEET_COPY_TARGET_SELECTED(235), 358 @UiEvent(doc = "User selected the nearby target.") 359 SHARESHEET_NEARBY_TARGET_SELECTED(626), 360 @UiEvent(doc = "User selected the edit target.") 361 SHARESHEET_EDIT_TARGET_SELECTED(669), 362 @UiEvent(doc = "User selected the modify share target.") 363 SHARESHEET_MODIFY_SHARE_SELECTED(1316), 364 @UiEvent(doc = "User selected a custom action.") 365 SHARESHEET_CUSTOM_ACTION_SELECTED(1317); 366 367 private final int mId; SharesheetTargetSelectedEvent(int id)368 SharesheetTargetSelectedEvent(int id) { 369 mId = id; 370 } getId()371 @Override public int getId() { 372 return mId; 373 } 374 fromTargetType(int targetType)375 public static SharesheetTargetSelectedEvent fromTargetType(int targetType) { 376 switch(targetType) { 377 case SELECTION_TYPE_SERVICE: 378 return SHARESHEET_SERVICE_TARGET_SELECTED; 379 case SELECTION_TYPE_APP: 380 return SHARESHEET_APP_TARGET_SELECTED; 381 case SELECTION_TYPE_STANDARD: 382 return SHARESHEET_STANDARD_TARGET_SELECTED; 383 case SELECTION_TYPE_COPY: 384 return SHARESHEET_COPY_TARGET_SELECTED; 385 case SELECTION_TYPE_NEARBY: 386 return SHARESHEET_NEARBY_TARGET_SELECTED; 387 case SELECTION_TYPE_EDIT: 388 return SHARESHEET_EDIT_TARGET_SELECTED; 389 case SELECTION_TYPE_MODIFY_SHARE: 390 return SHARESHEET_MODIFY_SHARE_SELECTED; 391 case SELECTION_TYPE_CUSTOM_ACTION: 392 return SHARESHEET_CUSTOM_ACTION_SELECTED; 393 default: 394 return INVALID; 395 } 396 } 397 } 398 399 /** 400 * The UiEvent enums that this class can log. 401 */ 402 enum SharesheetStandardEvent implements UiEventLogger.UiEventEnum { 403 INVALID(0), 404 @UiEvent(doc = "User clicked share.") 405 SHARESHEET_TRIGGERED(227), 406 @UiEvent(doc = "User changed from work to personal profile or vice versa.") 407 SHARESHEET_PROFILE_CHANGED(229), 408 @UiEvent(doc = "User expanded target list.") 409 SHARESHEET_EXPANDED(230), 410 @UiEvent(doc = "User collapsed target list.") 411 SHARESHEET_COLLAPSED(231), 412 @UiEvent(doc = "Sharesheet app targets is fully populated.") 413 SHARESHEET_APP_LOAD_COMPLETE(322), 414 @UiEvent(doc = "Sharesheet direct targets is fully populated.") 415 SHARESHEET_DIRECT_LOAD_COMPLETE(323), 416 @UiEvent(doc = "Sharesheet direct targets timed out.") 417 SHARESHEET_DIRECT_LOAD_TIMEOUT(324), 418 @UiEvent(doc = "Sharesheet app share ranking timed out.") 419 SHARESHEET_APP_SHARE_RANKING_TIMEOUT(831), 420 @UiEvent(doc = "Sharesheet empty direct share row.") 421 SHARESHEET_EMPTY_DIRECT_SHARE_ROW(828); 422 423 private final int mId; SharesheetStandardEvent(int id)424 SharesheetStandardEvent(int id) { 425 mId = id; 426 } getId()427 @Override public int getId() { 428 return mId; 429 } 430 } 431 432 /** 433 * Returns the enum used in sharesheet started atom to indicate what preview type was used. 434 */ typeFromPreviewInt(int previewType)435 private static int typeFromPreviewInt(int previewType) { 436 switch(previewType) { 437 case ContentPreviewType.CONTENT_PREVIEW_IMAGE: 438 return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_IMAGE; 439 case ContentPreviewType.CONTENT_PREVIEW_FILE: 440 return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_FILE; 441 case ContentPreviewType.CONTENT_PREVIEW_TEXT: 442 default: 443 return FrameworkStatsLog 444 .SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_TYPE_UNKNOWN; 445 } 446 } 447 448 /** 449 * Returns the enum used in sharesheet started atom to indicate what intent triggers the 450 * ChooserActivity. 451 */ typeFromIntentString(String intent)452 private static int typeFromIntentString(String intent) { 453 if (intent == null) { 454 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT; 455 } 456 switch (intent) { 457 case Intent.ACTION_VIEW: 458 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_VIEW; 459 case Intent.ACTION_EDIT: 460 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_EDIT; 461 case Intent.ACTION_SEND: 462 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND; 463 case Intent.ACTION_SENDTO: 464 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SENDTO; 465 case Intent.ACTION_SEND_MULTIPLE: 466 return FrameworkStatsLog 467 .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND_MULTIPLE; 468 case MediaStore.ACTION_IMAGE_CAPTURE: 469 return FrameworkStatsLog 470 .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_IMAGE_CAPTURE; 471 case Intent.ACTION_MAIN: 472 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_MAIN; 473 default: 474 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT; 475 } 476 } 477 478 @VisibleForTesting getTargetSelectionCategory(int targetType)479 static int getTargetSelectionCategory(int targetType) { 480 switch (targetType) { 481 case SELECTION_TYPE_SERVICE: 482 return MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET; 483 case SELECTION_TYPE_APP: 484 return MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET; 485 case SELECTION_TYPE_STANDARD: 486 return MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET; 487 default: 488 return 0; 489 } 490 } 491 492 private static class DefaultFrameworkStatsLogger implements FrameworkStatsLogger { 493 @Override write( int frameworkEventId, int appEventId, String packageName, int instanceId, String mimeType, int numAppProvidedDirectTargets, int numAppProvidedAppTargets, boolean isWorkProfile, int previewType, int intentType, int numCustomActions, boolean modifyShareActionProvided)494 public void write( 495 int frameworkEventId, 496 int appEventId, 497 String packageName, 498 int instanceId, 499 String mimeType, 500 int numAppProvidedDirectTargets, 501 int numAppProvidedAppTargets, 502 boolean isWorkProfile, 503 int previewType, 504 int intentType, 505 int numCustomActions, 506 boolean modifyShareActionProvided) { 507 FrameworkStatsLog.write( 508 frameworkEventId, 509 /* event_id = 1 */ appEventId, 510 /* package_name = 2 */ packageName, 511 /* instance_id = 3 */ instanceId, 512 /* mime_type = 4 */ mimeType, 513 /* num_app_provided_direct_targets */ numAppProvidedDirectTargets, 514 /* num_app_provided_app_targets */ numAppProvidedAppTargets, 515 /* is_workprofile */ isWorkProfile, 516 /* previewType = 8 */ previewType, 517 /* intentType = 9 */ intentType, 518 /* num_provided_custom_actions = 10 */ numCustomActions, 519 /* modify_share_action_provided = 11 */ modifyShareActionProvided); 520 } 521 522 @Override write( int frameworkEventId, int appEventId, String packageName, int instanceId, int positionPicked, boolean isPinned)523 public void write( 524 int frameworkEventId, 525 int appEventId, 526 String packageName, 527 int instanceId, 528 int positionPicked, 529 boolean isPinned) { 530 FrameworkStatsLog.write( 531 frameworkEventId, 532 /* event_id = 1 */ appEventId, 533 /* package_name = 2 */ packageName, 534 /* instance_id = 3 */ instanceId, 535 /* position_picked = 4 */ positionPicked, 536 /* is_pinned = 5 */ isPinned); 537 } 538 } 539 } 540