com.feedhenry.sdk.FH Maven / Gradle / Ivy
/**
* Copyright Red Hat, Inc, and individual contributors.
*
* 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.feedhenry.sdk;
import android.content.Context;
import com.feedhenry.sdk.api.FHActRequest;
import com.feedhenry.sdk.api.FHAuthRequest;
import com.feedhenry.sdk.api.FHAuthSession;
import com.feedhenry.sdk.api.FHCloudRequest;
import com.feedhenry.sdk.api.FHCloudRequest.Methods;
import com.feedhenry.sdk.api.FHInitializeRequest;
import com.feedhenry.sdk.exceptions.FHNotReadyException;
import com.feedhenry.sdk.utils.DataManager;
import com.feedhenry.sdk.utils.FHLog;
import cz.msebera.android.httpclient.Header;
import cz.msebera.android.httpclient.message.BasicHeader;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import org.jboss.aerogear.android.core.Callback;
import org.jboss.aerogear.android.unifiedpush.PushRegistrar;
import org.jboss.aerogear.android.unifiedpush.RegistrarManager;
import org.jboss.aerogear.android.unifiedpush.fcm.AeroGearFCMPushConfiguration;
import org.jboss.aerogear.android.unifiedpush.fcm.AeroGearFCMPushRegistrar;
import org.jboss.aerogear.android.unifiedpush.metrics.UnifiedPushMetricsMessage;
import org.json.fh.JSONObject;
/**
* The FH class provides static methods to initialize the library, create new instances of all the
* API request objects, and configure global settings.
*/
public class FH {
private static boolean mReady = false;
private static final String LOG_TAG = "com.feedhenry.sdk.FH";
private static final String FH_API_ACT = "act";
private static final String FH_API_AUTH = "auth";
private static final String FH_API_CLOUD = "cloud";
private static final String FH_PUSH_NAME = "FH";
public static final int LOG_LEVEL_VERBOSE = 1;
public static final int LOG_LEVEL_DEBUG = 2;
public static final int LOG_LEVEL_INFO = 3;
public static final int LOG_LEVEL_WARNING = 4;
public static final int LOG_LEVEL_ERROR = 5;
public static final int LOG_LEVEL_NONE = Integer.MAX_VALUE;
private static int mLogLevel = LOG_LEVEL_ERROR;
public static final String VERSION = "2.1.0"; // DO NOT CHANGE, the ant build task will automatically update this value. Update it in VERSION.txt
private static boolean mInitCalled = false;
private static Context mContext;
private FH() {
throw new UnsupportedOperationException("Not Supported");
}
/**
* Initializes the application.
* This must be called before the application can use the FH library.
* The initialization process happens in a background thread so that the UI thread won't be blocked.
* If you need to call other FH API methods, you need to make sure they are called after the init
* finishes. The best way to do it is to provide a FHActCallback instance and implement the success method.
* The callback functions are invoked on the main UI thread.
* For example, in your main activity class's onCreate method, you can do this:
*
*
* {@code
* FH.init(this, new FHActCallback() {
* public void success(FHResponse pRes) {
* //pRes will be null for init call if it succeeds, don't use it to access response data
* FHActRequest request = FH.buildActRequest("readData", new JSONObject());
* request.executeAsync(new FHActCallback(){
* public void success(FHResponse pResp){
* //process response data
* }
*
* public void fail(FHResponse pResp){
* //process error data
* }
* })
* }
*
* public void fail(FHResponse pRes) {
* Log.e("FHInit", pRes.getErrorMessage(), pRes.getError());
* }
* });
* }
*
*
* @param pContext your application's context
* @param pCallback the callback function to be executed after initialization is finished
*/
public static void init(Context pContext, FHActCallback pCallback) {
mContext = pContext;
if (!mInitCalled) {
DataManager.init(mContext).migrateLegacyData();
checkNetworkStatus();
try {
AppProps.load(mContext);
} catch (IOException e) {
mReady = false;
FHLog.e(LOG_TAG, "Can not load property file.", e);
}
mInitCalled = true;
}
if (mReady) {
if (pCallback != null) {
pCallback.success(null);
}
return;
}
final FHActCallback cb = pCallback;
if (AppProps.getInstance().isLocalDevelopment()) {
FHLog.i(
LOG_TAG,
"Local development mode enabled, loading properties from assets/fhconfig.local.properties file");
CloudProps.initDev();
mReady = true;
if (cb != null) {
cb.success(null);
}
return;
}
FHInitializeRequest initRequest = new FHInitializeRequest(mContext);
try {
initRequest.executeAsync(
new FHActCallback() {
@Override
public void success(FHResponse pResponse) {
mReady = true;
FHLog.v(LOG_TAG, "FH init response = " + pResponse.getJson().toString());
JSONObject cloudProps = pResponse.getJson();
CloudProps.init(cloudProps);
CloudProps.getInstance().save();
if (cb != null) {
cb.success(null);
}
}
@Override
public void fail(FHResponse pResponse) {
FHLog.e(
LOG_TAG,
"FH init failed with error = " + pResponse.getErrorMessage(),
pResponse.getError());
CloudProps props = CloudProps.load();
if (props != null) {
mReady = true;
FHLog.i(LOG_TAG, "Cached CloudProps data found");
if (cb != null) {
cb.success(null);
}
} else {
mReady = false;
FHLog.i(LOG_TAG, "No cache data found for CloudProps");
if (cb != null) {
cb.fail(pResponse);
}
}
}
});
} catch (Exception e) {
FHLog.e(LOG_TAG, "FH init exception = " + e.getMessage(), e);
}
}
private static void checkNetworkStatus() {
NetworkManager networkManager = NetworkManager.init(mContext);
networkManager.registerNetworkListener();
networkManager.checkNetworkStatus();
if (networkManager.isOnline() && !mReady && mInitCalled) {
init(mContext, null);
}
}
private static FHAct buildAction(String pAction) throws FHNotReadyException {
if (!mInitCalled) {
throw new FHNotReadyException();
}
FHAct action = null;
if (FH_API_ACT.equalsIgnoreCase(pAction)) {
action = new FHActRequest(mContext);
} else if (FH_API_AUTH.equalsIgnoreCase(pAction)) {
action = new FHAuthRequest(mContext);
} else if (FH_API_CLOUD.equalsIgnoreCase(pAction)) {
action = new FHCloudRequest(mContext);
} else {
FHLog.w(LOG_TAG, "Invalid action : " + pAction);
}
return action;
}
public static boolean isOnline() {
return NetworkManager.getInstance().isOnline();
}
public static void stop() {
NetworkManager.getInstance().unregisterNetworkListener();
}
/**
* Checks if FH is ready.
*
* @return whether FH has finished initialization
*/
public static boolean isReady() {
return mReady;
}
@Deprecated
/**
* Builds an instance of {@link FHActRequest} to perform an act request.
* @param pRemoteAction the name of the cloud side function
* @param pParams the parameters for the cloud side function
* @return an instance of FHActRequest
* @throws FHNotReadyException
*/
public static FHActRequest buildActRequest(String pRemoteAction, JSONObject pParams) throws FHNotReadyException {
FHActRequest request = (FHActRequest) buildAction(FH_API_ACT);
request.setRemoteAction(pRemoteAction);
request.setArgs(pParams);
return request;
}
/**
* Builds an instance of FHAuthRequest object to perform an authentication request.
*
* @return an instance of FHAuthRequest
* @throws FHNotReadyException if init has not been called
*/
public static FHAuthRequest buildAuthRequest() throws FHNotReadyException {
return (FHAuthRequest) buildAction(FH_API_AUTH);
}
/**
* Builds an instance of FHAuthRequest object to perform an authentication request with an auth policy id set.
*
* @param pPolicyId the auth policy id used by this auth request
* @return an instance of FHAuthRequest
* @throws FHNotReadyException if init has not been called
*/
public static FHAuthRequest buildAuthRequest(String pPolicyId) throws FHNotReadyException {
FHAuthRequest request = (FHAuthRequest) buildAction(FH_API_AUTH);
request.setAuthPolicyId(pPolicyId);
return request;
}
/**
* Builds an instance of FHAuthRequest to perform an authentication request with an auth policy id,
* user name, and password set.
*
* @param pPolicyId the auth policy id used by this auth request
* @param pUserName the required user name for the auth request
* @param pPassword the required password for the auth request
* @return an instance of FHAuthRequest
* @throws FHNotReadyException if init has not been called
*/
public static FHAuthRequest buildAuthRequest(String pPolicyId, String pUserName, String pPassword)
throws FHNotReadyException {
FHAuthRequest request = (FHAuthRequest) buildAction(FH_API_AUTH);
request.setAuthUser(pPolicyId, pUserName, pPassword);
return request;
}
/**
* Builds an instance of FHCloudRequest to call cloud APIs.
*
* @param pPath the path of the cloud API
* @param pMethod currently supports GET, POST, PUT and DELETE
* @param pHeaders headers need to be set, can be null
* @param pParams the request params, can be null
* @return an instance of FHCloudRequest
* @throws FHNotReadyException if init has not been called
* @throws IllegalArgumentException if pMethod is not one of GET, POST, PUT or DELETE
*/
public static FHCloudRequest buildCloudRequest(String pPath, String pMethod, Header[] pHeaders, JSONObject pParams)
throws FHNotReadyException
{
FHCloudRequest request = (FHCloudRequest) buildAction(FH_API_CLOUD);
request.setPath(pPath);
request.setHeaders(pHeaders);
request.setMethod(Methods.parse(pMethod));
request.setRequestArgs(pParams);
return request;
}
/**
* Gets the cloud host.
*
* @return the cloud host of the app
* @throws FHNotReadyException if init has not been called
*/
public static String getCloudHost() throws FHNotReadyException {
if (CloudProps.getInstance() == null) {
throw new FHNotReadyException();
}
return CloudProps.getInstance().getCloudHost();
}
/**
* Gets the default params for customised HTTP Requests.
* These params will be required to enable app analytics on the FH platform.
* You can either add the params to your request body as a JSONObject with the key "__fh", or use the
* {@link #getDefaultParamsAsHeaders(Header[]) getDefaultParamsAsHeaders} method to add them as HTTP request
* headers.
*
* @return a JSONObject contains the default params
* @throws IllegalStateException if the app property file is not loaded
*/
public static JSONObject getDefaultParams() {
AppProps appProps = AppProps.getInstance();
JSONObject defaultParams = new JSONObject();
defaultParams.put("appid", appProps.getAppId());
defaultParams.put("appkey", appProps.getAppApiKey());
defaultParams.put("cuid", Device.getDeviceId(mContext));
defaultParams.put("destination", "android");
defaultParams.put("sdk_version", "FH_ANDROID_SDK/" + FH.VERSION);
String projectId = appProps.getProjectId();
if (projectId != null && !projectId.isEmpty()) {
defaultParams.put("projectid", projectId);
}
String connectionTag = appProps.getConnectionTag();
if (connectionTag != null && !connectionTag.isEmpty()) {
defaultParams.put("connectiontag", connectionTag);
}
// Load init
String init = CloudProps.getInitValue();
if (init != null) {
JSONObject initObj = new JSONObject(init);
defaultParams.put("init", initObj);
}
if (FHAuthSession.exists()) {
defaultParams.put(FHAuthSession.SESSION_TOKEN_KEY, FHAuthSession.getToken());
}
return defaultParams;
}
/**
* Similar to {@link #getDefaultParams() getDefaultParams}, but returns HTTP headers instead.
*
* @param pHeaders existing headers
* @return new headers by combining existing headers and default headers
* @throws IllegalStateException if the app property file is not loaded
*/
public static Header[] getDefaultParamsAsHeaders(Header[] pHeaders) {
JSONObject defaultParams = FH.getDefaultParams();
ArrayList headers = new ArrayList(defaultParams.length());
for (Iterator it = defaultParams.keys(); it.hasNext(); ) {
String key = it.next();
headers.add(new BasicHeader("X-FH-" + key, defaultParams.getString(key)));
}
if (pHeaders != null) {
headers.ensureCapacity(pHeaders.length + 1);
Collections.addAll(headers, pHeaders);
}
return headers.toArray(new Header[headers.size()]);
}
/**
* Calls cloud APIs asynchronously.
*
* @param pPath the path to the cloud API
* @param pMethod currently supports GET, POST, PUT and DELETE
* @param pHeaders headers need to be set, can be null
* @param pParams the request params, can be null. Will be converted to query strings depending
* on the HTTP method
* @param pCallback the callback to be executed when the cloud call is finished
* @throws FHNotReadyException if init has not been called
* @throws IllegalArgumentException if pMethod is not one of GET, POST, PUT and DELETE
*/
public static void cloud(
String pPath,
String pMethod,
Header[] pHeaders,
JSONObject pParams,
FHActCallback pCallback) throws FHNotReadyException {
FHCloudRequest cloudRequest = buildCloudRequest(pPath, pMethod, pHeaders, pParams);
cloudRequest.executeAsync(pCallback);
}
/**
* Sets the log level for the library.
* The default level is {@link #LOG_LEVEL_ERROR}. Please make sure this is set to {@link #LOG_LEVEL_ERROR}
* or {@link #LOG_LEVEL_NONE} before releasing the application.
* The log level can be one of
*
* - {@link #LOG_LEVEL_VERBOSE}
* - {@link #LOG_LEVEL_DEBUG}
* - {@link #LOG_LEVEL_INFO}
* - {@link #LOG_LEVEL_WARNING}
* - {@link #LOG_LEVEL_ERROR}
* - {@link #LOG_LEVEL_NONE}
*
*
* @param pLogLevel The level of logging for the FH library
*/
public static void setLogLevel(int pLogLevel) {
mLogLevel = pLogLevel;
}
/**
* Gets the current log level for the FH library.
*
* @return The current log level
*/
public static int getLogLevel() {
return mLogLevel;
}
/**
* Gets the customized user-agent string for the SDK.
*
* @return customized user-agent string
*/
public static String getUserAgent() {
return Device.getUserAgent();
}
/**
* Registers a device on a push network.
* The push information will be loaded from fhconfig.properties.
*
* This method need to be called after an {@link #init(android.content.Context, FHActCallback)} success
* callback.
*
* @param pCallback the pCallback function to be executed after the device registration is finished
*/
public static void pushRegister(FHActCallback pCallback) {
pushRegister(new PushConfig(), pCallback);
}
/**
* Registers a device on a push network.
* The push information will be loaded from fhconfig.properties.
*
* This method needs to be called after an {@link #init(android.content.Context, FHActCallback)} success
* callback.
*
* @param pPushConfig extra configuration for push
* @param pCallback the pCallback function to be executed after the device registration is finished
*/
public static void pushRegister(final PushConfig pPushConfig, final FHActCallback pCallback) {
RegistrarManager.config(FH_PUSH_NAME, AeroGearFCMPushConfiguration.class)
.setPushServerURI(URI.create(AppProps.getInstance().getPushServerUrl()))
.setSenderId(AppProps.getInstance().getPushSenderId())
.setVariantID(AppProps.getInstance().getPushVariant())
.setSecret(AppProps.getInstance().getPushSecret())
.setAlias(pPushConfig.getAlias())
.setCategories(pPushConfig.getCategories())
.asRegistrar()
.register(
mContext, new Callback() {
@Override
public void onSuccess(Void aVoid) {
pCallback.success(new FHResponse(null, null, null, null));
}
@Override
public void onFailure(Exception e) {
pCallback.fail(new FHResponse(null, null, e, e.getMessage()));
}
});
}
/**
* Unregisters a device on a push network.
* The push information will be loaded from fhconfig.properties.
*
* This method needs to be called after an {@link #pushRegister(com.feedhenry.sdk.FHActCallback) } success
* callback.
*
* @param pCallback the pCallback function to be executed after the device registration is finished
*/
public static void pushUnregister (final FHActCallback pCallback) {
PushRegistrar reg = RegistrarManager.getRegistrar(FH_PUSH_NAME);
if (reg != null) {
reg.unregister(mContext, new Callback() {
@Override
public void onSuccess(Void aVoid) {
pCallback.success(new FHResponse(null, null, null, null));
}
@Override
public void onFailure(Exception e) {
pCallback.fail(new FHResponse(null, null, e, e.getMessage()));
}
});
}
}
/**
* Sends confirmation a message was opened.
*
* @param pMessageId Id of the message received
* @param pCallback the pCallback function to be executed after the metrics sent
*/
public static void sendPushMetrics(String pMessageId, final FHActCallback pCallback) {
AeroGearFCMPushRegistrar registrar = (AeroGearFCMPushRegistrar) RegistrarManager.getRegistrar(FH_PUSH_NAME);
registrar.sendMetrics(
new UnifiedPushMetricsMessage(pMessageId), new Callback() {
@Override
public void onSuccess(UnifiedPushMetricsMessage data) {
pCallback.success(new FHResponse(null, null, null, null));
}
@Override
public void onFailure(Exception e) {
pCallback.fail(new FHResponse(null, null, e, e.getMessage()));
}
});
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy