1 /*
2  * Copyright (C) 2018 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 
17 package com.android.dialer.speeddial;
18 
19 import android.content.Context;
20 import android.support.annotation.NonNull;
21 import android.support.annotation.VisibleForTesting;
22 import android.support.v7.widget.PopupMenu;
23 import android.support.v7.widget.PopupMenu.OnMenuItemClickListener;
24 import android.text.TextUtils;
25 import android.view.Gravity;
26 import android.view.MenuItem;
27 import android.view.View;
28 import com.android.dialer.common.Assert;
29 import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
30 import com.android.dialer.speeddial.loader.SpeedDialUiItem;
31 
32 /** {@link PopupMenu} which presents contact options for starred contacts. */
33 public class ContextMenu extends PopupMenu implements OnMenuItemClickListener {
34 
35   private final ContextMenuItemListener listener;
36 
37   private final SpeedDialUiItem speedDialUiItem;
38   private final Channel voiceChannel;
39   private final Channel videoChannel;
40 
41   private boolean visible;
42 
43   /**
44    * Creates a new context menu and displays it.
45    *
46    * @see #show()
47    */
show( Context context, View anchor, ContextMenuItemListener contextMenuListener, SpeedDialUiItem speedDialUiItem)48   public static ContextMenu show(
49       Context context,
50       View anchor,
51       ContextMenuItemListener contextMenuListener,
52       SpeedDialUiItem speedDialUiItem) {
53     ContextMenu menu = new ContextMenu(context, anchor, contextMenuListener, speedDialUiItem);
54     menu.show();
55     menu.visible = true;
56     return menu;
57   }
58 
59   /**
60    * Hides the context menu.
61    *
62    * @see #dismiss()
63    */
hide()64   public void hide() {
65     dismiss();
66     visible = false;
67   }
68 
ContextMenu( @onNull Context context, @NonNull View anchor, ContextMenuItemListener listener, SpeedDialUiItem speedDialUiItem)69   private ContextMenu(
70       @NonNull Context context,
71       @NonNull View anchor,
72       ContextMenuItemListener listener,
73       SpeedDialUiItem speedDialUiItem) {
74     super(context, anchor, Gravity.CENTER);
75     this.listener = listener;
76     this.speedDialUiItem = speedDialUiItem;
77     voiceChannel = speedDialUiItem.getDefaultVoiceChannel();
78     videoChannel = speedDialUiItem.getDefaultVideoChannel();
79 
80     setOnMenuItemClickListener(this);
81     getMenuInflater().inflate(R.menu.starred_contact_context_menu, getMenu());
82     getMenu().findItem(R.id.voice_call_container).setVisible(voiceChannel != null);
83     getMenu().findItem(R.id.video_call_container).setVisible(videoChannel != null);
84     getMenu().findItem(R.id.send_message_container).setVisible(voiceChannel != null);
85     if (voiceChannel != null) {
86       String secondaryInfo =
87           TextUtils.isEmpty(voiceChannel.label())
88               ? voiceChannel.number()
89               : context.getString(
90                   R.string.call_subject_type_and_number,
91                   voiceChannel.label(),
92                   voiceChannel.number());
93       getMenu().findItem(R.id.starred_contact_context_menu_title).setTitle(secondaryInfo);
94       getMenu().findItem(R.id.starred_contact_context_menu_title).setVisible(true);
95     } else {
96       getMenu().findItem(R.id.starred_contact_context_menu_title).setVisible(false);
97     }
98   }
99 
100   @Override
onMenuItemClick(MenuItem menuItem)101   public boolean onMenuItemClick(MenuItem menuItem) {
102     if (menuItem.getItemId() == R.id.voice_call_container) {
103       listener.placeCall(Assert.isNotNull(voiceChannel));
104     } else if (menuItem.getItemId() == R.id.video_call_container) {
105       listener.placeCall(Assert.isNotNull(videoChannel));
106     } else if (menuItem.getItemId() == R.id.send_message_container) {
107       listener.openSmsConversation(voiceChannel.number());
108     } else if (menuItem.getItemId() == R.id.remove_container) {
109       listener.removeFavoriteContact(speedDialUiItem);
110     } else if (menuItem.getItemId() == R.id.contact_info_container) {
111       listener.openContactInfo(speedDialUiItem);
112     } else {
113       throw Assert.createIllegalStateFailException("Menu option click not handled");
114     }
115     return true;
116   }
117 
118   @VisibleForTesting(otherwise = VisibleForTesting.NONE)
isVisible()119   public boolean isVisible() {
120     return visible;
121   }
122 
123   /** Listener to report user clicks on menu items. */
124   @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
125   public interface ContextMenuItemListener {
126 
127     /** Called when the user selects "voice call" or "video call" option from the context menu. */
placeCall(Channel channel)128     void placeCall(Channel channel);
129 
130     /** Called when the user selects "send message" from the context menu. */
openSmsConversation(String number)131     void openSmsConversation(String number);
132 
133     /** Called when the user selects "remove" from the context menu. */
removeFavoriteContact(SpeedDialUiItem speedDialUiItem)134     void removeFavoriteContact(SpeedDialUiItem speedDialUiItem);
135 
136     /** Called when the user selects "contact info" from the context menu. */
openContactInfo(SpeedDialUiItem speedDialUiItem)137     void openContactInfo(SpeedDialUiItem speedDialUiItem);
138   }
139 }
140