From 6c480f796e82794001109e5d46260770af63a7ee Mon Sep 17 00:00:00 2001 From: linyuh Date: Mon, 2 Apr 2018 17:15:36 -0700 Subject: Support placing Duo calls in the new UI's bottom sheet. Bug: 70988685 Test: DuoCallModuleTest, PlaceDuoCallEndToEndTest, Manual testing PiperOrigin-RevId: 191372706 Change-Id: I439be71c361eaca722820b81278e5f95322e100c --- .../android/dialer/calllog/ui/menu/Modules.java | 12 +++- .../dialer/constants/ActivityRequestCodes.java | 6 +- .../android/dialer/duo/PlaceDuoCallNotifier.java | 45 ++++++++++++ .../android/dialer/duo/PlaceDuoCallReceiver.java | 77 +++++++++++++++++++++ .../dialer/historyitemactions/DuoCallModule.java | 80 ++++++++++++++++++++++ .../dialer/historyitemactions/IntentModule.java | 2 +- .../com/android/dialer/main/impl/MainActivity.java | 8 +++ 7 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 java/com/android/dialer/duo/PlaceDuoCallNotifier.java create mode 100644 java/com/android/dialer/duo/PlaceDuoCallReceiver.java create mode 100644 java/com/android/dialer/historyitemactions/DuoCallModule.java (limited to 'java/com/android') diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java index aeb69a7a8..e316f66b5 100644 --- a/java/com/android/dialer/calllog/ui/menu/Modules.java +++ b/java/com/android/dialer/calllog/ui/menu/Modules.java @@ -27,8 +27,10 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.calllog.model.CoalescedRow; import com.android.dialer.calllogutils.CallLogEntryText; import com.android.dialer.calllogutils.NumberAttributesConverter; +import com.android.dialer.duo.DuoConstants; import com.android.dialer.glidephotomanager.PhotoInfo; import com.android.dialer.historyitemactions.DividerModule; +import com.android.dialer.historyitemactions.DuoCallModule; import com.android.dialer.historyitemactions.HistoryItemActionModule; import com.android.dialer.historyitemactions.IntentModule; import com.android.dialer.historyitemactions.SharedModules; @@ -134,9 +136,15 @@ final class Modules { // Add a video item if (1) the call log entry is for a video call, and (2) the call is not spam. if ((row.getFeatures() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO && !row.getNumberAttributes().getIsSpam()) { + boolean isDuoCall = + DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME + .flattenToString() + .equals(row.getPhoneAccountComponentName()); modules.add( - IntentModule.newVideoCallModule( - context, normalizedNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG)); + isDuoCall + ? new DuoCallModule(context, normalizedNumber, CallInitiationType.Type.CALL_LOG) + : IntentModule.newCarrierVideoCallModule( + context, normalizedNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG)); } // TODO(zachh): Also show video option if the call log entry is for an audio call but video diff --git a/java/com/android/dialer/constants/ActivityRequestCodes.java b/java/com/android/dialer/constants/ActivityRequestCodes.java index 66c38fa64..7fd619ba9 100644 --- a/java/com/android/dialer/constants/ActivityRequestCodes.java +++ b/java/com/android/dialer/constants/ActivityRequestCodes.java @@ -16,8 +16,6 @@ package com.android.dialer.constants; -import com.android.dialer.duo.Duo; - /** * Class containing {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)} * request codes. @@ -32,7 +30,9 @@ public final class ActivityRequestCodes { /** Request code for {@link com.android.dialer.callcomposer.CallComposerActivity} intent. */ public static final int DIALTACTS_CALL_COMPOSER = 2; - /** Request code for {@link Duo#getIntent(android.content.Context, String)}. */ + /** + * Request code for {@link com.android.dialer.duo.Duo#getIntent(android.content.Context, String)}. + */ public static final int DIALTACTS_DUO = 3; /** Request code for {@link com.android.dialer.calldetails.OldCallDetailsActivity} intent. */ diff --git a/java/com/android/dialer/duo/PlaceDuoCallNotifier.java b/java/com/android/dialer/duo/PlaceDuoCallNotifier.java new file mode 100644 index 000000000..8fde981a0 --- /dev/null +++ b/java/com/android/dialer/duo/PlaceDuoCallNotifier.java @@ -0,0 +1,45 @@ +/* + * 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.duo; + +import android.content.Context; +import android.content.Intent; +import android.support.v4.content.LocalBroadcastManager; +import com.android.dialer.common.LogUtil; + +/** Notifies that a Duo video call should be started. */ +public final class PlaceDuoCallNotifier { + + private PlaceDuoCallNotifier() {} + + /** + * Broadcasts an intent notifying that a Duo call should be started. + * + *

See {@link PlaceDuoCallReceiver} for how the intent is handled. + * + * @param phoneNumber The number to start a Duo call. It can be of any format. + */ + public static void notify(Context context, String phoneNumber) { + LogUtil.enterBlock("PlaceDuoCallNotifier.notify"); + + Intent intent = new Intent(); + intent.setAction(PlaceDuoCallReceiver.ACTION_START_DUO_CALL); + intent.putExtra(PlaceDuoCallReceiver.EXTRA_PHONE_NUMBER, phoneNumber); + + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + } +} diff --git a/java/com/android/dialer/duo/PlaceDuoCallReceiver.java b/java/com/android/dialer/duo/PlaceDuoCallReceiver.java new file mode 100644 index 000000000..913132c88 --- /dev/null +++ b/java/com/android/dialer/duo/PlaceDuoCallReceiver.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.duo; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.constants.ActivityRequestCodes; + +/** A {@link BroadcastReceiver} that starts a Duo video call. */ +public final class PlaceDuoCallReceiver extends BroadcastReceiver { + + static final String ACTION_START_DUO_CALL = "start_duo_call"; + static final String EXTRA_PHONE_NUMBER = "phone_number"; + + /** + * {@link Activity} needed to launch Duo. + * + *

A Duo call can only be placed via {@link Activity#startActivityForResult(Intent, int)}. + */ + private final Activity activity; + + /** Returns an {@link IntentFilter} containing all actions accepted by this broadcast receiver. */ + public static IntentFilter getIntentFilter() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(ACTION_START_DUO_CALL); + return intentFilter; + } + + public PlaceDuoCallReceiver(Activity activity) { + this.activity = activity; + } + + @Override + public void onReceive(Context context, Intent intent) { + LogUtil.enterBlock("PlaceDuoCallReceiver.onReceive"); + + String action = intent.getAction(); + + switch (Assert.isNotNull(action)) { + case ACTION_START_DUO_CALL: + startDuoCall(context, intent); + break; + default: + throw new IllegalStateException("Unsupported action: " + action); + } + } + + private void startDuoCall(Context context, Intent intent) { + LogUtil.enterBlock("PlaceDuoCallReceiver.startDuoCall"); + + Assert.checkArgument(intent.hasExtra(EXTRA_PHONE_NUMBER)); + String phoneNumber = intent.getStringExtra(EXTRA_PHONE_NUMBER); + + Duo duo = DuoComponent.get(context).getDuo(); + activity.startActivityForResult( + duo.getIntent(context, phoneNumber), ActivityRequestCodes.DIALTACTS_DUO); + } +} diff --git a/java/com/android/dialer/historyitemactions/DuoCallModule.java b/java/com/android/dialer/historyitemactions/DuoCallModule.java new file mode 100644 index 000000000..b0d6a11fc --- /dev/null +++ b/java/com/android/dialer/historyitemactions/DuoCallModule.java @@ -0,0 +1,80 @@ +/* + * 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.historyitemactions; + +import android.Manifest.permission; +import android.content.Context; +import android.support.annotation.RequiresPermission; +import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.duo.Duo; +import com.android.dialer.duo.DuoComponent; +import com.android.dialer.duo.PlaceDuoCallNotifier; +import com.android.dialer.precall.PreCall; + +/** {@link HistoryItemActionModule} for making a Duo call. */ +public class DuoCallModule implements HistoryItemActionModule { + + private final Context context; + private final String phoneNumber; + private final CallInitiationType.Type callInitiationType; + + /** + * Creates a module for making a Duo call. + * + * @param phoneNumber The number to start a Duo call. It can be of any format. + */ + public DuoCallModule( + Context context, String phoneNumber, CallInitiationType.Type callInitiationType) { + this.context = context; + this.phoneNumber = phoneNumber; + this.callInitiationType = callInitiationType; + } + + @Override + public int getStringId() { + return R.string.video_call; + } + + @Override + public int getDrawableId() { + return R.drawable.quantum_ic_videocam_vd_white_24; + } + + @Override + @RequiresPermission(permission.READ_PHONE_STATE) + public boolean onClick() { + if (canPlaceDuoCall(context, phoneNumber)) { + PlaceDuoCallNotifier.notify(context, phoneNumber); + } else { + // If a Duo call can't be placed, fall back to an IMS video call. + PreCall.start( + context, new CallIntentBuilder(phoneNumber, callInitiationType).setIsVideoCall(true)); + } + + return true; // Close the bottom sheet. + } + + private boolean canPlaceDuoCall(Context context, String phoneNumber) { + Duo duo = DuoComponent.get(context).getDuo(); + + return duo.isInstalled(context) + && duo.isEnabled(context) + && duo.isActivated(context) + && duo.isReachable(context, phoneNumber); + } +} diff --git a/java/com/android/dialer/historyitemactions/IntentModule.java b/java/com/android/dialer/historyitemactions/IntentModule.java index efb10e8bb..a5236c57a 100644 --- a/java/com/android/dialer/historyitemactions/IntentModule.java +++ b/java/com/android/dialer/historyitemactions/IntentModule.java @@ -77,7 +77,7 @@ public class IntentModule implements HistoryItemActionModule { R.drawable.quantum_ic_call_white_24); } - public static IntentModule newVideoCallModule( + public static IntentModule newCarrierVideoCallModule( Context context, String number, @Nullable PhoneAccountHandle phoneAccountHandle, diff --git a/java/com/android/dialer/main/impl/MainActivity.java b/java/com/android/dialer/main/impl/MainActivity.java index 2046b048f..3f660f56c 100644 --- a/java/com/android/dialer/main/impl/MainActivity.java +++ b/java/com/android/dialer/main/impl/MainActivity.java @@ -24,6 +24,7 @@ import com.android.dialer.blockreportspam.ShowBlockReportSpamDialogReceiver; import com.android.dialer.calllog.config.CallLogConfigComponent; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; +import com.android.dialer.duo.PlaceDuoCallReceiver; import com.android.dialer.interactions.PhoneNumberInteraction.DisambigDialogDismissedListener; import com.android.dialer.interactions.PhoneNumberInteraction.InteractionErrorCode; import com.android.dialer.interactions.PhoneNumberInteraction.InteractionErrorListener; @@ -47,6 +48,9 @@ public class MainActivity extends TransactionSafeActivity */ private ShowBlockReportSpamDialogReceiver showBlockReportSpamDialogReceiver; + /** {@link android.content.BroadcastReceiver} that starts a Duo call. */ + private PlaceDuoCallReceiver placeDuoCallReceiver; + public static Intent getShowCallLogIntent(Context context) { return getShowTabIntent(context, TabIndex.CALL_LOG); } @@ -79,6 +83,7 @@ public class MainActivity extends TransactionSafeActivity activePeer.onActivityCreate(savedInstanceState); showBlockReportSpamDialogReceiver = new ShowBlockReportSpamDialogReceiver(getFragmentManager()); + placeDuoCallReceiver = new PlaceDuoCallReceiver(/* activity = */ this); } protected MainActivityPeer getNewPeer() { @@ -104,6 +109,8 @@ public class MainActivity extends TransactionSafeActivity LocalBroadcastManager.getInstance(this) .registerReceiver( showBlockReportSpamDialogReceiver, ShowBlockReportSpamDialogReceiver.getIntentFilter()); + LocalBroadcastManager.getInstance(this) + .registerReceiver(placeDuoCallReceiver, PlaceDuoCallReceiver.getIntentFilter()); } @Override @@ -118,6 +125,7 @@ public class MainActivity extends TransactionSafeActivity activePeer.onActivityPause(); LocalBroadcastManager.getInstance(this).unregisterReceiver(showBlockReportSpamDialogReceiver); + LocalBroadcastManager.getInstance(this).unregisterReceiver(placeDuoCallReceiver); } @Override -- cgit v1.2.3