Merge "Implement NfcServiceManager and NfcFrameworkInitializer"

This commit is contained in:
Alisher Alikhodjaev
2023-03-02 19:26:41 +00:00
committed by Gerrit Code Review
7 changed files with 242 additions and 15 deletions

View File

@@ -5416,6 +5416,8 @@ android.nfc.NfcAdapter$CreateNdefMessageCallback
android.nfc.NfcAdapter android.nfc.NfcAdapter
android.nfc.NfcControllerAlwaysOnListener android.nfc.NfcControllerAlwaysOnListener
android.nfc.NfcManager android.nfc.NfcManager
android.nfc.NfcServiceManager$ServiceRegisterer
android.nfc.NfcServiceManager
android.nfc.Tag$1 android.nfc.Tag$1
android.nfc.Tag android.nfc.Tag
android.nfc.TechListParcel$1 android.nfc.TechListParcel$1

View File

@@ -297,6 +297,30 @@ package android.net.netstats {
} }
package android.nfc {
public class NfcFrameworkInitializer {
method public static void registerServiceWrappers();
method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager);
}
public class NfcServiceManager {
method @NonNull public android.nfc.NfcServiceManager.ServiceRegisterer getNfcManagerServiceRegisterer();
}
public static class NfcServiceManager.ServiceNotFoundException extends java.lang.Exception {
ctor public NfcServiceManager.ServiceNotFoundException(@NonNull String);
}
public static final class NfcServiceManager.ServiceRegisterer {
method @Nullable public android.os.IBinder get();
method @NonNull public android.os.IBinder getOrThrow() throws android.nfc.NfcServiceManager.ServiceNotFoundException;
method public void register(@NonNull android.os.IBinder);
method @Nullable public android.os.IBinder tryGet();
}
}
package android.os { package android.os {
public final class BatteryStatsManager { public final class BatteryStatsManager {

View File

@@ -109,6 +109,8 @@ import android.net.ConnectivityManager;
import android.net.Proxy; import android.net.Proxy;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.net.Uri; import android.net.Uri;
import android.nfc.NfcFrameworkInitializer;
import android.nfc.NfcServiceManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Binder; import android.os.Binder;
import android.os.BluetoothServiceManager; import android.os.BluetoothServiceManager;
@@ -7908,6 +7910,7 @@ public final class ActivityThread extends ClientTransactionHandler
BluetoothFrameworkInitializer.setBluetoothServiceManager(new BluetoothServiceManager()); BluetoothFrameworkInitializer.setBluetoothServiceManager(new BluetoothServiceManager());
BluetoothFrameworkInitializer.setBinderCallsStatsInitializer(context -> { BluetoothFrameworkInitializer.setBinderCallsStatsInitializer(context -> {
BinderCallsStats.startForBluetooth(context); }); BinderCallsStats.startForBluetooth(context); });
NfcFrameworkInitializer.setNfcServiceManager(new NfcServiceManager());
} }
private void purgePendingResources() { private void purgePendingResources() {

View File

@@ -148,7 +148,7 @@ import android.net.vcn.IVcnManagementService;
import android.net.vcn.VcnManager; import android.net.vcn.VcnManager;
import android.net.wifi.WifiFrameworkInitializer; import android.net.wifi.WifiFrameworkInitializer;
import android.net.wifi.nl80211.WifiNl80211Manager; import android.net.wifi.nl80211.WifiNl80211Manager;
import android.nfc.NfcManager; import android.nfc.NfcFrameworkInitializer;
import android.ondevicepersonalization.OnDevicePersonalizationFrameworkInitializer; import android.ondevicepersonalization.OnDevicePersonalizationFrameworkInitializer;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.os.BatteryStats; import android.os.BatteryStats;
@@ -457,13 +457,6 @@ public final class SystemServiceRegistry {
return new BatteryManager(ctx, stats, registrar); return new BatteryManager(ctx, stats, registrar);
}}); }});
registerService(Context.NFC_SERVICE, NfcManager.class,
new CachedServiceFetcher<NfcManager>() {
@Override
public NfcManager createService(ContextImpl ctx) {
return new NfcManager(ctx);
}});
registerService(Context.DROPBOX_SERVICE, DropBoxManager.class, registerService(Context.DROPBOX_SERVICE, DropBoxManager.class,
new CachedServiceFetcher<DropBoxManager>() { new CachedServiceFetcher<DropBoxManager>() {
@Override @Override
@@ -1514,6 +1507,7 @@ public final class SystemServiceRegistry {
JobSchedulerFrameworkInitializer.registerServiceWrappers(); JobSchedulerFrameworkInitializer.registerServiceWrappers();
BlobStoreManagerFrameworkInitializer.initialize(); BlobStoreManagerFrameworkInitializer.initialize();
BluetoothFrameworkInitializer.registerServiceWrappers(); BluetoothFrameworkInitializer.registerServiceWrappers();
NfcFrameworkInitializer.registerServiceWrappers();
TelephonyFrameworkInitializer.registerServiceWrappers(); TelephonyFrameworkInitializer.registerServiceWrappers();
AppSearchManagerFrameworkInitializer.initialize(); AppSearchManagerFrameworkInitializer.initialize();
WifiFrameworkInitializer.registerServiceWrappers(); WifiFrameworkInitializer.registerServiceWrappers();

View File

@@ -41,7 +41,6 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log; import android.util.Log;
import java.io.IOException; import java.io.IOException;
@@ -424,6 +423,7 @@ public final class NfcAdapter {
// recovery // recovery
@UnsupportedAppUsage @UnsupportedAppUsage
static INfcAdapter sService; static INfcAdapter sService;
static NfcServiceManager.ServiceRegisterer sServiceRegisterer;
static INfcTag sTagService; static INfcTag sTagService;
static INfcCardEmulation sCardEmulationService; static INfcCardEmulation sCardEmulationService;
static INfcFCardEmulation sNfcFCardEmulationService; static INfcFCardEmulation sNfcFCardEmulationService;
@@ -622,6 +622,12 @@ public final class NfcAdapter {
Log.v(TAG, "this device does not have NFC support"); Log.v(TAG, "this device does not have NFC support");
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
NfcServiceManager manager = NfcFrameworkInitializer.getNfcServiceManager();
if (manager == null) {
Log.e(TAG, "NfcServiceManager is null");
throw new UnsupportedOperationException();
}
sServiceRegisterer = manager.getNfcManagerServiceRegisterer();
sService = getServiceInterface(); sService = getServiceInterface();
if (sService == null) { if (sService == null) {
Log.e(TAG, "could not retrieve NFC service"); Log.e(TAG, "could not retrieve NFC service");
@@ -663,7 +669,7 @@ public final class NfcAdapter {
/** get handle to NFC service interface */ /** get handle to NFC service interface */
private static INfcAdapter getServiceInterface() { private static INfcAdapter getServiceInterface() {
/* get a handle to NFC service */ /* get a handle to NFC service */
IBinder b = ServiceManager.getService("nfc"); IBinder b = sServiceRegisterer.get();
if (b == null) { if (b == null) {
return null; return null;
} }
@@ -693,12 +699,13 @@ public final class NfcAdapter {
"context not associated with any application (using a mock context?)"); "context not associated with any application (using a mock context?)");
} }
if (getServiceInterface() == null) { if (sIsInitialized && sServiceRegisterer.tryGet() == null) {
// NFC is not available synchronized (NfcAdapter.class) {
return null; /* Stale sService pointer */
if (sIsInitialized) sIsInitialized = false;
}
} }
/* Try to initialize the service */
/* use getSystemService() for consistency */
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE); NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
if (manager == null) { if (manager == null) {
// NFC not available // NFC not available

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.nfc;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.SystemServiceRegistry;
import android.content.Context;
/**
* Class for performing registration for Nfc service.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public class NfcFrameworkInitializer {
private NfcFrameworkInitializer() {}
private static volatile NfcServiceManager sNfcServiceManager;
/**
* Sets an instance of {@link NfcServiceManager} that allows
* the nfc mainline module to register/obtain nfc binder services. This is called
* by the platform during the system initialization.
*
* @param nfcServiceManager instance of {@link NfcServiceManager} that allows
* the nfc mainline module to register/obtain nfcd binder services.
*/
public static void setNfcServiceManager(
@NonNull NfcServiceManager nfcServiceManager) {
if (sNfcServiceManager != null) {
throw new IllegalStateException("setNfcServiceManager called twice!");
}
if (nfcServiceManager == null) {
throw new IllegalArgumentException("nfcServiceManager must not be null");
}
sNfcServiceManager = nfcServiceManager;
}
/** @hide */
public static NfcServiceManager getNfcServiceManager() {
return sNfcServiceManager;
}
/**
* Called by {@link SystemServiceRegistry}'s static initializer and registers NFC service
* to {@link Context}, so that {@link Context#getSystemService} can return them.
*
* @throws IllegalStateException if this is called from anywhere besides
* {@link SystemServiceRegistry}
*/
public static void registerServiceWrappers() {
SystemServiceRegistry.registerContextAwareService(Context.NFC_SERVICE,
NfcManager.class, context -> new NfcManager(context));
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**********************************************************************
* This file is not a part of the NFC mainline modure *
* *******************************************************************/
package android.nfc;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemApi.Client;
import android.content.Context;
import android.os.IBinder;
import android.os.ServiceManager;
/**
* Provides a way to register and obtain the system service binder objects managed by the nfc
* service.
*
* @hide
*/
@SystemApi(client = Client.MODULE_LIBRARIES)
public class NfcServiceManager {
/**
* @hide
*/
public NfcServiceManager() {
}
/**
* A class that exposes the methods to register and obtain each system service.
*/
public static final class ServiceRegisterer {
private final String mServiceName;
/**
* @hide
*/
public ServiceRegisterer(String serviceName) {
mServiceName = serviceName;
}
/**
* Register a system server binding object for a service.
*/
public void register(@NonNull IBinder service) {
ServiceManager.addService(mServiceName, service);
}
/**
* Get the system server binding object for a service.
*
* <p>This blocks until the service instance is ready,
* or a timeout happens, in which case it returns null.
*/
@Nullable
public IBinder get() {
return ServiceManager.getService(mServiceName);
}
/**
* Get the system server binding object for a service.
*
* <p>This blocks until the service instance is ready,
* or a timeout happens, in which case it throws {@link ServiceNotFoundException}.
*/
@NonNull
public IBinder getOrThrow() throws ServiceNotFoundException {
try {
return ServiceManager.getServiceOrThrow(mServiceName);
} catch (ServiceManager.ServiceNotFoundException e) {
throw new ServiceNotFoundException(mServiceName);
}
}
/**
* Get the system server binding object for a service. If the specified service is
* not available, it returns null.
*/
@Nullable
public IBinder tryGet() {
return ServiceManager.checkService(mServiceName);
}
}
/**
* See {@link ServiceRegisterer#getOrThrow}.
*
*/
public static class ServiceNotFoundException extends ServiceManager.ServiceNotFoundException {
/**
* Constructor.
*
* @param name the name of the binder service that cannot be found.
*
*/
public ServiceNotFoundException(@NonNull String name) {
super(name);
}
}
/**
* Returns {@link ServiceRegisterer} for the "nfc" service.
*/
@NonNull
public ServiceRegisterer getNfcManagerServiceRegisterer() {
return new ServiceRegisterer(Context.NFC_SERVICE);
}
}