package com.evsuite.abrp; import android.content.Context; import android.content.SharedPreferences; /** * The ABRP credentials for sending live data straight from the car: the API key (which app is * sending) and the user token (which car in which ABRP account). Kept in {@link SecurePrefs} * next to the server settings, entered on the Live data tab or imported from a config file. * * The car is the only one that sends to ABRP: the server stores live data but does not forward * it. Without these, ABRP gets no live data. */ final class AbrpConfig { static final String KEY_API_KEY = "abrp_api_key"; static final String KEY_USER_TOKEN = "abrp_user_token"; final String apiKey; final String userToken; private static volatile AbrpConfig current; AbrpConfig(String apiKey, String userToken) { this.apiKey = apiKey; this.userToken = userToken; } boolean isConfigured() { return !apiKey.isEmpty() && !userToken.isEmpty(); } static AbrpConfig get(Context context) { AbrpConfig config = current; if (config != null) return config; synchronized (AbrpConfig.class) { if (current == null) { SharedPreferences prefs = SecurePrefs.get(context); current = new AbrpConfig(prefs.getString(KEY_API_KEY, ""), prefs.getString(KEY_USER_TOKEN, "")); } return current; } } /** Stores trimmed values; empty strings switch direct sending off. */ static synchronized void save(Context context, String apiKey, String userToken) { String key = apiKey == null ? "" : apiKey.trim(); String token = userToken == null ? "" : userToken.trim(); SecurePrefs.get(context).edit() .putString(KEY_API_KEY, key) .putString(KEY_USER_TOKEN, token) .apply(); current = new AbrpConfig(key, token); } /** Plausible as an ABRP credential: no spaces, not absurdly short or long. */ static boolean isPlausible(String value) { if (value == null) return false; String v = value.trim(); return v.length() >= 8 && v.length() <= 200 && !v.contains(" "); } }