diff options
author | Yorke Lee <yorkelee@google.com> | 2015-03-09 11:43:27 -0700 |
---|---|---|
committer | Yorke Lee <yorkelee@google.com> | 2015-03-13 17:24:27 -0700 |
commit | c1d1e8418d20edc5871b45263f43b9c28da2633d (patch) | |
tree | 959f0cddb904a5ae849c81a1d2f10018c5e69701 | |
parent | 153e86e1905e41e2ebeeccebaaff218d86184c09 (diff) |
Dynamically add AnswerFragment
AnswerPresenter is a little tricky because it is in charge of
responding to incoming calls, so we want it to be alive and getting
onIncomingCall callbacks, but we don't want to create an instance
of AnswerFragment, which it is dependent on.
Move some dependencies around so that AnswerPresenter is created
by InCallPresenter instead. It registers for callbacks via InCallPresenter
instead of directly to CallList, and shows/hides the AnswerFragment via
InCallActivity.
Change-Id: I7026150988bf3cda762dda8a319f48e1af132361
-rw-r--r-- | InCallUI/res/layout-land/call_card_fragment.xml (renamed from InCallUI/res/layout-land/call_card_content.xml) | 12 | ||||
-rw-r--r-- | InCallUI/res/layout/answer_fragment.xml | 6 | ||||
-rw-r--r-- | InCallUI/res/layout/call_card_fragment.xml (renamed from InCallUI/res/layout/call_card_content.xml) | 13 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/AnswerFragment.java | 10 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/AnswerPresenter.java | 109 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/CallCardFragment.java | 2 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/InCallActivity.java | 29 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/InCallPresenter.java | 11 |
8 files changed, 94 insertions, 98 deletions
diff --git a/InCallUI/res/layout-land/call_card_content.xml b/InCallUI/res/layout-land/call_card_fragment.xml index 496b6b399..4c76b95de 100644 --- a/InCallUI/res/layout-land/call_card_content.xml +++ b/InCallUI/res/layout-land/call_card_fragment.xml @@ -93,23 +93,13 @@ <!-- Placeholder for the dialpad which is replaced with the dialpad fragment when shown. --> <FrameLayout - android:id="@+id/dialpadFragmentContainer" + android:id="@+id/answer_and_dialpad_container" android:layout_toEndOf="@id/primary_call_info_container" android:layout_gravity="end|center_vertical" android:layout_alignParentEnd="true" android:layout_width="match_parent" android:layout_height="match_parent" /> - <fragment android:name="com.android.incallui.AnswerFragment" - android:id="@+id/answerFragment" - android:layout_toEndOf="@id/primary_call_info_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="start" - android:layout_gravity="end|center_vertical" - android:layout_marginBottom="@dimen/glowpadview_margin_bottom" - android:visibility="gone" /> - <FrameLayout android:id="@+id/floating_end_call_action_button_container" android:layout_width="@dimen/end_call_floating_action_button_diameter" diff --git a/InCallUI/res/layout/answer_fragment.xml b/InCallUI/res/layout/answer_fragment.xml index d663b837d..ec6ef30ac 100644 --- a/InCallUI/res/layout/answer_fragment.xml +++ b/InCallUI/res/layout/answer_fragment.xml @@ -19,13 +19,13 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dc="http://schemas.android.com/apk/res-auto" android:id="@+id/glow_pad_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_height="match_parent" android:focusable="true" android:layout_centerHorizontal="true" android:gravity="center" android:background="@color/glowpad_background_color" - android:visibility="gone" + android:layout_marginBottom="@dimen/glowpadview_margin_bottom" dc:targetDrawables="@array/incoming_call_widget_audio_with_sms_targets" dc:targetDescriptions="@array/incoming_call_widget_audio_with_sms_target_descriptions" diff --git a/InCallUI/res/layout/call_card_content.xml b/InCallUI/res/layout/call_card_fragment.xml index 7a42586ea..920f8cb4d 100644 --- a/InCallUI/res/layout/call_card_content.xml +++ b/InCallUI/res/layout/call_card_fragment.xml @@ -98,9 +98,9 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/photo" /> - <!-- Placeholder for the dialpad which is replaced with the dialpad fragment when shown. --> + <!-- Placeholder for various fragments that are added dynamically underneath the caller info --> <FrameLayout - android:id="@+id/dialpadFragmentContainer" + android:id="@+id/answer_and_dialpad_container" android:layout_below="@id/primary_call_info_container" android:layout_gravity="bottom|center_horizontal" android:layout_alignParentBottom="true" @@ -108,15 +108,6 @@ android:layout_height="match_parent" android:elevation="@dimen/dialpad_elevation" /> - <fragment android:name="com.android.incallui.AnswerFragment" - android:id="@+id/answerFragment" - android:layout_below="@id/primary_call_info_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="bottom|center_horizontal" - android:layout_marginBottom="@dimen/glowpadview_margin_bottom" - android:visibility="gone" /> - <FrameLayout android:id="@+id/floating_end_call_action_button_container" android:layout_width="@dimen/end_call_floating_action_button_diameter" diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java index cb09dfdcc..8cbce10c6 100644 --- a/InCallUI/src/com/android/incallui/AnswerFragment.java +++ b/InCallUI/src/com/android/incallui/AnswerFragment.java @@ -76,7 +76,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente @Override public AnswerPresenter createPresenter() { - return new AnswerPresenter(); + return InCallPresenter.getInstance().getAnswerPresenter(); } @Override @@ -108,11 +108,9 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente } @Override - public void showAnswerUi(boolean show) { - getView().setVisibility(show ? View.VISIBLE : View.GONE); - - Log.d(this, "Show answer UI: " + show); - if (show) { + public void onShowAnswerUi(boolean shown) { + Log.d(this, "Show answer UI: " + shown); + if (shown) { mGlowpad.startPing(); } else { mGlowpad.stopPing(); diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java index e579d643a..cc95e0190 100644 --- a/InCallUI/src/com/android/incallui/AnswerPresenter.java +++ b/InCallUI/src/com/android/incallui/AnswerPresenter.java @@ -17,15 +17,23 @@ package com.android.incallui; import android.content.Context; -import android.telecom.TelecomManager; + +import com.android.incallui.InCallPresenter.InCallState; import java.util.List; /** - * Presenter for the Incoming call widget. + * Presenter for the Incoming call widget. The {@link AnswerPresenter} handles the logic during + * incoming calls. It is also in charge of responding to incoming calls, so there needs to be + * an instance alive so that it can receive onIncomingCall callbacks. + * + * An instance of {@link AnswerPresenter} is created by InCallPresenter at startup, registers + * for callbacks via InCallPresenter, and shows/hides the {@link AnswerFragment} via IncallActivity. + * */ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> - implements CallList.CallUpdateListener, CallList.Listener { + implements CallList.CallUpdateListener, InCallPresenter.InCallUiListener, + InCallPresenter.IncomingCallListener { private static final String TAG = AnswerPresenter.class.getSimpleName(); @@ -34,57 +42,33 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> private boolean mHasTextMessages = false; @Override - public void onUiReady(AnswerUi ui) { - super.onUiReady(ui); - - final CallList calls = CallList.getInstance(); - Call call; - call = calls.getIncomingCall(); - if (call != null) { - processIncomingCall(call); - } - call = calls.getVideoUpgradeRequestCall(); - if (call != null) { - processVideoUpgradeRequestCall(call); - } - - // Listen for incoming calls. - calls.addListener(this); - } - - @Override - public void onUiUnready(AnswerUi ui) { - super.onUiUnready(ui); - - CallList.getInstance().removeListener(this); - - // This is necessary because the activity can be destroyed while an incoming call exists. - // This happens when back button is pressed while incoming call is still being shown. - if (mCallId != null) { - CallList.getInstance().removeCallUpdateListener(mCallId, this); + public void onUiShowing(boolean showing) { + if (showing) { + final CallList calls = CallList.getInstance(); + Call call; + call = calls.getIncomingCall(); + if (call != null) { + processIncomingCall(call); + } + call = calls.getVideoUpgradeRequestCall(); + if (call != null) { + processVideoUpgradeRequestCall(call); + } + } else { + // This is necessary because the activity can be destroyed while an incoming call exists. + // This happens when back button is pressed while incoming call is still being shown. + if (mCallId != null) { + CallList.getInstance().removeCallUpdateListener(mCallId, this); + } } } @Override - public void onCallListChange(CallList callList) { - // no-op - } - - @Override - public void onDisconnect(Call call) { - // no-op - } - - @Override - public void onIncomingCall(Call call) { - // TODO: Ui is being destroyed when the fragment detaches. Need clean up step to stop - // getting updates here. + public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { Log.d(this, "onIncomingCall: " + this); - if (getUi() != null) { - if (!call.getId().equals(mCallId)) { - // A new call is coming in. - processIncomingCall(call); - } + if (!call.getId().equals(mCallId)) { + // A new call is coming in. + processIncomingCall(call); } } @@ -96,9 +80,20 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> CallList.getInstance().addCallUpdateListener(mCallId, this); Log.d(TAG, "Showing incoming for call id: " + mCallId + " " + this); - final List<String> textMsgs = CallList.getInstance().getTextResponses(call.getId()); - getUi().showAnswerUi(true); - configureAnswerTargetsForSms(call, textMsgs); + if (showAnswerUi(true)) { + final List<String> textMsgs = CallList.getInstance().getTextResponses(call.getId()); + configureAnswerTargetsForSms(call, textMsgs); + } + } + + private boolean showAnswerUi(boolean show) { + final InCallActivity activity = InCallPresenter.getInstance().getActivity(); + if (activity != null) { + activity.showAnswerFragment(show); + return true; + } else { + return false; + } } private void processVideoUpgradeRequestCall(Call call) { @@ -107,7 +102,7 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> // Listen for call updates for the current call. CallList.getInstance().addCallUpdateListener(mCallId, this); - getUi().showAnswerUi(true); + showAnswerUi(true); getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST); } @@ -119,7 +114,7 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> // Stop listening for updates. CallList.getInstance().removeCallUpdateListener(mCallId, this); - getUi().showAnswerUi(false); + showAnswerUi(false); // mCallId will hold the state of the call. We don't clear the mCall variable here as // it may be useful for sending text messages after phone disconnects. @@ -175,6 +170,10 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> } private void configureAnswerTargetsForSms(Call call, List<String> textMsgs) { + if (getUi() == null) { + return; + } + final Context context = getUi().getContext(); mHasTextMessages = textMsgs != null; @@ -199,7 +198,7 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi> } interface AnswerUi extends Ui { - public void showAnswerUi(boolean show); + public void onShowAnswerUi(boolean shown); public void showTargets(int targetSet); public void showMessageDialog(); public void configureMessageDialog(List<String> textResponses); diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java index 1b17d35d3..6d7e1d581 100644 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ b/InCallUI/src/com/android/incallui/CallCardFragment.java @@ -149,7 +149,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr mTranslationOffset = getResources().getDimensionPixelSize(R.dimen.call_card_anim_translate_y_offset); - return inflater.inflate(R.layout.call_card_content, container, false); + return inflater.inflate(R.layout.call_card_fragment, container, false); } @Override diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java index a6b3a4139..da3d692f0 100644 --- a/InCallUI/src/com/android/incallui/InCallActivity.java +++ b/InCallUI/src/com/android/incallui/InCallActivity.java @@ -18,10 +18,12 @@ package com.android.incallui; import android.app.ActionBar; import android.app.Activity; +import android.app.ActivityManager; import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; +import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnCancelListener; @@ -29,6 +31,7 @@ import android.content.Intent; import android.content.res.Configuration; import android.graphics.Point; import android.os.Bundle; +import android.os.Trace; import android.telecom.DisconnectCause; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; @@ -281,8 +284,8 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { return mIsForegroundActivity; } - private boolean hasPendingErrorDialog() { - return mDialog != null; + private boolean hasPendingDialogs() { + return mDialog != null || (mAnswerFragment != null && mAnswerFragment.hasPendingDialogs()); } @Override @@ -290,8 +293,7 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { Log.i(this, "finish(). Dialog showing: " + (mDialog != null)); // skip finish if we are still showing a dialog. - if (!hasPendingErrorDialog() && mAnswerFragment != null - && !mAnswerFragment.hasPendingDialogs()) { + if (!hasPendingDialogs()) { super.finish(); } } @@ -465,6 +467,10 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { return mCallCardFragment; } + public AnswerFragment getAnswerFragment() { + return mAnswerFragment; + } + private void internalResolveIntent(Intent intent) { final String action = intent.getAction(); @@ -590,11 +596,6 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { .findFragmentById(R.id.callButtonFragment); mCallButtonFragment.getView().setVisibility(View.INVISIBLE); } - - if (mAnswerFragment == null) { - mAnswerFragment = (AnswerFragment) mChildFragmentManager - .findFragmentById(R.id.answerFragment); - } } public void dismissKeyguard(boolean dismiss) { @@ -610,6 +611,7 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { } private void showFragment(String tag, boolean show, boolean executeImmediately) { + Trace.beginSection("showFragment - " + tag); final FragmentManager fm = getFragmentManagerForTag(tag); if (fm == null) { @@ -639,6 +641,7 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { if (executeImmediately) { fm.executePendingTransactions(); } + Trace.endSection(); } private Fragment createNewFragmentForTag(String tag) { @@ -673,9 +676,9 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { private int getContainerIdForFragment(String tag) { if (TAG_DIALPAD_FRAGMENT.equals(tag)) { - return R.id.dialpadFragmentContainer; + return R.id.answer_and_dialpad_container; } else if (TAG_ANSWER_FRAGMENT.equals(tag)) { - return R.id.dialpadFragmentContainer; + return R.id.answer_and_dialpad_container; } else if (TAG_CONFERENCE_FRAGMENT.equals(tag)) { return R.id.main; } else if (TAG_CALLCARD_FRAGMENT.equals(tag)) { @@ -724,6 +727,10 @@ public class InCallActivity extends Activity implements FragmentDisplayManager { mCallCardFragment.getView().setVisibility(show ? View.GONE : View.VISIBLE); } + public void showAnswerFragment(boolean show) { + showFragment(TAG_ANSWER_FRAGMENT, show, true); + } + public void showPostCharWaitDialog(String callId, String chars) { if (isForegroundActivity()) { final PostCharDialogFragment fragment = new PostCharDialogFragment(callId, chars); diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java index f2aaea179..6a1295e21 100644 --- a/InCallUI/src/com/android/incallui/InCallPresenter.java +++ b/InCallUI/src/com/android/incallui/InCallPresenter.java @@ -97,6 +97,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener, private boolean mServiceConnected = false; private boolean mAccountSelectionCancelled = false; private InCallCameraManager mInCallCameraManager = null; + private AnswerPresenter mAnswerPresenter = new AnswerPresenter(); /** * Whether or not we are currently bound and waiting for Telecom to send us a new call. @@ -1372,10 +1373,20 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener, return mTelecomManager; } + InCallActivity getActivity() { + return mInCallActivity; + } + + AnswerPresenter getAnswerPresenter() { + return mAnswerPresenter; + } + /** * Private constructor. Must use getInstance() to get this singleton. */ private InCallPresenter() { + addIncomingCallListener(mAnswerPresenter); + addInCallUiListener(mAnswerPresenter); } /** |