1 /*
2  * Copyright (C) 2017 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.server.telecom.testapps;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.net.Uri;
22 import android.os.Bundle;
23 import android.telecom.ConnectionRequest;
24 import android.telecom.Log;
25 import android.telecom.PhoneAccount;
26 import android.telecom.PhoneAccountHandle;
27 import android.telecom.TelecomManager;
28 import android.util.ArrayMap;
29 
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Optional;
34 
35 /**
36  * Manages the list of {@link SelfManagedConnection} active in the sample third-party calling app.
37  */
38 public class SelfManagedCallList {
39     public abstract static class Listener {
onCreateIncomingConnectionFailed(ConnectionRequest request)40         public void onCreateIncomingConnectionFailed(ConnectionRequest request) {};
onCreateOutgoingConnectionFailed(ConnectionRequest request)41         public void onCreateOutgoingConnectionFailed(ConnectionRequest request) {};
onConnectionListChanged()42         public void onConnectionListChanged() {};
onConnectionServiceFocusLost()43         public void onConnectionServiceFocusLost() {};
onConnectionServiceFocusGained()44         public void onConnectionServiceFocusGained() {};
45     }
46 
47     public static String SELF_MANAGED_ACCOUNT_1 = "1";
48     public static String SELF_MANAGED_ACCOUNT_2 = "2";
49     public static String SELF_MANAGED_NAME_1 = "SuperCall";
50     public static String SELF_MANAGED_NAME_2 = "Mega Call";
51     public static String CUSTOM_URI_SCHEME = "custom";
52 
53     private static SelfManagedCallList sInstance;
54     private static ComponentName COMPONENT_NAME = new ComponentName(
55             SelfManagedCallList.class.getPackage().getName(),
56             SelfManagedConnectionService.class.getName());
57     private static Uri SELF_MANAGED_ADDRESS_1 = Uri.fromParts(PhoneAccount.SCHEME_TEL, "555-1212",
58             "");
59     private static Uri SELF_MANAGED_ADDRESS_2 = Uri.fromParts(PhoneAccount.SCHEME_SIP,
60             "me@test.org", "");
61     private static Map<String, PhoneAccountHandle> mPhoneAccounts = new ArrayMap();
62 
getInstance()63     public static SelfManagedCallList getInstance() {
64         if (sInstance == null) {
65             sInstance = new SelfManagedCallList();
66         }
67         return sInstance;
68     }
69 
70     private Listener mListener;
71 
72     private List<SelfManagedConnection> mConnections = new ArrayList<>();
73 
74     private SelfManagedConnection.Listener mConnectionListener =
75             new SelfManagedConnection.Listener() {
76                 @Override
77                 public void onConnectionStateChanged(SelfManagedConnection connection) {
78                     notifyCallModified();
79                 }
80 
81                 @Override
82                 public void onConnectionRemoved(SelfManagedConnection connection) {
83                     removeConnection(connection);
84                     notifyCallModified();
85                 }
86     };
87 
getConnectionListener()88     public SelfManagedConnection.Listener getConnectionListener() {
89         return mConnectionListener;
90     }
91 
92 
setListener(Listener listener)93     public void setListener(Listener listener) {
94         mListener = listener;
95     }
96 
registerPhoneAccounts(Context context)97     public void registerPhoneAccounts(Context context) {
98         registerPhoneAccount(context, SELF_MANAGED_ACCOUNT_1, SELF_MANAGED_ADDRESS_1,
99                 SELF_MANAGED_NAME_1, true /* areCallsLogged */);
100         registerPhoneAccount(context, SELF_MANAGED_ACCOUNT_2, SELF_MANAGED_ADDRESS_2,
101                 SELF_MANAGED_NAME_2, false /* areCallsLogged */);
102     }
103 
registerPhoneAccount(Context context, String id, Uri address, String name, boolean areCallsLogged)104     public void registerPhoneAccount(Context context, String id, Uri address, String name,
105                                      boolean areCallsLogged) {
106         PhoneAccountHandle handle = new PhoneAccountHandle(COMPONENT_NAME, id);
107         mPhoneAccounts.put(id, handle);
108         Bundle extras = new Bundle();
109         extras.putBoolean(PhoneAccount.EXTRA_SUPPORTS_HANDOVER_TO, true);
110         if (areCallsLogged) {
111             extras.putBoolean(PhoneAccount.EXTRA_LOG_SELF_MANAGED_CALLS, true);
112         }
113         PhoneAccount.Builder builder = PhoneAccount.builder(handle, name)
114                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
115                 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
116                 .addSupportedUriScheme(CUSTOM_URI_SCHEME)
117                 .setAddress(address)
118                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
119                         PhoneAccount.CAPABILITY_VIDEO_CALLING |
120                         PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING)
121                 .setExtras(extras)
122                 .setShortDescription(name);
123 
124         TelecomManager.from(context).registerPhoneAccount(builder.build());
125     }
126 
getPhoneAccountHandle(String id)127     public PhoneAccountHandle getPhoneAccountHandle(String id) {
128         return mPhoneAccounts.get(id);
129     }
130 
notifyCreateIncomingConnectionFailed(ConnectionRequest request)131     public void notifyCreateIncomingConnectionFailed(ConnectionRequest request) {
132         if (mListener != null) {
133             mListener.onCreateIncomingConnectionFailed(request);
134         }
135     }
136 
notifyCreateOutgoingConnectionFailed(ConnectionRequest request)137     public void notifyCreateOutgoingConnectionFailed(ConnectionRequest request) {
138         if (mListener != null) {
139             mListener.onCreateOutgoingConnectionFailed(request);
140         }
141     }
142 
notifyConnectionServiceFocusGained()143     public void notifyConnectionServiceFocusGained() {
144         if (mListener != null) {
145             mListener.onConnectionServiceFocusGained();
146         }
147     }
148 
notifyConnectionServiceFocusLost()149     public void notifyConnectionServiceFocusLost() {
150         if (mListener != null) {
151             mListener.onConnectionServiceFocusLost();
152         }
153     }
154 
addConnection(SelfManagedConnection connection)155     public void addConnection(SelfManagedConnection connection) {
156         Log.i(this, "addConnection %s", connection);
157         mConnections.add(connection);
158         if (mListener != null) {
159             Log.i(this, "addConnection calling onConnectionListChanged %s", connection);
160             mListener.onConnectionListChanged();
161         }
162     }
163 
removeConnection(SelfManagedConnection connection)164     public void removeConnection(SelfManagedConnection connection) {
165         Log.i(this, "removeConnection %s", connection);
166         mConnections.remove(connection);
167         if (mListener != null) {
168             Log.i(this, "removeConnection calling onConnectionListChanged %s", connection);
169             mListener.onConnectionListChanged();
170         }
171     }
172 
getConnections()173     public List<SelfManagedConnection> getConnections() {
174         return mConnections;
175     }
176 
getConnectionById(int callId)177     public SelfManagedConnection getConnectionById(int callId) {
178         Optional<SelfManagedConnection> foundOptional = mConnections.stream()
179                 .filter((c) -> {return c.getCallId() == callId;})
180                 .findFirst();
181         return foundOptional.orElse(null);
182     }
183 
notifyCallModified()184     public void notifyCallModified() {
185         if (mListener != null) {
186             mListener.onConnectionListChanged();
187         }
188     }
189 }
190