diff options
Diffstat (limited to 'InCallUI/src/com/android/incallui')
6 files changed, 284 insertions, 11 deletions
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java index 3324c91e5..261378235 100644 --- a/InCallUI/src/com/android/incallui/CallButtonFragment.java +++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java @@ -17,7 +17,11 @@ package com.android.incallui; import android.content.Context; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.StateListDrawable; import android.os.Bundle; import android.telecom.AudioState; import android.view.ContextThemeWrapper; @@ -34,6 +38,9 @@ import android.widget.PopupMenu; import android.widget.PopupMenu.OnDismissListener; import android.widget.PopupMenu.OnMenuItemClickListener; +import com.android.contacts.common.util.MaterialColorMapUtils; +import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; + /** * Fragment for call control buttons */ @@ -41,7 +48,6 @@ public class CallButtonFragment extends BaseFragment<CallButtonPresenter, CallButtonPresenter.CallButtonUi> implements CallButtonPresenter.CallButtonUi, OnMenuItemClickListener, OnDismissListener, View.OnClickListener, CompoundButton.OnCheckedChangeListener { - private ImageButton mAudioButton; private ImageButton mChangeToVoiceButton; private ImageButton mMuteButton; @@ -66,6 +72,7 @@ public class CallButtonFragment private static final int VISIBLE = 255; private boolean mIsEnabled; + private MaterialPalette mCurrentThemeColors; @Override CallButtonPresenter createPresenter() { @@ -130,6 +137,8 @@ public class CallButtonFragment getPresenter().refreshMuteState(); } super.onResume(); + + updateColors(); } @Override @@ -190,6 +199,108 @@ public class CallButtonFragment } } + public void updateColors() { + MaterialPalette themeColors = InCallPresenter.getInstance().getThemeColors(); + + if (mCurrentThemeColors != null && mCurrentThemeColors.equals(themeColors)) { + return; + } + + Resources res = getActivity().getResources(); + ImageButton[] compoundButtons = { + mAudioButton, + mMuteButton, + mShowDialpadButton, + mHoldButton, + mSwitchCameraButton, + mPauseVideoButton + }; + + for (ImageButton button : compoundButtons) { + final LayerDrawable layers = (LayerDrawable) button.getBackground(); + final StateListDrawable btnCompoundDrawable = compoundBackgroundDrawable(themeColors); + layers.setDrawableByLayerId(R.id.compoundBackgroundItem, btnCompoundDrawable); + } + + ImageButton[] normalButtons = { + mChangeToVoiceButton, + mSwapButton, + mChangeToVideoButton, + mAddCallButton, + mMergeButton, + mOverflowButton + }; + + for (ImageButton button : normalButtons) { + final LayerDrawable layers = (LayerDrawable) button.getBackground(); + final StateListDrawable btnCompoundDrawable = backgroundDrawable(themeColors); + layers.setDrawableByLayerId(R.id.backgroundItem, btnCompoundDrawable); + } + + mCurrentThemeColors = themeColors; + } + + /** + * Generate a StateListDrawable which will be the background for a compound button, i.e. + * a button with pressed and unpressed states. The unpressed state will be the same color + * as the rest of the call card, the pressed state will be the dark version of that color. + */ + private StateListDrawable compoundBackgroundDrawable(MaterialPalette palette) { + Resources res = getResources(); + StateListDrawable stateListDrawable = new StateListDrawable(); + + addSelectedAndFocused(res, stateListDrawable); + addFocused(res, stateListDrawable); + addSelected(res, stateListDrawable, palette); + addUnselected(res, stateListDrawable, palette); + + return stateListDrawable; + } + + /** + * Generate a StateListDrawable which will be the background of a button to ensure it + * is the same color as the rest of the call card. + */ + private StateListDrawable backgroundDrawable(MaterialPalette palette) { + Resources res = getResources(); + StateListDrawable stateListDrawable = new StateListDrawable(); + + addFocused(res, stateListDrawable); + addUnselected(res, stateListDrawable, palette); + + return stateListDrawable; + } + + // state_selected and state_focused + private void addSelectedAndFocused(Resources res, StateListDrawable drawable) { + int[] selectedAndFocused = {android.R.attr.state_selected, android.R.attr.state_focused}; + Drawable selectedAndFocusedDrawable = res.getDrawable(R.drawable.btn_selected_focused); + drawable.addState(selectedAndFocused, selectedAndFocusedDrawable); + } + + // state_focused + private void addFocused(Resources res, StateListDrawable drawable) { + int[] focused = {android.R.attr.state_focused}; + Drawable focusedDrawable = res.getDrawable(R.drawable.btn_unselected_focused); + drawable.addState(focused, focusedDrawable); + } + + // state_selected + private void addSelected(Resources res, StateListDrawable drawable, MaterialPalette palette) { + int[] selected = {android.R.attr.state_selected}; + LayerDrawable selectedDrawable = (LayerDrawable) res.getDrawable(R.drawable.btn_selected); + ((GradientDrawable) selectedDrawable.getDrawable(0)).setColor(palette.mSecondaryColor); + drawable.addState(selected, selectedDrawable); + } + + // default + private void addUnselected(Resources res, StateListDrawable drawable, MaterialPalette palette) { + LayerDrawable unselectedDrawable = + (LayerDrawable) res.getDrawable(R.drawable.btn_unselected); + ((GradientDrawable) unselectedDrawable.getDrawable(0)).setColor(palette.mPrimaryColor); + drawable.addState(new int[0], unselectedDrawable); + } + @Override public void setEnabled(boolean isEnabled) { mIsEnabled = isEnabled; diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java index 6643128b3..a3804b15d 100644 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ b/InCallUI/src/com/android/incallui/CallCardFragment.java @@ -46,7 +46,7 @@ import android.view.animation.AnimationUtils; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; - +import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; import com.android.contacts.common.widget.FloatingActionButtonController; import com.android.phone.common.animation.AnimUtils; @@ -112,6 +112,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr private int mVideoAnimationDuration; + private MaterialPalette mCurrentThemeColors; + @Override CallCardPresenter.CallCardUi getUi() { return this; @@ -791,6 +793,22 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr mManageConferenceCallButton.setVisibility(visible ? View.VISIBLE : View.GONE); } + /** + * Get the overall InCallUI background colors and apply to call card. + */ + public void updateColors() { + MaterialPalette themeColors = InCallPresenter.getInstance().getThemeColors(); + + if (mCurrentThemeColors != null && mCurrentThemeColors.equals(themeColors)) { + return; + } + + mPrimaryCallCardContainer.setBackgroundColor(themeColors.mPrimaryColor); + mCallButtonsContainer.setBackgroundColor(themeColors.mPrimaryColor); + + mCurrentThemeColors = themeColors; + } + private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) { if (view == null) return; final List<CharSequence> eventText = event.getText(); @@ -802,9 +820,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr } } - public void animateForNewOutgoingCall(Point touchPoint) { + public void animateForNewOutgoingCall(final Point touchPoint) { final ViewGroup parent = (ViewGroup) mPrimaryCallCardContainer.getParent(); - final Point startPoint = touchPoint; final ViewTreeObserver observer = getView().getViewTreeObserver(); @@ -835,7 +852,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr mCallTypeLabel.setAlpha(0); mCallNumberAndLabel.setAlpha(0); - final Animator revealAnimator = getRevealAnimator(startPoint); + final Animator revealAnimator = getRevealAnimator(touchPoint); final Animator shrinkAnimator = getShrinkAnimator(parent.getHeight(), originalHeight); @@ -903,6 +920,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr updateFabPosition(); } }); + + updateColors(); } /** diff --git a/InCallUI/src/com/android/incallui/DialpadFragment.java b/InCallUI/src/com/android/incallui/DialpadFragment.java index 6cb5d1f8f..63f6379fc 100644 --- a/InCallUI/src/com/android/incallui/DialpadFragment.java +++ b/InCallUI/src/com/android/incallui/DialpadFragment.java @@ -34,6 +34,7 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; +import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; import com.android.phone.common.dialpad.DialpadKeyButton; import com.android.phone.common.dialpad.DialpadView; @@ -48,6 +49,10 @@ public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPrese private static final int ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS = 50; + private final int[] mButtonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three, + R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star, + R.id.pound}; + /** * LinearLayout with getter and setter methods for the translationY property using floats, * for animation purposes. @@ -132,6 +137,8 @@ public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPrese private DialpadView mDialpadView; + private int mCurrentTextColor; + /** * Our own key listener, specialized for dealing with DTMF codes. * 1. Ignore the backspace since it is irrelevant. @@ -457,13 +464,35 @@ public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPrese // the edit (copy / paste / select) functions. mDtmfDialerField.setLongClickable(false); mDtmfDialerField.setElegantTextHeight(false); - configureKeypadListeners(mDialpadView); + configureKeypadListeners(); } return parent; } @Override + public void onResume() { + super.onResume(); + updateColors(); + } + + public void updateColors() { + int textColor = InCallPresenter.getInstance().getThemeColors().mPrimaryColor; + + if (mCurrentTextColor == textColor) { + return; + } + + DialpadKeyButton dialpadKey; + for (int i = 0; i < mButtonIds.length; i++) { + dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]); + ((TextView) dialpadKey.findViewById(R.id.dialpad_key_number)).setTextColor(textColor); + } + + mCurrentTextColor = textColor; + } + + @Override public void onDestroyView() { mDialerKeyListener = null; super.onDestroyView(); @@ -544,12 +573,10 @@ public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPrese } } - private void configureKeypadListeners(View fragmentView) { - final int[] buttonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, - R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star, R.id.pound}; + private void configureKeypadListeners() { DialpadKeyButton dialpadKey; - for (int i = 0; i < buttonIds.length; i++) { - dialpadKey = (DialpadKeyButton) fragmentView.findViewById(buttonIds[i]); + for (int i = 0; i < mButtonIds.length; i++) { + dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]); dialpadKey.setOnTouchListener(this); dialpadKey.setOnKeyListener(this); dialpadKey.setOnHoverListener(this); diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java index 27d17c4b5..5316b6dec 100644 --- a/InCallUI/src/com/android/incallui/InCallActivity.java +++ b/InCallUI/src/com/android/incallui/InCallActivity.java @@ -21,17 +21,20 @@ import android.app.Activity; import android.app.AlertDialog; 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; import android.content.Intent; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Point; import android.net.Uri; import android.os.Bundle; import android.telecom.DisconnectCause; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.view.MenuItem; @@ -46,6 +49,8 @@ import android.view.accessibility.AccessibilityEvent; import com.android.phone.common.animation.AnimUtils; import com.android.phone.common.animation.AnimationListenerAdapter; import com.android.contacts.common.interactions.TouchPointManager; +import com.android.contacts.common.util.MaterialColorMapUtils; +import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener; import com.android.incallui.Call.State; @@ -193,6 +198,9 @@ public class InCallActivity extends Activity { super.onResume(); mIsForegroundActivity = true; + + InCallPresenter.getInstance().setThemeColors(); + InCallPresenter.getInstance().onUiShowing(true); if (mShowDialpadRequested) { @@ -493,6 +501,7 @@ public class InCallActivity extends Activity { touchPoint = (Point) extras.getParcelable(TouchPointManager.TOUCH_POINT); } } + mCallCardFragment.animateForNewOutgoingCall(touchPoint); /* diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java index 1299dd32d..bd81f1036 100644 --- a/InCallUI/src/com/android/incallui/InCallPresenter.java +++ b/InCallUI/src/com/android/incallui/InCallPresenter.java @@ -27,6 +27,7 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneCapabilities; import android.telecom.Phone; import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.text.TextUtils; import android.view.Surface; @@ -34,6 +35,8 @@ import android.view.View; import com.google.common.base.Preconditions; +import com.android.contacts.common.util.MaterialColorMapUtils; +import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; import com.android.incalluibind.ObjectFactory; import java.util.Collections; @@ -143,6 +146,11 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { private Phone mPhone; + /** Display colors for the UI. Consists of a primary color and secondary (darker) color */ + private MaterialPalette mThemeColors; + + private TelecomManager mTelecomManager; + public static synchronized InCallPresenter getInstance() { if (sInCallPresenter == null) { sInCallPresenter = new InCallPresenter(); @@ -1101,6 +1109,53 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener { } /** + * Extract background color from call object. The theme colors will include a primary color + * and a secondary color. + */ + public void setThemeColors() { + if (mInCallActivity == null) { + return; + } + + Call call = CallList.getInstance().getFirstCall(); + TelecomManager tm = getTelecomManager(); + + int color = PhoneAccount.NO_COLOR; + + if (call != null && tm != null && tm.hasMultipleCallCapableAccounts()) { + PhoneAccount account = tm.getPhoneAccount(call.getAccountHandle()); + if (account != null) { + color = account.getColor(); + } + } + + // This method will set the background to default if the color is PhoneAccount.NO_COLOR. + mThemeColors = new InCallUIMaterialColorMapUtils(mContext.getResources()). + calculatePrimaryAndSecondaryColor(color); + + mInCallActivity.getWindow().setStatusBarColor(mThemeColors.mSecondaryColor); + } + + /** + * @return A palette for colors to display in the UI. + */ + public MaterialPalette getThemeColors() { + return mThemeColors; + } + + /** + * @return An instance of TelecomManager. + */ + private TelecomManager getTelecomManager() { + if (mTelecomManager == null) { + mTelecomManager = (TelecomManager) + mInCallActivity.getSystemService(Context.TELECOM_SERVICE); + } + return mTelecomManager; + } + + + /** * Private constructor. Must use getInstance() to get this singleton. */ private InCallPresenter() { diff --git a/InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java b/InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java new file mode 100644 index 000000000..efab45f21 --- /dev/null +++ b/InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java @@ -0,0 +1,52 @@ +package com.android.incallui; + +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.telecom.PhoneAccount; + +import com.android.contacts.common.util.MaterialColorMapUtils; +import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; + +public class InCallUIMaterialColorMapUtils extends MaterialColorMapUtils { + private final TypedArray sPrimaryColors; + private final TypedArray sSecondaryColors; + private final Resources mResources; + + public InCallUIMaterialColorMapUtils(Resources resources) { + super(resources); + sPrimaryColors = resources.obtainTypedArray( + com.android.incallui.R.array.background_colors); + sSecondaryColors = resources.obtainTypedArray( + com.android.contacts.common.R.array.background_colors_dark); + mResources = resources; + } + + /** + * Currently the InCallUI color will only vary by SIM color which is a list of colors + * defined in the background_colors array, so first search the list for the matching color and + * fall back to the closest matching color if an exact match does not exist. + */ + @Override + public MaterialPalette calculatePrimaryAndSecondaryColor(int color) { + if (color == PhoneAccount.NO_COLOR) { + return getDefaultPrimaryAndSecondaryColors(mResources); + } + + for (int i = 0; i < sPrimaryColors.length(); i++) { + if (sPrimaryColors.getColor(i, 0) == color) { + return new MaterialPalette( + sPrimaryColors.getColor(i, 0), + sSecondaryColors.getColor(i, 0)); + } + } + + // The color isn't in the list, so use the superclass to find an approximate color. + return super.calculatePrimaryAndSecondaryColor(color); + } + + public static MaterialPalette getDefaultPrimaryAndSecondaryColors(Resources resources) { + final int primaryColor = resources.getColor(R.color.dialer_theme_color); + final int secondaryColor = resources.getColor(R.color.dialer_theme_color_dark); + return new MaterialPalette(primaryColor, secondaryColor); + } +}
\ No newline at end of file |