From e851821a851b9b97a846a1c8babca5c7e114fc88 Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Tue, 22 Aug 2017 17:14:49 -0700 Subject: Created FakeInCallActivity for making EC w/ images. video (slow/3g): https://drive.google.com/open?id=0B2Hce9qilHmvMnZZbE90TTlNSTQ video (average): https://drive.google.com/open?id=0B2Hce9qilHmvazZNeVJjbU5Db0k video (cancelling): https://drive.google.com/open?id=0B2Hce9qilHmvRi1JUXQ3OHZOYXM Future CLs or updates to this CL will include activity transition improvements and testing. Bug: 38189742 Test: CallComposerActivityIntegrationTest PiperOrigin-RevId: 166137133 Change-Id: Iada3e96c83495fd9a1554b4556be968670513163 --- java/com/android/incallui/CallCardPresenter.java | 2 + java/com/android/incallui/InCallActivity.java | 2 + .../incallui/callpending/AndroidManifest.xml | 32 ++ .../incallui/callpending/CallPendingActivity.java | 342 +++++++++++++++++++++ .../res/layout/pending_incall_screen.xml | 22 ++ .../incallui/incall/impl/InCallFragment.java | 7 +- .../incallui/incall/impl/InCallPagerAdapter.java | 29 +- .../incallui/incall/protocol/PrimaryCallState.java | 6 +- .../incallui/incall/protocol/PrimaryInfo.java | 4 + 9 files changed, 436 insertions(+), 10 deletions(-) create mode 100644 java/com/android/incallui/callpending/AndroidManifest.xml create mode 100644 java/com/android/incallui/callpending/CallPendingActivity.java create mode 100644 java/com/android/incallui/callpending/res/layout/pending_incall_screen.xml (limited to 'java/com/android/incallui') diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java index 389b7c151..5f9f879a8 100644 --- a/java/com/android/incallui/CallCardPresenter.java +++ b/java/com/android/incallui/CallCardPresenter.java @@ -713,6 +713,7 @@ public class CallCardPresenter shouldShowLocation(), null /* contactInfoLookupKey */, null /* enrichedCallMultimediaData */, + true /* showInCallButtonGrid */, mPrimary.getNumberPresentation())); } else if (mPrimaryContactInfo != null) { LogUtil.v( @@ -760,6 +761,7 @@ public class CallCardPresenter shouldShowLocation(), mPrimaryContactInfo.lookupKey, multimediaData, + true /* showInCallButtonGrid */, mPrimary.getNumberPresentation())); } else { // Clear the primary display info. diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 90f532a95..178a404ba 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -49,6 +49,7 @@ import com.android.incallui.answerproximitysensor.PseudoScreenState; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCall.State; +import com.android.incallui.callpending.CallPendingActivity; import com.android.incallui.disconnectdialog.DisconnectMessage; import com.android.incallui.incall.bindings.InCallBindings; import com.android.incallui.incall.protocol.InCallButtonUiDelegate; @@ -141,6 +142,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); pseudoBlackScreenOverlay = findViewById(R.id.psuedo_black_screen_overlay); + sendBroadcast(CallPendingActivity.getFinishBroadcast()); Trace.endSection(); } diff --git a/java/com/android/incallui/callpending/AndroidManifest.xml b/java/com/android/incallui/callpending/AndroidManifest.xml new file mode 100644 index 000000000..231553e6c --- /dev/null +++ b/java/com/android/incallui/callpending/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + diff --git a/java/com/android/incallui/callpending/CallPendingActivity.java b/java/com/android/incallui/callpending/CallPendingActivity.java new file mode 100644 index 000000000..554d02165 --- /dev/null +++ b/java/com/android/incallui/callpending/CallPendingActivity.java @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.incallui.callpending; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import android.telecom.CallAudioState; +import android.telecom.TelecomManager; +import com.android.dialer.common.LogUtil; +import com.android.dialer.enrichedcall.EnrichedCallComponent; +import com.android.dialer.multimedia.MultimediaData; +import com.android.incallui.audiomode.AudioModeProvider; +import com.android.incallui.call.DialerCall.State; +import com.android.incallui.incall.bindings.InCallBindings; +import com.android.incallui.incall.protocol.ContactPhotoType; +import com.android.incallui.incall.protocol.InCallButtonIds; +import com.android.incallui.incall.protocol.InCallButtonUi; +import com.android.incallui.incall.protocol.InCallButtonUiDelegate; +import com.android.incallui.incall.protocol.InCallButtonUiDelegateFactory; +import com.android.incallui.incall.protocol.InCallScreen; +import com.android.incallui.incall.protocol.InCallScreenDelegate; +import com.android.incallui.incall.protocol.InCallScreenDelegateFactory; +import com.android.incallui.incall.protocol.PrimaryCallState; +import com.android.incallui.incall.protocol.PrimaryInfo; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + * Activity useful for showing the incall ui without an actual call being placed. + * + *

The UI currently displays the following: + * + *

+ * + * If the user presses the back or disconnect buttons, {@link #finish()} is called. + */ +public class CallPendingActivity extends FragmentActivity + implements InCallButtonUiDelegateFactory, InCallScreenDelegateFactory { + + private static final String TAG_IN_CALL_SCREEN = "tag_in_call_screen"; + private static final String ACTION_FINISH_BROADCAST = + "dialer.intent.action.CALL_PENDING_ACTIVITY_FINISH"; + + private static final String EXTRA_SESSION_ID = "extra_session_id"; + private static final String EXTRA_NUMBER = "extra_number"; + private static final String EXTRA_NAME = "extra_name"; + private static final String EXTRA_LABEL = "extra_LABEL"; + private static final String EXTRA_LOOKUP_KEY = "extra_LOOKUP_KEY"; + private static final String EXTRA_PHOTO_URI = "extra_photo_uri"; + + private final BroadcastReceiver finishReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context arg0, Intent intent) { + LogUtil.i("CallPendingActivity.onReceive", "finish broadcast received"); + String action = intent.getAction(); + if (action.equals(ACTION_FINISH_BROADCAST)) { + finish(); + } + } + }; + + private InCallButtonUiDelegate inCallButtonUiDelegate; + private InCallScreenDelegate inCallScreenDelegate; + + public static Intent getIntent( + Context context, + String name, + String number, + String label, + String lookupKey, + Uri photoUri, + long sessionId) { + Intent intent = new Intent(context, CallPendingActivity.class); + intent.putExtra(EXTRA_NAME, name); + intent.putExtra(EXTRA_NUMBER, number); + intent.putExtra(EXTRA_LABEL, label); + intent.putExtra(EXTRA_LOOKUP_KEY, lookupKey); + intent.putExtra(EXTRA_PHOTO_URI, photoUri); + intent.putExtra(EXTRA_SESSION_ID, sessionId); + return intent; + } + + public static Intent getFinishBroadcast() { + return new Intent(ACTION_FINISH_BROADCAST); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.pending_incall_screen); + registerReceiver(finishReceiver, new IntentFilter(ACTION_FINISH_BROADCAST)); + } + + @Override + protected void onStart() { + super.onStart(); + InCallScreen inCallScreen = InCallBindings.createInCallScreen(); + getSupportFragmentManager() + .beginTransaction() + .add(R.id.main, inCallScreen.getInCallScreenFragment(), TAG_IN_CALL_SCREEN) + .commit(); + } + + @Override + protected void onResume() { + super.onResume(); + setupInCallScreen(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(finishReceiver); + } + + private void setupInCallScreen() { + InCallScreen inCallScreen = + (InCallScreen) getSupportFragmentManager().findFragmentByTag(TAG_IN_CALL_SCREEN); + inCallScreen.setPrimary(createPrimaryInfo()); + inCallScreen.setCallState(PrimaryCallState.createEmptyPrimaryCallStateWithState(State.DIALING)); + inCallScreen.setEndCallButtonEnabled(true, true); + } + + private PrimaryInfo createPrimaryInfo() { + MultimediaData multimediaData = + EnrichedCallComponent.get(this) + .getEnrichedCallManager() + .getSession(getSessionId()) + .getMultimediaData(); + + Drawable photo = null; + try { + // TODO(calderwoodra) move to background thread + Uri photoUri = getPhotoUri(); + InputStream is = getContentResolver().openInputStream(photoUri); + photo = Drawable.createFromStream(is, photoUri.toString()); + } catch (FileNotFoundException e) { + LogUtil.e("CallPendingActivity.createPrimaryInfo", "Contact photo not found", e); + } + + String name = getName(); + String number = getNumber(); + + // DialerCall with caller that is a work contact. + return new PrimaryInfo( + number, + name, + name != null && name.equals(number), + null /* location */, + getPhoneLabel(), + photo, + ContactPhotoType.CONTACT, + false /* isSipCall */, + true /* isContactPhotoShown */, + false /* isWorkCall */, + false /* isSpam */, + false /* answeringDisconnectsOngoingCall */, + false /* shouldShowLocation */, + getLookupKey(), + multimediaData, + false /*showInCallButtonGrid */, + TelecomManager.PRESENTATION_ALLOWED); + } + + @Override + public InCallButtonUiDelegate newInCallButtonUiDelegate() { + if (inCallButtonUiDelegate != null) { + return inCallButtonUiDelegate; + } + return inCallButtonUiDelegate = + new InCallButtonUiDelegate() { + + @Override + public void onInCallButtonUiReady(InCallButtonUi inCallButtonUi) { + inCallButtonUi.showButton(InCallButtonIds.BUTTON_DIALPAD, true); + inCallButtonUi.showButton(InCallButtonIds.BUTTON_MUTE, true); + inCallButtonUi.showButton(InCallButtonIds.BUTTON_AUDIO, true); + inCallButtonUi.showButton(InCallButtonIds.BUTTON_ADD_CALL, true); + + inCallButtonUi.enableButton(InCallButtonIds.BUTTON_DIALPAD, false); + inCallButtonUi.enableButton(InCallButtonIds.BUTTON_MUTE, false); + inCallButtonUi.enableButton(InCallButtonIds.BUTTON_AUDIO, false); + inCallButtonUi.enableButton(InCallButtonIds.BUTTON_ADD_CALL, false); + } + + @Override + public void onInCallButtonUiUnready() {} + + @Override + public void onSaveInstanceState(Bundle outState) {} + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) {} + + @Override + public void refreshMuteState() {} + + @Override + public void addCallClicked() {} + + @Override + public void muteClicked(boolean checked, boolean clickedByUser) {} + + @Override + public void mergeClicked() {} + + @Override + public void holdClicked(boolean checked) {} + + @Override + public void swapClicked() {} + + @Override + public void showDialpadClicked(boolean checked) {} + + @Override + public void changeToVideoClicked() {} + + @Override + public void switchCameraClicked(boolean useFrontFacingCamera) {} + + @Override + public void toggleCameraClicked() {} + + @Override + public void pauseVideoClicked(boolean pause) {} + + @Override + public void toggleSpeakerphone() {} + + @Override + public CallAudioState getCurrentAudioState() { + return AudioModeProvider.getInstance().getAudioState(); + } + + @Override + public void setAudioRoute(int route) {} + + @Override + public void onEndCallClicked() {} + + @Override + public void showAudioRouteSelector() {} + + @Override + public Context getContext() { + return CallPendingActivity.this; + } + }; + } + + @Override + public InCallScreenDelegate newInCallScreenDelegate() { + if (inCallScreenDelegate != null) { + return inCallScreenDelegate; + } + return inCallScreenDelegate = + new InCallScreenDelegate() { + + @Override + public void onInCallScreenDelegateInit(InCallScreen inCallScreen) {} + + @Override + public void onInCallScreenReady() {} + + @Override + public void onInCallScreenUnready() {} + + @Override + public void onEndCallClicked() { + finish(); + } + + @Override + public void onSecondaryInfoClicked() {} + + @Override + public void onCallStateButtonClicked() {} + + @Override + public void onManageConferenceClicked() {} + + @Override + public void onShrinkAnimationComplete() {} + + @Override + public void onInCallScreenResumed() {} + + @Override + public void onInCallScreenPaused() {} + }; + } + + private long getSessionId() { + return getIntent().getLongExtra(EXTRA_SESSION_ID, -1); + } + + private String getNumber() { + return getIntent().getStringExtra(EXTRA_NUMBER); + } + + private String getName() { + return getIntent().getStringExtra(EXTRA_NAME); + } + + private String getPhoneLabel() { + return getIntent().getStringExtra(EXTRA_LABEL); + } + + private String getLookupKey() { + return getIntent().getStringExtra(EXTRA_LOOKUP_KEY); + } + + private Uri getPhotoUri() { + return getIntent().getParcelableExtra(EXTRA_PHOTO_URI); + } +} diff --git a/java/com/android/incallui/callpending/res/layout/pending_incall_screen.xml b/java/com/android/incallui/callpending/res/layout/pending_incall_screen.xml new file mode 100644 index 000000000..398042b03 --- /dev/null +++ b/java/com/android/incallui/callpending/res/layout/pending_incall_screen.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/java/com/android/incallui/incall/impl/InCallFragment.java b/java/com/android/incallui/incall/impl/InCallFragment.java index 7e39ceb40..f9abf2044 100644 --- a/java/com/android/incallui/incall/impl/InCallFragment.java +++ b/java/com/android/incallui/incall/impl/InCallFragment.java @@ -241,7 +241,7 @@ public class InCallFragment extends Fragment @Override public void setPrimary(@NonNull PrimaryInfo primaryInfo) { LogUtil.i("InCallFragment.setPrimary", primaryInfo.toString()); - setAdapterMedia(primaryInfo.multimediaData); + setAdapterMedia(primaryInfo.multimediaData, primaryInfo.showInCallButtonGrid); contactGridManager.setPrimary(primaryInfo); if (primaryInfo.shouldShowLocation) { @@ -267,9 +267,10 @@ public class InCallFragment extends Fragment } } - private void setAdapterMedia(MultimediaData multimediaData) { + private void setAdapterMedia(MultimediaData multimediaData, boolean showInCallButtonGrid) { if (adapter == null) { - adapter = new InCallPagerAdapter(getChildFragmentManager(), multimediaData); + adapter = + new InCallPagerAdapter(getChildFragmentManager(), multimediaData, showInCallButtonGrid); pager.setAdapter(adapter); } else { adapter.setAttachments(multimediaData); diff --git a/java/com/android/incallui/incall/impl/InCallPagerAdapter.java b/java/com/android/incallui/incall/impl/InCallPagerAdapter.java index d4b04feff..ead35344f 100644 --- a/java/com/android/incallui/incall/impl/InCallPagerAdapter.java +++ b/java/com/android/incallui/incall/impl/InCallPagerAdapter.java @@ -21,6 +21,7 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.PagerAdapter; +import com.android.dialer.common.Assert; import com.android.dialer.multimedia.MultimediaData; import com.android.incallui.sessiondata.MultimediaFragment; @@ -28,28 +29,44 @@ import com.android.incallui.sessiondata.MultimediaFragment; public class InCallPagerAdapter extends FragmentStatePagerAdapter { @Nullable private MultimediaData attachments; + private final boolean showInCallButtonGrid; - public InCallPagerAdapter(FragmentManager fragmentManager, @Nullable MultimediaData attachments) { + public InCallPagerAdapter( + FragmentManager fragmentManager, + @Nullable MultimediaData attachments, + boolean showInCallButtonGrid) { super(fragmentManager); this.attachments = attachments; + this.showInCallButtonGrid = showInCallButtonGrid; } @Override public Fragment getItem(int position) { - if (position == getButtonGridPosition()) { + if (!showInCallButtonGrid) { + // TODO(calderwoodra): handle fragment invalidation for when the data changes. + return MultimediaFragment.newInstance( + attachments, true /* isInteractive */, false /* showAvatar */, false /* isSpam */); + + } else if (position == getButtonGridPosition()) { return InCallButtonGridFragment.newInstance(); + } else { - // TODO(calderwoodra): handle fragment invalidation for when the data changes. - return MultimediaFragment.newInstance(attachments, true, false, false); + return MultimediaFragment.newInstance( + attachments, true /* isInteractive */, false /* showAvatar */, false /* isSpam */); } } @Override public int getCount() { + int count = 0; + if (showInCallButtonGrid) { + count++; + } if (attachments != null && attachments.hasData()) { - return 2; + count++; } - return 1; + Assert.checkArgument(count > 0, "InCallPager adapter doesn't have any pages."); + return count; } public void setAttachments(@Nullable MultimediaData attachments) { diff --git a/java/com/android/incallui/incall/protocol/PrimaryCallState.java b/java/com/android/incallui/incall/protocol/PrimaryCallState.java index 791f22ea7..1afa66a91 100644 --- a/java/com/android/incallui/incall/protocol/PrimaryCallState.java +++ b/java/com/android/incallui/incall/protocol/PrimaryCallState.java @@ -66,8 +66,12 @@ public class PrimaryCallState { // TODO: Convert to autovalue. b/34502119 public static PrimaryCallState createEmptyPrimaryCallState() { + return createEmptyPrimaryCallStateWithState(DialerCall.State.IDLE); + } + + public static PrimaryCallState createEmptyPrimaryCallStateWithState(int state) { return new PrimaryCallState( - DialerCall.State.IDLE, + state, false, /* isVideoCall */ SessionModificationState.NO_REQUEST, new DisconnectCause(DisconnectCause.UNKNOWN), diff --git a/java/com/android/incallui/incall/protocol/PrimaryInfo.java b/java/com/android/incallui/incall/protocol/PrimaryInfo.java index 761dd9a81..7fe0a0f6a 100644 --- a/java/com/android/incallui/incall/protocol/PrimaryInfo.java +++ b/java/com/android/incallui/incall/protocol/PrimaryInfo.java @@ -41,6 +41,7 @@ public class PrimaryInfo { // Used for consistent LetterTile coloring. @Nullable public final String contactInfoLookupKey; @Nullable public final MultimediaData multimediaData; + public final boolean showInCallButtonGrid; public final int numberPresentation; // TODO: Convert to autovalue. b/34502119 @@ -61,6 +62,7 @@ public class PrimaryInfo { false, null, null, + true, -1); } @@ -80,6 +82,7 @@ public class PrimaryInfo { boolean shouldShowLocation, @Nullable String contactInfoLookupKey, @Nullable MultimediaData multimediaData, + boolean showInCallButtonGrid, int numberPresentation) { this.number = number; this.name = name; @@ -96,6 +99,7 @@ public class PrimaryInfo { this.shouldShowLocation = shouldShowLocation; this.contactInfoLookupKey = contactInfoLookupKey; this.multimediaData = multimediaData; + this.showInCallButtonGrid = showInCallButtonGrid; this.numberPresentation = numberPresentation; } -- cgit v1.2.3