From ea1acce9b02cc6cf305c75cad733939527c7775b Mon Sep 17 00:00:00 2001 From: linyuh Date: Fri, 27 Apr 2018 09:58:00 -0700 Subject: Handle missing permission.READ_CALL_LOG when initializing the badge for missed calls. Bug: 78458610 Test: MainActivityOldPeerTest PiperOrigin-RevId: 194555035 Change-Id: Ib3ef02ec3f4a8ce7cfce6d052fce3b9b6daf75e5 --- java/com/android/dialer/main/impl/OldMainActivityPeer.java | 14 ++++++++++---- .../main/impl/bottomnav/MissedCallCountObserver.java | 9 +++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java index 9ac351094..e3d42fa9e 100644 --- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java +++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java @@ -457,6 +457,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen return DialpadFragment.isAddCallMode(intent); } + @SuppressLint("MissingPermission") @Override public void onActivityResume() { callLogFragmentListener.onActivityResume(); @@ -492,11 +493,16 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen bottomNavTabListener.ensureCorrectCallLogShown(); bottomNavTabListener.ensureCorrectVoicemailShown(); + // Config the badge of missed calls for the new call log. if (bottomNavTabListener.newCallLogFragmentActive()) { - missedCallCountObserver.onChange(false); // Set the initial value for the badge - activity - .getContentResolver() - .registerContentObserver(Calls.CONTENT_URI, true, missedCallCountObserver); + if (PermissionsUtil.hasCallLogReadPermissions(activity)) { + missedCallCountObserver.onChange(false); // Set the initial value for the badge + activity + .getContentResolver() + .registerContentObserver(Calls.CONTENT_URI, true, missedCallCountObserver); + } else { + bottomNav.setNotificationCount(TabIndex.CALL_LOG, 0); + } } // add 1 sec delay to get memory snapshot so that dialer wont react slowly on resume. diff --git a/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java b/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java index ee7f6d006..a4995c1e6 100644 --- a/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java +++ b/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java @@ -16,15 +16,15 @@ package com.android.dialer.main.impl.bottomnav; -import android.annotation.SuppressLint; +import android.Manifest; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.provider.CallLog.Calls; +import android.support.annotation.RequiresPermission; import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.common.concurrent.UiListener; import com.android.dialer.main.impl.bottomnav.BottomNavBar.TabIndex; -import com.android.dialer.util.PermissionsUtil; import com.google.common.util.concurrent.ListenableFuture; /** @@ -45,7 +45,7 @@ public final class MissedCallCountObserver extends ContentObserver { this.uiListener = uiListener; } - @SuppressLint("MissingPermission") + @RequiresPermission(Manifest.permission.READ_CALL_LOG) @Override public void onChange(boolean selfChange) { ListenableFuture countFuture = @@ -53,9 +53,6 @@ public final class MissedCallCountObserver extends ContentObserver { .backgroundExecutor() .submit( () -> { - if (!PermissionsUtil.hasCallLogReadPermissions(appContext)) { - return 0; - } try (Cursor cursor = appContext .getContentResolver() -- cgit v1.2.3 From 9bd6277786305f98dd85c4256f228b3ae191e05d Mon Sep 17 00:00:00 2001 From: yueg Date: Fri, 27 Apr 2018 10:39:27 -0700 Subject: HFP device support change. Test: manual PiperOrigin-RevId: 194561401 Change-Id: Ia94765a3979b5f3c3e4d02c1dc235f5e41fbf6f9 --- .../AudioRouteSelectorDialogFragment.java | 17 +++++++- .../audioroute/res/layout/audioroute_item.xml | 4 +- .../audioroute/res/layout/audioroute_selector.xml | 47 ++++++++++++---------- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java index 79cae098d..316dd128b 100644 --- a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java +++ b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java @@ -16,6 +16,7 @@ package com.android.incallui.audioroute; +import android.annotation.SuppressLint; import android.app.Dialog; import android.bluetooth.BluetoothDevice; import android.content.Context; @@ -35,6 +36,8 @@ import android.widget.TextView; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; import com.android.incallui.audiomode.BluetoothDeviceProviderComponent; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Set; /** Shows picker for audio routes */ @@ -142,7 +145,7 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment int selectedColor = getResources().getColor(R.color.dialer_theme_color); TextView textView = (TextView) getLayoutInflater().inflate(R.layout.audioroute_item, null, false); - textView.setText(bluetoothDevice.getName()); + textView.setText(getAliasName(bluetoothDevice)); if (selected) { textView.setTextColor(selectedColor); textView.setCompoundDrawableTintList(ColorStateList.valueOf(selectedColor)); @@ -163,4 +166,16 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment return textView; } + + @SuppressLint("PrivateApi") + private String getAliasName(BluetoothDevice bluetoothDevice) { + try { + Method getActiveDeviceMethod = bluetoothDevice.getClass().getDeclaredMethod("getAliasName"); + getActiveDeviceMethod.setAccessible(true); + return (String) getActiveDeviceMethod.invoke(bluetoothDevice); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + return bluetoothDevice.getName(); + } + } } diff --git a/java/com/android/incallui/audioroute/res/layout/audioroute_item.xml b/java/com/android/incallui/audioroute/res/layout/audioroute_item.xml index 66c83f67e..dfd795f04 100644 --- a/java/com/android/incallui/audioroute/res/layout/audioroute_item.xml +++ b/java/com/android/incallui/audioroute/res/layout/audioroute_item.xml @@ -18,4 +18,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableStart="@drawable/quantum_ic_bluetooth_audio_vd_theme_24" - android:drawableTint="@color/material_grey_600"/> \ No newline at end of file + android:drawableTint="@color/material_grey_600" + android:gravity="start" + android:textAlignment="viewStart"/> \ No newline at end of file diff --git a/java/com/android/incallui/audioroute/res/layout/audioroute_selector.xml b/java/com/android/incallui/audioroute/res/layout/audioroute_selector.xml index 145101dd1..b63f387c4 100644 --- a/java/com/android/incallui/audioroute/res/layout/audioroute_selector.xml +++ b/java/com/android/incallui/audioroute/res/layout/audioroute_selector.xml @@ -14,31 +14,34 @@ ~ limitations under the License --> - + android:orientation="vertical" + tools:layout_gravity="bottom"> + android:id="@+id/audioroute_speaker" + style="@style/AudioRouteItem" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:drawableStart="@drawable/quantum_ic_volume_up_grey600_24" + android:text="@string/audioroute_speaker" + android:textAlignment="viewStart"/> + android:id="@+id/audioroute_earpiece" + style="@style/AudioRouteItem" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:drawableStart="@drawable/ic_phone_audio_grey600_24dp" + android:text="@string/audioroute_phone" + android:textAlignment="viewStart"/> + -- cgit v1.2.3 From b493c3f93c3560cca8cb91525f043538d3721cd2 Mon Sep 17 00:00:00 2001 From: yueg Date: Fri, 27 Apr 2018 14:00:12 -0700 Subject: Logging for background calling and HFP device support. Bug: 74022483,74238896 Test: InCallPresenterTest, AudioRouteSelectorDialogFragmentTest PiperOrigin-RevId: 194589147 Change-Id: If8c6e79838d27b1ca33ed677c19f6555cbdb4494 --- .../android/dialer/logging/dialer_impression.proto | 11 +++++- java/com/android/incallui/InCallPresenter.java | 11 +++++- .../AudioRouteSelectorDialogFragment.java | 40 ++++++++++++++++++---- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/java/com/android/dialer/logging/dialer_impression.proto b/java/com/android/dialer/logging/dialer_impression.proto index 7cd22079c..55cef9a38 100644 --- a/java/com/android/dialer/logging/dialer_impression.proto +++ b/java/com/android/dialer/logging/dialer_impression.proto @@ -12,7 +12,7 @@ message DialerImpression { // Event enums to be used for Impression Logging in Dialer. // It's perfectly acceptable for this enum to be large // Values should be from 1000 to 100000. - // Next Tag: 1392 + // Next Tag: 1397 enum Type { UNKNOWN_AOSP_EVENT_TYPE = 1000; @@ -770,5 +770,14 @@ message DialerImpression { // Send button clicked in RTT call, this includes send button on keyboard. RTT_SEND_BUTTON_CLICKED = 1387; RTT_KEYBOARD_SEND_BUTTON_CLICKED = 1388; + + // For background calling + START_CALL_IN_BUBBLE_MODE = 1392; + + // Switch audio route + IN_CALL_SWITCH_AUDIO_ROUTE_SPEAKER = 1393; + IN_CALL_SWITCH_AUDIO_ROUTE_WIRED_HEADSET = 1394; + IN_CALL_SWITCH_AUDIO_ROUTE_EARPIECE = 1395; + IN_CALL_SWITCH_AUDIO_ROUTE_BLUETOOTH = 1396; } } diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 6e7daf551..6386c56be 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -52,6 +52,7 @@ import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.location.GeoUtil; +import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; import com.android.dialer.postcall.PostCall; @@ -429,7 +430,15 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud } Bundle extras = dialerCall.getIntentExtras(); - return shouldStartInBubbleModeWithExtras(extras); + boolean result = shouldStartInBubbleModeWithExtras(extras); + if (result) { + Logger.get(context) + .logCallImpression( + DialerImpression.Type.START_CALL_IN_BUBBLE_MODE, + dialerCall.getUniqueCallId(), + dialerCall.getTimeAddedMs()); + } + return result; } private boolean shouldStartInBubbleModeWithExtras(Bundle outgoingExtras) { diff --git a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java index 316dd128b..cd17c25da 100644 --- a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java +++ b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java @@ -35,7 +35,11 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; import com.android.incallui.audiomode.BluetoothDeviceProviderComponent; +import com.android.incallui.call.CallList; +import com.android.incallui.call.DialerCall; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Set; @@ -101,15 +105,18 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment initItem( (TextView) view.findViewById(R.id.audioroute_speaker), CallAudioState.ROUTE_SPEAKER, - audioState); + audioState, + DialerImpression.Type.IN_CALL_SWITCH_AUDIO_ROUTE_SPEAKER); initItem( (TextView) view.findViewById(R.id.audioroute_headset), CallAudioState.ROUTE_WIRED_HEADSET, - audioState); + audioState, + DialerImpression.Type.IN_CALL_SWITCH_AUDIO_ROUTE_WIRED_HEADSET); initItem( (TextView) view.findViewById(R.id.audioroute_earpiece), CallAudioState.ROUTE_EARPIECE, - audioState); + audioState, + DialerImpression.Type.IN_CALL_SWITCH_AUDIO_ROUTE_EARPIECE); // TODO(a bug): set peak height correctly to fully expand it in landscape mode. return view; @@ -123,7 +130,11 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment .onAudioRouteSelectorDismiss(); } - private void initItem(TextView item, final int itemRoute, CallAudioState audioState) { + private void initItem( + TextView item, + final int itemRoute, + CallAudioState audioState, + DialerImpression.Type impressionType) { int selectedColor = getResources().getColor(R.color.dialer_theme_color); if ((audioState.getSupportedRouteMask() & itemRoute) == 0) { item.setVisibility(View.GONE); @@ -134,10 +145,11 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment } item.setOnClickListener( (v) -> { - dismiss(); + logCallAudioRouteImpression(impressionType); FragmentUtils.getParentUnsafe( AudioRouteSelectorDialogFragment.this, AudioRouteSelectorPresenter.class) .onAudioRouteSelected(itemRoute); + dismiss(); }); } @@ -153,7 +165,7 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment } textView.setOnClickListener( (v) -> { - dismiss(); + logCallAudioRouteImpression(DialerImpression.Type.IN_CALL_SWITCH_AUDIO_ROUTE_BLUETOOTH); // Set Bluetooth audio route FragmentUtils.getParentUnsafe( AudioRouteSelectorDialogFragment.this, AudioRouteSelectorPresenter.class) @@ -162,6 +174,7 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment BluetoothDeviceProviderComponent.get(getContext()) .bluetoothDeviceProvider() .setActiveBluetoothDevice(bluetoothDevice); + dismiss(); }); return textView; @@ -178,4 +191,19 @@ public class AudioRouteSelectorDialogFragment extends BottomSheetDialogFragment return bluetoothDevice.getName(); } } + + private void logCallAudioRouteImpression(DialerImpression.Type impressionType) { + DialerCall dialerCall = CallList.getInstance().getOutgoingCall(); + if (dialerCall == null) { + dialerCall = CallList.getInstance().getActiveOrBackgroundCall(); + } + + if (dialerCall != null) { + Logger.get(getContext()) + .logCallImpression( + impressionType, dialerCall.getUniqueCallId(), dialerCall.getTimeAddedMs()); + } else { + Logger.get(getContext()).logImpression(impressionType); + } + } } -- cgit v1.2.3 From bb94ca670290484b4f6a801735870f21328d49c2 Mon Sep 17 00:00:00 2001 From: wangqi Date: Fri, 27 Apr 2018 14:34:04 -0700 Subject: Move DialerCall.State to an independent package. This refactoring will remove dependency on incall/call package for those classes only dependent on DialerCall.State. The benefit is to remove unnecessary dependency and avoid potential loop dependency in the future. Test: presubmit PiperOrigin-RevId: 194594382 Change-Id: I6b3241bcf10a0a15c495c3c90a13f174c32e3f72 --- .../incallui/ActiveCallsCallListListener.java | 4 +- java/com/android/incallui/CallButtonPresenter.java | 12 +- java/com/android/incallui/CallCardPresenter.java | 36 +++--- .../incallui/ConferenceParticipantListAdapter.java | 7 +- java/com/android/incallui/InCallActivity.java | 6 +- java/com/android/incallui/InCallPresenter.java | 5 +- java/com/android/incallui/StatusBarNotifier.java | 31 ++--- java/com/android/incallui/VideoCallPresenter.java | 37 +++--- .../com/android/incallui/VideoPauseController.java | 16 +-- .../incallui/answer/impl/AnswerFragment.java | 10 +- .../AnswerProximitySensor.java | 6 +- java/com/android/incallui/call/CallList.java | 62 +++++----- java/com/android/incallui/call/DialerCall.java | 128 ++++----------------- .../incallui/call/state/DialerCallState.java | 99 ++++++++++++++++ .../incallui/callpending/CallPendingActivity.java | 4 +- .../android/incallui/contactgrid/BottomRow.java | 11 +- java/com/android/incallui/contactgrid/TopRow.java | 17 +-- .../incallui/incall/protocol/PrimaryCallState.java | 7 +- .../incallui/ringtone/DialerRingtoneManager.java | 22 ++-- .../android/incallui/rtt/impl/RttChatFragment.java | 8 +- 20 files changed, 278 insertions(+), 250 deletions(-) create mode 100644 java/com/android/incallui/call/state/DialerCallState.java diff --git a/java/com/android/incallui/ActiveCallsCallListListener.java b/java/com/android/incallui/ActiveCallsCallListListener.java index ce9f9a36d..3e4cb9375 100644 --- a/java/com/android/incallui/ActiveCallsCallListListener.java +++ b/java/com/android/incallui/ActiveCallsCallListListener.java @@ -22,7 +22,7 @@ import com.android.dialer.activecalls.ActiveCallInfo; import com.android.dialer.activecalls.ActiveCallsComponent; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; @@ -49,7 +49,7 @@ public class ActiveCallsCallListListener implements CallList.Listener { public void onCallListChange(CallList callList) { ImmutableList.Builder activeCalls = ImmutableList.builder(); for (DialerCall call : callList.getAllCalls()) { - if (call.getState() != State.DISCONNECTED) { + if (call.getState() != DialerCallState.DISCONNECTED) { activeCalls.add( ActiveCallInfo.builder() .setPhoneAccountHandle(Optional.fromNullable(call.getAccountHandle())) diff --git a/java/com/android/incallui/CallButtonPresenter.java b/java/com/android/incallui/CallButtonPresenter.java index e30c70fec..3fd3ee64b 100644 --- a/java/com/android/incallui/CallButtonPresenter.java +++ b/java/com/android/incallui/CallButtonPresenter.java @@ -44,8 +44,8 @@ import com.android.incallui.audiomode.AudioModeProvider.AudioModeListener; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCall.CameraDirection; -import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.TelecomAdapter; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.incall.protocol.InCallButtonIds; import com.android.incallui.incall.protocol.InCallButtonUi; import com.android.incallui.incall.protocol.InCallButtonUiDelegate; @@ -458,7 +458,7 @@ public class CallButtonPresenter !showSwap && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD) && call.can(android.telecom.Call.Details.CAPABILITY_HOLD); - final boolean isCallOnHold = call.getState() == DialerCall.State.ONHOLD; + final boolean isCallOnHold = call.getState() == DialerCallState.ONHOLD; final boolean showAddCall = TelecomAdapter.getInstance().canAddCall() && UserManagerCompat.isUserUnlocked(context); @@ -480,20 +480,20 @@ public class CallButtonPresenter // Disabling local video doesn't seem to work when dialing. See a bug. final boolean showPauseVideo = isVideo - && call.getState() != DialerCall.State.DIALING - && call.getState() != DialerCall.State.CONNECTING; + && call.getState() != DialerCallState.DIALING + && call.getState() != DialerCallState.CONNECTING; otherAccount = TelecomUtil.getOtherAccount(getContext(), call.getAccountHandle()); boolean showSwapSim = !call.isEmergencyCall() && otherAccount != null && !call.isVoiceMailNumber() - && DialerCall.State.isDialing(call.getState()) + && DialerCallState.isDialing(call.getState()) // Most devices cannot make calls on 2 SIMs at the same time. && InCallPresenter.getInstance().getCallList().getAllCalls().size() == 1; boolean showUpgradeToRtt = call.canUpgradeToRttCall(); - boolean enableUpgradeToRtt = showUpgradeToRtt && call.getState() == State.ACTIVE; + boolean enableUpgradeToRtt = showUpgradeToRtt && call.getState() == DialerCallState.ACTIVE; inCallButtonUi.showButton(InCallButtonIds.BUTTON_AUDIO, true); inCallButtonUi.showButton(InCallButtonIds.BUTTON_SWAP, showSwap); diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java index 1f7a0d396..83c1aff5e 100644 --- a/java/com/android/incallui/CallCardPresenter.java +++ b/java/com/android/incallui/CallCardPresenter.java @@ -65,8 +65,8 @@ import com.android.incallui.InCallPresenter.InCallStateListener; import com.android.incallui.InCallPresenter.IncomingCallListener; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; -import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.DialerCallListener; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.calllocation.CallLocation; import com.android.incallui.calllocation.CallLocationComponent; import com.android.incallui.incall.protocol.ContactPhotoType; @@ -171,7 +171,7 @@ public class CallCardPresenter call.addListener(this); // start processing lookups right away. if (!call.isConferenceCall()) { - startContactInfoSearch(call, true, call.getState() == DialerCall.State.INCOMING); + startContactInfoSearch(call, true, call.getState() == DialerCallState.INCOMING); } else { updateContactEntry(null, true); } @@ -323,7 +323,7 @@ public class CallCardPresenter primaryContactInfo = ContactInfoCache.buildCacheEntryFromCall( - context, this.primary, this.primary.getState() == DialerCall.State.INCOMING); + context, this.primary, this.primary.getState() == DialerCallState.INCOMING); updatePrimaryDisplayInfo(); maybeStartSearch(this.primary, true); } @@ -341,14 +341,14 @@ public class CallCardPresenter // secondary call has changed secondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall( - context, this.secondary, this.secondary.getState() == DialerCall.State.INCOMING); + context, this.secondary, this.secondary.getState() == DialerCallState.INCOMING); updateSecondaryDisplayInfo(); maybeStartSearch(this.secondary, false); } } // Set the call state - int callState = DialerCall.State.IDLE; + int callState = DialerCallState.IDLE; if (this.primary != null) { callState = this.primary.getState(); updatePrimaryCallState(); @@ -362,7 +362,7 @@ public class CallCardPresenter getUi() .setEndCallButtonEnabled( shouldShowEndCallButton(this.primary, callState), - callState != DialerCall.State.INCOMING /* animate */); + callState != DialerCallState.INCOMING /* animate */); maybeSendAccessibilityEvent(oldState, newState, primaryChanged); Trace.endSection(); @@ -520,7 +520,7 @@ public class CallCardPresenter if (secondary == null) { return ButtonState.NOT_SUPPORT; } - if (primary.getState() == State.ACTIVE) { + if (primary.getState() == DialerCallState.ACTIVE) { return ButtonState.ENABLED; } return ButtonState.DISABLED; @@ -580,7 +580,7 @@ public class CallCardPresenter private void maybeStartSearch(DialerCall call, boolean isPrimary) { // no need to start search for conference calls which show generic info. if (call != null && !call.isConferenceCall()) { - startContactInfoSearch(call, isPrimary, call.getState() == DialerCall.State.INCOMING); + startContactInfoSearch(call, isPrimary, call.getState() == DialerCallState.INCOMING); } } @@ -978,7 +978,7 @@ public class CallCardPresenter if (primary == null) { return false; } - return DialerCall.State.isDialing(primary.getState()) + return DialerCallState.isDialing(primary.getState()) && primary.getGatewayInfo() != null && !primary.getGatewayInfo().isEmpty(); } @@ -1040,17 +1040,17 @@ public class CallCardPresenter } private boolean isPrimaryCallActive() { - return primary != null && primary.getState() == DialerCall.State.ACTIVE; + return primary != null && primary.getState() == DialerCallState.ACTIVE; } private boolean shouldShowEndCallButton(DialerCall primary, int callState) { if (primary == null) { return false; } - if ((!DialerCall.State.isConnectingOrConnected(callState) - && callState != DialerCall.State.DISCONNECTING - && callState != DialerCall.State.DISCONNECTED) - || callState == DialerCall.State.INCOMING) { + if ((!DialerCallState.isConnectingOrConnected(callState) + && callState != DialerCallState.DISCONNECTING + && callState != DialerCallState.DISCONNECTED) + || callState == DialerCallState.INCOMING) { return false; } if (this.primary.getVideoTech().getSessionModificationState() @@ -1141,8 +1141,8 @@ public class CallCardPresenter } boolean isIncomingOrWaiting = - primary.getState() == DialerCall.State.INCOMING - || primary.getState() == DialerCall.State.CALL_WAITING; + primary.getState() == DialerCallState.INCOMING + || primary.getState() == DialerCallState.CALL_WAITING; return isIncomingOrWaiting && !TextUtils.isEmpty(call.getCallSubject()) && call.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED @@ -1159,8 +1159,8 @@ public class CallCardPresenter private boolean shouldShowNoteSentToast(DialerCall call) { return call != null && hasCallSubject(call) - && (call.getState() == DialerCall.State.DIALING - || call.getState() == DialerCall.State.CONNECTING); + && (call.getState() == DialerCallState.DIALING + || call.getState() == DialerCallState.CONNECTING); } private InCallScreen getUi() { diff --git a/java/com/android/incallui/ConferenceParticipantListAdapter.java b/java/com/android/incallui/ConferenceParticipantListAdapter.java index dc793f7f8..597702b2a 100644 --- a/java/com/android/incallui/ConferenceParticipantListAdapter.java +++ b/java/com/android/incallui/ConferenceParticipantListAdapter.java @@ -41,6 +41,7 @@ import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest; import com.android.incallui.ContactInfoCache.ContactCacheEntry; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; +import com.android.incallui.call.state.DialerCallState; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; @@ -223,7 +224,7 @@ public class ConferenceParticipantListAdapter extends BaseAdapter { if (!participantInfo.isCacheLookupComplete()) { cache.findInfo( participantInfo.getCall(), - participantInfo.getCall().getState() == DialerCall.State.INCOMING, + participantInfo.getCall().getState() == DialerCallState.INCOMING, new ContactLookupCallback(this)); } @@ -299,7 +300,7 @@ public class ConferenceParticipantListAdapter extends BaseAdapter { final View endButton = view.findViewById(R.id.conferenceCallerDisconnect); final View separateButton = view.findViewById(R.id.conferenceCallerSeparate); - if (callState == DialerCall.State.ONHOLD) { + if (callState == DialerCallState.ONHOLD) { setViewsOnHold(photoView, statusTextView, nameTextView, numberTextView); } else { setViewsNotOnHold(photoView, statusTextView, nameTextView, numberTextView); @@ -401,7 +402,7 @@ public class ConferenceParticipantListAdapter extends BaseAdapter { if (contactCache == null) { contactCache = ContactInfoCache.buildCacheEntryFromCall( - getContext(), call, call.getState() == DialerCall.State.INCOMING); + getContext(), call, call.getState() == DialerCallState.INCOMING); } if (participantsByCallId.containsKey(callId)) { diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 02335b6e4..0f0e9d9f2 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -83,8 +83,8 @@ import com.android.incallui.answerproximitysensor.PseudoScreenState; import com.android.incallui.audiomode.AudioModeProvider; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; -import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.TelecomAdapter; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.callpending.CallPendingActivity; import com.android.incallui.disconnectdialog.DisconnectMessage; import com.android.incallui.incall.bindings.InCallBindings; @@ -348,7 +348,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity // If there's only one line in use, AND it's on hold, then we're sure the user // wants to use the dialpad toward the exact line, so un-hold the holding line. DialerCall call = CallList.getInstance().getActiveOrBackgroundCall(); - if (call != null && call.getState() == State.ONHOLD) { + if (call != null && call.getState() == DialerCallState.ONHOLD) { call.unhold(); } } @@ -1449,7 +1449,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity if (call == null) { call = CallList.getInstance().getBackgroundCall(); } - if (didShowAnswerScreen && (call == null || call.getState() == State.DISCONNECTED)) { + if (didShowAnswerScreen && (call == null || call.getState() == DialerCallState.DISCONNECTED)) { LogUtil.i("InCallActivity.getShouldShowAnswerUi", "found disconnecting incoming call"); return new ShouldShowUiResult(true, call); } diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 6386c56be..670af9d54 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -66,6 +66,7 @@ import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.ExternalCallList; import com.android.incallui.call.TelecomAdapter; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.disconnectdialog.DisconnectMessage; import com.android.incallui.incalluilock.InCallUiLock; import com.android.incallui.latencyreport.LatencyReport; @@ -1356,7 +1357,7 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud LogUtil.v("InCallPresenter.handleCallKey", "heldCall: " + heldCall + ", canHold: " + canHold); // (4) unhold call - if (heldCall.getState() == DialerCall.State.ONHOLD && canHold) { + if (heldCall.getState() == DialerCallState.ONHOLD && canHold) { heldCall.unhold(); return true; } @@ -1428,7 +1429,7 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud /** Instruct the in-call activity to show an error dialog or toast for a disconnected call. */ private void showDialogOrToastForDisconnectedCall(DialerCall call) { - if (call.getState() != DialerCall.State.DISCONNECTED) { + if (call.getState() != DialerCallState.DISCONNECTED) { return; } diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java index 9a2753219..32d202595 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -85,6 +85,7 @@ import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCallListener; import com.android.incallui.call.TelecomAdapter; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.ringtone.DialerRingtoneManager; import com.android.incallui.ringtone.InCallTonePlayer; import com.android.incallui.ringtone.ToneGeneratorFactory; @@ -117,7 +118,7 @@ public class StatusBarNotifier private final DialerRingtoneManager dialerRingtoneManager; @Nullable private ContactsPreferences contactsPreferences; private int currentNotification = NOTIFICATION_NONE; - private int callState = DialerCall.State.INVALID; + private int callState = DialerCallState.INVALID; private int videoState = VideoProfile.STATE_AUDIO_ONLY; private int savedIcon = 0; private String savedContent = null; @@ -244,8 +245,8 @@ public class StatusBarNotifier private void showNotification(final DialerCall call) { Trace.beginSection("StatusBarNotifier.showNotification"); final boolean isIncoming = - (call.getState() == DialerCall.State.INCOMING - || call.getState() == DialerCall.State.CALL_WAITING); + (call.getState() == DialerCallState.INCOMING + || call.getState() == DialerCallState.CALL_WAITING); setStatusBarCallListener(new StatusBarCallListener(call)); // we make a call to the contact info cache to query for supplemental data to what the @@ -287,8 +288,8 @@ public class StatusBarNotifier call.getVideoTech().getSessionModificationState() == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST; final int notificationType; - if (callState == DialerCall.State.INCOMING - || callState == DialerCall.State.CALL_WAITING + if (callState == DialerCallState.INCOMING + || callState == DialerCallState.CALL_WAITING || isVideoUpgradeRequest) { if (ConfigProviderBindings.get(context) .getBoolean("quiet_incoming_call_if_ui_showing", true)) { @@ -437,12 +438,12 @@ public class StatusBarNotifier setNotificationWhen(call, state, builder); // Add hang up option for any active calls (active | onhold), outgoing calls (dialing). - if (state == DialerCall.State.ACTIVE - || state == DialerCall.State.ONHOLD - || DialerCall.State.isDialing(state)) { + if (state == DialerCallState.ACTIVE + || state == DialerCallState.ONHOLD + || DialerCallState.isDialing(state)) { addHangupAction(builder); addSpeakerAction(builder, callAudioState); - } else if (state == DialerCall.State.INCOMING || state == DialerCall.State.CALL_WAITING) { + } else if (state == DialerCallState.INCOMING || state == DialerCallState.CALL_WAITING) { addDismissAction(builder); if (call.isVideoCall()) { addVideoCallAction(builder); @@ -458,7 +459,7 @@ public class StatusBarNotifier * at which the notification was created. */ private void setNotificationWhen(DialerCall call, int state, Notification.Builder builder) { - if (state == DialerCall.State.ACTIVE) { + if (state == DialerCallState.ACTIVE) { builder.setUsesChronometer(true); builder.setWhen(call.getConnectTimeMillis()); } else { @@ -642,7 +643,7 @@ public class StatusBarNotifier // different calls. So if both lines are in use, display info // from the foreground call. And if there's a ringing call, // display that regardless of the state of the other calls. - if (call.getState() == DialerCall.State.ONHOLD) { + if (call.getState() == DialerCallState.ONHOLD) { return R.drawable.quantum_ic_phone_paused_vd_theme_24; } else if (call.getVideoTech().getSessionModificationState() == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST @@ -668,8 +669,8 @@ public class StatusBarNotifier /** Returns the message to use with the notification. */ private CharSequence getContentString(DialerCall call, @UserType long userType) { boolean isIncomingOrWaiting = - call.getState() == DialerCall.State.INCOMING - || call.getState() == DialerCall.State.CALL_WAITING; + call.getState() == DialerCallState.INCOMING + || call.getState() == DialerCallState.CALL_WAITING; if (isIncomingOrWaiting && call.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED) { @@ -701,14 +702,14 @@ public class StatusBarNotifier } else { resId = R.string.notification_incoming_call; } - } else if (call.getState() == DialerCall.State.ONHOLD) { + } else if (call.getState() == DialerCallState.ONHOLD) { resId = R.string.notification_on_hold; } else if (call.isVideoCall()) { resId = call.getVideoTech().isPaused() ? R.string.notification_ongoing_paused_video_call : R.string.notification_ongoing_video_call; - } else if (DialerCall.State.isDialing(call.getState())) { + } else if (DialerCallState.isDialing(call.getState())) { resId = R.string.notification_dialing; } else if (call.getVideoTech().getSessionModificationState() == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { diff --git a/java/com/android/incallui/VideoCallPresenter.java b/java/com/android/incallui/VideoCallPresenter.java index 050ce9859..41c33543b 100644 --- a/java/com/android/incallui/VideoCallPresenter.java +++ b/java/com/android/incallui/VideoCallPresenter.java @@ -38,9 +38,9 @@ import com.android.incallui.InCallPresenter.IncomingCallListener; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCall.CameraDirection; -import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.InCallVideoCallCallbackNotifier; import com.android.incallui.call.InCallVideoCallCallbackNotifier.SurfaceChangeListener; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.util.AccessibilityUtil; import com.android.incallui.video.protocol.VideoCallScreen; import com.android.incallui.video.protocol.VideoCallScreenDelegate; @@ -101,7 +101,7 @@ public class VideoCallPresenter /** Determines if the current UI state represents a video call. */ private int currentVideoState; /** DialerCall's current state */ - private int currentCallState = DialerCall.State.INVALID; + private int currentCallState = DialerCallState.INVALID; /** Determines the device orientation (portrait/lanscape). */ private int deviceOrientation = InCallOrientationEventListener.SCREEN_ORIENTATION_UNKNOWN; /** Tracks the state of the preview surface negotiation with the telephony layer. */ @@ -166,10 +166,10 @@ public class VideoCallPresenter static boolean showIncomingVideo(int videoState, int callState) { boolean isPaused = VideoProfile.isPaused(videoState); - boolean isCallActive = callState == DialerCall.State.ACTIVE; + boolean isCallActive = callState == DialerCallState.ACTIVE; // Show incoming Video for dialing calls to support early media boolean isCallOutgoingPending = - DialerCall.State.isDialing(callState) || callState == DialerCall.State.CONNECTING; + DialerCallState.isDialing(callState) || callState == DialerCallState.CONNECTING; return !isPaused && (isCallActive || isCallOutgoingPending) @@ -318,7 +318,7 @@ public class VideoCallPresenter // Register for surface and video events from {@link InCallVideoCallListener}s. InCallVideoCallCallbackNotifier.getInstance().addSurfaceChangeListener(this); currentVideoState = VideoProfile.STATE_AUDIO_ONLY; - currentCallState = DialerCall.State.INVALID; + currentCallState = DialerCallState.INVALID; InCallPresenter.InCallState inCallState = InCallPresenter.getInstance().getInCallState(); onStateChange(inCallState, inCallState, CallList.getInstance()); @@ -541,7 +541,8 @@ public class VideoCallPresenter updateFullscreenAndGreenScreenMode( primaryCall.getState(), primaryCall.getVideoTech().getSessionModificationState()); } else { - updateFullscreenAndGreenScreenMode(State.INVALID, SessionModificationState.NO_REQUEST); + updateFullscreenAndGreenScreenMode( + DialerCallState.INVALID, SessionModificationState.NO_REQUEST); } } @@ -640,7 +641,7 @@ public class VideoCallPresenter private void updateCallCache(DialerCall call) { if (call == null) { currentVideoState = VideoProfile.STATE_AUDIO_ONLY; - currentCallState = DialerCall.State.INVALID; + currentCallState = DialerCallState.INVALID; videoCall = null; primaryCall = null; } else { @@ -699,9 +700,9 @@ public class VideoCallPresenter if (videoCallScreen != null) { boolean shouldShowFullscreen = InCallPresenter.getInstance().isFullscreen(); boolean shouldShowGreenScreen = - callState == State.DIALING - || callState == State.CONNECTING - || callState == State.INCOMING + callState == DialerCallState.DIALING + || callState == DialerCallState.CONNECTING + || callState == DialerCallState.INCOMING || isVideoUpgrade(sessionModificationState); videoCallScreen.updateFullscreenAndGreenScreenMode( shouldShowFullscreen, shouldShowGreenScreen); @@ -850,7 +851,7 @@ public class VideoCallPresenter showVideoUi( VideoProfile.STATE_AUDIO_ONLY, - DialerCall.State.ACTIVE, + DialerCallState.ACTIVE, SessionModificationState.NO_REQUEST, false /* isRemotelyHeld */); enableCamera(primaryCall, false); @@ -1019,7 +1020,7 @@ public class VideoCallPresenter return; } - if (!isVideoCall(call) || call.getState() == DialerCall.State.INCOMING) { + if (!isVideoCall(call) || call.getState() == DialerCallState.INCOMING) { LogUtil.i("VideoCallPresenter.maybeExitFullscreen", "exiting fullscreen"); InCallPresenter.getInstance().setFullScreen(false); } @@ -1038,7 +1039,7 @@ public class VideoCallPresenter } if (call == null - || call.getState() != DialerCall.State.ACTIVE + || call.getState() != DialerCallState.ACTIVE || !isBidirectionalVideoCall(call) || InCallPresenter.getInstance().isFullscreen() || (context != null && AccessibilityUtil.isTouchExplorationEnabled(context))) { @@ -1263,11 +1264,11 @@ public class VideoCallPresenter return false; } final int state = call.getState(); - return (state == DialerCall.State.INCOMING) || (state == DialerCall.State.CALL_WAITING); + return (state == DialerCallState.INCOMING) || (state == DialerCallState.CALL_WAITING); } private static boolean isActiveVideoCall(DialerCall call) { - return isVideoCall(call) && call.getState() == DialerCall.State.ACTIVE; + return isVideoCall(call) && call.getState() == DialerCallState.ACTIVE; } private static boolean isOutgoingVideoCall(DialerCall call) { @@ -1275,9 +1276,9 @@ public class VideoCallPresenter return false; } final int state = call.getState(); - return DialerCall.State.isDialing(state) - || state == DialerCall.State.CONNECTING - || state == DialerCall.State.SELECT_PHONE_ACCOUNT; + return DialerCallState.isDialing(state) + || state == DialerCallState.CONNECTING + || state == DialerCallState.SELECT_PHONE_ACCOUNT; } private static boolean isAudioCall(DialerCall call) { diff --git a/java/com/android/incallui/VideoPauseController.java b/java/com/android/incallui/VideoPauseController.java index 1a65010f0..2bdbce311 100644 --- a/java/com/android/incallui/VideoPauseController.java +++ b/java/com/android/incallui/VideoPauseController.java @@ -24,7 +24,7 @@ import com.android.incallui.InCallPresenter.InCallStateListener; import com.android.incallui.InCallPresenter.IncomingCallListener; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import java.util.Objects; /** @@ -43,7 +43,7 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener * *

These values are stored to detect specific changes in state between onStateChange calls. */ - private int prevCallState = State.INVALID; + private int prevCallState = DialerCallState.INVALID; private boolean wasVideoCall = false; @@ -74,8 +74,8 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener */ private static boolean isIncomingCall(DialerCall call) { return call != null - && (call.getState() == DialerCall.State.CALL_WAITING - || call.getState() == DialerCall.State.INCOMING); + && (call.getState() == DialerCallState.CALL_WAITING + || call.getState() == DialerCallState.INCOMING); } /** @@ -84,7 +84,7 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener * @return {@code true} if the call is dialing, {@code false} otherwise. */ private boolean wasDialing() { - return DialerCall.State.isDialing(prevCallState); + return DialerCallState.isDialing(prevCallState); } /** @@ -115,7 +115,7 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener private void clear() { inCallPresenter = null; primaryCall = null; - prevCallState = State.INVALID; + prevCallState = DialerCallState.INVALID; wasVideoCall = false; isInBackground = false; } @@ -237,7 +237,7 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener private void updatePrimaryCallContext(DialerCall call) { if (call == null) { primaryCall = null; - prevCallState = State.INVALID; + prevCallState = DialerCallState.INVALID; wasVideoCall = false; } else { primaryCall = call; @@ -322,6 +322,6 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener } private static boolean videoCanPause(DialerCall call) { - return call != null && call.isVideoCall() && call.getState() == DialerCall.State.ACTIVE; + return call != null && call.isVideoCall() && call.getState() == DialerCallState.ACTIVE; } } diff --git a/java/com/android/incallui/answer/impl/AnswerFragment.java b/java/com/android/incallui/answer/impl/AnswerFragment.java index 77352f94b..fb1de05bd 100644 --- a/java/com/android/incallui/answer/impl/AnswerFragment.java +++ b/java/com/android/incallui/answer/impl/AnswerFragment.java @@ -69,7 +69,7 @@ import com.android.incallui.answer.impl.utils.Interpolators; import com.android.incallui.answer.protocol.AnswerScreen; import com.android.incallui.answer.protocol.AnswerScreenDelegate; import com.android.incallui.answer.protocol.AnswerScreenDelegateFactory; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.contactgrid.ContactGridManager; import com.android.incallui.incall.protocol.ContactPhotoType; import com.android.incallui.incall.protocol.InCallScreen; @@ -889,7 +889,7 @@ public class AnswerFragment extends Fragment public void onAnswerProgressUpdate(@FloatRange(from = -1f, to = 1f) float answerProgress) { // Don't fade the window background for call waiting or video upgrades. Fading the background // shows the system wallpaper which looks bad because on reject we switch to another call. - if (primaryCallState.state() == State.INCOMING && !isVideoCall()) { + if (primaryCallState.state() == DialerCallState.INCOMING && !isVideoCall()) { answerScreenDelegate.updateWindowBackgroundColor(answerProgress); } @@ -1079,9 +1079,9 @@ public class AnswerFragment extends Fragment private boolean canRejectCallWithSms() { return primaryCallState != null - && !(primaryCallState.state() == State.DISCONNECTED - || primaryCallState.state() == State.DISCONNECTING - || primaryCallState.state() == State.IDLE); + && !(primaryCallState.state() == DialerCallState.DISCONNECTED + || primaryCallState.state() == DialerCallState.DISCONNECTING + || primaryCallState.state() == DialerCallState.IDLE); } private void createInCallScreenDelegate() { diff --git a/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java b/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java index 50f6ae695..939d12014 100644 --- a/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java +++ b/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java @@ -24,8 +24,8 @@ import android.view.Display; import com.android.dialer.common.LogUtil; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.incallui.call.DialerCall; -import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.DialerCallListener; +import com.android.incallui.call.state.DialerCallState; /** * This class prevents users from accidentally answering calls by keeping the screen off until the @@ -47,7 +47,7 @@ public class AnswerProximitySensor Trace.beginSection("AnswerProximitySensor.shouldUse"); // Don't use the AnswerProximitySensor for call waiting and other states. Those states are // handled by the general ProximitySensor code. - if (call.getState() != State.INCOMING) { + if (call.getState() != DialerCallState.INCOMING) { LogUtil.i("AnswerProximitySensor.shouldUse", "call state is not incoming"); Trace.endSection(); return false; @@ -129,7 +129,7 @@ public class AnswerProximitySensor @Override public void onDialerCallUpdate() { - if (call.getState() != State.INCOMING) { + if (call.getState() != DialerCallState.INCOMING) { LogUtil.i("AnswerProximitySensor.onDialerCallUpdate", "no longer incoming, cleaning up"); cleanup(); } diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java index 6b17962de..5d9db32d9 100644 --- a/java/com/android/incallui/call/CallList.java +++ b/java/com/android/incallui/call/CallList.java @@ -42,7 +42,7 @@ import com.android.dialer.shortcuts.ShortcutUsageReporter; import com.android.dialer.spam.Spam; import com.android.dialer.spam.SpamComponent; import com.android.dialer.telecom.TelecomCallUtil; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.latencyreport.LatencyReport; import com.android.incallui.videotech.utils.SessionModificationState; import java.util.Collection; @@ -155,8 +155,8 @@ public class CallList implements DialerCallDelegate { @Override public void onComplete(boolean isSpam) { boolean isIncomingCall = - call.getState() == DialerCall.State.INCOMING - || call.getState() == DialerCall.State.CALL_WAITING; + call.getState() == DialerCallState.INCOMING + || call.getState() == DialerCallState.CALL_WAITING; if (isSpam) { if (!isIncomingCall) { LogUtil.i( @@ -211,8 +211,8 @@ public class CallList implements DialerCallDelegate { call.getCountryIso()); Trace.endSection(); - if (call.getState() == DialerCall.State.INCOMING - || call.getState() == DialerCall.State.CALL_WAITING) { + if (call.getState() == DialerCallState.INCOMING + || call.getState() == DialerCallState.CALL_WAITING) { if (call.isActiveRttCall()) { Logger.get(context) .logCallImpression( @@ -233,7 +233,7 @@ public class CallList implements DialerCallDelegate { notifyGenericListeners(); } - if (call.getState() != State.INCOMING) { + if (call.getState() != DialerCallState.INCOMING) { // Only report outgoing calls ShortcutUsageReporter.onOutgoingCallAdded(context, call.getNumber()); } @@ -444,46 +444,46 @@ public class CallList implements DialerCallDelegate { /** A call that is waiting for {@link PhoneAccount} selection */ public DialerCall getWaitingForAccountCall() { - return getFirstCallWithState(DialerCall.State.SELECT_PHONE_ACCOUNT); + return getFirstCallWithState(DialerCallState.SELECT_PHONE_ACCOUNT); } public DialerCall getPendingOutgoingCall() { - return getFirstCallWithState(DialerCall.State.CONNECTING); + return getFirstCallWithState(DialerCallState.CONNECTING); } public DialerCall getOutgoingCall() { - DialerCall call = getFirstCallWithState(DialerCall.State.DIALING); + DialerCall call = getFirstCallWithState(DialerCallState.DIALING); if (call == null) { - call = getFirstCallWithState(DialerCall.State.REDIALING); + call = getFirstCallWithState(DialerCallState.REDIALING); } if (call == null) { - call = getFirstCallWithState(DialerCall.State.PULLING); + call = getFirstCallWithState(DialerCallState.PULLING); } return call; } public DialerCall getActiveCall() { - return getFirstCallWithState(DialerCall.State.ACTIVE); + return getFirstCallWithState(DialerCallState.ACTIVE); } public DialerCall getSecondActiveCall() { - return getCallWithState(DialerCall.State.ACTIVE, 1); + return getCallWithState(DialerCallState.ACTIVE, 1); } public DialerCall getBackgroundCall() { - return getFirstCallWithState(DialerCall.State.ONHOLD); + return getFirstCallWithState(DialerCallState.ONHOLD); } public DialerCall getDisconnectedCall() { - return getFirstCallWithState(DialerCall.State.DISCONNECTED); + return getFirstCallWithState(DialerCallState.DISCONNECTED); } public DialerCall getDisconnectingCall() { - return getFirstCallWithState(DialerCall.State.DISCONNECTING); + return getFirstCallWithState(DialerCallState.DISCONNECTING); } public DialerCall getSecondBackgroundCall() { - return getCallWithState(DialerCall.State.ONHOLD, 1); + return getCallWithState(DialerCallState.ONHOLD, 1); } public DialerCall getActiveOrBackgroundCall() { @@ -495,9 +495,9 @@ public class CallList implements DialerCallDelegate { } public DialerCall getIncomingCall() { - DialerCall call = getFirstCallWithState(DialerCall.State.INCOMING); + DialerCall call = getFirstCallWithState(DialerCallState.INCOMING); if (call == null) { - call = getFirstCallWithState(DialerCall.State.CALL_WAITING); + call = getFirstCallWithState(DialerCallState.CALL_WAITING); } return call; @@ -512,7 +512,7 @@ public class CallList implements DialerCallDelegate { result = getOutgoingCall(); } if (result == null) { - result = getFirstCallWithState(DialerCall.State.ACTIVE); + result = getFirstCallWithState(DialerCallState.ACTIVE); } if (result == null) { result = getDisconnectingCall(); @@ -592,9 +592,9 @@ public class CallList implements DialerCallDelegate { */ public boolean hasNonParentActiveOrBackgroundCall() { for (DialerCall call : callById.values()) { - if ((call.getState() == State.ACTIVE - || call.getState() == State.ONHOLD - || call.getState() == State.CONFERENCED) + if ((call.getState() == DialerCallState.ACTIVE + || call.getState() == DialerCallState.ONHOLD + || call.getState() == DialerCallState.CONFERENCED) && !call.wasParentCall()) { return true; } @@ -611,11 +611,11 @@ public class CallList implements DialerCallDelegate { public void clearOnDisconnect() { for (DialerCall call : callById.values()) { final int state = call.getState(); - if (state != DialerCall.State.IDLE - && state != DialerCall.State.INVALID - && state != DialerCall.State.DISCONNECTED) { + if (state != DialerCallState.IDLE + && state != DialerCallState.INVALID + && state != DialerCallState.DISCONNECTED) { - call.setState(DialerCall.State.DISCONNECTED); + call.setState(DialerCallState.DISCONNECTED); call.setDisconnectCause(new DisconnectCause(DisconnectCause.UNKNOWN)); updateCallInMap(call); } @@ -688,7 +688,7 @@ public class CallList implements DialerCallDelegate { boolean updated = false; - if (call.getState() == DialerCall.State.DISCONNECTED) { + if (call.getState() == DialerCallState.DISCONNECTED) { // update existing (but do not add!!) disconnected calls if (callById.containsKey(call.getId())) { // For disconnected calls, we want to keep them alive for a few seconds so that the @@ -718,7 +718,7 @@ public class CallList implements DialerCallDelegate { } private int getDelayForDisconnect(DialerCall call) { - if (call.getState() != DialerCall.State.DISCONNECTED) { + if (call.getState() != DialerCallState.DISCONNECTED) { throw new IllegalStateException(); } @@ -748,7 +748,7 @@ public class CallList implements DialerCallDelegate { private boolean isCallDead(DialerCall call) { final int state = call.getState(); - return DialerCall.State.IDLE == state || DialerCall.State.INVALID == state; + return DialerCallState.IDLE == state || DialerCallState.INVALID == state; } /** Sets up a call for deletion and notifies listeners of change. */ @@ -756,7 +756,7 @@ public class CallList implements DialerCallDelegate { if (pendingDisconnectCalls.contains(call)) { pendingDisconnectCalls.remove(call); } - call.setState(DialerCall.State.IDLE); + call.setState(DialerCallState.IDLE); updateCallInMap(call); notifyGenericListeners(); } diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java index da05b9d2a..d57de15e5 100644 --- a/java/com/android/incallui/call/DialerCall.java +++ b/java/com/android/incallui/call/DialerCall.java @@ -81,6 +81,7 @@ import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.theme.R; import com.android.dialer.util.PermissionsUtil; import com.android.incallui.audiomode.AudioModeProvider; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.latencyreport.LatencyReport; import com.android.incallui.speakeasy.runtime.Constraints; import com.android.incallui.videotech.VideoTech; @@ -146,7 +147,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa private boolean isSpeakEasyCall; private boolean isEmergencyCall; private Uri handle; - private int state = State.INVALID; + private int state = DialerCallState.INVALID; private DisconnectCause disconnectCause; private boolean hasShownLteToWiFiHandoverToast; @@ -200,7 +201,8 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa /** * Whether the call is put on hold by remote party. This is different than the {@link - * State#ONHOLD} state which indicates that the call is being held locally on the device. + * DialerCallState#ONHOLD} state which indicates that the call is being held locally on the + * device. */ private boolean isRemotelyHeld; @@ -427,25 +429,25 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa switch (state) { case Call.STATE_NEW: case Call.STATE_CONNECTING: - return DialerCall.State.CONNECTING; + return DialerCallState.CONNECTING; case Call.STATE_SELECT_PHONE_ACCOUNT: - return DialerCall.State.SELECT_PHONE_ACCOUNT; + return DialerCallState.SELECT_PHONE_ACCOUNT; case Call.STATE_DIALING: - return DialerCall.State.DIALING; + return DialerCallState.DIALING; case Call.STATE_PULLING_CALL: - return DialerCall.State.PULLING; + return DialerCallState.PULLING; case Call.STATE_RINGING: - return DialerCall.State.INCOMING; + return DialerCallState.INCOMING; case Call.STATE_ACTIVE: - return DialerCall.State.ACTIVE; + return DialerCallState.ACTIVE; case Call.STATE_HOLDING: - return DialerCall.State.ONHOLD; + return DialerCallState.ONHOLD; case Call.STATE_DISCONNECTED: - return DialerCall.State.DISCONNECTED; + return DialerCallState.DISCONNECTED; case Call.STATE_DISCONNECTING: - return DialerCall.State.DISCONNECTING; + return DialerCallState.DISCONNECTING; default: - return DialerCall.State.INVALID; + return DialerCallState.INVALID; } } @@ -570,7 +572,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa videoTech = null; // We want to potentially register a video call callback here. updateFromTelecomCall(); - if (oldState != getState() && getState() == DialerCall.State.DISCONNECTED) { + if (oldState != getState() && getState() == DialerCallState.DISCONNECTED) { for (DialerCallListener listener : listeners) { listener.onDialerCallDisconnect(); } @@ -596,7 +598,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa videoTechManager.dispatchCallStateChanged(telecomCall.getState(), getAccountHandle()); final int translatedState = translateState(telecomCall.getState()); - if (state != State.BLOCKED) { + if (state != DialerCallState.BLOCKED) { setState(translatedState); setDisconnectCause(telecomCall.getDetails().getDisconnectCause()); } @@ -805,7 +807,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa public void blockCall() { telecomCall.reject(false, null); - setState(State.BLOCKED); + setState(DialerCallState.BLOCKED); } @Nullable @@ -846,7 +848,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa public int getState() { if (telecomCall != null && telecomCall.getParent() != null) { - return State.CONFERENCED; + return DialerCallState.CONFERENCED; } else { return state; } @@ -857,9 +859,9 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa } public void setState(int state) { - if (state == State.INCOMING) { + if (state == DialerCallState.INCOMING) { logState.isIncoming = true; - } else if (state == State.DISCONNECTED) { + } else if (state == DialerCallState.DISCONNECTED) { long newDuration = getConnectTimeMillis() == 0 ? 0 : System.currentTimeMillis() - getConnectTimeMillis(); if (this.state != state) { @@ -927,7 +929,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa /** Returns call disconnect cause, defined by {@link DisconnectCause}. */ public DisconnectCause getDisconnectCause() { - if (state == State.DISCONNECTED || state == State.IDLE) { + if (state == DialerCallState.DISCONNECTED || state == DialerCallState.IDLE) { return disconnectCause; } @@ -1146,7 +1148,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa .setCallInitiationType(CallInitiationType.Type.EXTERNAL_INITIATION) .build(); } - if (getState() == State.INCOMING) { + if (getState() == DialerCallState.INCOMING) { logState.callSpecificAppData = logState .callSpecificAppData @@ -1169,7 +1171,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa "[%s, %s, %s, %s, children:%s, parent:%s, " + "conferenceable:%s, videoState:%s, mSessionModificationState:%d, CameraDir:%s]", id, - State.toString(getState()), + DialerCallState.toString(getState()), Details.capabilitiesToString(telecomCall.getDetails().getCallCapabilities()), Details.propertiesToString(telecomCall.getDetails().getCallProperties()), childCallIds, @@ -1366,7 +1368,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa public void disconnect() { LogUtil.i("DialerCall.disconnect", ""); - setState(DialerCall.State.DISCONNECTING); + setState(DialerCallState.DISCONNECTING); for (DialerCallListener listener : listeners) { listener.onDialerCallUpdate(); } @@ -1686,88 +1688,6 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa @Retention(RetentionPolicy.SOURCE) public @interface CallHistoryStatus {} - /* Defines different states of this call */ - public static class State { - - public static final int INVALID = 0; - public static final int NEW = 1; /* The call is new. */ - public static final int IDLE = 2; /* The call is idle. Nothing active */ - public static final int ACTIVE = 3; /* There is an active call */ - public static final int INCOMING = 4; /* A normal incoming phone call */ - public static final int CALL_WAITING = 5; /* Incoming call while another is active */ - public static final int DIALING = 6; /* An outgoing call during dial phase */ - public static final int REDIALING = 7; /* Subsequent dialing attempt after a failure */ - public static final int ONHOLD = 8; /* An active phone call placed on hold */ - public static final int DISCONNECTING = 9; /* A call is being ended. */ - public static final int DISCONNECTED = 10; /* State after a call disconnects */ - public static final int CONFERENCED = 11; /* DialerCall part of a conference call */ - public static final int SELECT_PHONE_ACCOUNT = 12; /* Waiting for account selection */ - public static final int CONNECTING = 13; /* Waiting for Telecom broadcast to finish */ - public static final int BLOCKED = 14; /* The number was found on the block list */ - public static final int PULLING = 15; /* An external call being pulled to the device */ - public static final int CALL_PENDING = 16; /* A call is pending on a long process to finish */ - - public static boolean isConnectingOrConnected(int state) { - switch (state) { - case ACTIVE: - case INCOMING: - case CALL_WAITING: - case CONNECTING: - case DIALING: - case PULLING: - case REDIALING: - case ONHOLD: - case CONFERENCED: - return true; - default: - return false; - } - } - - public static boolean isDialing(int state) { - return state == DIALING || state == PULLING || state == REDIALING; - } - - public static String toString(int state) { - switch (state) { - case INVALID: - return "INVALID"; - case NEW: - return "NEW"; - case IDLE: - return "IDLE"; - case ACTIVE: - return "ACTIVE"; - case INCOMING: - return "INCOMING"; - case CALL_WAITING: - return "CALL_WAITING"; - case DIALING: - return "DIALING"; - case PULLING: - return "PULLING"; - case REDIALING: - return "REDIALING"; - case ONHOLD: - return "ONHOLD"; - case DISCONNECTING: - return "DISCONNECTING"; - case DISCONNECTED: - return "DISCONNECTED"; - case CONFERENCED: - return "CONFERENCED"; - case SELECT_PHONE_ACCOUNT: - return "SELECT_PHONE_ACCOUNT"; - case CONNECTING: - return "CONNECTING"; - case BLOCKED: - return "BLOCKED"; - default: - return "UNKNOWN"; - } - } - } - /** Camera direction constants */ public static class CameraDirection { public static final int CAMERA_DIRECTION_UNKNOWN = -1; diff --git a/java/com/android/incallui/call/state/DialerCallState.java b/java/com/android/incallui/call/state/DialerCallState.java new file mode 100644 index 000000000..266d6d6f7 --- /dev/null +++ b/java/com/android/incallui/call/state/DialerCallState.java @@ -0,0 +1,99 @@ +/* + * 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.incallui.call.state; + +/** Defines different states of {@link com.android.incallui.call.DialerCall} */ +public class DialerCallState { + + public static final int INVALID = 0; + public static final int NEW = 1; /* The call is new. */ + public static final int IDLE = 2; /* The call is idle. Nothing active */ + public static final int ACTIVE = 3; /* There is an active call */ + public static final int INCOMING = 4; /* A normal incoming phone call */ + public static final int CALL_WAITING = 5; /* Incoming call while another is active */ + public static final int DIALING = 6; /* An outgoing call during dial phase */ + public static final int REDIALING = 7; /* Subsequent dialing attempt after a failure */ + public static final int ONHOLD = 8; /* An active phone call placed on hold */ + public static final int DISCONNECTING = 9; /* A call is being ended. */ + public static final int DISCONNECTED = 10; /* State after a call disconnects */ + public static final int CONFERENCED = 11; /* DialerCall part of a conference call */ + public static final int SELECT_PHONE_ACCOUNT = 12; /* Waiting for account selection */ + public static final int CONNECTING = 13; /* Waiting for Telecom broadcast to finish */ + public static final int BLOCKED = 14; /* The number was found on the block list */ + public static final int PULLING = 15; /* An external call being pulled to the device */ + public static final int CALL_PENDING = 16; /* A call is pending on a long process to finish */ + + public static boolean isConnectingOrConnected(int state) { + switch (state) { + case ACTIVE: + case INCOMING: + case CALL_WAITING: + case CONNECTING: + case DIALING: + case PULLING: + case REDIALING: + case ONHOLD: + case CONFERENCED: + return true; + default: + return false; + } + } + + public static boolean isDialing(int state) { + return state == DIALING || state == PULLING || state == REDIALING; + } + + public static String toString(int state) { + switch (state) { + case INVALID: + return "INVALID"; + case NEW: + return "NEW"; + case IDLE: + return "IDLE"; + case ACTIVE: + return "ACTIVE"; + case INCOMING: + return "INCOMING"; + case CALL_WAITING: + return "CALL_WAITING"; + case DIALING: + return "DIALING"; + case PULLING: + return "PULLING"; + case REDIALING: + return "REDIALING"; + case ONHOLD: + return "ONHOLD"; + case DISCONNECTING: + return "DISCONNECTING"; + case DISCONNECTED: + return "DISCONNECTED"; + case CONFERENCED: + return "CONFERENCED"; + case SELECT_PHONE_ACCOUNT: + return "SELECT_PHONE_ACCOUNT"; + case CONNECTING: + return "CONNECTING"; + case BLOCKED: + return "BLOCKED"; + default: + return "UNKNOWN"; + } + } +} diff --git a/java/com/android/incallui/callpending/CallPendingActivity.java b/java/com/android/incallui/callpending/CallPendingActivity.java index 831ebbd52..3c69f97b5 100644 --- a/java/com/android/incallui/callpending/CallPendingActivity.java +++ b/java/com/android/incallui/callpending/CallPendingActivity.java @@ -31,7 +31,7 @@ import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.Session; import com.android.dialer.multimedia.MultimediaData; import com.android.incallui.audiomode.AudioModeProvider; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.incall.bindings.InCallBindings; import com.android.incallui.incall.protocol.ContactPhotoType; import com.android.incallui.incall.protocol.InCallButtonIds; @@ -148,7 +148,7 @@ public class CallPendingActivity extends FragmentActivity inCallScreen.setPrimary(createPrimaryInfo()); inCallScreen.setCallState( PrimaryCallState.builder() - .setState(State.CALL_PENDING) + .setState(DialerCallState.CALL_PENDING) .setCustomLabel(getCallPendingLabel()) .build()); inCallScreen.setEndCallButtonEnabled(true, true); diff --git a/java/com/android/incallui/contactgrid/BottomRow.java b/java/com/android/incallui/contactgrid/BottomRow.java index dc86d819b..7388c50a8 100644 --- a/java/com/android/incallui/contactgrid/BottomRow.java +++ b/java/com/android/incallui/contactgrid/BottomRow.java @@ -22,7 +22,7 @@ import android.telephony.PhoneNumberUtils; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.incall.protocol.PrimaryCallState; import com.android.incallui.incall.protocol.PrimaryInfo; @@ -74,7 +74,7 @@ public class BottomRow { public static Info getInfo(Context context, PrimaryCallState state, PrimaryInfo primaryInfo) { CharSequence label; - boolean isTimerVisible = state.state() == State.ACTIVE; + boolean isTimerVisible = state.state() == DialerCallState.ACTIVE; boolean isForwardIconVisible = state.isForwardedNumber(); boolean isWorkIconVisible = state.isWorkCall(); boolean isHdIconVisible = state.isHdAudioCall() && !isForwardIconVisible; @@ -86,13 +86,13 @@ public class BottomRow { label = context.getString(R.string.contact_grid_incoming_suspected_spam); isSpamIconVisible = true; isHdIconVisible = false; - } else if (state.state() == State.DISCONNECTING) { + } else if (state.state() == DialerCallState.DISCONNECTING) { // While in the DISCONNECTING state we display a "Hanging up" message in order to make the UI // feel more responsive. (In GSM it's normal to see a delay of a couple of seconds while // negotiating the disconnect with the network, so the "Hanging up" state at least lets the // user know that we're doing something. This state is currently not used with CDMA.) label = context.getString(R.string.incall_hanging_up); - } else if (state.state() == State.DISCONNECTED) { + } else if (state.state() == DialerCallState.DISCONNECTED) { label = state.disconnectCause().getLabel(); if (TextUtils.isEmpty(label)) { label = context.getString(R.string.incall_call_ended); @@ -134,6 +134,7 @@ public class BottomRow { } private static boolean isIncoming(PrimaryCallState state) { - return state.state() == State.INCOMING || state.state() == State.CALL_WAITING; + return state.state() == DialerCallState.INCOMING + || state.state() == DialerCallState.CALL_WAITING; } } diff --git a/java/com/android/incallui/contactgrid/TopRow.java b/java/com/android/incallui/contactgrid/TopRow.java index 89300caa8..82a103a61 100644 --- a/java/com/android/incallui/contactgrid/TopRow.java +++ b/java/com/android/incallui/contactgrid/TopRow.java @@ -25,7 +25,7 @@ import android.text.TextDirectionHeuristics; import android.text.TextUtils; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.incall.protocol.PrimaryCallState; import com.android.incallui.incall.protocol.PrimaryInfo; import com.android.incallui.videotech.utils.SessionModificationState; @@ -69,7 +69,8 @@ public class TopRow { icon = context.getDrawable(R.drawable.quantum_ic_network_wifi_vd_theme_24); } - if (state.state() == State.INCOMING || state.state() == State.CALL_WAITING) { + if (state.state() == DialerCallState.INCOMING + || state.state() == DialerCallState.CALL_WAITING) { // Call from // [Wi-Fi icon] Video call from // Hey Jake, pick up! @@ -87,18 +88,20 @@ public class TopRow { } else if (VideoUtils.hasSentVideoUpgradeRequest(state.sessionModificationState()) || VideoUtils.hasReceivedVideoUpgradeRequest(state.sessionModificationState())) { label = getLabelForVideoRequest(context, state); - } else if (state.state() == State.PULLING) { + } else if (state.state() == DialerCallState.PULLING) { label = context.getString(R.string.incall_transferring); - } else if (state.state() == State.DIALING || state.state() == State.CONNECTING) { + } else if (state.state() == DialerCallState.DIALING + || state.state() == DialerCallState.CONNECTING) { // [Wi-Fi icon] Calling via Google Guest // Calling... label = getLabelForDialing(context, state); - } else if (state.state() == State.ACTIVE && state.isRemotelyHeld()) { + } else if (state.state() == DialerCallState.ACTIVE && state.isRemotelyHeld()) { label = context.getString(R.string.incall_remotely_held); - } else if (state.state() == State.ACTIVE + } else if (state.state() == DialerCallState.ACTIVE && shouldShowNumber(primaryInfo, false /* isIncoming */)) { label = spanDisplayNumber(primaryInfo.number()); - } else if (state.state() == State.CALL_PENDING && !TextUtils.isEmpty(state.customLabel())) { + } else if (state.state() == DialerCallState.CALL_PENDING + && !TextUtils.isEmpty(state.customLabel())) { label = state.customLabel(); } else { // Video calling... diff --git a/java/com/android/incallui/incall/protocol/PrimaryCallState.java b/java/com/android/incallui/incall/protocol/PrimaryCallState.java index 1d23036fc..423f86875 100644 --- a/java/com/android/incallui/incall/protocol/PrimaryCallState.java +++ b/java/com/android/incallui/incall/protocol/PrimaryCallState.java @@ -24,8 +24,7 @@ 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.call.state.DialerCallState; import com.android.incallui.videotech.utils.SessionModificationState; import com.google.auto.value.AutoValue; import java.lang.annotation.Retention; @@ -111,7 +110,7 @@ public abstract class PrimaryCallState { public static Builder builder() { return new AutoValue_PrimaryCallState.Builder() - .setState(DialerCall.State.IDLE) + .setState(DialerCallState.IDLE) .setIsVideoCall(false) .setSessionModificationState(SessionModificationState.NO_REQUEST) .setDisconnectCause(new DisconnectCause(DisconnectCause.UNKNOWN)) @@ -193,7 +192,7 @@ public abstract class PrimaryCallState { public PrimaryCallState build() { PrimaryCallState primaryCallState = autoBuild(); if (!TextUtils.isEmpty(primaryCallState.customLabel())) { - Assert.checkArgument(primaryCallState.state() == State.CALL_PENDING); + Assert.checkArgument(primaryCallState.state() == DialerCallState.CALL_PENDING); } return primaryCallState; } diff --git a/java/com/android/incallui/ringtone/DialerRingtoneManager.java b/java/com/android/incallui/ringtone/DialerRingtoneManager.java index b8a3071cc..777133ef5 100644 --- a/java/com/android/incallui/ringtone/DialerRingtoneManager.java +++ b/java/com/android/incallui/ringtone/DialerRingtoneManager.java @@ -22,7 +22,7 @@ import android.provider.Settings; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.android.incallui.call.CallList; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import java.util.Objects; /** @@ -44,7 +44,7 @@ public class DialerRingtoneManager { * Creates the DialerRingtoneManager with the given {@link InCallTonePlayer}. * * @param inCallTonePlayer the tone player used to play in-call tones. - * @param callList the CallList used to check for {@link State#CALL_WAITING} + * @param callList the CallList used to check for {@link DialerCallState#CALL_WAITING} * @throws NullPointerException if inCallTonePlayer or callList are null */ public DialerRingtoneManager( @@ -54,8 +54,8 @@ public class DialerRingtoneManager { } /** - * Determines if a ringtone should be played for the given call state (see {@link State}) and - * {@link Uri}. + * Determines if a ringtone should be played for the given call state (see {@link + * DialerCallState}) and {@link Uri}. * * @param callState the call state for the call being checked. * @param ringtoneUri the ringtone to potentially play. @@ -63,7 +63,7 @@ public class DialerRingtoneManager { */ public boolean shouldPlayRingtone(int callState, @Nullable Uri ringtoneUri) { return isDialerRingingEnabled() - && translateCallStateForCallWaiting(callState) == State.INCOMING + && translateCallStateForCallWaiting(callState) == DialerCallState.INCOMING && ringtoneUri != null; } @@ -79,14 +79,16 @@ public class DialerRingtoneManager { } /** - * The incoming callState is never set as {@link State#CALL_WAITING} because {@link + * The incoming callState is never set as {@link DialerCallState#CALL_WAITING} because {@link * DialerCall#translateState(int)} doesn't account for that case, check for it here */ private int translateCallStateForCallWaiting(int callState) { - if (callState != State.INCOMING) { + if (callState != DialerCallState.INCOMING) { return callState; } - return callList.getActiveCall() == null ? State.INCOMING : State.CALL_WAITING; + return callList.getActiveCall() == null + ? DialerCallState.INCOMING + : DialerCallState.CALL_WAITING; } private boolean isDialerRingingEnabled() { @@ -97,14 +99,14 @@ public class DialerRingtoneManager { /** * Determines if a call waiting tone should be played for the the given call state (see {@link - * State}). + * DialerCallState}). * * @param callState the call state for the call being checked. * @return {@code true} if the call waiting tone should be played, {@code false} otherwise. */ public boolean shouldPlayCallWaitingTone(int callState) { return isDialerRingingEnabled() - && translateCallStateForCallWaiting(callState) == State.CALL_WAITING + && translateCallStateForCallWaiting(callState) == DialerCallState.CALL_WAITING && !inCallTonePlayer.isPlayingTone(); } diff --git a/java/com/android/incallui/rtt/impl/RttChatFragment.java b/java/com/android/incallui/rtt/impl/RttChatFragment.java index 13e013fd3..1c43f512d 100644 --- a/java/com/android/incallui/rtt/impl/RttChatFragment.java +++ b/java/com/android/incallui/rtt/impl/RttChatFragment.java @@ -55,7 +55,7 @@ import com.android.dialer.rtt.RttTranscript; import com.android.dialer.rtt.RttTranscriptMessage; import com.android.dialer.util.DrawableConverter; import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter; -import com.android.incallui.call.DialerCall.State; +import com.android.incallui.call.state.DialerCallState; import com.android.incallui.hold.OnHoldFragment; import com.android.incallui.incall.protocol.ContactPhotoType; import com.android.incallui.incall.protocol.InCallButtonIds; @@ -452,7 +452,7 @@ public class RttChatFragment extends Fragment public void setCallState(@NonNull PrimaryCallState primaryCallState) { LogUtil.i("RttChatFragment.setCallState", primaryCallState.toString()); this.primaryCallState = primaryCallState; - if (!isTimerStarted && primaryCallState.state() == State.ACTIVE) { + if (!isTimerStarted && primaryCallState.state() == DialerCallState.ACTIVE) { LogUtil.i( "RttChatFragment.setCallState", "starting timer with base: %d", chronometer.getBase()); chronometer.setBase( @@ -469,12 +469,12 @@ public class RttChatFragment extends Fragment } adapter.showAdvisory(); } - if (primaryCallState.state() == State.DIALING) { + if (primaryCallState.state() == DialerCallState.DIALING) { showWaitingForJoinBanner(); } else { hideWaitingForJoinBanner(); } - if (primaryCallState.state() == State.DISCONNECTED) { + if (primaryCallState.state() == DialerCallState.DISCONNECTED) { rttCallScreenDelegate.onSaveRttTranscript(); } } -- cgit v1.2.3 From 859300301faa4a14415aa2080df9f0ddea2a5e2c Mon Sep 17 00:00:00 2001 From: yueg Date: Fri, 27 Apr 2018 15:15:23 -0700 Subject: Remove audio change behavior for background calling. Bug: 74022483 Test: manual PiperOrigin-RevId: 194600612 Change-Id: Idc15d873abfcb47a799e43468ffdd0fe1d90cc5c --- java/com/android/incallui/InCallPresenter.java | 35 -------------------------- 1 file changed, 35 deletions(-) diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 670af9d54..8193c6e05 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -273,8 +273,6 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud private SpeakEasyCallManager speakEasyCallManager; - private boolean audioRouteSetForBubbleMode; - /** Inaccessible constructor. Must use getRunningInstance() to get this singleton. */ @VisibleForTesting InCallPresenter() {} @@ -1612,8 +1610,6 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud isChangingConfigurations = false; - audioRouteSetForBubbleMode = false; - // blow away stale contact info so that we get fresh data on // the next set of calls if (contactInfoCache != null) { @@ -1893,42 +1889,11 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud @Override public void onAudioStateChanged(CallAudioState audioState) { - // Set sensible audio route for bubble mode when we get real audio state for the first time - // During the first time this function is called, supportedRouteMask is set to - // SUPPORTED_AUDIO_ROUTE_ALL, but it's OK since shouldStartInBubbleMode() is false at that time - // (callList not updated yet). - if (!audioRouteSetForBubbleMode && shouldStartInBubbleMode()) { - setAudioRouteForBubbleMode(audioState); - audioRouteSetForBubbleMode = true; - } - if (statusBarNotifier != null) { statusBarNotifier.updateNotification(); } } - /** - * Set audio route to make audio sensible. According to availability, set audio route to Bluetooth - * or wired headset or speaker. - */ - private void setAudioRouteForBubbleMode(CallAudioState audioState) { - if ((audioState.getSupportedRouteMask() & CallAudioState.ROUTE_BLUETOOTH) - == CallAudioState.ROUTE_BLUETOOTH) { - // Use Bluetooth if available - TelecomAdapter.getInstance().setAudioRoute(CallAudioState.ROUTE_BLUETOOTH); - LogUtil.i("InCallPrenter.setAudioRouteForBubbleMode", "bluetooth"); - } else if ((audioState.getSupportedRouteMask() & CallAudioState.ROUTE_WIRED_HEADSET) - == CallAudioState.ROUTE_WIRED_HEADSET) { - // Use wired headset if available - TelecomAdapter.getInstance().setAudioRoute(CallAudioState.ROUTE_WIRED_HEADSET); - LogUtil.i("InCallPrenter.setAudioRouteForBubbleMode", "wired headset"); - } else { - // Use speaker - TelecomAdapter.getInstance().setAudioRoute(CallAudioState.ROUTE_SPEAKER); - LogUtil.i("InCallPrenter.setAudioRouteForBubbleMode", "speaker"); - } - } - /** All the main states of InCallActivity. */ public enum InCallState { // InCall Screen is off and there are no calls -- cgit v1.2.3 From 6f0a22d53d997438721655573f9b9e31923f64ca Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Fri, 27 Apr 2018 15:58:27 -0700 Subject: Implemented remove starred contact from speed dial fragment. This is triggered by long pressing a SpeedDialUiItem and selecting remove in the resulting menu. This will remove it's assocaited entry from the SpeedDialEntry database and if the contact associated with the SpeedDialUiItem being removed only has one speed dial entry, additionally we will unstar the contact as well. Bug: 77761023 Test: WIP PiperOrigin-RevId: 194606709 Change-Id: I4d6fb104a388c39c77796f7626cd63e991303a51 --- .../dialer/speeddial/SpeedDialFragment.java | 41 +++++++++-- .../speeddial/loader/SpeedDialUiItemMutator.java | 80 ++++++++++++++++++++++ 2 files changed, 114 insertions(+), 7 deletions(-) diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index 018f97888..54709e491 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -105,6 +105,10 @@ public class SpeedDialFragment extends Fragment { LogUtil.enterBlock("SpeedDialFragment.onCreateView"); View rootLayout = inflater.inflate(R.layout.fragment_speed_dial, container, false); + speedDialLoaderListener = + DialerExecutorComponent.get(getContext()) + .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener"); + // Setup favorite contact context menu contextMenu = rootLayout.findViewById(R.id.favorite_contact_context_menu); contextMenuBackground = rootLayout.findViewById(R.id.context_menu_background); @@ -124,7 +128,11 @@ public class SpeedDialFragment extends Fragment { rootLayout, contextMenu, contextMenuBackground, - new SpeedDialContextMenuItemListener(getActivity(), getChildFragmentManager()), + new SpeedDialContextMenuItemListener( + getActivity(), + getChildFragmentManager(), + new UpdateSpeedDialAdapterListener(), + speedDialLoaderListener), layoutManager); adapter = new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener); @@ -138,10 +146,6 @@ public class SpeedDialFragment extends Fragment { ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView); adapter.setItemTouchHelper(touchHelper); - - speedDialLoaderListener = - DialerExecutorComponent.get(getContext()) - .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener"); return rootLayout; } @@ -437,11 +441,18 @@ public class SpeedDialFragment extends Fragment { private final FragmentActivity activity; private final FragmentManager childFragmentManager; + private final SupportUiListener> speedDialLoaderListener; + private final UpdateSpeedDialAdapterListener updateAdapterListener; SpeedDialContextMenuItemListener( - FragmentActivity activity, FragmentManager childFragmentManager) { + FragmentActivity activity, + FragmentManager childFragmentManager, + UpdateSpeedDialAdapterListener updateAdapterListener, + SupportUiListener> speedDialLoaderListener) { this.activity = activity; this.childFragmentManager = childFragmentManager; + this.updateAdapterListener = updateAdapterListener; + this.speedDialLoaderListener = speedDialLoaderListener; } @Override @@ -472,7 +483,15 @@ public class SpeedDialFragment extends Fragment { @Override public void removeFavoriteContact(SpeedDialUiItem speedDialUiItem) { - // TODO(calderwoodra): implement remove + speedDialLoaderListener.listen( + activity, + UiItemLoaderComponent.get(activity) + .speedDialUiItemMutator() + .removeSpeedDialUiItem(speedDialUiItem), + updateAdapterListener::updateAdapter, + throwable -> { + throw new RuntimeException(throwable); + }); } @Override @@ -485,6 +504,14 @@ public class SpeedDialFragment extends Fragment { } } + /** Listener for when a SpeedDialUiItem is updated. */ + private class UpdateSpeedDialAdapterListener { + + void updateAdapter(ImmutableList speedDialUiItems) { + onSpeedDialUiItemListLoaded(speedDialUiItems); + } + } + /** Interface for {@link SpeedDialFragment} to communicate with its host/parent. */ public interface HostInterface { diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java index 5dae2efab..e8892c431 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java @@ -54,6 +54,7 @@ import com.google.common.util.concurrent.ListeningExecutorService; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -108,6 +109,85 @@ public final class SpeedDialUiItemMutator { return dialerFutureSerializer.submit(this::loadSpeedDialUiItemsInternal, backgroundExecutor); } + /** + * Delete the SpeedDialUiItem. + * + *

If the item is starred, it's entry will be removed from the SpeedDialEntry database. + * Additionally, if the contact only has one entry in the database, it will be unstarred. + * + *

If the item isn't starred, it's usage data will be deleted but the suggestion can come back + * if the user calls that contact again. + * + * @return the updated list of SpeedDialUiItems. + */ + public ListenableFuture> removeSpeedDialUiItem( + SpeedDialUiItem speedDialUiItem) { + return dialerFutureSerializer.submit( + () -> removeSpeedDialUiItemInternal(speedDialUiItem), backgroundExecutor); + } + + @WorkerThread + private ImmutableList removeSpeedDialUiItemInternal( + SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + if (speedDialUiItem.isStarred()) { + removeStarredSpeedDialUiItem(speedDialUiItem); + } else { + removeSuggestedSpeedDialUiItem(speedDialUiItem); + } + return loadSpeedDialUiItemsInternal(); + } + + /** + * Delete the SpeedDialEntry associated with the passed in SpeedDialUiItem. Additionally, if the + * entry being deleted is the only entry for that contact, unstar it in the cp2. + */ + @WorkerThread + private void removeStarredSpeedDialUiItem(SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + Assert.checkArgument(speedDialUiItem.isStarred()); + SpeedDialEntryDao db = getSpeedDialEntryDao(); + ImmutableList entries = db.getAllEntries(); + + SpeedDialEntry entryToDelete = null; + int entriesForTheSameContact = 0; + for (SpeedDialEntry entry : entries) { + if (entry.contactId() == speedDialUiItem.contactId()) { + entriesForTheSameContact++; + } + + if (Objects.equals(entry.id(), speedDialUiItem.speedDialEntryId())) { + Assert.checkArgument(entryToDelete == null); + entryToDelete = entry; + } + } + db.delete(ImmutableList.of(entryToDelete.id())); + if (entriesForTheSameContact == 1) { + unstarContact(speedDialUiItem); + } + } + + @WorkerThread + private void unstarContact(SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + ContentValues contentValues = new ContentValues(); + contentValues.put(Phone.STARRED, 0); + appContext + .getContentResolver() + .update( + Phone.CONTENT_URI, + contentValues, + Phone.CONTACT_ID + " = ?", + new String[] {Long.toString(speedDialUiItem.contactId())}); + } + + @WorkerThread + @SuppressWarnings("unused") + private void removeSuggestedSpeedDialUiItem(SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + // TODO(calderwoodra): remove strequent contact + } + /** * Takes a contact uri from {@link Phone#CONTENT_URI} and updates {@link Phone#STARRED} to be * true, if it isn't already or Inserts the contact into the {@link SpeedDialEntryDatabaseHelper} -- cgit v1.2.3 From 16b77d4d484dca3d4a070709cfb046c6fba8c993 Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Fri, 27 Apr 2018 23:12:57 -0700 Subject: Updated logic on showing voice/video/sms options in favorites menus. Bug: 78492066 Test: numerous PiperOrigin-RevId: 194635336 Change-Id: I7be0efad4dc9e11beceb02c9b2f4c719d29dbbd1 --- java/com/android/dialer/speeddial/ContextMenu.java | 44 +++------ .../dialer/speeddial/SpeedDialFragment.java | 53 +---------- .../dialer/speeddial/loader/SpeedDialUiItem.java | 101 ++++++++++++++------- 3 files changed, 83 insertions(+), 115 deletions(-) diff --git a/java/com/android/dialer/speeddial/ContextMenu.java b/java/com/android/dialer/speeddial/ContextMenu.java index 126373c12..09505ab99 100644 --- a/java/com/android/dialer/speeddial/ContextMenu.java +++ b/java/com/android/dialer/speeddial/ContextMenu.java @@ -18,10 +18,12 @@ package com.android.dialer.speeddial; import android.content.Context; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; +import com.android.dialer.common.Assert; import com.android.dialer.speeddial.database.SpeedDialEntry.Channel; import com.android.dialer.speeddial.loader.SpeedDialUiItem; @@ -30,13 +32,13 @@ public class ContextMenu extends LinearLayout { private ContextMenuItemListener listener; + private TextView voiceView; private TextView videoView; private TextView smsView; private SpeedDialUiItem speedDialUiItem; private Channel voiceChannel; private Channel videoChannel; - private Channel smsChannel; public ContextMenu(Context context, @Nullable AttributeSet attrs) { super(context, attrs); @@ -50,9 +52,11 @@ public class ContextMenu extends LinearLayout { videoView.setOnClickListener(v -> placeVideoCall()); smsView = findViewById(R.id.send_message_container); - smsView.setOnClickListener(v -> listener.openSmsConversation(smsChannel.number())); + smsView.setOnClickListener(v -> listener.openSmsConversation(voiceChannel.number())); + + voiceView = findViewById(R.id.voice_call_container); + voiceView.setOnClickListener(v -> placeVoiceCall()); - findViewById(R.id.voice_call_container).setOnClickListener(v -> placeVoiceCall()); findViewById(R.id.remove_container) .setOnClickListener(v -> listener.removeFavoriteContact(speedDialUiItem)); findViewById(R.id.contact_info_container) @@ -76,14 +80,11 @@ public class ContextMenu extends LinearLayout { setX((float) (childLocation[0] + .5 * childLayout.getWidth() - .5 * getWidth())); setY(childLocation[1] - parentLocation[1] + childLayout.getHeight()); - voiceChannel = speedDialUiItem.getDeterministicVoiceChannel(); - videoChannel = speedDialUiItem.getDeterministicVideoChannel(); - videoView.setVisibility( - videoChannel == null && !speedDialUiItem.hasVideoChannels() ? View.GONE : View.VISIBLE); - - // TODO(calderwoodra): disambig dialog for texts? - smsChannel = voiceChannel; - smsView.setVisibility(smsChannel == null ? View.GONE : View.VISIBLE); + voiceChannel = speedDialUiItem.getDefaultVoiceChannel(); + videoChannel = speedDialUiItem.getDefaultVideoChannel(); + voiceView.setVisibility(videoChannel == null ? View.GONE : View.VISIBLE); + videoView.setVisibility(videoChannel == null ? View.GONE : View.VISIBLE); + smsView.setVisibility(voiceChannel == null ? View.GONE : View.VISIBLE); // TODO(calderwoodra): a11y // TODO(calderwoodra): animate this similar to the bubble menu @@ -102,19 +103,11 @@ public class ContextMenu extends LinearLayout { } private void placeVoiceCall() { - if (voiceChannel == null) { - listener.disambiguateCall(speedDialUiItem); - } else { - listener.placeCall(voiceChannel); - } + listener.placeCall(Assert.isNotNull(voiceChannel)); } private void placeVideoCall() { - if (videoChannel == null) { - listener.disambiguateCall(speedDialUiItem); - } else { - listener.placeCall(videoChannel); - } + listener.placeCall(Assert.isNotNull(videoChannel)); } public boolean isVisible() { @@ -122,19 +115,12 @@ public class ContextMenu extends LinearLayout { } /** Listener to report user clicks on menu items. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public interface ContextMenuItemListener { /** Called when the user selects "voice call" or "video call" option from the context menu. */ void placeCall(Channel channel); - /** - * Called when the user selects "voice call" or "video call" option from the context menu, but - * it's not clear which channel they want to call. - * - *

TODO(calderwoodra): discuss with product how we want to handle these cases - */ - void disambiguateCall(SpeedDialUiItem speedDialUiItem); - /** Called when the user selects "send message" from the context menu. */ void openSmsConversation(String number); diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index 54709e491..97a5facab 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -130,7 +130,6 @@ public class SpeedDialFragment extends Fragment { contextMenuBackground, new SpeedDialContextMenuItemListener( getActivity(), - getChildFragmentManager(), new UpdateSpeedDialAdapterListener(), speedDialLoaderListener), layoutManager); @@ -321,19 +320,17 @@ public class SpeedDialFragment extends Fragment { Channel defaultChannel = speedDialUiItem.defaultChannel(); // Add voice call module - Channel voiceChannel = speedDialUiItem.getDeterministicVoiceChannel(); + Channel voiceChannel = speedDialUiItem.getDefaultVoiceChannel(); if (voiceChannel != null) { modules.add( IntentModule.newCallModule( getContext(), new CallIntentBuilder(voiceChannel.number(), CallInitiationType.Type.SPEED_DIAL) .setAllowAssistedDial(true))); - } else { - modules.add(new DisambigDialogModule(speedDialUiItem, /* isVideo = */ false)); } // Add video if we can determine the correct channel - Channel videoChannel = speedDialUiItem.getDeterministicVideoChannel(); + Channel videoChannel = speedDialUiItem.getDefaultVideoChannel(); if (videoChannel != null) { modules.add( IntentModule.newCallModule( @@ -341,8 +338,6 @@ public class SpeedDialFragment extends Fragment { new CallIntentBuilder(videoChannel.number(), CallInitiationType.Type.SPEED_DIAL) .setIsVideoCall(true) .setAllowAssistedDial(true))); - } else if (speedDialUiItem.hasVideoChannels()) { - modules.add(new DisambigDialogModule(speedDialUiItem, /* isVideo = */ true)); } // Add sms module @@ -400,67 +395,23 @@ public class SpeedDialFragment extends Fragment { return false; } } - - private final class DisambigDialogModule implements HistoryItemActionModule { - - private final SpeedDialUiItem speedDialUiItem; - private final boolean isVideo; - - DisambigDialogModule(SpeedDialUiItem speedDialUiItem, boolean isVideo) { - this.speedDialUiItem = speedDialUiItem; - this.isVideo = isVideo; - } - - @Override - public int getStringId() { - if (isVideo) { - return R.string.contact_menu_video_call; - } else { - return R.string.contact_menu_voice_call; - } - } - - @Override - public int getDrawableId() { - if (isVideo) { - return R.drawable.quantum_ic_videocam_vd_theme_24; - } else { - return R.drawable.quantum_ic_phone_vd_theme_24; - } - } - - @Override - public boolean onClick() { - DisambigDialog.show(speedDialUiItem, getChildFragmentManager()); - return true; - } - } } private static final class SpeedDialContextMenuItemListener implements ContextMenuItemListener { private final FragmentActivity activity; - private final FragmentManager childFragmentManager; private final SupportUiListener> speedDialLoaderListener; private final UpdateSpeedDialAdapterListener updateAdapterListener; SpeedDialContextMenuItemListener( FragmentActivity activity, - FragmentManager childFragmentManager, UpdateSpeedDialAdapterListener updateAdapterListener, SupportUiListener> speedDialLoaderListener) { this.activity = activity; - this.childFragmentManager = childFragmentManager; this.updateAdapterListener = updateAdapterListener; this.speedDialLoaderListener = speedDialLoaderListener; } - @Override - public void disambiguateCall(SpeedDialUiItem speedDialUiItem) { - // TODO(calderwoodra): show only video or voice channels in the disambig dialog - DisambigDialog.show(speedDialUiItem, childFragmentManager); - } - @Override public void placeCall(Channel channel) { if (channel.technology() == Channel.DUO) { diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java index c5a3ea3ed..325af238a 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java @@ -162,61 +162,77 @@ public abstract class SpeedDialUiItem { } /** - * Returns a video channel if there is exactly one video channel or the default channel is a video - * channel. + * Returns one of the following: + * + *

    + *
  • The default channel if it's a video channel. + *
  • A video channel if it has the same attributes as the default channel, OR + *
  • null. (This is a deliberate product decision, even if there is only a single video + * reachable channel, we should still return null if it has different attributes from those + * in the default channel). + *
*/ @Nullable - public Channel getDeterministicVideoChannel() { - if (defaultChannel() != null && defaultChannel().isVideoTechnology()) { + public Channel getDefaultVideoChannel() { + if (defaultChannel() == null) { + return null; + } + + if (defaultChannel().isVideoTechnology()) { return defaultChannel(); } - Channel videoChannel = null; - for (Channel channel : channels()) { - if (channel.isVideoTechnology()) { - if (videoChannel != null) { - // We found two video channels, so we can't determine which one is correct.. - return null; - } - videoChannel = channel; - } + if (channels().size() == 1) { + // If there is only a single channel, it can't be a video channel + return null; } - // Only found one channel, so return it - return videoChannel; - } - /** Returns true if any channels are video channels. */ - public boolean hasVideoChannels() { - for (Channel channel : channels()) { - if (channel.isVideoTechnology()) { - return true; + // At this point, the default channel is a *voice* channel and there are more than + // one channel in total. + // + // Our defined assumptions about the channel list include that if a video channel + // follows a voice channel, it has the same attributes as that voice channel + // (see comments on method channels() for details). + // + // Therefore, if the default video channel exists, it must be the immediate successor + // of the default channel in the list. + // + // Note that we don't have to check if the last channel in the list is the default + // channel because even if it is, there will be no video channel under the assumption + // above. + for (int i = 0; i < channels().size() - 1; i++) { + // Find the default channel + if (Objects.equals(defaultChannel(), channels().get(i))) { + // Our defined assumptions about the list of channels is that if a video channel follows a + // voice channel, it has the same attributes as that voice channel. + Channel channel = channels().get(i + 1); + if (channel.isVideoTechnology()) { + return channel; + } + // Since the default voice channel isn't video reachable, we can't video call this number + return null; } } - return false; + throw Assert.createIllegalStateFailException("channels() doesn't contain defaultChannel()."); } /** - * Returns a voice channel if there is exactly one voice channel or the default channel is a voice + * Returns a voice channel if there is exactly one channel or the default channel is a voice * channel. */ @Nullable - public Channel getDeterministicVoiceChannel() { + public Channel getDefaultVoiceChannel() { if (defaultChannel() != null && !defaultChannel().isVideoTechnology()) { return defaultChannel(); } - Channel voiceChannel = null; - for (Channel channel : channels()) { - if (!channel.isVideoTechnology()) { - if (voiceChannel != null) { - // We found two voice channels, so we can't determine which one is correct.. - return null; - } - voiceChannel = channel; - } + if (channels().size() == 1) { + // If there is only a single channel, it must be a voice channel as per our defined + // assumptions (detailed in comments on method channels()). + return channels().get(0); } - // Only found one channel, so return it - return voiceChannel; + + return null; } /** @@ -254,6 +270,21 @@ public abstract class SpeedDialUiItem { * enumerate each one here so that the user can choose the correct one. Each channel here * represents a row in the {@link com.android.dialer.speeddial.DisambigDialog}. * + *

These channels have a few very strictly enforced assumption that are used heavily throughout + * the codebase. Those assumption are that: + * + *

    + *
  1. Each of the contact's numbers are voice reachable. So if a channel has it's technology + * set to anything other than {@link Channel#VOICE}, there is gaurenteed to be another + * channel with the exact same attributes, but technology will be {@link Channel#VOICE}. + *
  2. For each of the contact's phone numbers, there will be a voice channel, then the next + * channel will either be the same phone number but a video channel, or a new number. + *
+ * + * For example: Say a contact has two phone numbers (A & B) and A is duo reachable. Then you can + * assume the list of channels will be ordered as either {A_voice, A_duo, B_voice} or {B_voice, + * A_voice, A_duo}. + * * @see com.android.dialer.speeddial.database.SpeedDialEntry.Channel */ public abstract ImmutableList channels(); -- cgit v1.2.3