diff options
Diffstat (limited to 'java/com')
10 files changed, 462 insertions, 3 deletions
diff --git a/java/com/android/incallui/rtt/impl/RttChatFragment.java b/java/com/android/incallui/rtt/impl/RttChatFragment.java index deb205ce6..396b89e75 100644 --- a/java/com/android/incallui/rtt/impl/RttChatFragment.java +++ b/java/com/android/incallui/rtt/impl/RttChatFragment.java @@ -29,6 +29,7 @@ import android.telecom.CallAudioState; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -45,6 +46,8 @@ import android.widget.TextView.OnEditorActionListener; import com.android.dialer.common.Assert; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; +import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment; +import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter; import com.android.incallui.call.DialerCall.State; import com.android.incallui.incall.protocol.InCallButtonUi; import com.android.incallui.incall.protocol.InCallButtonUiDelegate; @@ -68,7 +71,8 @@ public class RttChatFragment extends Fragment MessageListener, RttCallScreen, InCallScreen, - InCallButtonUi { + InCallButtonUi, + AudioRouteSelectorPresenter { private static final String ARG_CALL_ID = "call_id"; @@ -94,6 +98,7 @@ public class RttChatFragment extends Fragment private TextView nameTextView; private Chronometer chronometer; private boolean isTimerStarted; + private RttOverflowMenu overflowMenu; /** * Create a new instance of RttChatFragment. @@ -173,6 +178,10 @@ public class RttChatFragment extends Fragment inCallButtonUiDelegate.onEndCallClicked(); }); + overflowMenu = new RttOverflowMenu(getContext(), inCallButtonUiDelegate); + view.findViewById(R.id.rtt_overflow_button) + .setOnClickListener(v -> overflowMenu.showAtLocation(v, Gravity.TOP | Gravity.RIGHT, 0, 0)); + nameTextView = view.findViewById(R.id.rtt_name_or_number); chronometer = view.findViewById(R.id.rtt_timer); return view; @@ -240,6 +249,9 @@ public class RttChatFragment extends Fragment public void onStop() { LogUtil.enterBlock("RttChatFragment.onStop"); super.onStop(); + if (overflowMenu.isShowing()) { + overflowMenu.dismiss(); + } onRttScreenStop(); } @@ -360,7 +372,11 @@ public class RttChatFragment extends Fragment public void setVideoPaused(boolean isPaused) {} @Override - public void setAudioState(CallAudioState audioState) {} + public void setAudioState(CallAudioState audioState) { + LogUtil.i("RttChatFragment.setAudioState", "audioState: " + audioState); + overflowMenu.setMuteButtonChecked(audioState.isMuted()); + overflowMenu.setAudioState(audioState); + } @Override public void updateButtonStates() {} @@ -374,5 +390,16 @@ public class RttChatFragment extends Fragment } @Override - public void showAudioRouteSelector() {} + public void showAudioRouteSelector() { + AudioRouteSelectorDialogFragment.newInstance(inCallButtonUiDelegate.getCurrentAudioState()) + .show(getChildFragmentManager(), null); + } + + @Override + public void onAudioRouteSelected(int audioRoute) { + inCallButtonUiDelegate.setAudioRoute(audioRoute); + } + + @Override + public void onAudioRouteSelectorDismiss() {} } diff --git a/java/com/android/incallui/rtt/impl/RttCheckableButton.java b/java/com/android/incallui/rtt/impl/RttCheckableButton.java new file mode 100644 index 000000000..ba15ca985 --- /dev/null +++ b/java/com/android/incallui/rtt/impl/RttCheckableButton.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2016 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.rtt.impl; + +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.view.SoundEffectConstants; +import android.widget.Checkable; +import android.widget.TextView; + +/** Image button that maintains a checked state. */ +public class RttCheckableButton extends TextView implements Checkable { + + private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked}; + + /** Callback interface to notify when the button's checked state has changed */ + public interface OnCheckedChangeListener { + + void onCheckedChanged(RttCheckableButton button, boolean isChecked); + } + + private boolean broadcasting; + private boolean isChecked; + private OnCheckedChangeListener onCheckedChangeListener; + private CharSequence contentDescriptionChecked; + private CharSequence contentDescriptionUnchecked; + + public RttCheckableButton(Context context) { + this(context, null); + } + + public RttCheckableButton(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RttCheckableButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RttCheckableButton); + setChecked(typedArray.getBoolean(R.styleable.RttCheckableButton_android_checked, false)); + contentDescriptionChecked = + typedArray.getText(R.styleable.RttCheckableButton_contentDescriptionChecked); + contentDescriptionUnchecked = + typedArray.getText(R.styleable.RttCheckableButton_contentDescriptionUnchecked); + typedArray.recycle(); + + updateContentDescription(); + setClickable(true); + setFocusable(true); + } + + @Override + public void setChecked(boolean checked) { + performSetChecked(checked); + } + + /** + * Called when the state of the button should be updated, this should not be the result of user + * interaction. + * + * @param checked {@code true} if the button should be in the checked state, {@code false} + * otherwise. + */ + private void performSetChecked(boolean checked) { + if (isChecked() == checked) { + return; + } + isChecked = checked; + CharSequence contentDescription = updateContentDescription(); + announceForAccessibility(contentDescription); + refreshDrawableState(); + } + + private CharSequence updateContentDescription() { + CharSequence contentDescription = + isChecked ? contentDescriptionChecked : contentDescriptionUnchecked; + setContentDescription(contentDescription); + return contentDescription; + } + + /** + * Called when the user interacts with a button. This should not result in the button updating + * state, rather the request should be propagated to the associated listener. + * + * @param checked {@code true} if the button should be in the checked state, {@code false} + * otherwise. + */ + private void userRequestedSetChecked(boolean checked) { + if (isChecked() == checked) { + return; + } + if (broadcasting) { + return; + } + broadcasting = true; + if (onCheckedChangeListener != null) { + onCheckedChangeListener.onCheckedChanged(this, checked); + } + broadcasting = false; + } + + @Override + public boolean isChecked() { + return isChecked; + } + + @Override + public void toggle() { + userRequestedSetChecked(!isChecked()); + } + + @Override + public int[] onCreateDrawableState(int extraSpace) { + final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); + if (isChecked()) { + mergeDrawableStates(drawableState, CHECKED_STATE_SET); + } + return drawableState; + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + invalidate(); + } + + public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { + this.onCheckedChangeListener = listener; + } + + @Override + public boolean performClick() { + if (!isCheckable()) { + return super.performClick(); + } + + toggle(); + final boolean handled = super.performClick(); + if (!handled) { + // View only makes a sound effect if the onClickListener was + // called, so we'll need to make one here instead. + playSoundEffect(SoundEffectConstants.CLICK); + } + return handled; + } + + private boolean isCheckable() { + return onCheckedChangeListener != null; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState savedState = (SavedState) state; + super.onRestoreInstanceState(savedState.getSuperState()); + performSetChecked(savedState.isChecked); + requestLayout(); + } + + @Override + public Parcelable onSaveInstanceState() { + return new SavedState(isChecked(), super.onSaveInstanceState()); + } + + private static class SavedState extends BaseSavedState { + + public final boolean isChecked; + + private SavedState(boolean isChecked, Parcelable superState) { + super(superState); + this.isChecked = isChecked; + } + + protected SavedState(Parcel in) { + super(in); + isChecked = in.readByte() != 0; + } + + public static final Creator<SavedState> CREATOR = + new Creator<SavedState>() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeByte((byte) (isChecked ? 1 : 0)); + } + } +} diff --git a/java/com/android/incallui/rtt/impl/RttOverflowMenu.java b/java/com/android/incallui/rtt/impl/RttOverflowMenu.java new file mode 100644 index 000000000..e0916bedf --- /dev/null +++ b/java/com/android/incallui/rtt/impl/RttOverflowMenu.java @@ -0,0 +1,78 @@ +/* + * 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.rtt.impl; + +import android.content.Context; +import android.telecom.CallAudioState; +import android.view.View; +import android.widget.PopupWindow; +import com.android.incallui.incall.protocol.InCallButtonUiDelegate; +import com.android.incallui.rtt.impl.RttCheckableButton.OnCheckedChangeListener; +import com.android.incallui.speakerbuttonlogic.SpeakerButtonInfo; +import com.android.incallui.speakerbuttonlogic.SpeakerButtonInfo.IconSize; + +/** Overflow menu for RTT call. */ +public class RttOverflowMenu extends PopupWindow implements OnCheckedChangeListener { + + private final RttCheckableButton muteButton; + private final RttCheckableButton speakerButton; + private final RttCheckableButton dialpadButton; + private final RttCheckableButton addCallButton; + private final InCallButtonUiDelegate inCallButtonUiDelegate; + + RttOverflowMenu(Context context, InCallButtonUiDelegate inCallButtonUiDelegate) { + super(context); + this.inCallButtonUiDelegate = inCallButtonUiDelegate; + View view = View.inflate(context, R.layout.overflow_menu, null); + setContentView(view); + setOnDismissListener(this::dismiss); + setFocusable(true); + setWidth(context.getResources().getDimensionPixelSize(R.dimen.rtt_overflow_menu_width)); + muteButton = view.findViewById(R.id.menu_mute); + muteButton.setOnCheckedChangeListener(this); + speakerButton = view.findViewById(R.id.menu_speaker); + speakerButton.setOnCheckedChangeListener(this); + dialpadButton = view.findViewById(R.id.menu_keypad); + dialpadButton.setOnCheckedChangeListener(this); + addCallButton = view.findViewById(R.id.menu_add_call); + addCallButton.setOnCheckedChangeListener(this); + } + + @Override + public void onCheckedChanged(RttCheckableButton button, boolean isChecked) { + if (button == muteButton) { + inCallButtonUiDelegate.muteClicked(isChecked, true); + } else if (button == speakerButton) { + inCallButtonUiDelegate.toggleSpeakerphone(); + } else if (button == dialpadButton) { + inCallButtonUiDelegate.showDialpadClicked(isChecked); + } else if (button == addCallButton) { + inCallButtonUiDelegate.addCallClicked(); + } + } + + void setMuteButtonChecked(boolean isChecked) { + muteButton.setChecked(isChecked); + } + + void setAudioState(CallAudioState audioState) { + SpeakerButtonInfo info = new SpeakerButtonInfo(audioState, IconSize.SIZE_24_DP); + if (info.checkable) { + speakerButton.setChecked(info.isChecked); + } + } +} diff --git a/java/com/android/incallui/rtt/impl/res/color/rtt_checkable_button_color.xml b/java/com/android/incallui/rtt/impl/res/color/rtt_checkable_button_color.xml new file mode 100644 index 000000000..cb3a4522f --- /dev/null +++ b/java/com/android/incallui/rtt/impl/res/color/rtt_checkable_button_color.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_checked="true" + android:color="@color/rtt_button_selected_color" /> + <item android:color="@color/rtt_button_unselected_color" /> +</selector>
\ No newline at end of file diff --git a/java/com/android/incallui/rtt/impl/res/drawable/overflow_menu_background.xml b/java/com/android/incallui/rtt/impl/res/drawable/overflow_menu_background.xml new file mode 100644 index 000000000..614298679 --- /dev/null +++ b/java/com/android/incallui/rtt/impl/res/drawable/overflow_menu_background.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@android:color/white"/> + <corners android:radius="2dp"/> +</shape>
\ No newline at end of file diff --git a/java/com/android/incallui/rtt/impl/res/layout/overflow_menu.xml b/java/com/android/incallui/rtt/impl/res/layout/overflow_menu.xml new file mode 100644 index 000000000..a29fad5f1 --- /dev/null +++ b/java/com/android/incallui/rtt/impl/res/layout/overflow_menu.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="180dp" + android:layout_height="wrap_content" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:background="@drawable/overflow_menu_background" + android:orientation="vertical"> + <com.android.incallui.rtt.impl.RttCheckableButton + android:id="@+id/menu_mute" + style="@style/RttButton" + android:drawableStart="@drawable/quantum_ic_mic_off_vd_theme_24" + android:text="@string/incall_label_mute" + app:contentDescriptionChecked="@string/incall_content_description_muted" + app:contentDescriptionUnchecked="@string/incall_content_description_unmuted"/> + <com.android.incallui.rtt.impl.RttCheckableButton + android:id="@+id/menu_speaker" + style="@style/RttButton" + android:drawableStart="@drawable/quantum_ic_volume_up_vd_theme_24" + android:text="@string/incall_label_speaker" + app:contentDescriptionChecked="@string/incall_content_description_speaker" + app:contentDescriptionUnchecked="@string/incall_content_description_earpiece"/> + <com.android.incallui.rtt.impl.RttCheckableButton + android:id="@+id/menu_keypad" + style="@style/RttButton" + android:drawableStart="@drawable/quantum_ic_dialpad_vd_theme_24" + android:text="@string/incall_label_dialpad"/> + <com.android.incallui.rtt.impl.RttCheckableButton + android:id="@+id/menu_add_call" + style="@style/RttButton" + android:drawableStart="@drawable/quantum_ic_add_call_vd_theme_24" + android:text="@string/incall_label_add_call"/> +</LinearLayout>
\ No newline at end of file diff --git a/java/com/android/incallui/rtt/impl/res/values/attrs.xml b/java/com/android/incallui/rtt/impl/res/values/attrs.xml new file mode 100644 index 000000000..2e7d899bb --- /dev/null +++ b/java/com/android/incallui/rtt/impl/res/values/attrs.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<resources> + <declare-styleable name="RttCheckableButton"> + <attr name="android:checked"/> + <attr name="contentDescriptionChecked" format="reference|string"/> + <attr name="contentDescriptionUnchecked" format="reference|string"/> + </declare-styleable> +</resources> diff --git a/java/com/android/incallui/rtt/impl/res/values/colors.xml b/java/com/android/incallui/rtt/impl/res/values/colors.xml index c25ad21f2..e1702ccdf 100644 --- a/java/com/android/incallui/rtt/impl/res/values/colors.xml +++ b/java/com/android/incallui/rtt/impl/res/values/colors.xml @@ -17,4 +17,6 @@ <resources> <color name="rtt_status_bar_color">#03165C</color> <color name="rtt_navigation_bar_color">#FAFAFA</color> + <color name="rtt_button_unselected_color">#757575</color> + <color name="rtt_button_selected_color">#2A56C6</color> </resources>
\ No newline at end of file diff --git a/java/com/android/incallui/rtt/impl/res/values/dimens.xml b/java/com/android/incallui/rtt/impl/res/values/dimens.xml index a3f230c08..4c3fe02d2 100644 --- a/java/com/android/incallui/rtt/impl/res/values/dimens.xml +++ b/java/com/android/incallui/rtt/impl/res/values/dimens.xml @@ -17,4 +17,5 @@ <resources> <dimen name="rtt_message_margin_top">16dp</dimen> <dimen name="rtt_same_group_message_margin_top">2dp</dimen> + <dimen name="rtt_overflow_menu_width">180dp</dimen> </resources>
\ No newline at end of file diff --git a/java/com/android/incallui/rtt/impl/res/values/styles.xml b/java/com/android/incallui/rtt/impl/res/values/styles.xml index 55207a3cc..515e0dfcf 100644 --- a/java/com/android/incallui/rtt/impl/res/values/styles.xml +++ b/java/com/android/incallui/rtt/impl/res/values/styles.xml @@ -15,9 +15,24 @@ ~ limitations under the License --> <resources> + <style name="Dialer.Incall.TextAppearance.RttMessage" parent="Dialer.Incall.TextAppearance"> <item name="android:fontFamily">sans-serif</item> <item name="android:textColor">#DD000000</item> <item name="android:textSize">16sp</item> </style> + + <style name="RttButton"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:drawablePadding">16dp</item> + <item name="android:paddingLeft">16dp</item> + <item name="android:paddingRight">16dp</item> + <item name="android:paddingTop">8dp</item> + <item name="android:paddingBottom">8dp</item> + <item name="android:drawableTint">@color/rtt_checkable_button_color</item> + <item name="android:textSize">16sp</item> + <item name="android:textColor">@color/rtt_checkable_button_color</item> + <item name="android:colorControlHighlight">#33000000</item> + </style> </resources>
\ No newline at end of file |