• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.systemui.car.ndo;
17 
18 import android.telecom.Call;
19 import android.telecom.PhoneAccountHandle;
20 import android.util.Slog;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.Nullable;
24 import androidx.lifecycle.MediatorLiveData;
25 
26 import com.android.car.telephony.calling.InCallServiceManager;
27 import com.android.car.telephony.common.CallDetail;
28 import com.android.systemui.car.telecom.InCallServiceImpl;
29 
30 import java.util.List;
31 
32 /**
33  * Livedata that provides first active call of the currently blocked calling activity.
34  * Returns null if no calls are found for the currently blocked activity.
35  * <p>
36  * Calls must be in an active or holding {@link Call.CallState}. Other states will not emit a value.
37  */
38 public class InCallLiveData extends MediatorLiveData<Call> implements
39         InCallServiceImpl.InCallListener {
40     private static final String TAG = "SysUi.InCallLiveData";
41 
42     private final InCallServiceManager mServiceManager;
43     private final String mBlockedActivity;
44 
InCallLiveData(InCallServiceManager serviceManager, String packageName)45     public InCallLiveData(InCallServiceManager serviceManager, String packageName) {
46         mServiceManager = serviceManager;
47         mBlockedActivity = packageName;
48     }
49 
50     @Override
onActive()51     protected void onActive() {
52         super.onActive();
53 
54         if (mServiceManager.getInCallService() == null) {
55             setValue(null);
56             return;
57         }
58         update();
59     }
60 
61     @Override
onInactive()62     protected void onInactive() {
63         super.onInactive();
64         setValue(null);
65     }
66 
67     @Override
onCallAdded(Call call)68     public void onCallAdded(Call call) {
69         Slog.d(TAG, "Call added: " + call);
70         update();
71     }
72 
73     @Override
onCallRemoved(Call call)74     public void onCallRemoved(Call call) {
75         Slog.d(TAG, "Call removed: " + call);
76         update();
77     }
78 
79     @Override
onStateChanged(Call call, int state)80     public void onStateChanged(Call call, int state) {
81         Slog.d(TAG, "onStateChanged: " + call + " state: " + state);
82         update();
83     }
84 
85     @Override
onParentChanged(Call call, Call parent)86     public void onParentChanged(Call call, Call parent) {
87         Slog.d(TAG, "onParentChanged: " + call);
88         update();
89     }
90 
91     @Override
onChildrenChanged(Call call, List<Call> children)92     public void onChildrenChanged(Call call, List<Call> children) {
93         Slog.d(TAG, "onChildrenChanged: " + call);
94         update();
95     }
96 
update()97     private void update() {
98         setValue(getFirstBlockedActivityCall());
99     }
100 
101     @Nullable
getFirstBlockedActivityCall()102     private Call getFirstBlockedActivityCall() {
103         InCallServiceImpl inCallService = (InCallServiceImpl) mServiceManager.getInCallService();
104 
105         if (inCallService == null) {
106             Slog.i(TAG, "null InCallService");
107             return null;
108         }
109 
110         List<Call> callList = inCallService.getCalls();
111         List<Call> blockedAppCallList = callList.stream()
112                 .filter(call -> contains(mBlockedActivity, getSelfManagedCallAppPackageName(call)))
113                 .toList();
114 
115         return blockedAppCallList.isEmpty() ? null : blockedAppCallList.get(0);
116     }
117 
contains(String a, String b)118     private boolean contains(String a, String b) {
119         if (a == null || b == null) {
120             return false;
121         }
122         return a.contains(b);
123     }
124 
125     @Nullable
getSelfManagedCallAppPackageName(@onNull Call call)126     private String getSelfManagedCallAppPackageName(@NonNull Call call) {
127         int callState = call.getDetails().getState();
128 
129         if (callState != Call.STATE_ACTIVE && callState != Call.STATE_HOLDING) {
130             return null;
131         }
132         CallDetail callDetails = CallDetail.fromTelecomCallDetail(call.getDetails());
133         if (callDetails.isSelfManaged()) {
134             PhoneAccountHandle phoneAccountHandle = callDetails.getPhoneAccountHandle();
135             return phoneAccountHandle == null ? null
136                     : phoneAccountHandle.getComponentName().getPackageName();
137         }
138         return null;
139     }
140 }
141