summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/com/android/dialer/app/DialtactsActivity.java7
-rw-r--r--java/com/android/dialer/app/MainComponent.java40
-rw-r--r--java/com/android/dialer/app/calllog/CallLogGroupBuilder.java16
-rw-r--r--java/com/android/dialer/app/calllog/MissedCallNotifier.java11
-rw-r--r--java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java10
-rw-r--r--java/com/android/dialer/app/manifests/activities/AndroidManifest.xml25
-rw-r--r--java/com/android/dialer/app/res/menu/dialtacts_options.xml4
-rw-r--r--java/com/android/dialer/binary/aosp/AospDialerRootComponent.java2
-rw-r--r--java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java4
-rw-r--r--java/com/android/dialer/binary/common/DialerApplication.java25
-rw-r--r--java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java2
-rw-r--r--java/com/android/dialer/callintent/CallIntentBuilder.java2
-rw-r--r--java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java18
-rw-r--r--java/com/android/dialer/calllog/CallLogComponent.java4
-rw-r--r--java/com/android/dialer/calllog/CallLogFramework.java46
-rw-r--r--java/com/android/dialer/calllog/config/AndroidManifest.xml32
-rw-r--r--java/com/android/dialer/calllog/config/CallLogConfig.java40
-rw-r--r--java/com/android/dialer/calllog/config/CallLogConfigComponent.java (renamed from java/com/android/dialer/main/MainComponent.java)20
-rw-r--r--java/com/android/dialer/calllog/config/CallLogConfigImpl.java (renamed from java/com/android/dialer/calllog/CallLogConfig.java)63
-rw-r--r--java/com/android/dialer/calllog/config/CallLogConfigModule.java (renamed from java/com/android/dialer/main/impl/MainModule.java)17
-rw-r--r--java/com/android/dialer/commandline/impl/CallCommand.java20
-rw-r--r--java/com/android/dialer/dialpadview/DialpadFragment.java97
-rw-r--r--java/com/android/dialer/dialpadview/DialpadView.java6
-rw-r--r--java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml61
-rw-r--r--java/com/android/dialer/dialpadview/res/values/strings.xml6
-rw-r--r--java/com/android/dialer/main/Main.java30
-rw-r--r--java/com/android/dialer/main/impl/AndroidManifest.xml72
-rw-r--r--java/com/android/dialer/main/impl/MainImpl.java65
-rw-r--r--java/com/android/dialer/precall/impl/CallingAccountSelector.java5
-rw-r--r--java/com/android/dialer/precall/impl/MalformedNumberRectifier.java77
-rw-r--r--java/com/android/dialer/precall/impl/PreCallImpl.java6
-rw-r--r--java/com/android/dialer/precall/impl/UkRegionPrefixInInternationalFormatHandler.java69
-rw-r--r--java/com/android/dialer/preferredsim/PreferredAccountWorker.java4
-rw-r--r--java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java2
-rw-r--r--java/com/android/incallui/CallCardPresenter.java17
-rw-r--r--java/com/android/incallui/PhoneLookupHistoryRecorder.java8
-rw-r--r--java/com/android/incallui/contactgrid/ContactGridManager.java4
-rw-r--r--java/com/android/incallui/contactgrid/TopRow.java33
-rw-r--r--java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_top_row.xml2
-rw-r--r--java/com/android/incallui/contactgrid/res/values/strings.xml11
-rw-r--r--java/com/android/incallui/incall/protocol/PrimaryCallState.java6
-rw-r--r--java/com/android/voicemail/impl/settings/VisualVoicemailSettingsUtil.java75
-rw-r--r--java/com/android/voicemail/impl/utils/VoicemailDatabaseUtil.java10
43 files changed, 641 insertions, 433 deletions
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index a9a11e008..3d61f7371 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -725,9 +725,6 @@ public class DialtactsActivity extends TransactionSafeActivity
handleMenuSettings();
Logger.get(this).logScreenView(ScreenEvent.Type.SETTINGS, this);
return true;
- } else if (resId == R.id.menu_new_ui_launcher_shortcut) {
- MainComponent.createNewUiLauncherShortcut(this);
- return true;
}
return false;
}
@@ -1599,10 +1596,6 @@ public class DialtactsActivity extends TransactionSafeActivity
} else {
simulatorMenuItem.setVisible(false);
}
-
- menu.findItem(R.id.menu_new_ui_launcher_shortcut)
- .setVisible(MainComponent.isNewUiEnabled(context));
-
super.show();
}
}
diff --git a/java/com/android/dialer/app/MainComponent.java b/java/com/android/dialer/app/MainComponent.java
index f8d457c5f..c223723c6 100644
--- a/java/com/android/dialer/app/MainComponent.java
+++ b/java/com/android/dialer/app/MainComponent.java
@@ -19,44 +19,14 @@ package com.android.dialer.app;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-/** This class is a copy of dialer.main.impl.MainImpl to get around a dependency issue. */
+/**
+ * Main activity intents.
+ *
+ * <p>TODO(calderwoodra): Move this elsewhere.
+ */
public class MainComponent {
- public static boolean isNewUiEnabled(Context context) {
- return ConfigProviderBindings.get(context).getBoolean("is_nui_shortcut_enabled", false);
- }
-
- public static void createNewUiLauncherShortcut(Context context) {
- enableComponent(context);
- }
-
- public static boolean isNuiComponentEnabled(Context context) {
- if (!isNewUiEnabled(context)) {
- return false;
- }
- return context
- .getPackageManager()
- .getComponentEnabledSetting(new ComponentName(context, getComponentName()))
- == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
- }
-
- /**
- * Enables the NUI activity component. By default the component is disabled and can't be accessed.
- * Once the component has been enabled the user will get an option to use the new UI to handle
- * DIAL (and other) intents.
- */
- private static void enableComponent(Context context) {
- context
- .getPackageManager()
- .setComponentEnabledSetting(
- new ComponentName(context, getComponentName()),
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP);
- }
-
/**
* @param context Context of the application package implementing MainActivity class.
* @return intent for MainActivity.class
diff --git a/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java b/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java
index 4a0d78d57..e4bae5e5f 100644
--- a/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java
+++ b/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java
@@ -17,8 +17,6 @@
package com.android.dialer.app.calllog;
import android.database.Cursor;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.telephony.PhoneNumberUtils;
@@ -104,10 +102,8 @@ public class CallLogGroupBuilder {
// Instantiate other group values to those of the first call in the cursor.
String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
- String groupPostDialDigits =
- (VERSION.SDK_INT >= VERSION_CODES.N) ? cursor.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
- String groupViaNumbers =
- (VERSION.SDK_INT >= VERSION_CODES.N) ? cursor.getString(CallLogQuery.VIA_NUMBER) : "";
+ String groupPostDialDigits = cursor.getString(CallLogQuery.POST_DIAL_DIGITS);
+ String groupViaNumbers = cursor.getString(CallLogQuery.VIA_NUMBER);
int groupCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
int groupSize = 1;
@@ -123,12 +119,8 @@ public class CallLogGroupBuilder {
while (cursor.moveToNext()) {
// Obtain the values for the current call to group.
number = cursor.getString(CallLogQuery.NUMBER);
- numberPostDialDigits =
- (VERSION.SDK_INT >= VERSION_CODES.N)
- ? cursor.getString(CallLogQuery.POST_DIAL_DIGITS)
- : "";
- numberViaNumbers =
- (VERSION.SDK_INT >= VERSION_CODES.N) ? cursor.getString(CallLogQuery.VIA_NUMBER) : "";
+ numberPostDialDigits = cursor.getString(CallLogQuery.POST_DIAL_DIGITS);
+ numberViaNumbers = cursor.getString(CallLogQuery.VIA_NUMBER);
callType = cursor.getInt(CallLogQuery.CALL_TYPE);
callFeatures = cursor.getInt(CallLogQuery.FEATURES);
accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
index 158ae2b03..772feed53 100644
--- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java
+++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
@@ -42,12 +42,10 @@ import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
import android.util.ArraySet;
import com.android.contacts.common.ContactsUtils;
-import com.android.dialer.app.DialtactsActivity;
import com.android.dialer.app.MainComponent;
import com.android.dialer.app.R;
import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall;
import com.android.dialer.app.contactinfo.ContactPhotoLoader;
-import com.android.dialer.app.list.DialtactsPagerAdapter;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.common.Assert;
@@ -454,13 +452,8 @@ public class MissedCallNotifier implements Worker<Pair<Integer, String>, Void> {
* @param callUri Uri of the call to jump to. May be null
*/
private PendingIntent createCallLogPendingIntent(@Nullable Uri callUri) {
- Intent contentIntent;
- if (MainComponent.isNuiComponentEnabled(context)) {
- contentIntent = MainComponent.getShowCallLogIntent(context);
- } else {
- contentIntent =
- DialtactsActivity.getShowTabIntent(context, DialtactsPagerAdapter.TAB_INDEX_HISTORY);
- }
+ Intent contentIntent = MainComponent.getShowCallLogIntent(context);
+
// TODO (a bug): scroll to call
contentIntent.setData(callUri);
return PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
diff --git a/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java b/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java
index cba389cc3..793d9627c 100644
--- a/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java
+++ b/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java
@@ -38,7 +38,6 @@ import com.android.dialer.app.MainComponent;
import com.android.dialer.app.R;
import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall;
import com.android.dialer.app.contactinfo.ContactPhotoLoader;
-import com.android.dialer.app.list.DialtactsPagerAdapter;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.android.provider.VoicemailCompat;
import com.android.dialer.logging.DialerImpression;
@@ -267,13 +266,8 @@ final class VisualVoicemailNotifier {
private static PendingIntent newVoicemailIntent(
@NonNull Context context, @Nullable NewCall voicemail) {
- Intent intent;
- if (MainComponent.isNuiComponentEnabled(context)) {
- intent = MainComponent.getShowVoicemailIntent(context);
- } else {
- intent =
- DialtactsActivity.getShowTabIntent(context, DialtactsPagerAdapter.TAB_INDEX_VOICEMAIL);
- }
+ Intent intent = MainComponent.getShowVoicemailIntent(context);
+
// TODO (a bug): scroll to this voicemail
if (voicemail != null) {
intent.setData(voicemail.voicemailUri);
diff --git a/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml b/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml
index b9e5f6201..31960c979 100644
--- a/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml
+++ b/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml
@@ -37,16 +37,11 @@
<!-- The entrance point for Phone UI.
stateAlwaysHidden is set to suppress keyboard show up on
dialpad screen. -->
- <activity
- android:enabled="false"
- android:clearTaskOnLaunch="true"
- android:directBootAware="true"
- android:label="@string/launcherActivityLabel"
- android:launchMode="singleTask"
- android:name="com.android.dialer.app.DialtactsActivity"
- android:resizeableActivity="true"
- android:theme="@style/DialtactsActivityTheme"
- android:windowSoftInputMode="stateAlwaysHidden|adjustNothing">
+ <activity-alias
+ android:exported="true"
+ android:name="com.android.dialer.app.DialtactsActivity"
+ android:targetActivity="com.android.dialer.main.impl.MainActivity">
+
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
@@ -106,23 +101,17 @@
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.TAB"/>
</intent-filter>
- <intent-filter android:label="@string/callHistoryIconLabel">
+ <intent-filter android:label="@string/main_call_history_tab_description">
<action android:name="com.android.phone.action.RECENT_CALLS"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.TAB"/>
</intent-filter>
-
- <meta-data
- android:name="com.android.keyguard.layout"
- android:resource="@layout/keyguard_preview"/>
- </activity>
+ </activity-alias>
<activity-alias
android:exported="true"
android:name="com.android.dialer.DialtactsActivity"
android:targetActivity="com.android.dialer.main.impl.MainActivity"/>
-
</application>
-
</manifest>
diff --git a/java/com/android/dialer/app/res/menu/dialtacts_options.xml b/java/com/android/dialer/app/res/menu/dialtacts_options.xml
index b50e6ad5f..fcd520a1e 100644
--- a/java/com/android/dialer/app/res/menu/dialtacts_options.xml
+++ b/java/com/android/dialer/app/res/menu/dialtacts_options.xml
@@ -28,8 +28,4 @@
<item
android:id="@+id/menu_simulator_submenu"
android:title="@string/simulator_submenu_label"/>
- <item
- android:id="@+id/menu_new_ui_launcher_shortcut"
- android:title="@string/new_ui_launcher_shortcut_label"/>
-
</menu>
diff --git a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
index 969172b7f..21a282ded 100644
--- a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
+++ b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
@@ -19,6 +19,7 @@ package com.android.dialer.binary.aosp;
import com.android.bubble.stub.StubBubbleModule;
import com.android.dialer.binary.basecomponent.BaseDialerRootComponent;
import com.android.dialer.calllog.CallLogModule;
+import com.android.dialer.calllog.config.CallLogConfigModule;
import com.android.dialer.commandline.CommandLineModule;
import com.android.dialer.common.concurrent.DialerExecutorModule;
import com.android.dialer.configprovider.SharedPrefConfigProviderModule;
@@ -49,6 +50,7 @@ import javax.inject.Singleton;
@Component(
modules = {
CallLogModule.class,
+ CallLogConfigModule.class,
CommandLineModule.class,
ContextModule.class,
DialerExecutorModule.class,
diff --git a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
index 2cafb260f..b668d9114 100644
--- a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
+++ b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
@@ -18,6 +18,7 @@ package com.android.dialer.binary.basecomponent;
import com.android.bubble.BubbleComponent;
import com.android.dialer.calllog.CallLogComponent;
+import com.android.dialer.calllog.config.CallLogConfigComponent;
import com.android.dialer.calllog.database.CallLogDatabaseComponent;
import com.android.dialer.calllog.ui.CallLogUiComponent;
import com.android.dialer.commandline.CommandLineComponent;
@@ -27,7 +28,6 @@ import com.android.dialer.duo.DuoComponent;
import com.android.dialer.enrichedcall.EnrichedCallComponent;
import com.android.dialer.feedback.FeedbackComponent;
import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
-import com.android.dialer.main.MainComponent;
import com.android.dialer.metrics.MetricsComponent;
import com.android.dialer.phonelookup.PhoneLookupComponent;
import com.android.dialer.phonelookup.database.PhoneLookupDatabaseComponent;
@@ -51,6 +51,7 @@ public interface BaseDialerRootComponent
extends BubbleComponent.HasComponent,
CallLocationComponent.HasComponent,
CallLogComponent.HasComponent,
+ CallLogConfigComponent.HasComponent,
CallLogDatabaseComponent.HasComponent,
CallLogUiComponent.HasComponent,
ConfigProviderComponent.HasComponent,
@@ -60,7 +61,6 @@ public interface BaseDialerRootComponent
EnrichedCallComponent.HasComponent,
FeedbackComponent.HasComponent,
GlidePhotoManagerComponent.HasComponent,
- MainComponent.HasComponent,
MapsComponent.HasComponent,
MetricsComponent.HasComponent,
PhoneLookupComponent.HasComponent,
diff --git a/java/com/android/dialer/binary/common/DialerApplication.java b/java/com/android/dialer/binary/common/DialerApplication.java
index 9e9b03b5f..3247c7053 100644
--- a/java/com/android/dialer/binary/common/DialerApplication.java
+++ b/java/com/android/dialer/binary/common/DialerApplication.java
@@ -23,14 +23,15 @@ import android.support.v4.os.BuildCompat;
import com.android.dialer.blocking.BlockedNumbersAutoMigrator;
import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
import com.android.dialer.calllog.CallLogComponent;
-import com.android.dialer.common.concurrent.DefaultFutureCallback;
+import com.android.dialer.calllog.CallLogFramework;
+import com.android.dialer.calllog.config.CallLogConfig;
+import com.android.dialer.calllog.config.CallLogConfigComponent;
+import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.inject.HasRootComponent;
import com.android.dialer.notification.NotificationChannelManager;
import com.android.dialer.persistentlog.PersistentLogger;
import com.android.dialer.strictmode.StrictModeComponent;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.MoreExecutors;
/** A common application subclass for all Dialer build variants. */
public abstract class DialerApplication extends Application implements HasRootComponent {
@@ -48,11 +49,7 @@ public abstract class DialerApplication extends Application implements HasRootCo
new FilteredNumberAsyncQueryHandler(this),
DialerExecutorComponent.get(this).dialerExecutorFactory())
.asyncAutoMigrate();
- CallLogComponent.get(this).callLogFramework().onApplicationCreate();
- Futures.addCallback(
- CallLogComponent.get(this).getAnnotatedCallLogMigrator().migrate(),
- new DefaultFutureCallback<>(),
- MoreExecutors.directExecutor());
+ initializeAnnotatedCallLog();
PersistentLogger.initialize(this);
if (BuildCompat.isAtLeastO()) {
@@ -61,6 +58,18 @@ public abstract class DialerApplication extends Application implements HasRootCo
Trace.endSection();
}
+ private void initializeAnnotatedCallLog() {
+ CallLogConfig callLogConfig = CallLogConfigComponent.get(this).callLogConfig();
+ callLogConfig.schedulePollingJob();
+
+ if (callLogConfig.isCallLogFrameworkEnabled()) {
+ CallLogFramework callLogFramework = CallLogComponent.get(this).callLogFramework();
+ callLogFramework.registerContentObservers();
+ } else {
+ LogUtil.i("DialerApplication.initializeAnnotatedCallLog", "framework not enabled");
+ }
+ }
+
/**
* Returns a new instance of the root component for the application. Sub classes should define a
* root component that extends all the sub components "HasComponent" intefaces. The component
diff --git a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
index f9f561a0e..0da2f9577 100644
--- a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
+++ b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
@@ -19,6 +19,7 @@ package com.android.dialer.binary.google;
import com.android.bubble.stub.StubBubbleModule;
import com.android.dialer.binary.basecomponent.BaseDialerRootComponent;
import com.android.dialer.calllog.CallLogModule;
+import com.android.dialer.calllog.config.CallLogConfigModule;
import com.android.dialer.commandline.CommandLineModule;
import com.android.dialer.common.concurrent.DialerExecutorModule;
import com.android.dialer.configprovider.SharedPrefConfigProviderModule;
@@ -53,6 +54,7 @@ import javax.inject.Singleton;
modules = {
CallLocationModule.class,
CallLogModule.class,
+ CallLogConfigModule.class,
CommandLineModule.class,
ContextModule.class,
DialerExecutorModule.class,
diff --git a/java/com/android/dialer/callintent/CallIntentBuilder.java b/java/com/android/dialer/callintent/CallIntentBuilder.java
index ff490c296..9d9fcf4da 100644
--- a/java/com/android/dialer/callintent/CallIntentBuilder.java
+++ b/java/com/android/dialer/callintent/CallIntentBuilder.java
@@ -25,6 +25,7 @@ import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
+import android.telecom.Call.Details;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -168,6 +169,7 @@ public class CallIntentBuilder implements Parcelable {
return callSubject;
}
+ /** Additional data the in call UI can read with {@link Details#getIntentExtras()} */
public Bundle getOutgoingCallExtras() {
return outgoingCallExtras;
}
diff --git a/java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java b/java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java
index a12a98f0e..71bfb753c 100644
--- a/java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java
+++ b/java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java
@@ -16,12 +16,9 @@
package com.android.dialer.calllog;
-import android.content.Context;
import android.content.SharedPreferences;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.inject.ApplicationContext;
import com.android.dialer.storage.Unencrypted;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@@ -37,18 +34,15 @@ public final class AnnotatedCallLogMigrator {
private static final String PREF_MIGRATED = "annotatedCallLogMigratorMigrated";
- private final Context appContext;
private final SharedPreferences sharedPreferences;
private final RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker;
private final ListeningExecutorService backgroundExecutor;
@Inject
AnnotatedCallLogMigrator(
- @ApplicationContext Context appContext,
@Unencrypted SharedPreferences sharedPreferences,
@BackgroundExecutor ListeningExecutorService backgroundExecutor,
RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker) {
- this.appContext = appContext;
this.sharedPreferences = sharedPreferences;
this.backgroundExecutor = backgroundExecutor;
this.refreshAnnotatedCallLogWorker = refreshAnnotatedCallLogWorker;
@@ -78,17 +72,7 @@ public final class AnnotatedCallLogMigrator {
}
private ListenableFuture<Boolean> shouldMigrate() {
- return backgroundExecutor.submit(
- () -> {
- if (!(ConfigProviderBindings.get(appContext)
- .getBoolean("is_nui_shortcut_enabled", false))) {
- return false;
- }
- if (sharedPreferences.getBoolean(PREF_MIGRATED, false)) {
- return false;
- }
- return true;
- });
+ return backgroundExecutor.submit(() -> !sharedPreferences.getBoolean(PREF_MIGRATED, false));
}
/**
diff --git a/java/com/android/dialer/calllog/CallLogComponent.java b/java/com/android/dialer/calllog/CallLogComponent.java
index c7b44a818..4f147f1a6 100644
--- a/java/com/android/dialer/calllog/CallLogComponent.java
+++ b/java/com/android/dialer/calllog/CallLogComponent.java
@@ -30,12 +30,8 @@ public abstract class CallLogComponent {
public abstract RefreshAnnotatedCallLogWorker getRefreshAnnotatedCallLogWorker();
- public abstract AnnotatedCallLogMigrator getAnnotatedCallLogMigrator();
-
public abstract ClearMissedCalls getClearMissedCalls();
- public abstract CallLogConfig callLogConfig();
-
public static CallLogComponent get(Context context) {
return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
.callLogComponent();
diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java
index 936f2bbf6..53ff43057 100644
--- a/java/com/android/dialer/calllog/CallLogFramework.java
+++ b/java/com/android/dialer/calllog/CallLogFramework.java
@@ -16,12 +16,9 @@
package com.android.dialer.calllog;
-import android.content.Context;
import com.android.dialer.calllog.datasources.CallLogDataSource;
import com.android.dialer.calllog.datasources.DataSources;
import com.android.dialer.common.LogUtil;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.inject.ApplicationContext;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
@@ -38,46 +35,39 @@ import javax.inject.Singleton;
@Singleton
public final class CallLogFramework {
- private final Context appContext;
private final DataSources dataSources;
+ private final AnnotatedCallLogMigrator annotatedCallLogMigrator;
@Inject
- CallLogFramework(@ApplicationContext Context appContext, DataSources dataSources) {
- this.appContext = appContext;
+ CallLogFramework(DataSources dataSources, AnnotatedCallLogMigrator annotatedCallLogMigrator) {
this.dataSources = dataSources;
- }
-
- /** Performs necessary setup work when the application is created. */
- public void onApplicationCreate() {
- registerContentObservers();
- CallLogConfig.schedulePollingJob(appContext);
+ this.annotatedCallLogMigrator = annotatedCallLogMigrator;
}
/** Registers the content observers for all data sources. */
public void registerContentObservers() {
LogUtil.enterBlock("CallLogFramework.registerContentObservers");
-
- // This is the same condition used in MainImpl#isNewUiEnabled. It means that bugfood/debug
- // users will have "new call log" content observers firing. These observers usually do simple
- // things like writing shared preferences.
- // TODO(zachh): Find a way to access Main#isNewUiEnabled without creating a circular dependency.
- if (ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false)) {
- for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) {
- dataSource.registerContentObservers();
- }
- } else {
- LogUtil.i("CallLogFramework.registerContentObservers", "not registering content observers");
+ for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) {
+ dataSource.registerContentObservers();
}
}
+ /** Enables the framework. */
+ public ListenableFuture<Void> enable() {
+ registerContentObservers();
+ return annotatedCallLogMigrator.migrate();
+ }
+
/** Disables the framework. */
public ListenableFuture<Void> disable() {
- LogUtil.enterBlock("CallLogFramework.disable");
+ return Futures.transform(
+ Futures.allAsList(disableDataSources(), annotatedCallLogMigrator.clearData()),
+ unused -> null,
+ MoreExecutors.directExecutor());
+ }
- if (!ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false)) {
- LogUtil.i("CallLogFramework.disable", "not disabling");
- return Futures.immediateFuture(null);
- }
+ private ListenableFuture<Void> disableDataSources() {
+ LogUtil.enterBlock("CallLogFramework.disableDataSources");
for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) {
dataSource.unregisterContentObservers();
diff --git a/java/com/android/dialer/calllog/config/AndroidManifest.xml b/java/com/android/dialer/calllog/config/AndroidManifest.xml
new file mode 100644
index 000000000..7f65fac5d
--- /dev/null
+++ b/java/com/android/dialer/calllog/config/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<!--
+ ~ 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
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.dialer.calllog.config">
+
+ <uses-sdk
+ android:minSdkVersion="24"
+ android:targetSdkVersion="27"/>
+
+ <application>
+
+ <service
+ android:exported="false"
+ android:name=".CallLogConfigImpl$PollingJob"
+ android:permission="android.permission.BIND_JOB_SERVICE"/>
+
+ </application>
+
+</manifest>
diff --git a/java/com/android/dialer/calllog/config/CallLogConfig.java b/java/com/android/dialer/calllog/config/CallLogConfig.java
new file mode 100644
index 000000000..15fd5c1c2
--- /dev/null
+++ b/java/com/android/dialer/calllog/config/CallLogConfig.java
@@ -0,0 +1,40 @@
+/*
+ * 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.calllog.config;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+/** Determines if new call log components are enabled. */
+public interface CallLogConfig {
+
+ /**
+ * Updates the config values. This may kick off a lot of work so should be done infrequently, for
+ * example by a scheduled job or broadcast receiver which rarely fires.
+ */
+ ListenableFuture<Void> update();
+
+ boolean isNewCallLogFragmentEnabled();
+
+ boolean isNewVoicemailFragmentEnabled();
+
+ boolean isNewPeerEnabled();
+
+ boolean isCallLogFrameworkEnabled();
+
+ /** Schedules a job to periodically update the config. */
+ void schedulePollingJob();
+}
diff --git a/java/com/android/dialer/main/MainComponent.java b/java/com/android/dialer/calllog/config/CallLogConfigComponent.java
index e735457f4..c325025f3 100644
--- a/java/com/android/dialer/main/MainComponent.java
+++ b/java/com/android/dialer/calllog/config/CallLogConfigComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -13,27 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-
-package com.android.dialer.main;
+package com.android.dialer.calllog.config;
import android.content.Context;
import com.android.dialer.inject.HasRootComponent;
-import com.android.dialer.main.impl.MainModule;
import dagger.Subcomponent;
-/** Subcomponent that can be used to access the main implementation. */
-@Subcomponent(modules = MainModule.class)
-public abstract class MainComponent {
+/** Dagger component for the call log config. */
+@Subcomponent
+public abstract class CallLogConfigComponent {
- public abstract Main getMain();
+ public abstract CallLogConfig callLogConfig();
- public static MainComponent get(Context context) {
+ public static CallLogConfigComponent get(Context context) {
return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
- .mainComponent();
+ .callLogConfigComponent();
}
/** Used to refer to the root application component. */
public interface HasComponent {
- MainComponent mainComponent();
+ CallLogConfigComponent callLogConfigComponent();
}
}
diff --git a/java/com/android/dialer/calllog/CallLogConfig.java b/java/com/android/dialer/calllog/config/CallLogConfigImpl.java
index 12056c758..9c7f472d5 100644
--- a/java/com/android/dialer/calllog/CallLogConfig.java
+++ b/java/com/android/dialer/calllog/config/CallLogConfigImpl.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.dialer.calllog;
+package com.android.dialer.calllog.config;
import android.annotation.SuppressLint;
import android.app.job.JobInfo;
@@ -25,13 +25,14 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v4.os.UserManagerCompat;
+import com.android.dialer.calllog.CallLogFramework;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
-import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.configprovider.ConfigProvider;
import com.android.dialer.constants.ScheduledJobIds;
+import com.android.dialer.inject.ApplicationContext;
import com.android.dialer.storage.Unencrypted;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
@@ -51,7 +52,7 @@ import javax.inject.Inject;
* <p>New UI application components should use this class instead of reading flags directly from the
* {@link ConfigProvider}.
*/
-public final class CallLogConfig {
+public final class CallLogConfigImpl implements CallLogConfig {
private static final String NEW_CALL_LOG_FRAGMENT_ENABLED_PREF_KEY = "newCallLogFragmentEnabled";
private static final String NEW_VOICEMAIL_FRAGMENT_ENABLED_PREF_KEY =
@@ -60,33 +61,27 @@ public final class CallLogConfig {
private static final String NEW_CALL_LOG_FRAMEWORK_ENABLED_PREF_KEY =
"newCallLogFrameworkEnabled";
+ private final Context appContext;
private final CallLogFramework callLogFramework;
private final SharedPreferences sharedPreferences;
private final ConfigProvider configProvider;
- private final AnnotatedCallLogMigrator annotatedCallLogMigrator;
private final ListeningExecutorService backgroundExecutor;
- private final ListeningExecutorService lightweightExecutor;
@Inject
- public CallLogConfig(
+ public CallLogConfigImpl(
+ @ApplicationContext Context appContext,
CallLogFramework callLogFramework,
@Unencrypted SharedPreferences sharedPreferences,
ConfigProvider configProvider,
- AnnotatedCallLogMigrator annotatedCallLogMigrator,
- @BackgroundExecutor ListeningExecutorService backgroundExecutor,
- @LightweightExecutor ListeningExecutorService lightweightExecutor) {
+ @BackgroundExecutor ListeningExecutorService backgroundExecutor) {
+ this.appContext = appContext;
this.callLogFramework = callLogFramework;
this.sharedPreferences = sharedPreferences;
this.configProvider = configProvider;
- this.annotatedCallLogMigrator = annotatedCallLogMigrator;
this.backgroundExecutor = backgroundExecutor;
- this.lightweightExecutor = lightweightExecutor;
}
- /**
- * Updates the config values. This may kick off a lot of work so should be done infrequently, for
- * example by a scheduled job or broadcast receiver which rarely fires.
- */
+ @Override
public ListenableFuture<Void> update() {
boolean newCallLogFragmentEnabledInConfigProvider =
configProvider.getBoolean("new_call_log_fragment_enabled", false);
@@ -102,7 +97,7 @@ public final class CallLogConfig {
if (callLogFrameworkShouldBeEnabled && !isCallLogFrameworkEnabled) {
return Futures.transform(
- enableFramework(),
+ callLogFramework.enable(),
unused -> {
// Reflect the flag changes only after the framework is enabled.
sharedPreferences
@@ -134,7 +129,9 @@ public final class CallLogConfig {
return null;
});
return Futures.transformAsync(
- writeSharedPrefsFuture, unused -> disableFramework(), MoreExecutors.directExecutor());
+ writeSharedPrefsFuture,
+ unused -> callLogFramework.disable(),
+ MoreExecutors.directExecutor());
} else {
// We didn't need to enable/disable the framework, but we still need to update the
// individual flags.
@@ -155,35 +152,17 @@ public final class CallLogConfig {
}
}
- private ListenableFuture<Void> enableFramework() {
- ListenableFuture<Void> registerObserversFuture =
- lightweightExecutor.submit(
- () -> {
- callLogFramework.registerContentObservers();
- return null;
- });
- ListenableFuture<Void> migratorFuture = annotatedCallLogMigrator.migrate();
- return Futures.transform(
- Futures.allAsList(registerObserversFuture, migratorFuture),
- unused -> null,
- MoreExecutors.directExecutor());
- }
-
- private ListenableFuture<Void> disableFramework() {
- return Futures.transform(
- Futures.allAsList(callLogFramework.disable(), annotatedCallLogMigrator.clearData()),
- unused -> null,
- MoreExecutors.directExecutor());
- }
-
+ @Override
public boolean isNewCallLogFragmentEnabled() {
return sharedPreferences.getBoolean(NEW_CALL_LOG_FRAGMENT_ENABLED_PREF_KEY, false);
}
+ @Override
public boolean isNewVoicemailFragmentEnabled() {
return sharedPreferences.getBoolean(NEW_VOICEMAIL_FRAGMENT_ENABLED_PREF_KEY, false);
}
+ @Override
public boolean isNewPeerEnabled() {
return sharedPreferences.getBoolean(NEW_PEER_ENABLED_PREF_KEY, false);
}
@@ -192,11 +171,13 @@ public final class CallLogConfig {
* Returns true if the new call log framework is enabled, meaning that content observers are
* firing and PhoneLookupHistory is being populated, etc.
*/
+ @Override
public boolean isCallLogFrameworkEnabled() {
return sharedPreferences.getBoolean(NEW_CALL_LOG_FRAMEWORK_ENABLED_PREF_KEY, false);
}
- static void schedulePollingJob(Context appContext) {
+ @Override
+ public void schedulePollingJob() {
if (UserManagerCompat.isUserUnlocked(appContext)) {
JobScheduler jobScheduler = Assert.isNotNull(appContext.getSystemService(JobScheduler.class));
@SuppressLint("MissingPermission") // Dialer has RECEIVE_BOOT permission
@@ -209,7 +190,7 @@ public final class CallLogConfig {
.setRequiresCharging(true)
.setRequiresDeviceIdle(true)
.build();
- LogUtil.i("CallLogConfig.schedulePollingJob", "scheduling");
+ LogUtil.i("CallLogConfigImpl.schedulePollingJob", "scheduling");
jobScheduler.schedule(jobInfo);
}
}
@@ -226,7 +207,7 @@ public final class CallLogConfig {
public boolean onStartJob(JobParameters params) {
LogUtil.enterBlock("PollingJob.onStartJob");
Futures.addCallback(
- CallLogComponent.get(getApplicationContext()).callLogConfig().update(),
+ CallLogConfigComponent.get(getApplicationContext()).callLogConfig().update(),
new FutureCallback<Void>() {
@Override
public void onSuccess(Void unused) {
diff --git a/java/com/android/dialer/main/impl/MainModule.java b/java/com/android/dialer/calllog/config/CallLogConfigModule.java
index 90342cf59..d982e2bd8 100644
--- a/java/com/android/dialer/main/impl/MainModule.java
+++ b/java/com/android/dialer/calllog/config/CallLogConfigModule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,17 +14,14 @@
* limitations under the License
*/
-package com.android.dialer.main.impl;
+package com.android.dialer.calllog.config;
-import com.android.dialer.main.Main;
+import dagger.Binds;
import dagger.Module;
-import dagger.Provides;
-/** This module provides an instance of {@link Main}. */
+/** Binds {@link CallLogConfigImpl}. */
@Module
-public final class MainModule {
- @Provides
- public static Main provideMain() {
- return new MainImpl();
- }
+public abstract class CallLogConfigModule {
+ @Binds
+ abstract CallLogConfig to(CallLogConfigImpl impl);
}
diff --git a/java/com/android/dialer/commandline/impl/CallCommand.java b/java/com/android/dialer/commandline/impl/CallCommand.java
index a6d78f4de..b3ea8601f 100644
--- a/java/com/android/dialer/commandline/impl/CallCommand.java
+++ b/java/com/android/dialer/commandline/impl/CallCommand.java
@@ -53,7 +53,10 @@ public class CallCommand implements Command {
@NonNull
@Override
public String getUsage() {
- return "call number\n\nuse 'voicemail' to call voicemail";
+ return "call [flags --] number\n"
+ + "\nuse 'voicemail' to call voicemail"
+ + "\n\nflags:"
+ + "\n--direct send intent to telecom instead of pre call";
}
@Override
@@ -73,11 +76,16 @@ public class CallCommand implements Command {
} else {
callIntentBuilder = new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD);
}
-
- Intent intent = PreCall.getIntent(appContext, callIntentBuilder);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- appContext.startActivity(intent);
-
+ if (args.getBoolean("direct", false)) {
+ Intent intent = callIntentBuilder.build();
+ appContext
+ .getSystemService(TelecomManager.class)
+ .placeCall(intent.getData(), intent.getExtras());
+ } else {
+ Intent intent = PreCall.getIntent(appContext, callIntentBuilder);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ appContext.startActivity(intent);
+ }
return Futures.immediateFuture("Calling " + number);
}
}
diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java
index 833b91f59..6f8d677e8 100644
--- a/java/com/android/dialer/dialpadview/DialpadFragment.java
+++ b/java/com/android/dialer/dialpadview/DialpadFragment.java
@@ -16,6 +16,7 @@
package com.android.dialer.dialpadview;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -34,6 +35,8 @@ import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.net.Uri;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Trace;
import android.provider.Contacts.People;
@@ -48,6 +51,7 @@ import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.text.Editable;
import android.text.Selection;
@@ -75,6 +79,7 @@ import android.widget.TextView;
import com.android.contacts.common.dialog.CallSubjectDialog;
import com.android.contacts.common.util.StopWatch;
import com.android.dialer.animation.AnimUtils;
+import com.android.dialer.animation.AnimUtils.AnimationCallback;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.common.Assert;
@@ -141,7 +146,18 @@ public class DialpadFragment extends Fragment
private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent";
private static final String PREF_IS_DIALPAD_SLIDE_OUT = "pref_is_dialpad_slide_out";
+ /**
+ * Hidden key in carrier config to determine if no emergency call over wifi warning is required.
+ *
+ * <p>"Time delay (in ms) after which we show the notification for emergency calls, while the
+ * device is registered over WFC. Default value is -1, which indicates that this notification is
+ * not pertinent for a particular carrier. We've added a delay to prevent false positives."
+ */
+ @VisibleForTesting
+ static final String KEY_EMERGENCY_NOTIFICATION_DELAY_INT = "emergency_notification_delay_int";
+
private static Optional<String> currentCountryIsoForTesting = Optional.absent();
+ private static Boolean showEmergencyCallWarningForTest = null;
private final Object toneGeneratorLock = new Object();
/** Set of dialpad keys that are currently being pressed */
@@ -303,6 +319,7 @@ public class DialpadFragment extends Fragment
activity.invalidateOptionsMenu();
updateMenuOverflowButton(wasEmptyBeforeTextChange);
}
+ updateDialpadHint();
}
// DTMF Tones do not need to be played here any longer -
@@ -439,6 +456,73 @@ public class DialpadFragment extends Fragment
return fragmentView;
}
+ /**
+ * The dialpad hint is a TextView overlaid above the digit EditText. {@link EditText#setHint(int)}
+ * is not used because the digits has auto resize and makes setting the size of the hint
+ * difficult.
+ */
+ private void updateDialpadHint() {
+ TextView hint = dialpadView.getDigitsHint();
+ if (!TextUtils.isEmpty(digits.getText())) {
+ hint.setVisibility(View.GONE);
+ return;
+ }
+
+ if (shouldShowEmergencyCallWarning(getContext())) {
+ hint.setText(getContext().getString(R.string.dialpad_hint_emergency_calling_not_available));
+ hint.setVisibility(View.VISIBLE);
+ return;
+ }
+ hint.setVisibility(View.GONE);
+ }
+
+ /**
+ * Only show the "emergency call not available" warning when on wifi call and carrier requires it.
+ *
+ * <p>internal method tested because the conditions cannot be setup in espresso, and the layout
+ * cannot be inflated in robolectric.
+ */
+ @SuppressWarnings("missingPermission")
+ @TargetApi(VERSION_CODES.O)
+ @VisibleForTesting
+ static boolean shouldShowEmergencyCallWarning(Context context) {
+ if (showEmergencyCallWarningForTest != null) {
+ return showEmergencyCallWarningForTest;
+ }
+ if (VERSION.SDK_INT < VERSION_CODES.O) {
+ return false;
+ }
+ if (!PermissionsUtil.hasReadPhoneStatePermissions(context)) {
+ return false;
+ }
+ TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+ // A delay of -1 means wifi emergency call is available/the warning is not required.
+ if (telephonyManager.getCarrierConfig().getInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1)
+ == -1) {
+ return false;
+ }
+
+ // TelephonyManager.getVoiceNetworkType() Doesn't always return NETWORK_TYPE_IWLAN when on wifi.
+ // other wifi calling checks are hidden API. Emergency calling is not available without service
+ // regardless of the wifi state so this check is omitted.
+
+ switch (telephonyManager.getServiceState().getState()) {
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ case ServiceState.STATE_POWER_OFF:
+ return true;
+ case ServiceState.STATE_EMERGENCY_ONLY:
+ case ServiceState.STATE_IN_SERVICE:
+ return false;
+ default:
+ throw new AssertionError("unknown state " + telephonyManager.getServiceState().getState());
+ }
+ }
+
+ @VisibleForTesting
+ static void setShowEmergencyCallWarningForTest(Boolean value) {
+ showEmergencyCallWarningForTest = value;
+ }
+
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -732,6 +816,8 @@ public class DialpadFragment extends Fragment
overflowMenuButton.setOnClickListener(this);
overflowMenuButton.setVisibility(isDigitsEmpty() ? View.INVISIBLE : View.VISIBLE);
+ updateDialpadHint();
+
if (firstLaunch) {
// The onHiddenChanged callback does not get called the first time the fragment is
// attached, so call it ourselves here.
@@ -1392,7 +1478,16 @@ public class DialpadFragment extends Fragment
if (transitionIn) {
AnimUtils.fadeIn(overflowMenuButton, AnimUtils.DEFAULT_DURATION);
} else {
- AnimUtils.fadeOut(overflowMenuButton, AnimUtils.DEFAULT_DURATION);
+ AnimUtils.fadeOut(
+ overflowMenuButton,
+ AnimUtils.DEFAULT_DURATION,
+ new AnimationCallback() {
+ @Override
+ public void onAnimationEnd() {
+ // AnimUtils will set the visibility to GONE and cause the layout to move around.
+ overflowMenuButton.setVisibility(View.INVISIBLE);
+ }
+ });
}
}
diff --git a/java/com/android/dialer/dialpadview/DialpadView.java b/java/com/android/dialer/dialpadview/DialpadView.java
index 58ba233bd..1bd8bad4f 100644
--- a/java/com/android/dialer/dialpadview/DialpadView.java
+++ b/java/com/android/dialer/dialpadview/DialpadView.java
@@ -82,6 +82,7 @@ public class DialpadView extends LinearLayout {
private final int translateDistance;
private EditText digits;
+ private TextView digitsHint;
private ImageButton delete;
private View overflowMenuButton;
private ViewGroup rateContainer;
@@ -134,6 +135,7 @@ public class DialpadView extends LinearLayout {
setupKeypad();
digits = (EditText) findViewById(R.id.digits);
+ digitsHint = findViewById(R.id.digits_hint);
delete = (ImageButton) findViewById(R.id.deleteButton);
overflowMenuButton = findViewById(R.id.dialpad_overflow);
rateContainer = (ViewGroup) findViewById(R.id.rate_container);
@@ -311,6 +313,10 @@ public class DialpadView extends LinearLayout {
return digits;
}
+ public TextView getDigitsHint() {
+ return digitsHint;
+ }
+
public ImageButton getDeleteButton() {
return delete;
}
diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml
index 13c11f1ce..69d23a9b6 100644
--- a/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml
+++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml
@@ -13,9 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<view xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.dialer.dialpadview.DialpadView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialpad_view"
- class="com.android.dialer.dialpadview.DialpadView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
@@ -100,29 +99,39 @@
android:tint="?attr/dialpad_icon_tint"
android:tintMode="src_in"
android:visibility="gone"/>
-
- <view xmlns:ex="http://schemas.android.com/apk/res-auto"
- android:id="@+id/digits"
- class="com.android.dialer.dialpadview.DigitsEditText"
- android:textStyle="normal"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="@android:color/transparent"
- android:cursorVisible="false"
- android:focusableInTouchMode="true"
- android:fontFamily="sans-serif"
- android:freezesText="true"
- android:gravity="center"
- android:importantForAutofill="no"
- android:maxLines="1"
- android:scrollHorizontally="true"
- android:singleLine="true"
- android:textColor="?attr/dialpad_text_color"
- android:textCursorDrawable="@null"
- android:textSize="?attr/dialpad_digits_adjustable_text_size"
- ex:resizing_text_min_size="@dimen/dialpad_digits_text_min_size"/>
-
+ <FrameLayout android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1">
+ <TextView android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/digits_hint"
+ android:focusable="false"
+ android:gravity="center"
+ android:textSize="14sp"
+ android:textColor="@color/secondary_text_color"
+ android:visibility="gone"
+ />
+ <com.android.dialer.dialpadview.DigitsEditText
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/digits"
+ android:textStyle="normal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/transparent"
+ android:cursorVisible="false"
+ android:focusableInTouchMode="true"
+ android:fontFamily="sans-serif"
+ android:freezesText="true"
+ android:gravity="center"
+ android:importantForAutofill="no"
+ android:maxLines="1"
+ android:scrollHorizontally="true"
+ android:singleLine="true"
+ android:textColor="?attr/dialpad_text_color"
+ android:textCursorDrawable="@null"
+ android:textSize="?attr/dialpad_digits_adjustable_text_size"
+ ex:resizing_text_min_size="@dimen/dialpad_digits_text_min_size"/>
+ </FrameLayout>
<ImageButton
android:id="@+id/deleteButton"
android:layout_width="wrap_content"
@@ -152,4 +161,4 @@
android:layout_width="match_parent"
android:layout_height="@dimen/dialpad_space_below_keys"/>
-</view>
+</com.android.dialer.dialpadview.DialpadView>
diff --git a/java/com/android/dialer/dialpadview/res/values/strings.xml b/java/com/android/dialer/dialpadview/res/values/strings.xml
index 51367b644..5d8d8e6a5 100644
--- a/java/com/android/dialer/dialpadview/res/values/strings.xml
+++ b/java/com/android/dialer/dialpadview/res/values/strings.xml
@@ -97,7 +97,11 @@
Ignored if empty. -->
<string name="config_prohibited_phone_number_regexp" translatable="false"></string>
+ <!-- Warning hint shown in the dialpad input field when emergency call (911, etc.) cannot be made.
+ [CHAR_LIMIT=60] -->
+ <string name="dialpad_hint_emergency_calling_not_available">Emergency calling not available</string>
+
<!-- Dialog message which is shown when the user tries to make a phone call
to prohibited phone numbers [CHAR LIMIT=NONE] -->
- <string msgid="4313552620858880999" name="dialog_phone_call_prohibited_message">Can\'t call this number</string>
+ <string name="dialog_phone_call_prohibited_message" msgid="4313552620858880999">Can\'t call this number</string>
</resources>
diff --git a/java/com/android/dialer/main/Main.java b/java/com/android/dialer/main/Main.java
deleted file mode 100644
index e7295f199..000000000
--- a/java/com/android/dialer/main/Main.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.main;
-
-import android.content.Context;
-
-/** Used to display the main activity for Dialer. This hosts favorites, dial pad, search, etc... */
-public interface Main {
-
- boolean isNewUiEnabled(Context context);
-
- // TODO(38502365): Remove this when we're ready to launch the new UI. */
- void createNewUiLauncherShortcut(Context context);
-
- void disableComponentForTesting(Context context);
-}
diff --git a/java/com/android/dialer/main/impl/AndroidManifest.xml b/java/com/android/dialer/main/impl/AndroidManifest.xml
index b3d916bee..4608e4299 100644
--- a/java/com/android/dialer/main/impl/AndroidManifest.xml
+++ b/java/com/android/dialer/main/impl/AndroidManifest.xml
@@ -22,8 +22,6 @@
<activity
android:clearTaskOnLaunch="true"
android:directBootAware="true"
- android:exported="true"
- android:icon="@drawable/nui_launcher_icon"
android:label="@string/main_activity_label"
android:launchMode="singleTask"
android:name="com.android.dialer.main.impl.MainActivity"
@@ -31,79 +29,9 @@
android:theme="@style/NuiActivityTheme"
android:windowSoftInputMode="stateAlwaysHidden|adjustNothing">
-
- <intent-filter>
- <action android:name="android.intent.action.DIAL"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
-
- <data android:mimeType="vnd.android.cursor.item/phone"/>
- <data android:mimeType="vnd.android.cursor.item/person"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.DIAL"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
-
- <data android:scheme="voicemail"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.DIAL"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- <category android:name="android.intent.category.BROWSABLE"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.VIEW"/>
- <action android:name="android.intent.action.DIAL"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
-
- <data android:scheme="tel"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.VIEW"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
-
- <data android:mimeType="vnd.android.cursor.dir/calls"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.CALL_BUTTON"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
- </intent-filter>
- <!-- This was never intended to be public, but is here for backward
- compatibility. Use Intent.ACTION_DIAL instead. -->
- <intent-filter>
- <action android:name="com.android.phone.action.TOUCH_DIALER"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.TAB"/>
- </intent-filter>
- <intent-filter android:label="@string/main_call_history_tab_description">
- <action android:name="com.android.phone.action.RECENT_CALLS"/>
-
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.TAB"/>
- </intent-filter>
-
-
<meta-data
android:name="com.android.keyguard.layout"
android:resource="@layout/keyguard_preview"/>
</activity>
-
</application>
-
</manifest>
diff --git a/java/com/android/dialer/main/impl/MainImpl.java b/java/com/android/dialer/main/impl/MainImpl.java
deleted file mode 100644
index 717350e5f..000000000
--- a/java/com/android/dialer/main/impl/MainImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2017 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.main.impl;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.main.Main;
-import javax.inject.Inject;
-
-/** The entry point for the main feature. */
-final class MainImpl implements Main {
-
- @Inject
- MainImpl() {}
-
- @Override
- public boolean isNewUiEnabled(Context context) {
- return ConfigProviderBindings.get(context).getBoolean("is_nui_shortcut_enabled", false);
- }
-
- @Override
- public void createNewUiLauncherShortcut(Context context) {
- enableComponent(context);
- }
-
- /**
- * Enables the NUI activity component. By default the component is disabled and can't be accessed.
- * Once the component has been enabled the user will get an option to use the new UI to handle
- * DIAL (and other) intents.
- */
- private static void enableComponent(Context context) {
- context
- .getPackageManager()
- .setComponentEnabledSetting(
- new ComponentName(context, MainActivity.class),
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP);
- }
-
- @Override
- public void disableComponentForTesting(Context context) {
- context
- .getPackageManager()
- .setComponentEnabledSetting(
- new ComponentName(context, MainActivity.class),
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- }
-}
diff --git a/java/com/android/dialer/precall/impl/CallingAccountSelector.java b/java/com/android/dialer/precall/impl/CallingAccountSelector.java
index b7f071d58..a5dc6a097 100644
--- a/java/com/android/dialer/precall/impl/CallingAccountSelector.java
+++ b/java/com/android/dialer/precall/impl/CallingAccountSelector.java
@@ -159,6 +159,11 @@ public class CallingAccountSelector implements PreCallAction {
LogUtil.i(
"CallingAccountSelector.processPreferredAccount", "Auto selected suggestion");
builder.setPhoneAccountHandle(result.getSuggestion().get().phoneAccountHandle);
+ builder
+ .getOutgoingCallExtras()
+ .putString(
+ SuggestionProvider.EXTRA_SIM_SUGGESTION_REASON,
+ result.getSuggestion().get().reason.name());
pendingAction.finish();
return;
}
diff --git a/java/com/android/dialer/precall/impl/MalformedNumberRectifier.java b/java/com/android/dialer/precall/impl/MalformedNumberRectifier.java
new file mode 100644
index 000000000..2e414632b
--- /dev/null
+++ b/java/com/android/dialer/precall/impl/MalformedNumberRectifier.java
@@ -0,0 +1,77 @@
+/*
+ * 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.precall.impl;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.annotation.MainThread;
+import android.telecom.PhoneAccount;
+import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.precall.PreCallAction;
+import com.android.dialer.precall.PreCallCoordinator;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Fix common malformed number before it is dialed. Rewrite the number to the first handler that can
+ * handle it
+ */
+public class MalformedNumberRectifier implements PreCallAction {
+
+ /** Handler for individual rules. */
+ public interface MalformedNumberHandler {
+
+ /** @return the number to be corrected to. */
+ @MainThread
+ Optional<String> handle(Context context, String number);
+ }
+
+ private final ImmutableList<MalformedNumberHandler> handlers;
+
+ MalformedNumberRectifier(ImmutableList<MalformedNumberHandler> handlers) {
+ this.handlers = handlers;
+ }
+
+ @Override
+ public boolean requiresUi(Context context, CallIntentBuilder builder) {
+ return false;
+ }
+
+ @Override
+ public void runWithoutUi(Context context, CallIntentBuilder builder) {
+ if (!PhoneAccount.SCHEME_TEL.equals(builder.getUri().getScheme())) {
+ return;
+ }
+ String number = builder.getUri().getSchemeSpecificPart();
+
+ for (MalformedNumberHandler handler : handlers) {
+ Optional<String> result = handler.handle(context, number);
+ if (result.isPresent()) {
+ builder.setUri(Uri.fromParts(PhoneAccount.SCHEME_TEL, result.get(), null));
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void runWithUi(PreCallCoordinator coordinator) {
+ runWithoutUi(coordinator.getActivity(), coordinator.getBuilder());
+ }
+
+ @Override
+ public void onDiscard() {}
+}
diff --git a/java/com/android/dialer/precall/impl/PreCallImpl.java b/java/com/android/dialer/precall/impl/PreCallImpl.java
index f75c8d9ec..bd23f9ece 100644
--- a/java/com/android/dialer/precall/impl/PreCallImpl.java
+++ b/java/com/android/dialer/precall/impl/PreCallImpl.java
@@ -39,7 +39,11 @@ public class PreCallImpl implements PreCall {
@Override
public ImmutableList<PreCallAction> getActions() {
return ImmutableList.of(
- new PermissionCheckAction(), new CallingAccountSelector(), new AssistedDialAction());
+ new PermissionCheckAction(),
+ new MalformedNumberRectifier(
+ ImmutableList.of(new UkRegionPrefixInInternationalFormatHandler())),
+ new CallingAccountSelector(),
+ new AssistedDialAction());
}
@NonNull
diff --git a/java/com/android/dialer/precall/impl/UkRegionPrefixInInternationalFormatHandler.java b/java/com/android/dialer/precall/impl/UkRegionPrefixInInternationalFormatHandler.java
new file mode 100644
index 000000000..b8f54d873
--- /dev/null
+++ b/java/com/android/dialer/precall/impl/UkRegionPrefixInInternationalFormatHandler.java
@@ -0,0 +1,69 @@
+/*
+ * 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.precall.impl;
+
+import android.content.Context;
+import android.telephony.PhoneNumberUtils;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.configprovider.ConfigProviderBindings;
+import com.android.dialer.precall.impl.MalformedNumberRectifier.MalformedNumberHandler;
+import com.google.common.base.Optional;
+
+/**
+ * It is customary in UK to present numbers as "+44 (0) xx xxxx xxxx". This is actually a amalgam of
+ * international (+44 xx xxxx xxxx) and regional (0xx xxxx xxxx) format, and is in fact invalid. It
+ * might be rejected depending on the carrier.
+ *
+ * <p>This class removes the "0" region code prefix if the first dialable digits are "+440". UK
+ * short codes and region codes in international format will never start with a 0.
+ */
+class UkRegionPrefixInInternationalFormatHandler implements MalformedNumberHandler {
+
+ private static final String MALFORMED_PREFIX = "+440";
+
+ @Override
+ public Optional<String> handle(Context context, String number) {
+ if (!ConfigProviderBindings.get(context)
+ .getBoolean("uk_region_prefix_in_international_format_fix_enabled", true)) {
+ return Optional.absent();
+ }
+ if (!PhoneNumberUtils.normalizeNumber(number).startsWith(MALFORMED_PREFIX)) {
+ return Optional.absent();
+ }
+ LogUtil.i("UkRegionPrefixInInternationalFormatHandler.handle", "removing (0) in UK numbers");
+
+ // libPhoneNumber is not used because we want to keep post dial digits, and this is on the main
+ // thread.
+ String convertedNumber = PhoneNumberUtils.convertKeypadLettersToDigits(number);
+ StringBuilder result = new StringBuilder();
+ int prefixPosition = 0;
+ for (int i = 0; i < convertedNumber.length(); i++) {
+ char c = convertedNumber.charAt(i);
+ if (c != MALFORMED_PREFIX.charAt(prefixPosition)) {
+ result.append(c);
+ continue;
+ }
+ prefixPosition++;
+ if (prefixPosition == MALFORMED_PREFIX.length()) {
+ result.append(convertedNumber.substring(i + 1));
+ break;
+ }
+ result.append(c);
+ }
+ return Optional.of(result.toString());
+ }
+}
diff --git a/java/com/android/dialer/preferredsim/PreferredAccountWorker.java b/java/com/android/dialer/preferredsim/PreferredAccountWorker.java
index aa617889e..df743c342 100644
--- a/java/com/android/dialer/preferredsim/PreferredAccountWorker.java
+++ b/java/com/android/dialer/preferredsim/PreferredAccountWorker.java
@@ -34,6 +34,7 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.telecom.PhoneAccountHandle;
+import android.text.TextUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.DialerExecutor.Worker;
@@ -128,6 +129,9 @@ public class PreferredAccountWorker implements Worker<Context, Result> {
private static Optional<String> getDataId(
@NonNull Context context, @Nullable String phoneNumber) {
Assert.isWorkerThread();
+ if (TextUtils.isEmpty(phoneNumber)) {
+ return Optional.absent();
+ }
try (Cursor cursor =
context
.getContentResolver()
diff --git a/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java b/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java
index cfa37c883..f710f734c 100644
--- a/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java
+++ b/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java
@@ -30,6 +30,8 @@ import java.util.List;
/** Provides hints to the user when selecting a SIM to make a call. */
public interface SuggestionProvider {
+ String EXTRA_SIM_SUGGESTION_REASON = "sim_suggestion_reason";
+
/** The reason the suggestion is made. */
enum Reason {
UNKNOWN,
diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java
index 8eb07c579..49f819bab 100644
--- a/java/com/android/incallui/CallCardPresenter.java
+++ b/java/com/android/incallui/CallCardPresenter.java
@@ -54,6 +54,7 @@ import com.android.dialer.multimedia.MultimediaData;
import com.android.dialer.oem.MotorolaUtils;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.android.dialer.postcall.PostCall;
+import com.android.dialer.preferredsim.suggestion.SuggestionProvider;
import com.android.incallui.ContactInfoCache.ContactCacheEntry;
import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
import com.android.incallui.InCallPresenter.InCallDetailsListener;
@@ -478,6 +479,7 @@ public class CallCardPresenter
.setSessionModificationState(primary.getVideoTech().getSessionModificationState())
.setDisconnectCause(primary.getDisconnectCause())
.setConnectionLabel(getConnectionLabel())
+ .setSimSuggestionReason(getSimSuggestionReason())
.setConnectionIcon(getCallStateIcon())
.setGatewayNumber(getGatewayNumber())
.setCallSubject(shouldShowCallSubject(primary) ? primary.getCallSubject() : null)
@@ -988,6 +990,21 @@ public class CallCardPresenter
return primary.getCallProviderLabel();
}
+ @Nullable
+ private SuggestionProvider.Reason getSimSuggestionReason() {
+ String value =
+ primary.getIntentExtras().getString(SuggestionProvider.EXTRA_SIM_SUGGESTION_REASON);
+ if (value == null) {
+ return null;
+ }
+ try {
+ return SuggestionProvider.Reason.valueOf(value);
+ } catch (IllegalArgumentException e) {
+ LogUtil.e("CallCardPresenter.getConnectionLabel", "unknown reason " + value);
+ return null;
+ }
+ }
+
private Drawable getCallStateIcon() {
// Return connection icon if one exists.
StatusHints statusHints = primary.getStatusHints();
diff --git a/java/com/android/incallui/PhoneLookupHistoryRecorder.java b/java/com/android/incallui/PhoneLookupHistoryRecorder.java
index 16d73ced9..2b8075878 100644
--- a/java/com/android/incallui/PhoneLookupHistoryRecorder.java
+++ b/java/com/android/incallui/PhoneLookupHistoryRecorder.java
@@ -20,10 +20,10 @@ import android.content.Context;
import android.support.annotation.Nullable;
import android.telecom.Call;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.calllog.config.CallLogConfigComponent;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
-import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.location.GeoUtil;
import com.android.dialer.phonelookup.PhoneLookupComponent;
import com.android.dialer.phonelookup.PhoneLookupInfo;
@@ -45,11 +45,11 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
final class PhoneLookupHistoryRecorder {
/**
- * If the new UI is enabled, fetches the current {@link PhoneLookupInfo} for the provided call and
- * writes it to the PhoneLookupHistory. Otherwise does nothing.
+ * If the call log framework is enabled, fetches the current {@link PhoneLookupInfo} for the
+ * provided call and writes it to the PhoneLookupHistory. Otherwise does nothing.
*/
static void recordPhoneLookupInfo(Context appContext, Call call) {
- if (!(ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false))) {
+ if (!CallLogConfigComponent.get(appContext).callLogConfig().isCallLogFrameworkEnabled()) {
return;
}
diff --git a/java/com/android/incallui/contactgrid/ContactGridManager.java b/java/com/android/incallui/contactgrid/ContactGridManager.java
index 327eaf2b8..d8b1f5004 100644
--- a/java/com/android/incallui/contactgrid/ContactGridManager.java
+++ b/java/com/android/incallui/contactgrid/ContactGridManager.java
@@ -244,6 +244,10 @@ public class ContactGridManager {
statusTextView.setText(info.label);
statusTextView.setVisibility(View.VISIBLE);
statusTextView.setSingleLine(info.labelIsSingleLine);
+ // Required to start the marquee
+ // This will send a AccessibilityEvent.TYPE_VIEW_SELECTED, but has no observable effect on
+ // talkback.
+ statusTextView.setSelected(true);
}
if (info.icon == null) {
diff --git a/java/com/android/incallui/contactgrid/TopRow.java b/java/com/android/incallui/contactgrid/TopRow.java
index f551092d4..89300caa8 100644
--- a/java/com/android/incallui/contactgrid/TopRow.java
+++ b/java/com/android/incallui/contactgrid/TopRow.java
@@ -166,7 +166,22 @@ public class TopRow {
private static CharSequence getLabelForDialing(Context context, PrimaryCallState state) {
if (!TextUtils.isEmpty(state.connectionLabel()) && !state.isWifi()) {
- return context.getString(R.string.incall_calling_via_template, state.connectionLabel());
+ CharSequence label = getCallingViaLabel(context, state);
+
+ if (state.isAssistedDialed() && state.assistedDialingExtras() != null) {
+ LogUtil.i("TopRow.getLabelForDialing", "using assisted dialing with via label.");
+ String countryCode =
+ String.valueOf(state.assistedDialingExtras().transformedNumberCountryCallingCode());
+ label =
+ TextUtils.concat(
+ label,
+ " • ",
+ context.getString(
+ R.string.incall_connecting_assited_dialed_component,
+ countryCode,
+ state.assistedDialingExtras().userHomeCountryCode()));
+ }
+ return label;
} else {
if (state.isVideoCall()) {
if (state.isWifi()) {
@@ -189,6 +204,22 @@ public class TopRow {
}
}
+ private static CharSequence getCallingViaLabel(Context context, PrimaryCallState state) {
+ if (state.simSuggestionReason() != null) {
+ switch (state.simSuggestionReason()) {
+ case FREQUENT:
+ return context.getString(
+ R.string.incall_calling_on_recent_choice_template, state.connectionLabel());
+ case INTRA_CARRIER:
+ return context.getString(
+ R.string.incall_calling_on_same_carrier_template, state.connectionLabel());
+ default:
+ break;
+ }
+ }
+ return context.getString(R.string.incall_calling_via_template, state.connectionLabel());
+ }
+
private static CharSequence getConnectionLabel(PrimaryCallState state) {
if (!TextUtils.isEmpty(state.connectionLabel())
&& (isAccount(state) || state.isWifi() || state.isConference())) {
diff --git a/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_top_row.xml b/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_top_row.xml
index 42066f286..2f9ca3ea8 100644
--- a/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_top_row.xml
+++ b/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_top_row.xml
@@ -40,6 +40,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
+ android:ellipsize="marquee"
+ android:scrollHorizontally="true"
android:textAppearance="@style/Dialer.Incall.TextAppearance"
tools:text="Captain Holt"/>
</LinearLayout>
diff --git a/java/com/android/incallui/contactgrid/res/values/strings.xml b/java/com/android/incallui/contactgrid/res/values/strings.xml
index c6bdb11ba..7c0f5a679 100644
--- a/java/com/android/incallui/contactgrid/res/values/strings.xml
+++ b/java/com/android/incallui/contactgrid/res/values/strings.xml
@@ -20,6 +20,14 @@
[CHAR LIMIT=40] -->
<string name="incall_calling_via_template">Calling via <xliff:g id="provider_name">%s</xliff:g></string>
+ <!-- Title displayed in the overlay for outgoing calls when the provider is automatically chosen
+ because it is the same provider the callee is using. [CHAR LIMIT=60] -->
+ <string name="incall_calling_on_same_carrier_template">Calling on same carrier <xliff:g id="provider_name">%s</xliff:g></string>
+
+ <!-- Title displayed in the overlay for outgoing calls when the provider is automatically chosen
+ because the user has selected it multiple times. [CHAR LIMIT=60] -->
+ <string name="incall_calling_on_recent_choice_template">Calling on recent choice <xliff:g id="provider_name">%s</xliff:g></string>
+
<!-- Displayed above the contact name during an outgoing phone call. Indicates that the call is
in the connecting stage. -->
<string name="incall_connecting">Calling…</string>
@@ -27,6 +35,9 @@
<!-- Display information related to assisted dialing, for example Calling using +1 (US)… -->
<string name="incall_connecting_assited_dialed">Calling using +<xliff:g example="1" id="ad_country_code">%1$s</xliff:g> (<xliff:g example="1" id="ad_user_home_locale">%2$s</xliff:g>)\u2026</string>
+ <!-- String appended to the outgoing call title for additional information related to assisted dialing, for example "Calling via <CARRIER> • Using +1 (US)… "-->
+ <string name="incall_connecting_assited_dialed_component">Using +<xliff:g example="1" id="ad_country_code">%1$s</xliff:g> (<xliff:g example="1" id="ad_user_home_locale">%2$s</xliff:g>)\u2026</string>
+
<!-- Displayed above the contact name when an external call is being pulled to the local
device. -->
<string name="incall_transferring">Transferring…</string>
diff --git a/java/com/android/incallui/incall/protocol/PrimaryCallState.java b/java/com/android/incallui/incall/protocol/PrimaryCallState.java
index 1d536e9b9..1d23036fc 100644
--- a/java/com/android/incallui/incall/protocol/PrimaryCallState.java
+++ b/java/com/android/incallui/incall/protocol/PrimaryCallState.java
@@ -23,6 +23,7 @@ import android.telecom.DisconnectCause;
import android.text.TextUtils;
import com.android.dialer.assisteddialing.TransformationInfo;
import com.android.dialer.common.Assert;
+import com.android.dialer.preferredsim.suggestion.SuggestionProvider;
import com.android.incallui.call.DialerCall;
import com.android.incallui.call.DialerCall.State;
import com.android.incallui.videotech.utils.SessionModificationState;
@@ -60,6 +61,9 @@ public abstract class PrimaryCallState {
public abstract String connectionLabel();
@Nullable
+ public abstract SuggestionProvider.Reason simSuggestionReason();
+
+ @Nullable
public abstract Drawable connectionIcon();
@Nullable
@@ -141,6 +145,8 @@ public abstract class PrimaryCallState {
public abstract Builder setConnectionLabel(String connectionLabel);
+ public abstract Builder setSimSuggestionReason(SuggestionProvider.Reason reason);
+
public abstract Builder setConnectionIcon(Drawable connectionIcon);
public abstract Builder setGatewayNumber(String gatewayNumber);
diff --git a/java/com/android/voicemail/impl/settings/VisualVoicemailSettingsUtil.java b/java/com/android/voicemail/impl/settings/VisualVoicemailSettingsUtil.java
index 3e006988e..e7248c40f 100644
--- a/java/com/android/voicemail/impl/settings/VisualVoicemailSettingsUtil.java
+++ b/java/com/android/voicemail/impl/settings/VisualVoicemailSettingsUtil.java
@@ -15,18 +15,22 @@
*/
package com.android.voicemail.impl.settings;
+import android.content.ContentValues;
import android.content.Context;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.provider.VoicemailContract.Voicemails;
import android.support.annotation.VisibleForTesting;
import android.telecom.PhoneAccountHandle;
import com.android.dialer.common.Assert;
import com.android.dialer.common.concurrent.DialerExecutor.Worker;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
+import com.android.dialer.common.database.Selection;
import com.android.voicemail.VoicemailComponent;
import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper;
import com.android.voicemail.impl.VisualVoicemailPreferences;
import com.android.voicemail.impl.VvmLog;
import com.android.voicemail.impl.sync.VvmAccountManager;
-import com.android.voicemail.impl.utils.VoicemailDatabaseUtil;
/** Save whether or not a particular account is enabled in shared to be retrieved later. */
public class VisualVoicemailSettingsUtil {
@@ -88,6 +92,28 @@ public class VisualVoicemailSettingsUtil {
.edit()
.putBoolean(TRANSCRIBE_VOICEMAILS_KEY, isEnabled)
.apply();
+
+ if (!isEnabled) {
+ VvmLog.i(
+ "VisualVoicemailSettingsUtil.setVoicemailTranscriptionEnabled",
+ "clear all Google transcribed voicemail.");
+ DialerExecutorComponent.get(context)
+ .dialerExecutorFactory()
+ .createNonUiTaskBuilder(new ClearGoogleTranscribedVoicemailTranscriptionWorker(context))
+ .onSuccess(
+ (result) ->
+ VvmLog.i(
+ "VisualVoicemailSettingsUtil.setVoicemailTranscriptionEnabled",
+ "voicemail transciptions cleared successfully"))
+ .onFailure(
+ (throwable) ->
+ VvmLog.e(
+ "VisualVoicemailSettingsUtil.setVoicemailTranscriptionEnabled",
+ "unable to clear Google transcribed voicemails",
+ throwable))
+ .build()
+ .executeParallel(null);
+ }
}
public static void setVoicemailDonationEnabled(
@@ -153,6 +179,7 @@ public class VisualVoicemailSettingsUtil {
return prefs.contains(IS_ENABLED_KEY);
}
+ /** Delete all the voicemails whose source_package field matches this package */
private static class VoicemailDeleteWorker implements Worker<Void, Void> {
private final Context context;
@@ -162,9 +189,53 @@ public class VisualVoicemailSettingsUtil {
@Override
public Void doInBackground(Void unused) {
- int deleted = VoicemailDatabaseUtil.deleteAll(context);
+ int deleted =
+ context
+ .getContentResolver()
+ .delete(Voicemails.buildSourceUri(context.getPackageName()), null, null);
+
VvmLog.i("VisualVoicemailSettingsUtil.doInBackground", "deleted " + deleted + " voicemails");
return null;
}
}
+
+ /**
+ * Clears all the voicemail transcripts in the call log whose source_package field matches this
+ * package
+ */
+ private static class ClearGoogleTranscribedVoicemailTranscriptionWorker
+ implements Worker<Void, Void> {
+ private final Context context;
+
+ ClearGoogleTranscribedVoicemailTranscriptionWorker(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Void doInBackground(Void unused) {
+
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Voicemails.TRANSCRIPTION, "");
+
+ Selection selection =
+ Selection.builder()
+ .and(Selection.column(CallLog.Calls.TYPE).is("=", Calls.VOICEMAIL_TYPE))
+ .and(Selection.column(Voicemails.SOURCE_PACKAGE).is("=", context.getPackageName()))
+ .build();
+
+ int cleared =
+ context
+ .getContentResolver()
+ .update(
+ Calls.CONTENT_URI_WITH_VOICEMAIL,
+ contentValues,
+ selection.getSelection(),
+ selection.getSelectionArgs());
+
+ VvmLog.i(
+ "VisualVoicemailSettingsUtil.doInBackground",
+ "cleared " + cleared + " voicemail transcription");
+ return null;
+ }
+ }
}
diff --git a/java/com/android/voicemail/impl/utils/VoicemailDatabaseUtil.java b/java/com/android/voicemail/impl/utils/VoicemailDatabaseUtil.java
index ef5447d32..711d6a8a4 100644
--- a/java/com/android/voicemail/impl/utils/VoicemailDatabaseUtil.java
+++ b/java/com/android/voicemail/impl/utils/VoicemailDatabaseUtil.java
@@ -57,16 +57,6 @@ public class VoicemailDatabaseUtil {
return voicemails.size();
}
- /**
- * Delete all the voicemails whose source_package field matches this package
- *
- * @return the number of voicemails deleted
- */
- public static int deleteAll(Context context) {
- ContentResolver contentResolver = context.getContentResolver();
- return contentResolver.delete(Voicemails.buildSourceUri(context.getPackageName()), null, null);
- }
-
/** Maps structured {@link Voicemail} to {@link ContentValues} in content provider. */
private static ContentValues getContentValues(Voicemail voicemail) {
ContentValues contentValues = new ContentValues();