diff --git a/java/com/android/dialer/callintent/CallIntent.java b/java/com/android/dialer/callintent/CallIntent.java
new file mode 100644
index 0000000..ba61d56
--- /dev/null
+++ b/java/com/android/dialer/callintent/CallIntent.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2018 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.callintent;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.text.TextUtils;
+import com.android.dialer.common.Assert;
+import com.android.dialer.performancereport.PerformanceReport;
+import com.android.dialer.util.CallUtil;
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableMap;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+/** Creates an intent to start a new outgoing call. */
+@AutoValue
+public abstract class CallIntent implements Parcelable {
+  private static int lightbringerButtonAppearInExpandedCallLogItemCount = 0;
+  private static int lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
+  private static int lightbringerButtonAppearInSearchCount = 0;
+
+  abstract Uri number();
+
+  abstract CallSpecificAppData callSpecificAppData();
+
+  @Nullable
+  abstract PhoneAccountHandle phoneAccountHandle();
+
+  abstract boolean isVideoCall();
+
+  @Nullable
+  abstract String callSubject();
+
+  abstract boolean allowAssistedDial();
+
+  abstract ImmutableMap<String, String> stringInCallUiIntentExtras();
+
+  abstract ImmutableMap<String, Long> longInCallUiIntentExtras();
+
+  abstract ImmutableMap<String, String> stringPlaceCallExtras();
+
+  abstract ImmutableMap<String, Long> longPlaceCallExtras();
+
+  public static Builder builder() {
+    return new AutoValue_CallIntent.Builder().setIsVideoCall(false).setAllowAssistedDial(false);
+  }
+
+  public abstract Builder toBuilder();
+
+  /** Builder class for CallIntent info. */
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public Builder setTelNumber(String number) {
+      return setNumber(CallUtil.getCallUri(Assert.isNotNull(number)));
+    }
+
+    public Builder setVoicemailNumber(@Nullable PhoneAccountHandle phoneAccountHandle) {
+      return setNumber(Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null))
+          .setPhoneAccountHandle(phoneAccountHandle);
+    }
+
+    public abstract Builder setNumber(@NonNull Uri number);
+
+    public Builder setCallInitiationType(CallInitiationType.Type callInitiationType) {
+      return setCallSpecificAppData(
+          CallSpecificAppData.newBuilder().setCallInitiationType(callInitiationType).build());
+    }
+
+    abstract CallSpecificAppData callSpecificAppData();
+
+    public abstract Builder setCallSpecificAppData(
+        @NonNull CallSpecificAppData callSpecificAppData);
+
+    public abstract Builder setPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle);
+
+    public abstract Builder setIsVideoCall(boolean isVideoCall);
+
+    public abstract Builder setCallSubject(String callSubject);
+
+    public abstract Builder setAllowAssistedDial(boolean allowAssistedDial);
+
+    abstract ImmutableMap.Builder<String, String> stringInCallUiIntentExtrasBuilder();
+
+    abstract ImmutableMap.Builder<String, Long> longInCallUiIntentExtrasBuilder();
+
+    public Builder addInCallUiIntentExtra(String key, String value) {
+      stringInCallUiIntentExtrasBuilder().put(key, value);
+      return this;
+    }
+
+    public Builder addInCallUiIntentExtra(String key, Long value) {
+      longInCallUiIntentExtrasBuilder().put(key, value);
+      return this;
+    }
+
+    abstract ImmutableMap.Builder<String, String> stringPlaceCallExtrasBuilder();
+
+    abstract ImmutableMap.Builder<String, Long> longPlaceCallExtrasBuilder();
+
+    public Builder addPlaceCallExtra(String key, String value) {
+      stringPlaceCallExtrasBuilder().put(key, value);
+      return this;
+    }
+
+    public Builder addPlaceCallExtra(String key, Long value) {
+      longPlaceCallExtrasBuilder().put(key, value);
+      return this;
+    }
+
+    abstract CallIntent autoBuild();
+
+    public Intent build() {
+      CallSpecificAppData.Builder builder =
+          CallSpecificAppData.newBuilder(callSpecificAppData())
+              .setLightbringerButtonAppearInExpandedCallLogItemCount(
+                  lightbringerButtonAppearInExpandedCallLogItemCount)
+              .setLightbringerButtonAppearInCollapsedCallLogItemCount(
+                  lightbringerButtonAppearInCollapsedCallLogItemCount)
+              .setLightbringerButtonAppearInSearchCount(lightbringerButtonAppearInSearchCount);
+      lightbringerButtonAppearInExpandedCallLogItemCount = 0;
+      lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
+      lightbringerButtonAppearInSearchCount = 0;
+
+      if (PerformanceReport.isRecording()) {
+        builder
+            .setTimeSinceAppLaunch(PerformanceReport.getTimeSinceAppLaunch())
+            .setTimeSinceFirstClick(PerformanceReport.getTimeSinceFirstClick())
+            .addAllUiActionsSinceAppLaunch(PerformanceReport.getActions())
+            .addAllUiActionTimestampsSinceAppLaunch(PerformanceReport.getActionTimestamps())
+            .setStartingTabIndex(PerformanceReport.getStartingTabIndex())
+            .build();
+        PerformanceReport.stopRecording();
+      }
+
+      setCallSpecificAppData(builder.build());
+
+      // Validate CallIntent.
+      CallIntent callIntent = autoBuild();
+      Assert.isNotNull(callIntent.number());
+      Assert.isNotNull(callIntent.callSpecificAppData());
+      Assert.checkArgument(
+          callIntent.callSpecificAppData().getCallInitiationType()
+              != CallInitiationType.Type.UNKNOWN_INITIATION);
+
+      return autoBuild().newIntent();
+    }
+  }
+
+  // Creates the intent which can start a call
+  private Intent newIntent() {
+    Intent intent = new Intent(Intent.ACTION_CALL, number());
+
+    intent.putExtra(
+        TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
+        isVideoCall() ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY);
+
+    Bundle inCallUiIntentExtras = createInCallUiIntentExtras();
+    inCallUiIntentExtras.putLong(
+        Constants.EXTRA_CALL_CREATED_TIME_MILLIS, SystemClock.elapsedRealtime());
+
+    intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, inCallUiIntentExtras);
+
+    if (phoneAccountHandle() != null) {
+      intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle());
+    }
+
+    if (!TextUtils.isEmpty(callSubject())) {
+      intent.putExtra(TelecomManager.EXTRA_CALL_SUBJECT, callSubject());
+    }
+
+    intent.putExtras(createPlaceCallExtras());
+
+    return intent;
+  }
+
+  @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs.
+  private Bundle createInCallUiIntentExtras() {
+    Bundle bundle = new Bundle();
+    stringInCallUiIntentExtras().forEach(bundle::putString);
+    longInCallUiIntentExtras().forEach(bundle::putLong);
+    CallIntentParser.putCallSpecificAppData(bundle, callSpecificAppData());
+    return bundle;
+  }
+
+  @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs.
+  private Bundle createPlaceCallExtras() {
+    Bundle bundle = new Bundle();
+    stringPlaceCallExtras().forEach(bundle::putString);
+    longPlaceCallExtras().forEach(bundle::putLong);
+    CallIntentParser.putCallSpecificAppData(bundle, callSpecificAppData());
+    return bundle;
+  }
+
+  public static void increaseLightbringerCallButtonAppearInExpandedCallLogItemCount() {
+    CallIntent.lightbringerButtonAppearInExpandedCallLogItemCount++;
+  }
+
+  public static void increaseLightbringerCallButtonAppearInCollapsedCallLogItemCount() {
+    CallIntent.lightbringerButtonAppearInCollapsedCallLogItemCount++;
+  }
+
+  public static void increaseLightbringerCallButtonAppearInSearchCount() {
+    CallIntent.lightbringerButtonAppearInSearchCount++;
+  }
+
+  @VisibleForTesting
+  public static int getLightbringerButtonAppearInExpandedCallLogItemCount() {
+    return lightbringerButtonAppearInExpandedCallLogItemCount;
+  }
+
+  @VisibleForTesting
+  public static int getLightbringerButtonAppearInCollapsedCallLogItemCount() {
+    return lightbringerButtonAppearInCollapsedCallLogItemCount;
+  }
+
+  @VisibleForTesting
+  public static int getLightbringerButtonAppearInSearchCount() {
+    return lightbringerButtonAppearInSearchCount;
+  }
+
+  @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+  public static void clearLightbringerCounts() {
+    lightbringerButtonAppearInCollapsedCallLogItemCount = 0;
+    lightbringerButtonAppearInExpandedCallLogItemCount = 0;
+    lightbringerButtonAppearInSearchCount = 0;
+  }
+
+  @Override
+  public int describeContents() {
+    return 0;
+  }
+
+  @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs.
+  @Override
+  public void writeToParcel(Parcel dest, int flags) {
+    dest.writeParcelable(number(), flags);
+    dest.writeByteArray(callSpecificAppData().toByteArray());
+    dest.writeParcelable(phoneAccountHandle(), flags);
+    dest.writeInt(isVideoCall() ? 1 : 0);
+    dest.writeString(callSubject());
+    dest.writeInt(allowAssistedDial() ? 1 : 0);
+    Bundle stringInCallUiIntentExtrasBundle = new Bundle();
+    stringInCallUiIntentExtras().forEach(stringInCallUiIntentExtrasBundle::putString);
+    dest.writeBundle(stringInCallUiIntentExtrasBundle);
+    Bundle longInCallUiIntentExtrasBundle = new Bundle();
+    longInCallUiIntentExtras().forEach(longInCallUiIntentExtrasBundle::putLong);
+    dest.writeBundle(longInCallUiIntentExtrasBundle);
+  }
+
+  // @TODO(justinmcclain): Investigate deleting the parcelable logic and instead switching
+  // to using an internal proto for serialization.
+  public static final Creator<CallIntent> CREATOR =
+      new Creator<CallIntent>() {
+        @Override
+        public CallIntent createFromParcel(Parcel source) {
+          CallIntent.Builder callIntentBuilder = builder();
+          ClassLoader classLoader = CallIntent.class.getClassLoader();
+          callIntentBuilder.setNumber(source.readParcelable(classLoader));
+          CallSpecificAppData data;
+          try {
+            data = CallSpecificAppData.parseFrom(source.createByteArray());
+          } catch (InvalidProtocolBufferException e) {
+            data = CallSpecificAppData.getDefaultInstance();
+          }
+          callIntentBuilder
+              .setCallSpecificAppData(data)
+              .setPhoneAccountHandle(source.readParcelable(classLoader))
+              .setIsVideoCall(source.readInt() != 0)
+              .setCallSubject(source.readString())
+              .setAllowAssistedDial(source.readInt() != 0);
+          Bundle stringInCallUiIntentExtrasBundle = source.readBundle(classLoader);
+          for (String key : stringInCallUiIntentExtrasBundle.keySet()) {
+            callIntentBuilder.addInCallUiIntentExtra(
+                key, stringInCallUiIntentExtrasBundle.getString(key));
+          }
+          Bundle longInCallUiIntentExtrasBundle = source.readBundle(classLoader);
+          for (String key : longInCallUiIntentExtrasBundle.keySet()) {
+            callIntentBuilder.addInCallUiIntentExtra(
+                key, longInCallUiIntentExtrasBundle.getLong(key));
+          }
+          return callIntentBuilder.autoBuild();
+        }
+
+        @Override
+        public CallIntent[] newArray(int size) {
+          return new CallIntent[0];
+        }
+      };
+}
