Revise metrics for emergency dialer

Statistics of UI usage when a user has intention to make an emergency
call.

Bug: 124427605
Test: Manually. Check the result of
'adb logcat -b events | grep -e sysui_multi_action'

Change-Id: Ib6736ae194496370456c8cc79e700d6894b78b18
diff --git a/src/com/android/phone/EccShortcutAdapter.java b/src/com/android/phone/EccShortcutAdapter.java
index 19b1fec..53fa702 100644
--- a/src/com/android/phone/EccShortcutAdapter.java
+++ b/src/com/android/phone/EccShortcutAdapter.java
@@ -138,6 +138,19 @@
         }
     }
 
+    boolean hasShortcut(String number) {
+        if (mEccDisplayMaterialList == null) {
+            return false;
+        }
+
+        for (EccDisplayMaterial displayMaterial : mEccDisplayMaterialList) {
+            if (displayMaterial.number.equals(number)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Nullable
     private String pickEmergencyNumberForCategory(int category,
             @NonNull List<EmergencyNumber> emergencyNumbers) {
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index d6b7b41..3cf74c8 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -23,7 +23,6 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.KeyguardManager;
 import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -32,18 +31,12 @@
 import android.database.DataSetObserver;
 import android.graphics.Color;
 import android.graphics.Point;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
-import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.PersistableBundle;
-import android.os.SystemClock;
 import android.provider.Settings;
 import android.telecom.ParcelableCallAnalytics;
 import android.telecom.PhoneAccount;
@@ -78,8 +71,9 @@
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.colorextraction.drawable.ScrimDrawable;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.phone.EmergencyDialerMetricsLogger.DialedFrom;
+import com.android.phone.EmergencyDialerMetricsLogger.PhoneNumberType;
+import com.android.phone.EmergencyDialerMetricsLogger.UiModeErrorCode;
 import com.android.phone.common.dialpad.DialpadKeyButton;
 import com.android.phone.common.util.ViewUtil;
 import com.android.phone.common.widget.ResizingTextEditText;
@@ -107,72 +101,9 @@
 public class EmergencyDialer extends Activity implements View.OnClickListener,
         View.OnLongClickListener, View.OnKeyListener, TextWatcher,
         DialpadKeyButton.OnPressedListener, ColorExtractor.OnColorsChangedListener,
-        EmergencyShortcutButton.OnConfirmClickListener, SensorEventListener,
+        EmergencyShortcutButton.OnConfirmClickListener,
         EmergencyInfoGroup.OnConfirmClickListener {
 
-    private class MetricsWriter {
-        // Metrics constants indicating the UI that user made phone call.
-        public static final int CALL_SOURCE_DIALPAD = 0;
-        public static final int CALL_SOURCE_SHORTCUT = 1;
-
-        // Metrics constants indicating the phone number type of a call user made.
-        public static final int PHONE_NUMBER_TYPE_GENERAL = 0;
-        public static final int PHONE_NUMBER_TYPE_EMERGENCY = 1;
-
-        // Metrics constants indicating the actions performed by user.
-        public static final int USER_ACTION_NONE = 0x0;
-        public static final int USER_ACTION_OPEN_DIALPAD = 0x1;
-        public static final int USER_ACTION_OPEN_EMERGENCY_INFO = 0x2;
-        public static final int USER_ACTION_MAKE_CALL_VIA_DIALPAD = 0x4;
-        public static final int USER_ACTION_MAKE_CALL_VIA_SHORTCUT = 0x8;
-
-        private MetricsLogger mMetricsLogger = new MetricsLogger();
-
-        public void writeMetricsForEnter() {
-            if (!mShortcutViewConfig.isEnabled()) {
-                return;
-            }
-
-            KeyguardManager keyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
-            mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER)
-                    .setType(MetricsEvent.TYPE_OPEN)
-                    .setSubtype(mEntryType)
-                    .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_IS_SCREEN_LOCKED,
-                            keyguard.isKeyguardLocked() ? 1 : 0));
-        }
-
-        public void writeMetricsForExit() {
-            if (!mShortcutViewConfig.isEnabled()) {
-                return;
-            }
-
-            long userStayDuration = SystemClock.elapsedRealtime() - mUserEnterTimeMillis;
-            mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER)
-                    .setType(MetricsEvent.TYPE_CLOSE)
-                    .setSubtype(mEntryType)
-                    .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_USER_ACTIONS, mUserActions)
-                    .addTaggedData(
-                            MetricsEvent.FIELD_EMERGENCY_DIALER_DURATION_MS, userStayDuration));
-        }
-
-        public void writeMetricsForMakingCall(int callSource, int phoneNumberType,
-                boolean hasShortcut) {
-            if (!mShortcutViewConfig.isEnabled()) {
-                return;
-            }
-
-            mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER_MAKE_CALL)
-                    .setType(MetricsEvent.TYPE_ACTION)
-                    .setSubtype(callSource)
-                    .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_PHONE_NUMBER_TYPE,
-                            phoneNumberType)
-                    .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_PHONE_NUMBER_HAS_SHORTCUT,
-                            hasShortcut ? 1 : 0)
-                    .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_IN_POCKET,
-                            mIsProximityNear ? 1 : 0));
-        }
-    }
-
     // Keys used with onSaveInstanceState().
     private static final String LAST_NUMBER = "lastNumber";
 
@@ -291,21 +222,7 @@
     private int mEntryType;
     private ShortcutViewUtils.Config mShortcutViewConfig;
 
-    private MetricsWriter mMetricsWriter;
-    private SensorManager mSensorManager;
-    private Sensor mProximitySensor;
-    private boolean mIsProximityNear = false;
-
-    /**
-     * The time, in millis, since boot when user opened emergency dialer.
-     * This is used when calculating the user stay duration for metrics data.
-     */
-    private long mUserEnterTimeMillis = 0;
-
-    /**
-     * Bit flag indicating the actions performed by user. This is used for metrics data.
-     */
-    private int mUserActions = MetricsWriter.USER_ACTION_NONE;
+    private EmergencyDialerMetricsLogger mMetricsLogger;
 
     @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -341,15 +258,11 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        mMetricsLogger = new EmergencyDialerMetricsLogger(this);
+
         mEntryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN);
         Log.d(LOG_TAG, "Launched from " + entryTypeToString(mEntryType));
 
-        mMetricsWriter = new MetricsWriter();
-        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-        if (mSensorManager != null) {
-            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
-        }
-
         // Allow this activity to be displayed in front of the keyguard / lockscreen.
         setShowWhenLocked(true);
         // Allow turning screen on
@@ -583,18 +496,15 @@
     @Override
     public void onConfirmClick(EmergencyShortcutButton button) {
         if (button == null) return;
-
-        mUserActions |= MetricsWriter.USER_ACTION_MAKE_CALL_VIA_SHORTCUT;
-
-        // We interest on the context when user has intention to make phone call,
-        // so write metrics here for shortcut number even the call may not be created.
-        mMetricsWriter.writeMetricsForMakingCall(MetricsWriter.CALL_SOURCE_SHORTCUT,
-                MetricsWriter.PHONE_NUMBER_TYPE_EMERGENCY, true);
-
         String phoneNumber = button.getPhoneNumber();
 
         if (!TextUtils.isEmpty(phoneNumber)) {
             if (DBG) Log.d(LOG_TAG, "dial emergency number: " + Rlog.pii(LOG_TAG, phoneNumber));
+
+            // Write metrics when user has intention to make a call from a shortcut button.
+            mMetricsLogger.logPlaceCall(DialedFrom.SHORTCUT, PhoneNumberType.HAS_SHORTCUT,
+                    mShortcutViewConfig.getPhoneInfo());
+
             placeCall(phoneNumber, ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_SHORTCUT,
                     mShortcutViewConfig.getPhoneInfo());
         } else {
@@ -606,7 +516,6 @@
     public void onConfirmClick(EmergencyInfoGroup button) {
         if (button == null) return;
 
-        mUserActions |= MetricsWriter.USER_ACTION_OPEN_EMERGENCY_INFO;
         Intent intent = (Intent) button.getTag(R.id.tag_intent);
         if (intent != null) {
             startActivity(intent);
@@ -632,7 +541,6 @@
                 return;
             }
             case R.id.floating_action_button_dialpad: {
-                mUserActions |= MetricsWriter.USER_ACTION_OPEN_DIALPAD;
                 mDigits.getText().clear();
                 switchView(mDialpadView, mEmergencyShortcutView, true);
                 return;
@@ -733,9 +641,9 @@
     protected void onStart() {
         super.onStart();
 
-        mUserEnterTimeMillis = SystemClock.elapsedRealtime();
-        mUserActions = MetricsWriter.USER_ACTION_NONE;
-        mMetricsWriter.writeMetricsForEnter();
+        mMetricsLogger.logLaunchEmergencyDialer(mEntryType,
+                mShortcutViewConfig.isEnabled() ? UiModeErrorCode.SUCCESS
+                        : UiModeErrorCode.UNSPECIFIED_ERROR);
 
         if (mShortcutViewConfig.isEnabled()) {
             // Shortcut view doesn't support dark text theme.
@@ -759,11 +667,6 @@
     protected void onResume() {
         super.onResume();
 
-        if (mProximitySensor != null) {
-            mSensorManager.registerListener(
-                    this, mProximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
-        }
-
         // retrieve the DTMF tone play back setting.
         mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
                 Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
@@ -788,15 +691,11 @@
     @Override
     public void onPause() {
         super.onPause();
-        if (mProximitySensor != null) {
-            mSensorManager.unregisterListener(this, mProximitySensor);
-        }
     }
 
     @Override
     protected void onStop() {
         super.onStop();
-        mMetricsWriter.writeMetricsForExit();
         mColorExtractor.removeOnColorsChangedListener(this);
     }
 
@@ -835,7 +734,6 @@
      * place the call, but check to make sure it is a viable number.
      */
     private void placeCall() {
-        mUserActions |= MetricsWriter.USER_ACTION_MAKE_CALL_VIA_DIALPAD;
         mLastNumber = mDigits.getText().toString();
 
         // Convert into emergency number according to emergency conversion map.
@@ -843,14 +741,28 @@
         // nothing and just returns input number.
         mLastNumber = PhoneNumberUtils.convertToEmergencyNumber(this, mLastNumber);
 
+        @DialedFrom final int dialedFrom =
+                mShortcutViewConfig.isEnabled() ? DialedFrom.FASTER_LAUNCHER_DIALPAD
+                        : DialedFrom.TRADITIONAL_DIALPAD;
+        @PhoneNumberType final int phoneNumberType;
+
         boolean isEmergencyNumber;
         ShortcutViewUtils.PhoneInfo phoneToMakeCall = null;
-        if (mShortcutViewConfig.hasPromotedEmergencyNumber(mLastNumber)) {
+        if (mShortcutAdapter != null && mShortcutAdapter.hasShortcut(mLastNumber)) {
             isEmergencyNumber = true;
             phoneToMakeCall = mShortcutViewConfig.getPhoneInfo();
+            phoneNumberType = PhoneNumberType.HAS_SHORTCUT;
+        } else if (mShortcutViewConfig.hasPromotedEmergencyNumber(mLastNumber)) {
+            // If a number from SIM/network/... is categoried as police/ambulance/fire,
+            // hasPromotedEmergencyNumber() will return true, but it maybe not promoted as a
+            // shortcut button because a number provided by database has higher priority.
+            isEmergencyNumber = true;
+            phoneToMakeCall = mShortcutViewConfig.getPhoneInfo();
+            phoneNumberType = PhoneNumberType.NO_SHORTCUT;
         } else {
-            TelephonyManager tm = getSystemService(TelephonyManager.class);
-            isEmergencyNumber = tm.isEmergencyNumber(mLastNumber);
+            isEmergencyNumber = getSystemService(TelephonyManager.class)
+                    .isEmergencyNumber(mLastNumber);
+            phoneNumberType = PhoneNumberType.NO_SHORTCUT;
         }
 
         if (isEmergencyNumber) {
@@ -863,18 +775,18 @@
                 return;
             }
 
-            mMetricsWriter.writeMetricsForMakingCall(MetricsWriter.CALL_SOURCE_DIALPAD,
-                    MetricsWriter.PHONE_NUMBER_TYPE_EMERGENCY, isShortcutNumber(mLastNumber));
+            // Write metrics when user has intention to make a call from dialpad
+            mMetricsLogger.logPlaceCall(dialedFrom, phoneNumberType, phoneToMakeCall);
 
             placeCall(mLastNumber, ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_DIALPAD,
                     phoneToMakeCall);
         } else {
             if (DBG) Log.d(LOG_TAG, "rejecting bad requested number " + mLastNumber);
 
-            // We interest on the context when user has intention to make phone call,
-            // so write metrics here for non-emergency numbers even these numbers are rejected.
-            mMetricsWriter.writeMetricsForMakingCall(MetricsWriter.CALL_SOURCE_DIALPAD,
-                    MetricsWriter.PHONE_NUMBER_TYPE_GENERAL, false);
+            // Write metrics when user has intention to make a call of a non-emergency number, even
+            // this number is rejected.
+            mMetricsLogger.logPlaceCall(dialedFrom, PhoneNumberType.NOT_EMERGENCY_NUMBER,
+                    phoneToMakeCall);
 
             showDialog(BAD_EMERGENCY_NUMBER_DIALOG);
         }
@@ -1288,17 +1200,6 @@
                 });
     }
 
-    @Override
-    public void onSensorChanged(SensorEvent event) {
-        float distance = event.values[0];
-        mIsProximityNear = (distance < mProximitySensor.getMaximumRange());
-    }
-
-    @Override
-    public void onAccuracyChanged(Sensor sensor, int accuracy) {
-        // Not used.
-    }
-
     private boolean isShortcutNumber(String number) {
         if (TextUtils.isEmpty(number) || mEmergencyShortcutButtonList == null) {
             return false;
diff --git a/src/com/android/phone/EmergencyDialerMetricsLogger.java b/src/com/android/phone/EmergencyDialerMetricsLogger.java
new file mode 100644
index 0000000..b9ba352
--- /dev/null
+++ b/src/com/android/phone/EmergencyDialerMetricsLogger.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2019 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.phone;
+
+import android.annotation.IntDef;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.metrics.LogMaker;
+import android.os.Build;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * EmergencyCallMetricsLogger is a utility to collect metrics of emergency calls
+ */
+class EmergencyDialerMetricsLogger {
+    private static final String LOG_TAG = "EmergencyDialerLogger";
+
+    @IntDef({
+            DialedFrom.TRADITIONAL_DIALPAD,
+            DialedFrom.SHORTCUT,
+            DialedFrom.FASTER_LAUNCHER_DIALPAD,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DialedFrom {
+        int TRADITIONAL_DIALPAD = 0;
+        int SHORTCUT = 1;
+        int FASTER_LAUNCHER_DIALPAD = 2;
+    }
+
+    @IntDef({
+            LaunchedFrom.UNDEFINED,
+            LaunchedFrom.LOCK_SCREEN,
+            LaunchedFrom.POWER_KEY_MENU,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface LaunchedFrom {
+        int UNDEFINED = 0;
+        int LOCK_SCREEN = 1;
+        int POWER_KEY_MENU = 2;
+    }
+
+    @IntDef({
+            PhoneNumberType.HAS_SHORTCUT,
+            PhoneNumberType.NO_SHORTCUT,
+            PhoneNumberType.NOT_EMERGENCY_NUMBER,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface PhoneNumberType {
+        int HAS_SHORTCUT = 0;
+        int NO_SHORTCUT = 1;
+        int NOT_EMERGENCY_NUMBER = 2;
+    }
+
+    @IntDef({
+            UiModeErrorCode.UNSPECIFIED_ERROR,
+            UiModeErrorCode.SUCCESS,
+            UiModeErrorCode.CONFIG_ENTRY_POINT,
+            UiModeErrorCode.CONFIG_SIM_OPERATOR,
+            UiModeErrorCode.UNSUPPORTED_COUNTRY,
+            UiModeErrorCode.AIRPLANE_MODE,
+            UiModeErrorCode.NO_PROMOTED_NUMBER,
+            UiModeErrorCode.NO_CAPABLE_PHONE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface UiModeErrorCode {
+        int UNSPECIFIED_ERROR = -1;
+        int SUCCESS = 0;
+        int CONFIG_ENTRY_POINT = 1;
+        int CONFIG_SIM_OPERATOR = 2;
+        int UNSUPPORTED_COUNTRY = 3;
+        int AIRPLANE_MODE = 4;
+        int NO_PROMOTED_NUMBER = 5;
+        int NO_CAPABLE_PHONE = 6;
+    }
+
+    private class TelephonyInfo {
+        private final String mNetworkCountryIso;
+        private final String mNetworkOperator;
+
+        TelephonyInfo(String networkCountryIso, String networkOperator) {
+            mNetworkCountryIso = networkCountryIso;
+            mNetworkOperator = networkOperator;
+        }
+    }
+
+    private final MetricsLogger mMetricsLogger = new MetricsLogger();
+
+    private final Context mAppContext;
+
+    @LaunchedFrom
+    private int mLaunchedFrom;
+    @UiModeErrorCode
+    private int mUiModeErrorCode;
+
+    EmergencyDialerMetricsLogger(Context context) {
+        mAppContext = context.getApplicationContext();
+    }
+
+    /**
+     * Log when Emergency Dialer is launched.
+     * - Where the user launch Emergency Dialer from.
+     * - Whether shortcut view is enabled, and the reason why it's not enabled.
+     *
+     * @param entryType
+     * @param uiModeErrorCode
+     */
+    public void logLaunchEmergencyDialer(int entryType,
+            @UiModeErrorCode int uiModeErrorCode) {
+        final @EmergencyDialerMetricsLogger.LaunchedFrom int launchedFrom;
+        if (entryType == EmergencyDialer.ENTRY_TYPE_LOCKSCREEN_BUTTON) {
+            launchedFrom = EmergencyDialerMetricsLogger.LaunchedFrom.LOCK_SCREEN;
+        } else if (entryType == EmergencyDialer.ENTRY_TYPE_POWER_MENU) {
+            launchedFrom = EmergencyDialerMetricsLogger.LaunchedFrom.POWER_KEY_MENU;
+        } else {
+            launchedFrom = EmergencyDialerMetricsLogger.LaunchedFrom.UNDEFINED;
+        }
+
+        mLaunchedFrom = launchedFrom;
+        mUiModeErrorCode = uiModeErrorCode;
+    }
+
+    /**
+     * Log when user tring to place an emergency call.
+     * - Which UI (traditional dialpad, shortcut button, dialpad in shortcut view) the user place
+     *   the call from.
+     * - The number is promoted in shortcut view or not, or not even an emergency number?
+     * - Whether the device is locked.
+     * - Network country ISO and network operator.
+     *
+     * @param dialedFrom
+     * @param phoneNumberType
+     * @param phoneInfo
+     */
+    public void logPlaceCall(@DialedFrom int dialedFrom,
+            @PhoneNumberType int phoneNumberType,
+            @Nullable ShortcutViewUtils.PhoneInfo phoneInfo) {
+        TelephonyInfo telephonyInfo = getTelephonyInfo(phoneNumberType, phoneInfo);
+        final KeyguardManager keyguard = mAppContext.getSystemService(KeyguardManager.class);
+
+        logBeforeMakeCall(dialedFrom, phoneNumberType, keyguard.isKeyguardLocked(),
+                telephonyInfo.mNetworkCountryIso, telephonyInfo.mNetworkOperator);
+    }
+
+    private TelephonyInfo getTelephonyInfo(@PhoneNumberType int phoneNumberType,
+            @Nullable ShortcutViewUtils.PhoneInfo phoneInfo) {
+        final TelephonyManager telephonyManager = mAppContext.getSystemService(
+                TelephonyManager.class);
+        final TelephonyManager subTelephonyManager;
+        final String networkCountryIso;
+        final String networkOperator;
+        if (phoneNumberType == PhoneNumberType.HAS_SHORTCUT && phoneInfo != null) {
+            subTelephonyManager = telephonyManager.createForSubscriptionId(phoneInfo.getSubId());
+            networkCountryIso = phoneInfo.getCountryIso();
+        } else {
+            // No specific phone to make this call. Take information of default network.
+            subTelephonyManager = null;
+            networkCountryIso = telephonyManager.getNetworkCountryIso();
+        }
+        if (subTelephonyManager != null) {
+            networkOperator = subTelephonyManager.getNetworkOperator();
+        } else {
+            // This could be:
+            // - No specific phone to make this call.
+            // - Subscription changed! Maybe the device roamed to another network?
+            // Take information of default network.
+            networkOperator = telephonyManager.getNetworkOperator();
+        }
+
+        return new TelephonyInfo(networkCountryIso, networkOperator);
+    }
+
+    private void logBeforeMakeCall(@DialedFrom int dialedFrom,
+            @PhoneNumberType int phoneNumberType,
+            boolean isDeviceLocked,
+            String networkCountryIso,
+            String networkOperator) {
+        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+            Log.d(LOG_TAG, "EmergencyDialer session: dialedFrom=" + dialFromToString(dialedFrom)
+                    + ", launchedFrom=" + launchedFromToString(mLaunchedFrom)
+                    + ", uimode=" + uiModeErrorCodeToString(mUiModeErrorCode)
+                    + ", type=" + phoneNumberTypeToString(phoneNumberType)
+                    + ", locked=" + isDeviceLocked
+                    + ", country=" + networkCountryIso
+                    + ", operator=" + networkOperator);
+        }
+        mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER_MAKE_CALL_V2)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(dialedFrom)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_LAUNCH_FROM, mLaunchedFrom)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_UI_MODE_ERROR_CODE,
+                        mUiModeErrorCode)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_PHONE_NUMBER_TYPE,
+                        phoneNumberType)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_IS_DEVICE_LOCKED,
+                        isDeviceLocked ? 1 : 0)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_NETWORK_COUNTRY_ISO,
+                        networkCountryIso)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_NETWORK_OPERATOR,
+                        networkOperator)
+                .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_RADIO_VERSION,
+                        Build.getRadioVersion())
+        );
+    }
+
+    private String dialFromToString(@DialedFrom int dialedFrom) {
+        switch (dialedFrom) {
+            case DialedFrom.TRADITIONAL_DIALPAD:
+                return "traditional";
+            case DialedFrom.SHORTCUT:
+                return "shortcut";
+            case DialedFrom.FASTER_LAUNCHER_DIALPAD:
+                return "dialpad";
+            default:
+                return "unknown_error";
+        }
+    }
+
+    private String launchedFromToString(@LaunchedFrom int launchedFrom) {
+        switch (launchedFrom) {
+            case LaunchedFrom.UNDEFINED:
+                return "undefined";
+            case LaunchedFrom.LOCK_SCREEN:
+                return "lockscreen";
+            case LaunchedFrom.POWER_KEY_MENU:
+                return "powermenu";
+            default:
+                return "unknown_error";
+        }
+    }
+
+    private String phoneNumberTypeToString(@PhoneNumberType int phoneNumberType) {
+        switch (phoneNumberType) {
+            case PhoneNumberType.HAS_SHORTCUT:
+                return "has_shortcut";
+            case PhoneNumberType.NO_SHORTCUT:
+                return "no_shortcut";
+            case PhoneNumberType.NOT_EMERGENCY_NUMBER:
+                return "not_emergency";
+            default:
+                return "unknown_error";
+        }
+    }
+
+    private String uiModeErrorCodeToString(@UiModeErrorCode int uiModeErrorCode) {
+        switch (uiModeErrorCode) {
+            case UiModeErrorCode.UNSPECIFIED_ERROR:
+                return "unspecified_error";
+            case UiModeErrorCode.SUCCESS:
+                return "success";
+            case UiModeErrorCode.CONFIG_ENTRY_POINT:
+                return "config_entry_point";
+            case UiModeErrorCode.CONFIG_SIM_OPERATOR:
+                return "config_sim_operator";
+            case UiModeErrorCode.UNSUPPORTED_COUNTRY:
+                return "unsupported_country";
+            case UiModeErrorCode.AIRPLANE_MODE:
+                return "airplane_mode";
+            case UiModeErrorCode.NO_PROMOTED_NUMBER:
+                return "no_promoted_number";
+            case UiModeErrorCode.NO_CAPABLE_PHONE:
+                return "no_capable_phone";
+            default:
+                return "unknown_error";
+        }
+    }
+}