UserEventDispatcher.java revision 8ce6063c4a5bd90810f0a21c946e5bbad3ce9de4
1ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song/* 2ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * Copyright (C) 2012 The Android Open Source Project 3ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * 4ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * Licensed under the Apache License, Version 2.0 (the "License"); 5ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * you may not use this file except in compliance with the License. 6ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * You may obtain a copy of the License at 7ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * 8ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * http://www.apache.org/licenses/LICENSE-2.0 9ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * 10ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * Unless required by applicable law or agreed to in writing, software 11ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * distributed under the License is distributed on an "AS IS" BASIS, 12ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * See the License for the specific language governing permissions and 14ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * limitations under the License. 15ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song */ 16ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 17a9c69ce09c164c8ad0191e05318460d0955825a7Hyunyoung Songpackage com.android.launcher3.logging; 18a9c69ce09c164c8ad0191e05318460d0955825a7Hyunyoung Song 196470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Songimport android.content.ComponentName; 20ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport android.content.Intent; 2164976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyalimport android.util.Log; 22ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport android.view.View; 23ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport android.view.ViewParent; 248fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 25ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport com.android.launcher3.ItemInfo; 2655c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickhamimport com.android.launcher3.userevent.nano.LauncherLogProto; 2746ab2276f97518e9ba71e4bf3109b8ebd924cbabSunny Goyalimport com.android.launcher3.userevent.nano.LauncherLogProto.Action; 28ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent; 29ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport com.android.launcher3.userevent.nano.LauncherLogProto.Target; 30ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport com.android.launcher3.util.ComponentKey; 31ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 32ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Songimport java.util.List; 3364976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyalimport java.util.Locale; 348fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 35aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song/** 36aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song * Manages the creation of {@link LauncherEvent}. 37aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song */ 3864976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyalpublic class UserEventDispatcher { 3964976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal 4064976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal private static final boolean DEBUG_LOGGING = false; 41ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5; 425aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song 43ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song /** 44ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * Implemented by containers to provide a launch source for a given child. 45ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song */ 46ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song public interface LaunchSourceProvider { 47ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 48ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song /** 49ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * Copies data from the source to the destination proto. 505aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song * 515aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song * @param v source of the data 525aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song * @param info source of the data 535aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song * @param target dest of the data 545aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song * @param targetParent dest of the data 55ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song */ 56ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song void fillInLaunchSourceData(View v, ItemInfo info, Target target, Target targetParent); 57ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 58ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 59ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song /** 60ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song * Recursively finds the parent of the given child which implements IconLogInfoProvider 61ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song */ 62ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song public static LaunchSourceProvider getLaunchProviderRecursive(View v) { 63ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song ViewParent parent = null; 64ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song if (v != null) { 65ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song parent = v.getParent(); 66ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } else { 67ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song return null; 68ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 69ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 70ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // Optimization to only check up to 5 parents. 71ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song int count = MAXIMUM_VIEW_HIERARCHY_LEVEL; 72ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song while (parent != null && count-- > 0) { 73ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song if (parent instanceof LaunchSourceProvider) { 74ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song return (LaunchSourceProvider) parent; 75ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } else { 76ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song parent = parent.getParent(); 77ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 78ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 79ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song return null; 80ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 81ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 82aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song private String TAG = "UserEvent"; 838fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 848fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song private long mElapsedContainerMillis; 858fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song private long mElapsedSessionMillis; 868fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song private long mActionDurationMillis; 878fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 88ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // Used for filling in predictedRank on {@link Target}s. 89ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song private List<ComponentKey> mPredictedApps; 90ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 91ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // APP_ICON SHORTCUT WIDGET 92ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // -------------------------------------------------------------- 93ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // packageNameHash required optional required 94ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // componentNameHash required required 95ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // intentHash required 96ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // -------------------------------------------------------------- 978fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 986470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song protected LauncherEvent createLauncherEvent(View v, Intent intent) { 99ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song LauncherEvent event = LoggerUtils.initLauncherEvent( 1008ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song Action.TOUCH, v, Target.CONTAINER); 101ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song event.action.touch = Action.TAP; 1028fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 103ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // Fill in grid(x,y), pageIndex of the child and container type of the parent 104ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // TODO: make this percolate up the view hierarchy if needed. 105ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song int idx = 0; 106ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song LaunchSourceProvider provider = getLaunchProviderRecursive(v); 1078ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song if (!(v.getTag() instanceof ItemInfo)) { 1088ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song return null; 1098ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song } 1106470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song ItemInfo itemInfo = (ItemInfo) v.getTag(); 1116470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song provider.fillInLaunchSourceData(v, itemInfo, event.srcTarget[idx], event.srcTarget[idx + 1]); 1126470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song 1136470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song event.srcTarget[idx].intentHash = intent.hashCode(); 1146470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song ComponentName cn = intent.getComponent(); 1156470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song if (cn != null) { 1166470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song event.srcTarget[idx].packageNameHash = cn.getPackageName().hashCode(); 1176470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song event.srcTarget[idx].componentHash = cn.hashCode(); 118373f5718f6ace627cfb17a4c9da2acfb9263c0f5Hyunyoung Song if (mPredictedApps != null) { 119373f5718f6ace627cfb17a4c9da2acfb9263c0f5Hyunyoung Song event.srcTarget[idx].predictedRank = mPredictedApps.indexOf( 120373f5718f6ace627cfb17a4c9da2acfb9263c0f5Hyunyoung Song new ComponentKey(cn, itemInfo.user)); 121373f5718f6ace627cfb17a4c9da2acfb9263c0f5Hyunyoung Song } 1226470cf449f1caf6a030e7ea93e785bb6ba414a59Hyunyoung Song } 1238fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 124ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song // Fill in the duration of time spent navigating in Launcher and the container. 1258fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song event.elapsedContainerMillis = System.currentTimeMillis() - mElapsedContainerMillis; 1268fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song event.elapsedSessionMillis = System.currentTimeMillis() - mElapsedSessionMillis; 12746ab2276f97518e9ba71e4bf3109b8ebd924cbabSunny Goyal return event; 12846ab2276f97518e9ba71e4bf3109b8ebd924cbabSunny Goyal } 129ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 130aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song public void logAppLaunch(View v, Intent intent) { 1318ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song LauncherEvent ev = createLauncherEvent(v, intent); 1328ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song if (ev == null) { 1338ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song return; 1348ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song } 1358ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song dispatchUserEvent(ev, intent); 136ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 137ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 1385aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song public void logActionOnControl(int action, int controlType) { 1395aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song LauncherEvent event = LoggerUtils.initLauncherEvent(Action.TOUCH, Target.CONTROL); 1405aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.action.touch = action; 1415aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.srcTarget[0].controlType = controlType; 1425aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.elapsedContainerMillis = System.currentTimeMillis() - mElapsedContainerMillis; 1435aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.elapsedSessionMillis = System.currentTimeMillis() - mElapsedSessionMillis; 1445aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song dispatchUserEvent(event, null); 145ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 146ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 1475aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song public void logActionOnContainer(int action, int dir, int containerType) { 1485aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song LauncherEvent event = LoggerUtils.initLauncherEvent(Action.TOUCH, Target.CONTAINER); 1495aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.action.touch = action; 1505aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.action.dir = dir; 1515aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.srcTarget[0].containerType = containerType; 1525aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.elapsedContainerMillis = System.currentTimeMillis() - mElapsedContainerMillis; 1535aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song event.elapsedSessionMillis = System.currentTimeMillis() - mElapsedSessionMillis; 1545aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song dispatchUserEvent(event, null); 155ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song } 156ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song 157be06874c8105cf1beec8171235600da9f4ee035eTony Wickham public void logDeepShortcutsOpen(View icon) { 15855c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham LauncherEvent event = LoggerUtils.initLauncherEvent( 1598ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song Action.TOUCH, icon, Target.CONTAINER); 160be06874c8105cf1beec8171235600da9f4ee035eTony Wickham LaunchSourceProvider provider = getLaunchProviderRecursive(icon); 1618ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song if (!(icon.getTag() instanceof ItemInfo)) { 1628ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song return; 1638ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song } 164be06874c8105cf1beec8171235600da9f4ee035eTony Wickham ItemInfo info = (ItemInfo) icon.getTag(); 165be06874c8105cf1beec8171235600da9f4ee035eTony Wickham provider.fillInLaunchSourceData(icon, info, event.srcTarget[0], event.srcTarget[1]); 166be06874c8105cf1beec8171235600da9f4ee035eTony Wickham event.action.touch = Action.LONGPRESS; 16755c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham event.elapsedContainerMillis = System.currentTimeMillis() - mElapsedContainerMillis; 16855c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham event.elapsedSessionMillis = System.currentTimeMillis() - mElapsedSessionMillis; 16955c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham dispatchUserEvent(event, null); 17055c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham } 17155c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham 172ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song public void setPredictedApps(List<ComponentKey> predictedApps) { 173ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song mPredictedApps = predictedApps; 1748fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1758fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 1768fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song /** 1778fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song * Currently logs following containers: workspace, allapps, widget tray. 1788fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song */ 1798fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song public final void resetElapsedContainerMillis() { 1808fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mElapsedContainerMillis = System.currentTimeMillis(); 1818fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1828fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 1838fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song public final void resetElapsedSessionMillis() { 1848fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mElapsedSessionMillis = System.currentTimeMillis(); 1858fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mElapsedContainerMillis = System.currentTimeMillis(); 1868fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1878fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 1888fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song public final void resetActionDurationMillis() { 1898fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mActionDurationMillis = System.currentTimeMillis(); 1908fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1918fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song 19264976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal public void dispatchUserEvent(LauncherEvent ev, Intent intent) { 19364976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal if (DEBUG_LOGGING) { 19455c6691e3a2e953dc9882ad0bc0a4c1ee2d42e67Tony Wickham Log.d(TAG, String.format(Locale.US, 1958ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song "\naction:%s\n Source child:%s\tparent:%s", 19664976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal LoggerUtils.getActionStr(ev.action), 1975aa2714959405043639cb2d0b8d9ab8c6eef0bd2Hyunyoung Song LoggerUtils.getTargetStr(ev.srcTarget != null ? ev.srcTarget[0] : null), 1988ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song LoggerUtils.getTargetStr(ev.srcTarget.length > 1 ? ev.srcTarget[1] : null))); 1998ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song if (ev.destTarget != null && ev.destTarget.length > 0) { 2008ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song Log.d(TAG, String.format(Locale.US, 2018ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song " Destination child:%s\tparent:%s", 2028ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song LoggerUtils.getTargetStr(ev.destTarget != null ? ev.destTarget[0] : null), 2038ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song LoggerUtils.getTargetStr(ev.destTarget.length > 1 ? ev.destTarget[1] : null))); 2048ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song } 2058ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song Log.d(TAG, String.format(Locale.US, 2068ce6063c4a5bd90810f0a21c946e5bbad3ce9de4Hyunyoung Song " Elapsed container %d ms session %d ms", 20764976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal ev.elapsedContainerMillis, 20864976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal ev.elapsedSessionMillis)); 20964976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal } 21064976d5a5667f52ed3fe4346ea5ab910dcc2dc2dSunny Goyal } 211ddec1c739ef37c3a042982b8943fe42e04b65f4cHyunyoung Song} 212