PageRenderTime 85ms CodeModel.GetById 47ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/android/dialer/calllog/CallTypeIconsView.java

https://gitlab.com/Atomic-ROM/packages_apps_Dialer
Java | 224 lines | 126 code | 32 blank | 66 comment | 4 complexity | 54344817f0966adb24d21bc8a8fb184f MD5 | raw file
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.android.dialer.calllog;
  17. import android.content.Context;
  18. import android.graphics.Bitmap;
  19. import android.graphics.BitmapFactory;
  20. import android.graphics.Canvas;
  21. import android.graphics.PorterDuff;
  22. import android.graphics.drawable.BitmapDrawable;
  23. import android.graphics.drawable.Drawable;
  24. import android.provider.CallLog.Calls;
  25. import android.util.AttributeSet;
  26. import android.view.View;
  27. import com.android.contacts.common.testing.NeededForTesting;
  28. import com.android.contacts.common.util.BitmapUtil;
  29. import com.android.dialer.R;
  30. import com.google.common.collect.Lists;
  31. import java.util.List;
  32. /**
  33. * View that draws one or more symbols for different types of calls (missed calls, outgoing etc).
  34. * The symbols are set up horizontally. As this view doesn't create subviews, it is better suited
  35. * for ListView-recycling that a regular LinearLayout using ImageViews.
  36. */
  37. public class CallTypeIconsView extends View {
  38. private List<Integer> mCallTypes = Lists.newArrayListWithCapacity(3);
  39. private boolean mShowVideo = false;
  40. private Resources mResources;
  41. private int mWidth;
  42. private int mHeight;
  43. public CallTypeIconsView(Context context) {
  44. this(context, null);
  45. }
  46. public CallTypeIconsView(Context context, AttributeSet attrs) {
  47. super(context, attrs);
  48. mResources = new Resources(context);
  49. }
  50. public void clear() {
  51. mCallTypes.clear();
  52. mWidth = 0;
  53. mHeight = 0;
  54. invalidate();
  55. }
  56. public void add(int callType) {
  57. mCallTypes.add(callType);
  58. final Drawable drawable = getCallTypeDrawable(callType);
  59. mWidth += drawable.getIntrinsicWidth() + mResources.iconMargin;
  60. mHeight = Math.max(mHeight, drawable.getIntrinsicHeight());
  61. invalidate();
  62. }
  63. /**
  64. * Determines whether the video call icon will be shown.
  65. *
  66. * @param showVideo True where the video icon should be shown.
  67. */
  68. public void setShowVideo(boolean showVideo) {
  69. mShowVideo = showVideo;
  70. if (showVideo) {
  71. mWidth += mResources.videoCall.getIntrinsicWidth();
  72. mHeight = Math.max(mHeight, mResources.videoCall.getIntrinsicHeight());
  73. invalidate();
  74. }
  75. }
  76. /**
  77. * Determines if the video icon should be shown.
  78. *
  79. * @return True if the video icon should be shown.
  80. */
  81. public boolean isVideoShown() {
  82. return mShowVideo;
  83. }
  84. @NeededForTesting
  85. public int getCount() {
  86. return mCallTypes.size();
  87. }
  88. @NeededForTesting
  89. public int getCallType(int index) {
  90. return mCallTypes.get(index);
  91. }
  92. private Drawable getCallTypeDrawable(int callType) {
  93. switch (callType) {
  94. case Calls.INCOMING_TYPE:
  95. return mResources.incoming;
  96. case Calls.OUTGOING_TYPE:
  97. return mResources.outgoing;
  98. case Calls.MISSED_TYPE:
  99. return mResources.missed;
  100. case Calls.VOICEMAIL_TYPE:
  101. return mResources.voicemail;
  102. default:
  103. // It is possible for users to end up with calls with unknown call types in their
  104. // call history, possibly due to 3rd party call log implementations (e.g. to
  105. // distinguish between rejected and missed calls). Instead of crashing, just
  106. // assume that all unknown call types are missed calls.
  107. return mResources.missed;
  108. }
  109. }
  110. @Override
  111. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  112. setMeasuredDimension(mWidth, mHeight);
  113. }
  114. @Override
  115. protected void onDraw(Canvas canvas) {
  116. int left = 0;
  117. for (Integer callType : mCallTypes) {
  118. final Drawable drawable = getCallTypeDrawable(callType);
  119. final int right = left + drawable.getIntrinsicWidth();
  120. drawable.setBounds(left, 0, right, drawable.getIntrinsicHeight());
  121. drawable.draw(canvas);
  122. left = right + mResources.iconMargin;
  123. }
  124. // If showing the video call icon, draw it scaled appropriately.
  125. if (mShowVideo) {
  126. final Drawable drawable = mResources.videoCall;
  127. final int right = left + mResources.videoCall.getIntrinsicWidth();
  128. drawable.setBounds(left, 0, right, mResources.videoCall.getIntrinsicHeight());
  129. drawable.draw(canvas);
  130. }
  131. }
  132. private static class Resources {
  133. /**
  134. * Drawable representing an incoming answered call.
  135. */
  136. public final Drawable incoming;
  137. /**
  138. * Drawable respresenting an outgoing call.
  139. */
  140. public final Drawable outgoing;
  141. /**
  142. * Drawable representing an incoming missed call.
  143. */
  144. public final Drawable missed;
  145. /**
  146. * Drawable representing a voicemail.
  147. */
  148. public final Drawable voicemail;
  149. /**
  150. * Drawable repesenting a video call.
  151. */
  152. public final Drawable videoCall;
  153. /**
  154. * The margin to use for icons.
  155. */
  156. public final int iconMargin;
  157. /**
  158. * Configures the call icon drawables.
  159. * A single white call arrow which points down and left is used as a basis for all of the
  160. * call arrow icons, applying rotation and colors as needed.
  161. *
  162. * @param context The current context.
  163. */
  164. public Resources(Context context) {
  165. final android.content.res.Resources r = context.getResources();
  166. incoming = r.getDrawable(R.drawable.ic_call_arrow);
  167. incoming.setColorFilter(r.getColor(R.color.answered_call), PorterDuff.Mode.MULTIPLY);
  168. // Create a rotated instance of the call arrow for outgoing calls.
  169. outgoing = BitmapUtil.getRotatedDrawable(r, R.drawable.ic_call_arrow, 180f);
  170. outgoing.setColorFilter(r.getColor(R.color.answered_call), PorterDuff.Mode.MULTIPLY);
  171. // Need to make a copy of the arrow drawable, otherwise the same instance colored
  172. // above will be recolored here.
  173. missed = r.getDrawable(R.drawable.ic_call_arrow).mutate();
  174. missed.setColorFilter(r.getColor(R.color.missed_call), PorterDuff.Mode.MULTIPLY);
  175. voicemail = r.getDrawable(R.drawable.ic_call_voicemail_holo_dark);
  176. // Get the video call icon, scaled to match the height of the call arrows.
  177. // We want the video call icon to be the same height as the call arrows, while keeping
  178. // the same width aspect ratio.
  179. Bitmap videoIcon = BitmapFactory.decodeResource(context.getResources(),
  180. R.drawable.ic_videocam_24dp);
  181. int scaledHeight = missed.getIntrinsicHeight();
  182. int scaledWidth = (int) ((float) videoIcon.getWidth() *
  183. ((float) missed.getIntrinsicHeight() /
  184. (float) videoIcon.getHeight()));
  185. Bitmap scaled = Bitmap.createScaledBitmap(videoIcon, scaledWidth, scaledHeight, false);
  186. videoCall = new BitmapDrawable(context.getResources(), scaled);
  187. videoCall.setColorFilter(r.getColor(R.color.dialtacts_secondary_text_color),
  188. PorterDuff.Mode.MULTIPLY);
  189. iconMargin = r.getDimensionPixelSize(R.dimen.call_log_icon_margin);
  190. }
  191. }
  192. }