diff --git a/src/com/android/incallui/Call.java b/src/com/android/incallui/Call.java
index 16a53b2..b768cdd 100644
--- a/src/com/android/incallui/Call.java
+++ b/src/com/android/incallui/Call.java
@@ -332,48 +332,7 @@
                             mTelecommCall.getChildren().get(i)).getId());
         }
 
-        Bundle callExtras = mTelecommCall.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(mTelecommCall.getDetails().getExtras());
 
         // If the handle of the call has changed, update state for the call determining if it is an
         // emergency call.
@@ -400,6 +359,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;
+            }
+        }
+    }
+
     private static int translateState(int state) {
         switch (state) {
             case android.telecom.Call.STATE_NEW:
diff --git a/tests/src/com/android/incallui/CallTest.java b/tests/src/com/android/incallui/CallTest.java
new file mode 100644
index 0000000..118ec38
--- /dev/null
+++ b/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);
+        }
+    }
+}
