From 58e68a9513495cbe76188d6066c4ffa467313175 Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Fri, 6 Nov 2015 10:35:30 -0800 Subject: More work to hook up screen event logging * Change logScreenView to log by an integer rather than string representing a screen name * Add some missing log events (SmartDialSearchFragment, etc) * Add mapping of integer to screen name strings for AnalyticsUtil Bug: 23164804 Change-Id: If34a01b71a3fb598caa237e4b679cfeb30c4dd01 --- src/com/android/dialer/DialtactsActivity.java | 10 +- .../android/dialer/calllog/CallLogActivity.java | 18 +-- src/com/android/dialer/list/ListsFragment.java | 16 +-- .../android/dialer/list/RegularSearchFragment.java | 3 +- .../dialer/list/SmartDialSearchFragment.java | 8 ++ src/com/android/dialer/logging/Logger.java | 46 ++----- src/com/android/dialer/logging/ScreenEvent.java | 153 +++++++++++++++++++++ 7 files changed, 189 insertions(+), 65 deletions(-) create mode 100644 src/com/android/dialer/logging/ScreenEvent.java (limited to 'src') diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index 4fa4bc2d7..cc457bd6c 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -82,6 +82,7 @@ import com.android.dialer.list.SearchFragment; import com.android.dialer.list.SmartDialSearchFragment; import com.android.dialer.list.SpeedDialFragment; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.ScreenEvent; import com.android.dialer.settings.DialerSettingsActivity; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; @@ -527,7 +528,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O // This is only called when the activity goes from resumed -> paused -> resumed, so it // will not cause an extra view to be sent out on rotation if (mIsDialpadShown) { - Logger.logFragmentView(mDialpadFragment); + Logger.logScreenView(ScreenEvent.DIALPAD, this); } mIsRestarting = false; } @@ -682,12 +683,15 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O ImportExportDialogFragment.show(getFragmentManager(), true, DialtactsActivity.class, ImportExportDialogFragment.EXPORT_MODE_DEFAULT); } + Logger.logScreenView(ScreenEvent.IMPORT_EXPORT_CONTACTS, this); return true; case R.id.menu_clear_frequents: ClearFrequentsDialog.show(getFragmentManager()); + Logger.logScreenView(ScreenEvent.CLEAR_FREQUENTS, this); return true; case R.id.menu_call_settings: handleMenuSettings(); + Logger.logScreenView(ScreenEvent.SETTINGS, this); return true; } return false; @@ -742,9 +746,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } mDialpadFragment.setAnimate(animate); - // logScreenView is used here explicitly to provide the activity as the DialpadFragment - // might not have been attached yet. - Logger.logScreenView(DialpadFragment.class.getSimpleName(), this, null); + Logger.logScreenView(ScreenEvent.DIALPAD, this); ft.commit(); if (animate) { diff --git a/src/com/android/dialer/calllog/CallLogActivity.java b/src/com/android/dialer/calllog/CallLogActivity.java index f6defcfd9..243eda9b1 100644 --- a/src/com/android/dialer/calllog/CallLogActivity.java +++ b/src/com/android/dialer/calllog/CallLogActivity.java @@ -41,6 +41,7 @@ import com.android.dialer.DialtactsActivity; import com.android.dialer.R; import com.android.dialer.TransactionSafeActivity; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.ScreenEvent; import com.android.dialer.util.DialerUtils; public class CallLogActivity extends TransactionSafeActivity implements ViewPager.OnPageChangeListener { @@ -223,22 +224,7 @@ public class CallLogActivity extends TransactionSafeActivity implements ViewPage } private void sendScreenViewForChildFragment(int position) { - Logger.logScreenView(CallLogFragment.class.getSimpleName(), this, - getFragmentTagForPosition(position)); - } - - /** - * Returns the fragment located at the given position in the {@link ViewPagerAdapter}. May - * be null if the position is invalid. - */ - private String getFragmentTagForPosition(int position) { - switch (position) { - case TAB_INDEX_ALL: - return "All"; - case TAB_INDEX_MISSED: - return "Missed"; - } - return null; + Logger.logScreenView(ScreenEvent.CALL_LOG_FILTER, this); } private int getRtlPosition(int position) { diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java index 08a23732f..4c80cc817 100644 --- a/src/com/android/dialer/list/ListsFragment.java +++ b/src/com/android/dialer/list/ListsFragment.java @@ -46,6 +46,7 @@ import com.android.dialer.calllog.CallLogFragment; import com.android.dialer.calllog.CallLogQueryHandler; import com.android.dialer.calllog.ContactInfoHelper; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.ScreenEvent; import com.android.dialer.util.DialerUtils; import com.android.dialer.voicemail.VoicemailStatusHelper; import com.android.dialer.voicemail.VoicemailStatusHelperImpl; @@ -403,25 +404,22 @@ public class ListsFragment extends Fragment return; } - String fragmentName; - String tag = null; + int screenType; switch (getCurrentTabIndex()) { case TAB_INDEX_SPEED_DIAL: - fragmentName = SpeedDialFragment.class.getSimpleName(); + screenType = ScreenEvent.SPEED_DIAL; break; case TAB_INDEX_HISTORY: - fragmentName = CallLogFragment.class.getSimpleName(); - tag = "History"; + screenType = ScreenEvent.CALL_LOG; break; case TAB_INDEX_ALL_CONTACTS: - fragmentName = AllContactsFragment.class.getSimpleName(); + screenType = ScreenEvent.ALL_CONTACTS; break; case TAB_INDEX_VOICEMAIL: - fragmentName = CallLogFragment.class.getSimpleName(); - tag = "Voicemail"; + screenType = ScreenEvent.VOICEMAIL_LOG; default: return; } - Logger.logScreenView(fragmentName, getActivity(), tag); + Logger.logScreenView(screenType, getActivity()); } } diff --git a/src/com/android/dialer/list/RegularSearchFragment.java b/src/com/android/dialer/list/RegularSearchFragment.java index c0807c35c..3acf967a1 100644 --- a/src/com/android/dialer/list/RegularSearchFragment.java +++ b/src/com/android/dialer/list/RegularSearchFragment.java @@ -31,6 +31,7 @@ import com.android.incallui.Call.LogState; import com.android.dialer.R; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.ScreenEvent; import com.android.dialer.service.CachedNumberLookupService; import com.android.dialer.widget.EmptyContentView; import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; @@ -58,7 +59,7 @@ public class RegularSearchFragment extends SearchFragment @Override public void onStart() { super.onStart(); - Logger.logFragmentView(this); + Logger.logScreenView(ScreenEvent.REGULAR_SEARCH, getActivity()); } public void configureDirectorySearch() { diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java index 9aedfe847..ee76a1319 100644 --- a/src/com/android/dialer/list/SmartDialSearchFragment.java +++ b/src/com/android/dialer/list/SmartDialSearchFragment.java @@ -28,6 +28,8 @@ import android.view.View; import com.android.contacts.common.list.ContactEntryListAdapter; import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.dialpad.SmartDialCursorLoader; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.ScreenEvent; import com.android.dialer.R; import com.android.dialer.widget.EmptyContentView; import com.android.incallui.Call.LogState; @@ -43,6 +45,12 @@ public class SmartDialSearchFragment extends SearchFragment private static final int CALL_PHONE_PERMISSION_REQUEST_CODE = 1; + @Override + public void onStart() { + super.onStart(); + Logger.logScreenView(ScreenEvent.SMART_DIAL_SEARCH, getActivity()); + } + /** * Creates a SmartDialListAdapter to display and operate on search results. */ diff --git a/src/com/android/dialer/logging/Logger.java b/src/com/android/dialer/logging/Logger.java index ee23dc8e7..fc19c8f8a 100644 --- a/src/com/android/dialer/logging/Logger.java +++ b/src/com/android/dialer/logging/Logger.java @@ -17,8 +17,8 @@ package com.android.dialer.logging; import android.app.Activity; -import android.app.Fragment; import android.text.TextUtils; +import android.util.Log; import com.android.contacts.commonbind.analytics.AnalyticsUtil; import com.android.dialerbind.ObjectFactory; @@ -28,7 +28,7 @@ import com.android.incallui.Call; * Single entry point for all logging/analytics-related work for all user interactions. */ public abstract class Logger { - public static final String FRAGMENT_TAG_SEPARATOR = "#"; + public static final String TAG = "Logger"; public static Logger getInstance() { return ObjectFactory.getLoggerInstance(); @@ -46,50 +46,26 @@ public abstract class Logger { } } - /** - * Logs an event indicating that a fragment was displayed. - * - * @param fragment to log an event for. - */ - public static void logFragmentView(Fragment fragment) { - if (fragment == null) { - return; - } - - logScreenView(fragment.getClass().getSimpleName(), fragment.getActivity(), null); - } - /** * Logs an event indicating that a screen was displayed. * - * @param screenName of the displayed screen. + * @param screenType integer identifier of the displayed screen * @param activity Parent activity of the displayed screen. - * @param tag Optional string used to provide additional information about the screen. */ - public static void logScreenView(String screenName, Activity activity, String tag) { + public static void logScreenView(int screenType, Activity activity) { final Logger logger = getInstance(); if (logger != null) { - logger.logScreenViewImpl(getScreenNameWithTag(screenName, tag)); + logger.logScreenViewImpl(screenType); } - AnalyticsUtil.sendScreenView(screenName, activity, tag); - } - - /** - * Build a tagged version of the provided screenName if the tag is non-empty. - * - * @param screenName Name of the screen. - * @param tag Optional tag describing the screen. - * @return the unchanged screenName if the tag is {@code null} or empty, the tagged version of - * the screenName otherwise. - */ - public static String getScreenNameWithTag(String screenName, String tag) { - if (TextUtils.isEmpty(tag)) { - return screenName; + final String screenName = ScreenEvent.getScreenName(screenType); + if (!TextUtils.isEmpty(screenName)) { + AnalyticsUtil.sendScreenView(screenName, activity, null); + } else { + Log.w(TAG, "Unknown screenType: " + screenType); } - return screenName + FRAGMENT_TAG_SEPARATOR + tag; } public abstract void logCallImpl(Call call); - public abstract void logScreenViewImpl(String screenName); + public abstract void logScreenViewImpl(int screenType); } diff --git a/src/com/android/dialer/logging/ScreenEvent.java b/src/com/android/dialer/logging/ScreenEvent.java new file mode 100644 index 000000000..c88a7b767 --- /dev/null +++ b/src/com/android/dialer/logging/ScreenEvent.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.dialer.logging; + +import android.text.TextUtils; + +import com.android.contacts.common.dialog.ClearFrequentsDialog; +import com.android.contacts.common.interactions.ImportExportDialogFragment; +import com.android.dialer.calllog.CallLogFragment; +import com.android.dialer.dialpad.DialpadFragment; +import com.android.dialer.list.AllContactsFragment; +import com.android.dialer.list.RegularSearchFragment; +import com.android.dialer.list.SmartDialSearchFragment; +import com.android.dialer.list.SpeedDialFragment; +import com.android.dialer.settings.DialerSettingsActivity; +import com.android.incallui.AnswerFragment; +import com.android.incallui.CallCardFragment; +import com.android.incallui.ConferenceManagerFragment; +import com.android.incallui.InCallActivity; + +import java.util.HashMap; +import java.util.Map; + +/** + * Stores constants identifying individual screens/dialogs/fragments in the application, and also + * provides a mapping of integer id -> screen name mappings for analytics purposes. + */ +public class ScreenEvent { + private static final Map sScreenNameMap = new HashMap<>(); + + public static final String FRAGMENT_TAG_SEPARATOR = "#"; + + public static final int UNKNOWN = 0; + + // The dialpad in the main Dialer activity + public static final int DIALPAD = 1; + + // The speed dial tab in the main Dialer activity + public static final int SPEED_DIAL = 2; + + // The recents tab in the main Dialer activity + public static final int CALL_LOG = 3; + + // The voicemail tab in the main Dialer activity + public static final int VOICEMAIL_LOG = 4; + + // The all contacts tab in the main Dialer activity + public static final int ALL_CONTACTS = 5; + + // List of search results returned by typing into the search box. + public static final int REGULAR_SEARCH = 6; + + // List of search results returned by typing into the dialpad. + public static final int SMART_DIAL_SEARCH = 7; + + // The All and Missed call log tabs in CallLogActivity + public static final int CALL_LOG_FILTER = 8; + + // Dialer settings screen. + public static final int SETTINGS = 9; + + // The "Import/export contacts" dialog launched via the overflow menu. + public static final int IMPORT_EXPORT_CONTACTS = 10; + + // The "Clear frequents" dialog launched via the overflow menu. + public static final int CLEAR_FREQUENTS = 11; + + // The "Send feedback" dialog launched via the overflow menu. + public static final int SEND_FEEDBACK = 12; + + // The main in call screen that displays caller details and contact photos + public static final int INCALL = 13; + + // The screen that displays the glowpad widget (slide right to answer, + // slide left to dismiss). + public static final int INCOMING_CALL = 14; + + // Conference management fragment displayed for conferences that support + // management of individual calls within the conference. + public static final int CONFERENCE_MANAGEMENT = 15; + + // The dialpad displayed in-call that is used to send dtmf tones. + public static final int INCALL_DIALPAD = 16; + + static { + sScreenNameMap.put(ScreenEvent.DIALPAD, + getScreenNameWithTag(DialpadFragment.class.getSimpleName(), "Dialer")); + sScreenNameMap.put(ScreenEvent.SPEED_DIAL, SpeedDialFragment.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.CALL_LOG, + getScreenNameWithTag(CallLogFragment.class.getSimpleName(), "History")); + sScreenNameMap.put(ScreenEvent.VOICEMAIL_LOG, + getScreenNameWithTag(CallLogFragment.class.getSimpleName(), "Voicemail")); + sScreenNameMap.put(ScreenEvent.ALL_CONTACTS, AllContactsFragment.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.REGULAR_SEARCH, + RegularSearchFragment.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.SMART_DIAL_SEARCH, + SmartDialSearchFragment.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.CALL_LOG_FILTER, + getScreenNameWithTag(CallLogFragment.class.getSimpleName(), "Filtered")); + sScreenNameMap.put(ScreenEvent.SETTINGS, + DialerSettingsActivity.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.IMPORT_EXPORT_CONTACTS, + ImportExportDialogFragment.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.CLEAR_FREQUENTS, + ClearFrequentsDialog.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.SEND_FEEDBACK, "SendFeedback"); + sScreenNameMap.put(ScreenEvent.INCALL, InCallActivity.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.INCOMING_CALL, AnswerFragment.class.getSimpleName()); + sScreenNameMap.put(ScreenEvent.CONFERENCE_MANAGEMENT, + ConferenceManagerFragment.class.getSimpleName()); + } + + /** + * For a given screen type, returns the actual screen name that is used for logging/analytics + * purposes. + * + * @param screenType unique ID of a type of screen + * + * @return the tagged version of the screen name corresponding to the provided screenType, + * or {@null} if the provided screenType is unknown. + */ + public static String getScreenName(int screenType) { + return sScreenNameMap.get(screenType); + } + + /** + * Build a tagged version of the provided screenName if the tag is non-empty. + * + * @param screenName Name of the screen. + * @param tag Optional tag describing the screen. + * @return the unchanged screenName if the tag is {@code null} or empty, the tagged version of + * the screenName otherwise. + */ + public static String getScreenNameWithTag(String screenName, String tag) { + if (TextUtils.isEmpty(tag)) { + return screenName; + } + return screenName + FRAGMENT_TAG_SEPARATOR + tag; + } +} -- cgit v1.2.3