diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-01-04 02:10:40 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-01-04 02:10:40 +0000 |
commit | e5f230198f25f68b95b42b429c928647de1630fe (patch) | |
tree | 5a8a02f6cd77315952f6905a15b475663dd98c65 | |
parent | 11a3e7f96eaed1d294a19a2353e77f36a24040d4 (diff) | |
parent | 61ce7cb45d71b2f344143e78f7cd1159bcd9a9a1 (diff) | |
download | Dialer-e5f230198f25f68b95b42b429c928647de1630fe.tar.gz |
Snap for 6109783 from 61ce7cb45d71b2f344143e78f7cd1159bcd9a9a1 to qt-qpr2-release
Change-Id: I3ae88b685c3ca2046b3835e7622ba27db045af59
5 files changed, 83 insertions, 42 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml index 02373561..0418d13f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -86,7 +86,7 @@ <string name="contact_list_empty">No contacts</string> <!-- Secondary message shown when the contact list page or call history page do not have any contents but will be available after syncing from phone [CHAR_LIMIT=200] --> - <string name="available_after_sync">Available after syncing. Make sure you have allowed to share contacts on your phone.</string> + <string name="available_after_sync">Available after syncing. Make sure you have allowed sharing contacts on your phone.</string> <!-- Error message shown when on the favorites page without any favorites added [CHAR_LIMIT=50] --> <string name="favorites_empty">No favorites</string> diff --git a/src/com/android/car/dialer/notification/InCallNotificationController.java b/src/com/android/car/dialer/notification/InCallNotificationController.java index e8a0cf16..e68b35b7 100644 --- a/src/com/android/car/dialer/notification/InCallNotificationController.java +++ b/src/com/android/car/dialer/notification/InCallNotificationController.java @@ -29,13 +29,12 @@ import android.text.TextUtils; import androidx.annotation.StringRes; -import com.android.car.dialer.Constants; import com.android.car.dialer.R; import com.android.car.dialer.log.L; -import com.android.car.dialer.ui.activecall.InCallActivity; import com.android.car.telephony.common.CallDetail; -import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.CompletableFuture; /** Controller that manages the heads up notification for incoming calls. */ @@ -81,6 +80,7 @@ public final class InCallNotificationController { private final Context mContext; private final NotificationManager mNotificationManager; private final Notification.Builder mNotificationBuilder; + private final Set<String> mActiveInCallNotifications; private CompletableFuture<Void> mNotificationFuture; @TargetApi(26) @@ -94,19 +94,14 @@ public final class InCallNotificationController { NotificationManager.IMPORTANCE_HIGH); mNotificationManager.createNotificationChannel(notificationChannel); - Intent intent = new Intent(mContext, InCallActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Constants.Intents.EXTRA_SHOW_INCOMING_CALL, true); - PendingIntent fullscreenIntent = PendingIntent.getActivity(mContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - mNotificationBuilder = new Notification.Builder(mContext, CHANNEL_ID) .setSmallIcon(R.drawable.ic_phone) .setContentText(mContext.getString(R.string.notification_incoming_call)) - .setFullScreenIntent(fullscreenIntent, /* highPriority= */true) .setCategory(Notification.CATEGORY_CALL) .setOngoing(true) .setAutoCancel(false); + + mActiveInCallNotifications = new HashSet<>(); } @@ -121,8 +116,10 @@ public final class InCallNotificationController { CallDetail callDetail = CallDetail.fromTelecomCallDetail(call.getDetails()); String number = callDetail.getNumber(); - String tag = call.getDetails().getTelecomCallId(); + String callId = call.getDetails().getTelecomCallId(); + mActiveInCallNotifications.add(callId); mNotificationBuilder + .setFullScreenIntent(getFullscreenIntent(call), /* highPriority= */true) .setLargeIcon((Icon) null) .setContentTitle(number) .setActions( @@ -131,21 +128,20 @@ public final class InCallNotificationController { getAction(call, R.string.decline_call, NotificationService.ACTION_DECLINE_CALL)); mNotificationManager.notify( - tag, + callId, NOTIFICATION_ID, mNotificationBuilder.build()); mNotificationFuture = NotificationUtils.getDisplayNameAndRoundedAvatar(mContext, number) .thenAcceptAsync((pair) -> { // Check that the notification hasn't already been dismissed - if (Arrays.stream(mNotificationManager.getActiveNotifications()).anyMatch((n) -> - n.getId() == NOTIFICATION_ID && TextUtils.equals(n.getTag(), tag))) { + if (mActiveInCallNotifications.contains(callId)) { mNotificationBuilder .setLargeIcon(pair.second) .setContentTitle(pair.first); mNotificationManager.notify( - tag, + callId, NOTIFICATION_ID, mNotificationBuilder.build()); } @@ -156,8 +152,26 @@ public final class InCallNotificationController { public void cancelInCallNotification(Call call) { L.d(TAG, "cancelInCallNotification"); if (call.getDetails() != null) { - mNotificationManager.cancel(call.getDetails().getTelecomCallId(), NOTIFICATION_ID); + String callId = call.getDetails().getTelecomCallId(); + cancelInCallNotification(callId); + } + } + + /** + * Cancel the incoming call notification for the given call id. Any action that dismisses the + * notification needs to call this explicitly. + */ + void cancelInCallNotification(String callId) { + if (TextUtils.isEmpty(callId)) { + return; } + mActiveInCallNotifications.remove(callId); + mNotificationManager.cancel(callId, NOTIFICATION_ID); + } + + private PendingIntent getFullscreenIntent(Call call) { + Intent intent = getIntent(NotificationService.ACTION_SHOW_FULLSCREEN_UI, call); + return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } private Notification.Action getAction(Call call, @StringRes int actionText, diff --git a/src/com/android/car/dialer/notification/NotificationService.java b/src/com/android/car/dialer/notification/NotificationService.java index 2f282907..f7b8a01c 100644 --- a/src/com/android/car/dialer/notification/NotificationService.java +++ b/src/com/android/car/dialer/notification/NotificationService.java @@ -25,6 +25,7 @@ import androidx.core.app.JobIntentService; import com.android.car.dialer.Constants; import com.android.car.dialer.telecom.UiCallManager; +import com.android.car.dialer.ui.activecall.InCallActivity; import com.android.car.telephony.common.TelecomUtils; import java.util.List; @@ -37,6 +38,7 @@ import java.util.List; public class NotificationService extends JobIntentService { static final String ACTION_ANSWER_CALL = "CD.ACTION_ANSWER_CALL"; static final String ACTION_DECLINE_CALL = "CD.ACTION_DECLINE_CALL"; + static final String ACTION_SHOW_FULLSCREEN_UI = "CD.ACTION_SHOW_FULLSCREEN_UI"; static final String ACTION_CALL_BACK_MISSED = "CD.ACTION_CALL_BACK_MISSED"; static final String ACTION_MESSAGE_MISSED = "CD.ACTION_MESSAGE_MISSED"; static final String ACTION_READ_ALL_MISSED = "CD.ACTION_READ_ALL_MISSED"; @@ -62,9 +64,19 @@ public class NotificationService extends JobIntentService { switch (action) { case ACTION_ANSWER_CALL: answerCall(callId); + InCallNotificationController.get().cancelInCallNotification(callId); break; case ACTION_DECLINE_CALL: declineCall(callId); + InCallNotificationController.get().cancelInCallNotification(callId); + break; + case ACTION_SHOW_FULLSCREEN_UI: + Intent inCallActivityIntent = new Intent(getApplicationContext(), + InCallActivity.class); + inCallActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + inCallActivityIntent.putExtra(Constants.Intents.EXTRA_SHOW_INCOMING_CALL, true); + startActivity(inCallActivityIntent); + InCallNotificationController.get().cancelInCallNotification(callId); break; case ACTION_CALL_BACK_MISSED: UiCallManager.get().placeCall(callId); diff --git a/src/com/android/car/dialer/ui/activecall/InCallActivity.java b/src/com/android/car/dialer/ui/activecall/InCallActivity.java index 7b8215c6..015dc085 100644 --- a/src/com/android/car/dialer/ui/activecall/InCallActivity.java +++ b/src/com/android/car/dialer/ui/activecall/InCallActivity.java @@ -1,11 +1,11 @@ -/** +/* * Copyright (C) 2019 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 + * 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, @@ -60,9 +60,8 @@ public class InCallActivity extends FragmentActivity { InCallViewModel inCallViewModel = ViewModelProviders.of(this).get(InCallViewModel.class); mIncomingCallLiveData = LiveDataFunctions.iff(mShowIncomingCall, inCallViewModel.getIncomingCall()); - mIncomingCallLiveData.observe(this, this::updateIncomingCallVisibility); LiveDataFunctions.pair(inCallViewModel.getOngoingCallList(), mIncomingCallLiveData).observe( - this, this::maybeFinishActivity); + this, this::updateVisibility); handleIntent(); } @@ -71,7 +70,7 @@ public class InCallActivity extends FragmentActivity { protected void onStop() { super.onStop(); L.d(TAG, "onStop"); - if (mShowIncomingCall.getValue()) { + if (mIncomingCallLiveData.getValue() != null) { InCallNotificationController.get() .showInCallNotification(mIncomingCallLiveData.getValue()); } @@ -85,11 +84,14 @@ public class InCallActivity extends FragmentActivity { handleIntent(); } - private void maybeFinishActivity(Pair<List<Call>, Call> callList) { + private void updateVisibility(Pair<List<Call>, Call> callList) { if ((callList.first == null || callList.first.isEmpty()) && callList.second == null) { L.d(TAG, "No call to show. Finish InCallActivity"); finish(); + return; } + + updateIncomingCallVisibility(callList.second); } private void handleIntent() { @@ -105,13 +107,21 @@ public class InCallActivity extends FragmentActivity { private void updateIncomingCallVisibility(Call incomingCall) { if (incomingCall == null) { - getSupportFragmentManager().beginTransaction().show(mOngoingCallFragment).hide( - mIncomingCallFragment).commit(); + getSupportFragmentManager() + .beginTransaction() + .show(mOngoingCallFragment) + .hide(mIncomingCallFragment) + .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out) + .commit(); mShowIncomingCall.setValue(false); setIntent(null); } else { - getSupportFragmentManager().beginTransaction().show(mIncomingCallFragment).hide( - mOngoingCallFragment).commit(); + getSupportFragmentManager() + .beginTransaction() + .show(mIncomingCallFragment) + .hide(mOngoingCallFragment) + .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out) + .commit(); } } } diff --git a/src/com/android/car/dialer/ui/activecall/InCallViewModel.java b/src/com/android/car/dialer/ui/activecall/InCallViewModel.java index 9d3781cd..328695b5 100644 --- a/src/com/android/car/dialer/ui/activecall/InCallViewModel.java +++ b/src/com/android/car/dialer/ui/activecall/InCallViewModel.java @@ -57,10 +57,10 @@ public class InCallViewModel extends AndroidViewModel implements private static final String TAG = "CD.InCallViewModel"; private final MutableLiveData<List<Call>> mCallListLiveData; - private final LiveData<List<Call>> mOngoingCallListLiveData; + private final MutableLiveData<List<Call>> mOngoingCallListLiveData; private final Comparator<Call> mCallComparator; - private final LiveData<Call> mIncomingCallLiveData; + private final MutableLiveData<Call> mIncomingCallLiveData; private final LiveData<CallDetail> mCallDetailLiveData; private final LiveData<Integer> mCallStateLiveData; @@ -99,7 +99,11 @@ public class InCallViewModel extends AndroidViewModel implements private final Call.Callback mCallStateChangedCallback = new Call.Callback() { @Override public void onStateChanged(Call call, int state) { - // Sets value to trigger the live data for incoming call and active call list to update. + // Don't show in call activity by declining a ringing call to avoid UI flashing. + if (call.equals(mIncomingCallLiveData.getValue()) && state == Call.STATE_DISCONNECTED) { + return; + } + // Sets value to trigger incoming call and active call list to update. mCallListLiveData.setValue(mCallListLiveData.getValue()); } }; @@ -108,20 +112,21 @@ public class InCallViewModel extends AndroidViewModel implements super(application); mContext = application.getApplicationContext(); - mCallListLiveData = new MutableLiveData<>(); + mIncomingCallLiveData = new MutableLiveData<>(); + mOngoingCallListLiveData = new MutableLiveData<>(); mCallComparator = new CallComparator(); - - mIncomingCallLiveData = Transformations.map(mCallListLiveData, - callList -> firstMatch(callList, + mCallListLiveData = new MutableLiveData<List<Call>>() { + @Override + public void setValue(List<Call> callList) { + super.setValue(callList); + List<Call> activeCallList = filter(callList, + call -> call != null && call.getState() != Call.STATE_RINGING); + activeCallList.sort(mCallComparator); + mOngoingCallListLiveData.setValue(activeCallList); + mIncomingCallLiveData.setValue(firstMatch(callList, call -> call != null && call.getState() == Call.STATE_RINGING)); - - mOngoingCallListLiveData = Transformations.map(mCallListLiveData, - callList -> { - List<Call> activeCallList = filter(callList, - call -> call != null && call.getState() != Call.STATE_RINGING); - activeCallList.sort(mCallComparator); - return activeCallList; - }); + } + }; mPrimaryCallLiveData = Transformations.map(mOngoingCallListLiveData, input -> input.isEmpty() ? null : input.get(0)); |