blob: 70481f8332c958ae8d32b21b341f89e2907a1a8a [file] [log] [blame]
nxpandroid34627bd2016-05-27 15:52:30 +05301/*
2 * Copyright (C) 2015 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
17package com.android.nfc.cardemulation;
18
19import android.app.ActivityManager;
20import android.content.ComponentName;
21import android.content.Context;
22import android.nfc.cardemulation.NfcFServiceInfo;
23import android.util.Log;
24
25import java.io.FileDescriptor;
26import java.io.PrintWriter;
27import java.util.ArrayList;
28import java.util.Iterator;
29import java.util.List;
30import java.util.Map;
31import java.util.HashMap;
nxf500513a018e72019-04-23 17:11:41 +053032import android.os.SystemProperties;
nxpandroid34627bd2016-05-27 15:52:30 +053033
34public class RegisteredT3tIdentifiersCache {
35 static final String TAG = "RegisteredT3tIdentifiersCache";
36
nxf500513a018e72019-04-23 17:11:41 +053037 static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false);
nxpandroid34627bd2016-05-27 15:52:30 +053038
39 // All NFC-F services that have registered
40 List<NfcFServiceInfo> mServices = new ArrayList<NfcFServiceInfo>();
41
42 final HashMap<String, NfcFServiceInfo> mForegroundT3tIdentifiersCache =
43 new HashMap<String, NfcFServiceInfo>();
44
45 ComponentName mEnabledForegroundService;
46
47 final class T3tIdentifier {
48 public final String systemCode;
49 public final String nfcid2;
nxpandroid6fd9cdb2017-07-12 18:25:41 +053050 public final String t3tPmm;
nxf500513a018e72019-04-23 17:11:41 +053051
nxpandroid6fd9cdb2017-07-12 18:25:41 +053052 T3tIdentifier(String systemCode, String nfcid2, String t3tPmm) {
nxpandroid34627bd2016-05-27 15:52:30 +053053 this.systemCode = systemCode;
54 this.nfcid2 = nfcid2;
nxpandroid6fd9cdb2017-07-12 18:25:41 +053055 this.t3tPmm = t3tPmm;
nxpandroid34627bd2016-05-27 15:52:30 +053056 }
57
58 @Override
59 public boolean equals(Object o) {
60 if (this == o) return true;
61 if (o == null || getClass() != o.getClass()) return false;
62
63 T3tIdentifier that = (T3tIdentifier) o;
64 if (!systemCode.equalsIgnoreCase(that.systemCode)) return false;
65 if (!nfcid2.equalsIgnoreCase(that.nfcid2)) return false;
66
67 return true;
68 }
69
70 @Override
71 public int hashCode() {
72 int result = systemCode.hashCode();
73 result = 31 * result + nfcid2.hashCode();
74 return result;
75 }
76 }
77
78 final Context mContext;
79 final SystemCodeRoutingManager mRoutingManager;
80
81 final Object mLock = new Object();
82
83 boolean mNfcEnabled = false;
84
85 public RegisteredT3tIdentifiersCache(Context context) {
86 Log.d(TAG, "RegisteredT3tIdentifiersCache");
87 mContext = context;
88 mRoutingManager = new SystemCodeRoutingManager();
89 }
90
91 public NfcFServiceInfo resolveNfcid2(String nfcid2) {
92 synchronized (mLock) {
93 if (DBG) Log.d(TAG, "resolveNfcid2: resolving NFCID " + nfcid2);
94 NfcFServiceInfo resolveInfo;
95 resolveInfo = mForegroundT3tIdentifiersCache.get(nfcid2);
96 Log.d(TAG,
97 "Resolved to: " + (resolveInfo == null ? "null" : resolveInfo.toString()));
98 return resolveInfo;
99 }
100 }
101
102 void generateForegroundT3tIdentifiersCacheLocked() {
103 if (DBG) Log.d(TAG, "generateForegroundT3tIdentifiersCacheLocked");
104 mForegroundT3tIdentifiersCache.clear();
105 if (mEnabledForegroundService != null) {
106 for (NfcFServiceInfo service : mServices) {
107 if (mEnabledForegroundService.equals(service.getComponent())) {
108 if (!service.getSystemCode().equalsIgnoreCase("NULL") &&
109 !service.getNfcid2().equalsIgnoreCase("NULL")) {
110 mForegroundT3tIdentifiersCache.put(service.getNfcid2(), service);
111 }
112 break;
113 }
114 }
115 }
116
117 if (DBG) {
118 Log.d(TAG, "mForegroundT3tIdentifiersCache: size=" +
119 mForegroundT3tIdentifiersCache.size());
120 for (Map.Entry<String, NfcFServiceInfo> entry :
121 mForegroundT3tIdentifiersCache.entrySet()) {
122 Log.d(TAG, " " + entry.getKey() +
123 "/" + entry.getValue().getComponent().toString());
124 }
125 }
126
nxf500513a018e72019-04-23 17:11:41 +0530127 updateRoutingLocked(false);
nxpandroid34627bd2016-05-27 15:52:30 +0530128 }
129
nxf500513a018e72019-04-23 17:11:41 +0530130 void updateRoutingLocked(boolean force) {
nxpandroid34627bd2016-05-27 15:52:30 +0530131 if (DBG) Log.d(TAG, "updateRoutingLocked");
132 if (!mNfcEnabled) {
133 Log.d(TAG, "Not updating routing table because NFC is off.");
134 return;
135 }
136 List<T3tIdentifier> t3tIdentifiers = new ArrayList<T3tIdentifier>();
nxf500513a018e72019-04-23 17:11:41 +0530137
138 // Sending an empty table will de-register all entries
139 if (force) {
140 mRoutingManager.configureRouting(t3tIdentifiers);
141 }
nxpandroid34627bd2016-05-27 15:52:30 +0530142 Iterator<Map.Entry<String, NfcFServiceInfo>> it;
143 // Register foreground service
144 it = mForegroundT3tIdentifiersCache.entrySet().iterator();
145 while (it.hasNext()) {
146 Map.Entry<String, NfcFServiceInfo> entry =
147 (Map.Entry<String, NfcFServiceInfo>) it.next();
148 t3tIdentifiers.add(new T3tIdentifier(
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530149 entry.getValue().getSystemCode(), entry.getValue().getNfcid2(), entry.getValue().getT3tPmm()));
nxpandroid34627bd2016-05-27 15:52:30 +0530150 }
151 mRoutingManager.configureRouting(t3tIdentifiers);
152 }
153
nxf500513a018e72019-04-23 17:11:41 +0530154 public void onSecureNfcToggled() {
155 synchronized(mLock) {
156 updateRoutingLocked(true);
157 }
158 }
159
nxpandroid34627bd2016-05-27 15:52:30 +0530160 public void onServicesUpdated(int userId, List<NfcFServiceInfo> services) {
161 if (DBG) Log.d(TAG, "onServicesUpdated");
162 synchronized (mLock) {
163 if (ActivityManager.getCurrentUser() == userId) {
164 // Rebuild our internal data-structures
165 mServices = services;
166 } else {
167 Log.d(TAG, "Ignoring update because it's not for the current user.");
168 }
169 }
170 }
171
172 public void onEnabledForegroundNfcFServiceChanged(ComponentName component) {
173 if (DBG) Log.d(TAG, "Enabled foreground service changed.");
174 synchronized (mLock) {
175 if (component != null) {
176 if (mEnabledForegroundService != null) {
177 return;
178 }
179 mEnabledForegroundService = component;
180 } else {
181 if (mEnabledForegroundService == null) {
182 return;
183 }
184 mEnabledForegroundService = null;
185 }
186 generateForegroundT3tIdentifiersCacheLocked();
187 }
188 }
189
190 public void onNfcEnabled() {
191 synchronized (mLock) {
192 mNfcEnabled = true;
193 }
194 }
195
196 public void onNfcDisabled() {
197 synchronized (mLock) {
198 mNfcEnabled = false;
199 mForegroundT3tIdentifiersCache.clear();
200 mEnabledForegroundService = null;
201 }
202 mRoutingManager.onNfccRoutingTableCleared();
203 }
204
205 public void onUserSwitched() {
206 synchronized (mLock) {
207 mForegroundT3tIdentifiersCache.clear();
nxf500513a018e72019-04-23 17:11:41 +0530208 updateRoutingLocked(false);
nxpandroid34627bd2016-05-27 15:52:30 +0530209 mEnabledForegroundService = null;
210 }
211 }
212
213 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
nxpandroid53038072017-09-14 11:14:26 +0530214 pw.println("T3T Identifier cache entries: ");
nxpandroid34627bd2016-05-27 15:52:30 +0530215 for (Map.Entry<String, NfcFServiceInfo> entry : mForegroundT3tIdentifiersCache.entrySet()) {
216 pw.println(" NFCID2: " + entry.getKey());
217 pw.println(" NfcFServiceInfo: ");
218 entry.getValue().dump(fd, pw, args);
219 }
220 pw.println("");
221 mRoutingManager.dump(fd, pw, args);
222 pw.println("");
223 }
224}