diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java
index 3ec94f9..aec806f 100644
--- a/InCallUI/src/com/android/incallui/Call.java
+++ b/InCallUI/src/com/android/incallui/Call.java
@@ -552,48 +552,7 @@
         // maximum number of conferenced child calls as the metric for conference call usage.
         mLogState.conferencedCalls = Math.max(numChildCalls, mLogState.conferencedCalls);
 
-        Bundle callExtras = mTelecomCall.getDetails().getExtras();
-        if (callExtras != null) {
-            // Check for a change in the child address and notify any listeners.
-            if (callExtras.containsKey(Connection.EXTRA_CHILD_ADDRESS)) {
-                String childNumber = callExtras.getString(Connection.EXTRA_CHILD_ADDRESS);
-
-                if (!Objects.equals(childNumber, mChildNumber)) {
-                    mChildNumber = childNumber;
-                    CallList.getInstance().onChildNumberChange(this);
-                }
-            }
-
-            // Last forwarded number comes in as an array of strings.  We want to choose the last
-            // item in the array.  The forwarding numbers arrive independently of when the call is
-            // originally set up, so we need to notify the the UI of the change.
-            if (callExtras.containsKey(Connection.EXTRA_LAST_FORWARDED_NUMBER)) {
-                ArrayList<String> lastForwardedNumbers =
-                        callExtras.getStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER);
-
-                if (lastForwardedNumbers != null) {
-                    String lastForwardedNumber = null;
-                    if (!lastForwardedNumbers.isEmpty()) {
-                        lastForwardedNumber = lastForwardedNumbers.get(
-                                lastForwardedNumbers.size() - 1);
-                    }
-
-                    if (!Objects.equals(lastForwardedNumber, mLastForwardedNumber)) {
-                        mLastForwardedNumber = lastForwardedNumber;
-                        CallList.getInstance().onLastForwardedNumberChange(this);
-                    }
-                }
-            }
-
-            // Call subject is present in the extras at the start of call, so we do not need to
-            // notify any other listeners of this.
-            if (callExtras.containsKey(Connection.EXTRA_CALL_SUBJECT)) {
-                String callSubject = callExtras.getString(Connection.EXTRA_CALL_SUBJECT);
-                if (!Objects.equals(mCallSubject, callSubject)) {
-                    mCallSubject = callSubject;
-                }
-            }
-        }
+        updateFromCallExtras(mTelecomCall.getDetails().getExtras());
 
         // If the handle of the call has changed, update state for the call determining if it is an
         // emergency call.
@@ -622,6 +581,77 @@
     }
 
     /**
+     * Tests corruption of the {@code callExtras} bundle by calling {@link
+     * Bundle#containsKey(String)}. If the bundle is corrupted a {@link IllegalArgumentException}
+     * will be thrown and caught by this function.
+     *
+     * @param callExtras the bundle to verify
+     * @returns {@code true} if the bundle is corrupted, {@code false} otherwise.
+     */
+    protected boolean areCallExtrasCorrupted(Bundle callExtras) {
+        /**
+         * There's currently a bug in Telephony service (b/25613098) that could corrupt the
+         * extras bundle, resulting in a IllegalArgumentException while validating data under
+         * {@link Bundle#containsKey(String)}.
+         */
+        try {
+            callExtras.containsKey(Connection.EXTRA_CHILD_ADDRESS);
+            return false;
+        } catch (IllegalArgumentException e) {
+            Log.e(this, "CallExtras is corrupted, ignoring exception", e);
+            return true;
+        }
+    }
+
+    protected void updateFromCallExtras(Bundle callExtras) {
+        if (callExtras == null || areCallExtrasCorrupted(callExtras)) {
+            /**
+             * If the bundle is corrupted, abandon information update as a work around. These are
+             * not critical for the dialer to function.
+             */
+            return;
+        }
+        // Check for a change in the child address and notify any listeners.
+        if (callExtras.containsKey(Connection.EXTRA_CHILD_ADDRESS)) {
+            String childNumber = callExtras.getString(Connection.EXTRA_CHILD_ADDRESS);
+            if (!Objects.equals(childNumber, mChildNumber)) {
+                mChildNumber = childNumber;
+                CallList.getInstance().onChildNumberChange(this);
+            }
+        }
+
+        // Last forwarded number comes in as an array of strings.  We want to choose the
+        // last item in the array.  The forwarding numbers arrive independently of when the
+        // call is originally set up, so we need to notify the the UI of the change.
+        if (callExtras.containsKey(Connection.EXTRA_LAST_FORWARDED_NUMBER)) {
+            ArrayList<String> lastForwardedNumbers =
+                    callExtras.getStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER);
+
+            if (lastForwardedNumbers != null) {
+                String lastForwardedNumber = null;
+                if (!lastForwardedNumbers.isEmpty()) {
+                    lastForwardedNumber = lastForwardedNumbers.get(
+                            lastForwardedNumbers.size() - 1);
+                }
+
+                if (!Objects.equals(lastForwardedNumber, mLastForwardedNumber)) {
+                    mLastForwardedNumber = lastForwardedNumber;
+                    CallList.getInstance().onLastForwardedNumberChange(this);
+                }
+            }
+        }
+
+        // Call subject is present in the extras at the start of call, so we do not need to
+        // notify any other listeners of this.
+        if (callExtras.containsKey(Connection.EXTRA_CALL_SUBJECT)) {
+            String callSubject = callExtras.getString(Connection.EXTRA_CALL_SUBJECT);
+            if (!Objects.equals(mCallSubject, callSubject)) {
+                mCallSubject = callSubject;
+            }
+        }
+    }
+
+    /**
      * Determines if a received upgrade to video request should be cancelled.  This can happen if
      * another InCall UI responds to the upgrade to video request.
      *
diff --git a/InCallUI/tests/src/com/android/incallui/CallTest.java b/InCallUI/tests/src/com/android/incallui/CallTest.java
new file mode 100644
index 0000000..118ec38
--- /dev/null
+++ b/InCallUI/tests/src/com/android/incallui/CallTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 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.incallui;
+
+import android.os.Bundle;
+import android.telecom.Connection;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+// @formatter:off
+/**
+ * Run test with
+ * adb shell am instrument -e class com.android.incallui.CallTest -w com.google.android.dialer.tests/android.test.InstrumentationTestRunner
+ */
+// @formatter:on
+
+@SmallTest
+public class CallTest extends AndroidTestCase {
+
+    private TestCall mCall;
+
+    private final static String CHILD_NUMBER = "123";
+    private final static ArrayList<String> LAST_FORWARDED_NUMBER_LIST =
+            new ArrayList(Arrays.asList("456", "789"));
+    private final static String LAST_FORWARDED_NUMBER = "789";
+    private final static String CALL_SUBJECT = "foo";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mCall = new TestCall();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testUpdateFromCallExtras() {
+        mCall.updateFromCallExtras(getTestBundle());
+        verifyTestBundleResult();
+    }
+
+    public void testUpdateFromCallExtras_corruptedBundle() {
+        mCall.setBundleCorrupted(true);
+        mCall.updateFromCallExtras(getTestBundle());
+
+        assertEquals(mCall.getChildNumber(), null);
+        assertEquals(mCall.getLastForwardedNumber(), null);
+        assertEquals(mCall.getCallSubject(), null);
+    }
+
+    public void testUpdateFromCallExtras_corruptedBundleOverwrite() {
+
+        mCall.updateFromCallExtras(getTestBundle());
+        mCall.setBundleCorrupted(true);
+        Bundle bundle = new Bundle();
+        bundle.putString(Connection.EXTRA_CHILD_ADDRESS, "321");
+        bundle.putStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER,
+                new ArrayList(Arrays.asList("654", "987")));
+        bundle.putString(Connection.EXTRA_CALL_SUBJECT, "bar");
+        mCall.updateFromCallExtras(bundle);
+        //corrupted bundle should not overwrite existing values.
+        verifyTestBundleResult();
+    }
+
+    private Bundle getTestBundle() {
+        Bundle bundle = new Bundle();
+        bundle.putString(Connection.EXTRA_CHILD_ADDRESS, CHILD_NUMBER);
+        bundle.putStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER,
+                LAST_FORWARDED_NUMBER_LIST);
+        bundle.putString(Connection.EXTRA_CALL_SUBJECT, CALL_SUBJECT);
+        return bundle;
+    }
+
+    private void verifyTestBundleResult() {
+        assertEquals(CHILD_NUMBER, mCall.getChildNumber());
+        assertEquals(LAST_FORWARDED_NUMBER, mCall.getLastForwardedNumber());
+        assertEquals(CALL_SUBJECT, mCall.getCallSubject());
+    }
+
+    private class TestCall extends Call {
+
+        private boolean mBundleCorrupted = false;
+
+        public TestCall() {
+            super(Call.State.NEW);
+        }
+
+        @Override
+        public void updateFromCallExtras(Bundle bundle) {
+            super.updateFromCallExtras(bundle);
+        }
+
+        public void setBundleCorrupted(boolean value) {
+            this.mBundleCorrupted = value;
+        }
+
+        @Override
+        protected boolean areCallExtrasCorrupted(Bundle callExtras) {
+            if (mBundleCorrupted) {
+                return true;
+            }
+            return super.areCallExtrasCorrupted(callExtras);
+        }
+    }
+}
