diff options
15 files changed, 111 insertions, 17 deletions
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java index 3e6b50cae..a4c075c51 100644 --- a/java/com/android/dialer/app/DialtactsActivity.java +++ b/java/com/android/dialer/app/DialtactsActivity.java @@ -1410,7 +1410,7 @@ public class DialtactsActivity extends TransactionSafeActivity } private boolean phoneIsInUse() { - return TelecomUtil.isInCall(this); + return TelecomUtil.isInManagedCall(this); } private boolean canIntentBeHandled(Intent intent) { diff --git a/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java b/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java index de4e1cc4a..685357ace 100644 --- a/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java +++ b/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java @@ -516,7 +516,7 @@ public class VoicemailPlaybackPresenter mView.disableUiElements(); mIsPrepared = false; - if (mContext != null && TelecomUtil.isInCall(mContext)) { + if (mContext != null && TelecomUtil.isInManagedCall(mContext)) { handleError(new IllegalStateException("Cannot play voicemail when call is in progress")); return; } diff --git a/java/com/android/dialer/callcomposer/CallComposerActivity.java b/java/com/android/dialer/callcomposer/CallComposerActivity.java index fa380cc19..4a6cdbbd8 100644 --- a/java/com/android/dialer/callcomposer/CallComposerActivity.java +++ b/java/com/android/dialer/callcomposer/CallComposerActivity.java @@ -438,7 +438,7 @@ public class CallComposerActivity extends AppCompatActivity maybeShowPrivacyToast(data); if (data.hasImageData() && ConfigProviderBindings.get(this).getBoolean("enable_delayed_ec_images", true) - && !TelecomUtil.isInCall(this)) { + && !TelecomUtil.isInManagedCall(this)) { timeoutHandler.postDelayed(placeTelecomCallRunnable, getRCSTimeoutMillis()); startActivity( CallPendingActivity.getIntent( diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java index e22250c6f..86a83796e 100644 --- a/java/com/android/dialer/dialpadview/DialpadFragment.java +++ b/java/com/android/dialer/dialpadview/DialpadFragment.java @@ -1278,7 +1278,7 @@ public class DialpadFragment extends Fragment * or ringing or dialing, or on hold). */ private boolean isPhoneInUse() { - return getContext() != null && TelecomUtil.isInCall(getContext()); + return getContext() != null && TelecomUtil.isInManagedCall(getContext()); } /** @return true if the phone is a CDMA phone type */ diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java index 910e454f8..5b3532cdb 100644 --- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java +++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java @@ -32,6 +32,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor; import com.android.dialer.animation.AnimUtils; import com.android.dialer.callintent.CallInitiationType; @@ -198,6 +200,7 @@ public final class NewSearchFragment extends Fragment } } + /** Translate the search fragment and resize it to fit on the screen. */ public void animatePosition(int start, int end, int duration) { // Called before the view is ready, prepare a runnable to run in onCreateView if (getView() == null) { @@ -206,11 +209,30 @@ public final class NewSearchFragment extends Fragment } boolean slideUp = start > end; Interpolator interpolator = slideUp ? AnimUtils.EASE_IN : AnimUtils.EASE_OUT; + int startHeight = getView().getHeight(); + int endHeight = startHeight - (end - start); getView().setTranslationY(start); - getView().animate().translationY(end).setInterpolator(interpolator).setDuration(duration); + getView() + .animate() + .translationY(end) + .setInterpolator(interpolator) + .setDuration(duration) + .setUpdateListener( + animation -> setHeight(startHeight, endHeight, animation.getAnimatedFraction())); updatePositionRunnable = null; } + private void setHeight(int start, int end, float percentage) { + View view = getView(); + if (view == null) { + return; + } + + FrameLayout.LayoutParams params = (LayoutParams) view.getLayoutParams(); + params.height = (int) (start + (end - start) * percentage); + view.setLayoutParams(params); + } + @Override public void onDestroy() { super.onDestroy(); diff --git a/java/com/android/dialer/telecom/TelecomUtil.java b/java/com/android/dialer/telecom/TelecomUtil.java index 573bfe2d9..8ff4b3967 100644 --- a/java/com/android/dialer/telecom/TelecomUtil.java +++ b/java/com/android/dialer/telecom/TelecomUtil.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; import android.provider.CallLog.Calls; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; @@ -140,7 +142,11 @@ public abstract class TelecomUtil { return new ArrayList<>(); } - public static boolean isInCall(Context context) { + /** + * Returns true if there is a dialer managed call in progress. Self managed calls starting from O + * are not included. + */ + public static boolean isInManagedCall(Context context) { return instance.isInCall(context); } @@ -234,7 +240,19 @@ public abstract class TelecomUtil { public boolean isInCall(Context context) { if (hasReadPhoneStatePermission(context)) { - return getTelecomManager(context).isInCall(); + // The TelecomManager#isInCall method returns true anytime the user is in a call. + // Starting in O, the APIs include support for self-managed ConnectionServices so that other + // apps like Duo can tell Telecom about its calls. So, if the user is in a Duo call, + // isInCall would return true. + // Dialer uses this to determine whether to show the "return to call in progress" when + // Dialer is launched. + // Instead, Dialer should use TelecomManager#isInManagedCall, which only returns true if the + // device is in a managed call which Dialer would know about. + if (VERSION.SDK_INT >= VERSION_CODES.O) { + return getTelecomManager(context).isInManagedCall(); + } else { + return getTelecomManager(context).isInCall(); + } } return false; } diff --git a/java/com/android/incallui/ContactInfoCache.java b/java/com/android/incallui/ContactInfoCache.java index 9b92b487c..7bac6d329 100644 --- a/java/com/android/incallui/ContactInfoCache.java +++ b/java/com/android/incallui/ContactInfoCache.java @@ -25,6 +25,7 @@ import android.net.Uri; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.SystemClock; +import android.os.Trace; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.DisplayNameSources; @@ -123,8 +124,10 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { } private ContactInfoCache(Context context) { + Trace.beginSection("ContactInfoCache constructor"); mContext = context; mPhoneNumberService = Bindings.get(context).newPhoneNumberService(context); + Trace.endSection(); } public static synchronized ContactInfoCache getInstance(Context mContext) { @@ -343,6 +346,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { @NonNull final DialerCall call, final boolean isIncoming, @NonNull ContactInfoCacheCallback callback) { + Trace.beginSection("ContactInfoCache.findInfo"); Assert.isMainThread(); Objects.requireNonNull(callback); @@ -364,6 +368,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { callback.onContactInfoComplete(callId, cacheEntry); // If no other callbacks are in flight, we're done. if (callBacks == null) { + Trace.endSection(); return; } } @@ -374,6 +379,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { callBacks.add(callback); if (!forceQuery) { Log.d(TAG, "No need to query again, just return and wait for existing query to finish"); + Trace.endSection(); return; } } else { @@ -412,6 +418,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { callId, call.getNumberPresentation(), callerInfo, false, queryToken); sendInfoNotifications(callId, initialCacheEntry); } + Trace.endSection(); } @AnyThread @@ -421,6 +428,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { CallerInfo callerInfo, boolean didLocalLookup, CallerInfoQueryToken queryToken) { + Trace.beginSection("ContactInfoCache.updateCallerInfoInCacheOnAnyThread"); Log.d( TAG, "updateCallerInfoInCacheOnAnyThread: callId = " @@ -488,6 +496,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { Log.d(TAG, "put entry into map if not exists: " + cacheEntry); mInfoMap.putIfAbsent(callId, cacheEntry); } + Trace.endSection(); return cacheEntry; } @@ -644,6 +653,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { /** Sends the updated information to call the callbacks for the entry. */ @MainThread private void sendInfoNotifications(String callId, ContactCacheEntry entry) { + Trace.beginSection("ContactInfoCache.sendInfoNotifications"); Assert.isMainThread(); final Set<ContactInfoCacheCallback> callBacks = mCallBacks.get(callId); if (callBacks != null) { @@ -651,10 +661,12 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { callBack.onContactInfoComplete(callId, entry); } } + Trace.endSection(); } @MainThread private void sendImageNotifications(String callId, ContactCacheEntry entry) { + Trace.beginSection("ContactInfoCache.sendImageNotifications"); Assert.isMainThread(); final Set<ContactInfoCacheCallback> callBacks = mCallBacks.get(callId); if (callBacks != null && entry.photo != null) { @@ -662,6 +674,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { callBack.onImageLoadComplete(callId, entry); } } + Trace.endSection(); } private void clearCallbacks(String callId) { diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 9b1f674bd..3f87a592d 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -769,15 +769,19 @@ public class InCallPresenter implements CallList.Listener { "InCallPresenter.onIncomingCall", "Phone switching state: " + oldState + " -> " + newState); mInCallState = newState; + Trace.beginSection("listener.onIncomingCall"); for (IncomingCallListener listener : mIncomingCallListeners) { listener.onIncomingCall(oldState, mInCallState, call); } + Trace.endSection(); + Trace.beginSection("onPrimaryCallStateChanged"); if (mInCallActivity != null) { // Re-evaluate which fragment is being shown. mInCallActivity.onPrimaryCallStateChanged(); } Trace.endSection(); + Trace.endSection(); } @Override @@ -1278,6 +1282,7 @@ public class InCallPresenter implements CallList.Listener { * UI needs to be started or finished depending on the new state and does it. */ private InCallState startOrFinishUi(InCallState newState) { + Trace.beginSection("InCallPresenter.startOrFinishUi"); LogUtil.d( "InCallPresenter.startOrFinishUi", "startOrFinishUi: " + mInCallState + " -> " + newState); @@ -1286,6 +1291,7 @@ public class InCallPresenter implements CallList.Listener { // If the state isn't changing we have already done any starting/stopping of activities in // a previous pass...so lets cut out early if (newState == mInCallState) { + Trace.endSection(); return newState; } @@ -1364,6 +1370,7 @@ public class InCallPresenter implements CallList.Listener { LogUtil.i( "InCallPresenter.startOrFinishUi", "Undo the state change: " + newState + " -> " + mInCallState); + Trace.endSection(); return mInCallState; } @@ -1390,6 +1397,7 @@ public class InCallPresenter implements CallList.Listener { attemptCleanup(); } + Trace.endSection(); return newState; } diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java index e5c761820..e54102ca8 100644 --- a/java/com/android/incallui/ReturnToCallController.java +++ b/java/com/android/incallui/ReturnToCallController.java @@ -94,7 +94,7 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio if (showing) { hide(); } else { - if (TelecomUtil.isInCall(context)) { + if (TelecomUtil.isInManagedCall(context)) { show(); } } @@ -175,7 +175,7 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio } if (bubble != null && bubble.isVisible() - && (!TelecomUtil.isInCall(context) + && (!TelecomUtil.isInManagedCall(context) || CallList.getInstance().getActiveOrBackgroundCall() != null)) { bubble.showText(context.getText(R.string.incall_call_ended)); } diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java index e6969c147..92ffae37c 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -40,6 +40,7 @@ import android.media.AudioAttributes; import android.net.Uri; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; +import android.os.Trace; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -236,6 +237,7 @@ public class StatusBarNotifier @RequiresPermission(Manifest.permission.READ_PHONE_STATE) private void showNotification(final CallList callList, final DialerCall call) { + Trace.beginSection("StatusBarNotifier.showNotification"); final boolean isIncoming = (call.getState() == DialerCall.State.INCOMING || call.getState() == DialerCall.State.CALL_WAITING); @@ -269,20 +271,24 @@ public class StatusBarNotifier } } }); + Trace.endSection(); } /** Sets up the main Ui for the notification */ @RequiresPermission(Manifest.permission.READ_PHONE_STATE) private void buildAndSendNotification( CallList callList, DialerCall originalCall, ContactCacheEntry contactInfo) { + Trace.beginSection("StatusBarNotifier.buildAndSendNotification"); // This can get called to update an existing notification after contact information has come // back. However, it can happen much later. Before we continue, we need to make sure that // the call being passed in is still the one we want to show in the notification. final DialerCall call = getCallToShow(callList); if (call == null || !call.getId().equals(originalCall.getId())) { + Trace.endSection(); return; } + Trace.beginSection("prepare work"); final int callState = call.getState(); // Check if data has changed; if nothing is different, don't issue another notification. @@ -314,6 +320,7 @@ public class StatusBarNotifier } else { notificationType = NOTIFICATION_IN_CALL; } + Trace.endSection(); // prepare work if (!checkForChangeAndSaveData( iconResId, @@ -323,6 +330,7 @@ public class StatusBarNotifier callState, notificationType, contactInfo.contactRingtoneUri)) { + Trace.endSection(); return; } @@ -409,6 +417,7 @@ public class StatusBarNotifier addPersonReference(builder, contactInfo, call); + Trace.beginSection("fire notification"); // Fire off the notification Notification notification = builder.build(); @@ -448,8 +457,10 @@ public class StatusBarNotifier memoryInfo.availMem), e); } + Trace.endSection(); call.getLatencyReport().onNotificationShown(); mCurrentNotification = notificationType; + Trace.endSection(); } @Nullable diff --git a/java/com/android/incallui/answer/impl/AnswerFragment.java b/java/com/android/incallui/answer/impl/AnswerFragment.java index db6d43d49..18de72e8b 100644 --- a/java/com/android/incallui/answer/impl/AnswerFragment.java +++ b/java/com/android/incallui/answer/impl/AnswerFragment.java @@ -29,6 +29,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.Trace; import android.support.annotation.DrawableRes; import android.support.annotation.FloatRange; import android.support.annotation.NonNull; @@ -657,6 +658,7 @@ public class AnswerFragment extends Fragment @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Trace.beginSection("AnswerFragment.onCreateView"); Bundle arguments = getArguments(); Assert.checkState(arguments.containsKey(ARG_CALL_ID)); Assert.checkState(arguments.containsKey(ARG_IS_VIDEO_CALL)); @@ -729,6 +731,7 @@ public class AnswerFragment extends Fragment } } + Trace.endSection(); return view; } diff --git a/java/com/android/incallui/contactgrid/ContactGridManager.java b/java/com/android/incallui/contactgrid/ContactGridManager.java index ddf16e340..18bab6ab3 100644 --- a/java/com/android/incallui/contactgrid/ContactGridManager.java +++ b/java/com/android/incallui/contactgrid/ContactGridManager.java @@ -315,6 +315,7 @@ public class ContactGridManager { info.isAssistedDialedVisisble ? View.VISIBLE : View.GONE); if (hdIconImageView.getVisibility() == View.GONE) { if (info.isHdAttemptingIconVisible) { + hdIconImageView.setImageResource(R.drawable.asd_hd_icon); hdIconImageView.setVisibility(View.VISIBLE); hdIconImageView.setActivated(false); Drawable drawableCurrent = hdIconImageView.getDrawable().getCurrent(); @@ -322,6 +323,7 @@ public class ContactGridManager { ((Animatable) drawableCurrent).start(); } } else if (info.isHdIconVisible) { + hdIconImageView.setImageResource(R.drawable.asd_hd_icon); hdIconImageView.setVisibility(View.VISIBLE); hdIconImageView.setActivated(true); } diff --git a/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_bottom_row.xml b/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_bottom_row.xml index 8850dd856..c545c25cd 100644 --- a/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_bottom_row.xml +++ b/java/com/android/incallui/contactgrid/res/layout/incall_contactgrid_bottom_row.xml @@ -29,7 +29,6 @@ <ImageView android:id="@+id/contactgrid_hdIcon" style="@style/BottomRowIcon" - android:src="@drawable/asd_hd_icon" android:visibility="gone"/> <ImageView android:id="@+id/contactgrid_assistedDialingIcon" diff --git a/java/com/android/voicemail/impl/ActivationTask.java b/java/com/android/voicemail/impl/ActivationTask.java index 320ea2aaa..d7a122ce3 100644 --- a/java/com/android/voicemail/impl/ActivationTask.java +++ b/java/com/android/voicemail/impl/ActivationTask.java @@ -23,6 +23,7 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.provider.Settings; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.telecom.PhoneAccountHandle; import android.telephony.ServiceState; @@ -64,6 +65,8 @@ public class ActivationTask extends BaseTask { private final RetryPolicy mRetryPolicy; + @Nullable private OmtpVvmCarrierConfigHelper configForTest; + private Bundle mMessageData; public ActivationTask() { @@ -132,19 +135,27 @@ public class ActivationTask extends BaseTask { PreOMigrationHandler.migrate(getContext(), phoneAccountHandle); - if (!VisualVoicemailSettingsUtil.isEnabled(getContext(), phoneAccountHandle)) { - VvmLog.i(TAG, "VVM is disabled"); - return; + OmtpVvmCarrierConfigHelper helper; + if (configForTest != null) { + helper = configForTest; + } else { + helper = new OmtpVvmCarrierConfigHelper(getContext(), phoneAccountHandle); } - - OmtpVvmCarrierConfigHelper helper = - new OmtpVvmCarrierConfigHelper(getContext(), phoneAccountHandle); if (!helper.isValid()) { VvmLog.i(TAG, "VVM not supported on phoneAccountHandle " + phoneAccountHandle); VvmAccountManager.removeAccount(getContext(), phoneAccountHandle); return; } + if (!VisualVoicemailSettingsUtil.isEnabled(getContext(), phoneAccountHandle)) { + if (helper.isLegacyModeEnabled()) { + VvmLog.i(TAG, "Setting up filter for legacy mode"); + helper.activateSmsFilter(); + } + VvmLog.i(TAG, "VVM is disabled"); + return; + } + // OmtpVvmCarrierConfigHelper can start the activation process; it will pass in a vvm // content provider URI which we will use. On some occasions, setting that URI will // fail, so we will perform a few attempts to ensure that the vvm content provider has @@ -278,4 +289,9 @@ public class ActivationTask extends BaseTask { .createForPhoneAccountHandle(phoneAccountHandle); return telephonyManager.getServiceState().getState() == ServiceState.STATE_IN_SERVICE; } + + @VisibleForTesting + void setConfigForTest(OmtpVvmCarrierConfigHelper config) { + configForTest = config; + } } diff --git a/java/com/android/voicemail/impl/scheduling/BaseTask.java b/java/com/android/voicemail/impl/scheduling/BaseTask.java index bbdca8c88..773d026bf 100644 --- a/java/com/android/voicemail/impl/scheduling/BaseTask.java +++ b/java/com/android/voicemail/impl/scheduling/BaseTask.java @@ -23,6 +23,7 @@ import android.os.SystemClock; import android.support.annotation.CallSuper; import android.support.annotation.MainThread; import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.telecom.PhoneAccountHandle; import com.android.dialer.proguard.UsedByReflection; @@ -38,7 +39,8 @@ import java.util.List; @UsedByReflection(value = "Tasks.java") public abstract class BaseTask implements Task { - private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle"; + @VisibleForTesting + public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle"; private static final String EXTRA_EXECUTION_TIME = "extra_execution_time"; |