blob: 50d427384100380becfdc904d31f8f6c35540e73 [file] [log] [blame]
/******************************************************************************
*
* Copyright 2020-2021 NXP
*
* 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 com.android.nfc;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.nfc.NdefMessage;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import com.nxp.nfc.INxpWlcCallBack;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.NoSuchElementException;
/*******************************************************************************
*WlcServiceProxy maps WlcService functions to NfcService module through
*reflection and acts as interface between NfcService and WlcService to access
*Wlc functionalities.
*If WlcService module is not accessible through reflection (WlcService aar not
*included indicates feature not supported in runtime), it can return appropriate
*error status to application.
*******************************************************************************/
public class WlcServiceProxy {
/************************private members starts******************************/
private static final String TAG = "WlcServiceProxy";
private static final int WLC_STATUS_SUCCESS = 0x00;
private static final int WLC_STATUS_FAILED = 0x03;
private Context mContext;
private SharedPreferences mNxpPrefs;
private SharedPreferences.Editor mNxpPrefsEditor;
private INxpWlcCallBack mWlcCback;
final Object mResponseEvent = new Object();
private Class mClientClass = null;
private Object mClientObj = null;
private int mStatus = WLC_STATUS_FAILED;
private Method mClientConnect = null, mClientGetinstance = null, mClientChekIsListener = null,
mClientEnable = null, mClientIsEnabled = null, mClientActivated = null,
mClientStopCharging = null, mClientDeactivated = null, mClientDisable = null;
private boolean mServiceConnected = false;
private boolean mIsWlcEnebled = true, mIsWlcSupported = true;
private boolean isFeatureSupported = false;
private static NfcService sService;
private void mapReflectionContext() {
try {
mClientClass = Class.forName("com.android.nfc.wlc.WlcClient");
mClientGetinstance = mClientClass.getDeclaredMethod("getInstance");
mClientConnect = mClientClass.getDeclaredMethod("connect", Context.class);
mClientChekIsListener = mClientClass.getDeclaredMethod("isWlcListener", NdefMessage.class);
mClientEnable = mClientClass.getDeclaredMethod("enable");
mClientIsEnabled = mClientClass.getDeclaredMethod("isEnabled");
mClientStopCharging = mClientClass.getDeclaredMethod("stopCharging");
mClientDeactivated = mClientClass.getDeclaredMethod("deactivated");
mClientDisable = mClientClass.getDeclaredMethod("disable");
mClientObj = mClientGetinstance.invoke(new Object[] {null});
Log.d(TAG, "Successfully mapped wlc library methods");
} catch (Exception e) {
Log.e(TAG, "caught Exception during wlcClientInvocation!! " + e);
}
}
private void notifyStatus(int status) {
try {
if (mWlcCback != null)
mWlcCback.updateStatus(status);
} catch (Exception e) {
Log.e(TAG, "caught Exception during notifyStatus!! " + e);
}
}
private void updateWlcEnablePersistStatus(boolean status) {
mNxpPrefsEditor = mNxpPrefs.edit();
mNxpPrefsEditor.putBoolean("PREF_WLC_ENABLE_STATUS", status);
mNxpPrefsEditor.commit();
}
/************************private members ends********************************/
/*********************public members starts here*****************************/
enum PersistStatus { UPDATE, IGNORE }
public WlcServiceProxy(Context context, SharedPreferences mPrefs) {
Log.e(TAG, "WlcServiceProxy constructor enter");
mContext = context;
mNxpPrefs = mPrefs;
mWlcCback = null;
sService = NfcService.getInstance();
mapReflectionContext();
}
public void registerCallBack(INxpWlcCallBack wlcCallBack) {
mWlcCback = wlcCallBack;
}
public void deRegisterCallBack() {
mWlcCback = null;
}
public boolean isToBeEnabled() {
return mNxpPrefs.getBoolean("PREF_WLC_ENABLE_STATUS", false);
}
public void enable(PersistStatus instruction) {
if (!isServiceConnected() || (mClientObj == null) || (mClientEnable == null)) {
notifyStatus(WLC_STATUS_FAILED);
return;
}
int status = WLC_STATUS_FAILED;
try {
status = (int) mClientEnable.invoke(mClientObj);
if ((instruction == PersistStatus.UPDATE) && (status == WLC_STATUS_SUCCESS))
updateWlcEnablePersistStatus(true);
} catch (Exception e) {
Log.e(TAG, " Failed!! Cause : " + e.toString());
status = WLC_STATUS_FAILED;
} finally {
notifyStatus(status);
}
}
public boolean isEnabled() {
if (!isServiceConnected() || (mClientObj == null) || (mClientIsEnabled == null))
return false;
try {
return (boolean) mClientIsEnabled.invoke(mClientObj);
} catch (Exception e) {
Log.e(TAG, " Failed!! Cause : " + e.toString());
return false;
}
}
public void disable(PersistStatus instruction) {
if (!isServiceConnected() || (mClientObj == null) || (mClientDisable == null)) {
notifyStatus(WLC_STATUS_FAILED);
return;
}
int status = WLC_STATUS_FAILED;
try {
status = (int) mClientDisable.invoke(mClientObj);
if ((instruction == PersistStatus.UPDATE) && (status == WLC_STATUS_SUCCESS))
updateWlcEnablePersistStatus(false);
} catch (Exception e) {
Log.e(TAG, " Failed!! Cause : " + e.toString());
status = WLC_STATUS_FAILED;
} finally {
notifyStatus(status);
}
}
public boolean isWlcListenerDetected(NdefMessage ndefMsg) {
if (!isServiceConnected() || (mClientObj == null) || (mClientChekIsListener == null))
return false;
int status = WLC_STATUS_FAILED;
try {
status = (int) mClientChekIsListener.invoke(mClientObj, ndefMsg);
} catch (Exception e) {
Log.e(TAG, " Failed!! Cause : " + e.toString());
status = WLC_STATUS_FAILED;
} finally {
return (status == WLC_STATUS_SUCCESS);
}
}
public void stopCharging() throws RemoteException {
if (!isServiceConnected() || (mClientObj == null) || (mClientStopCharging == null))
return;
try {
if (mClientObj != null) {
mClientStopCharging.invoke(mClientObj);
}
} catch (Exception e) {
Log.e(TAG, "Exception invoking stopCharging!! " + e);
throw new RemoteException();
}
}
public void deactivated() throws RemoteException {
if (!isServiceConnected() || (mClientObj == null) || (mClientDeactivated == null))
return;
try {
if (mClientObj != null) {
mClientDeactivated.invoke(mClientObj);
}
} catch (Exception e) {
Log.e(TAG, "Exception invoking deactivate!! " + e);
throw new RemoteException();
}
}
public boolean isServiceConnected() {
if ((mClientObj == null) || (mClientConnect == null))
return false;
try {
if (mServiceConnected)
return true;
mServiceConnected = (boolean) mClientConnect.invoke(mClientObj, mContext);
return mServiceConnected;
} catch (IllegalAccessException | InvocationTargetException e) {
return false;
}
}
/***********************public members ends**********************************/
}