diff --git a/.gitignore b/.gitignore index 0250fe5..72a39ff 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,8 @@ res/values/com_crashlytics_export_strings.xml SECRET.md TODO.md +mainActivity/release/ + # IntelliJ *.iml .gradle/ diff --git a/.idea/modules.xml b/.idea/modules.xml index e8853cb..476da80 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,9 +2,9 @@ - - - + + + \ No newline at end of file diff --git a/Privacy Policy.pdf b/Privacy Policy.pdf new file mode 100644 index 0000000..97e6577 Binary files /dev/null and b/Privacy Policy.pdf differ diff --git a/build.gradle b/build.gradle index bbe9eb2..ab7f0f5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,19 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.2.21' repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.3' + classpath 'com.android.tools.build:gradle:3.2.0-alpha05' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { jcenter() + google() } } diff --git a/comcrashlyticssdkandroid_crashlytics/comcrashlyticssdkandroid_crashlytics.iml b/comcrashlyticssdkandroid_crashlytics/comcrashlyticssdkandroid_crashlytics.iml index ee4c648..192d03a 100644 --- a/comcrashlyticssdkandroid_crashlytics/comcrashlyticssdkandroid_crashlytics.iml +++ b/comcrashlyticssdkandroid_crashlytics/comcrashlyticssdkandroid_crashlytics.iml @@ -1,5 +1,5 @@ - + @@ -13,9 +13,9 @@ - - - + + + @@ -27,7 +27,6 @@ - - + \ No newline at end of file diff --git a/mainActivity/build.gradle b/mainActivity/build.gradle index c05f4b7..3843e48 100644 --- a/mainActivity/build.gradle +++ b/mainActivity/build.gradle @@ -1,4 +1,5 @@ buildscript { + ext.anko_version = '0.10.0' repositories { maven { url 'https://maven.fabric.io/public' } } @@ -8,22 +9,27 @@ buildscript { } } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' apply plugin: 'io.fabric' +apply plugin: 'kotlin-android-extensions' repositories { maven { url 'https://maven.fabric.io/public' } + maven { + url "https://repo.eclipse.org/content/repositories/paho-snapshots/" + } + mavenCentral() } android { - compileSdkVersion 22 - buildToolsVersion '24.0.1' + compileSdkVersion 27 defaultConfig { applicationId 'com.sierrawireless.avphone' minSdkVersion 22 - targetSdkVersion 22 - versionName '1.0.6' + targetSdkVersion 27 + versionName '2.0.1' } buildTypes { @@ -38,13 +44,26 @@ android { } dependencies { - compile project(':comcrashlyticssdkandroid_crashlytics') - compile 'com.android.support:support-v4:22.0.0' - compile 'com.android.support:appcompat-v7:22.0.0' - compile 'com.google.code.gson:gson:2.2.4' - compile files('libs/mqtt-client-0.4.0.jar') - compile files('libs/okhttp-1.2.1-jar-with-dependencies.jar') - compile('com.crashlytics.sdk.android:crashlytics:2.6.1@aar') { - transitive = true; + implementation 'com.android.support:support-v4:27.0.2' + implementation 'com.android.support:appcompat-v7:27.0.2' + implementation 'com.google.code.gson:gson:2.8.0' + implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2' + implementation 'com.baoyz.swipemenulistview:library:1.3.0' + implementation files('libs/okhttp-1.2.1-jar-with-dependencies.jar') + implementation('com.crashlytics.sdk.android:crashlytics:2.9.0@aar') { + transitive = true + } + implementation('com.crashlytics.sdk.android:crashlytics-ndk:2.0.1@aar') { + transitive = true } + implementation 'com.android.support.constraint:constraint-layout:1.0.2' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.anko:anko-common:$anko_version" + implementation "org.jetbrains.kotlin:kotlin-reflect:1.2.21" +} + +crashlytics { + enableNdk true + androidNdkOut 'src/main/obj' + androidNdkLibsOut 'src/main/libs' } diff --git a/mainActivity/src/main/AndroidManifest.xml b/mainActivity/src/main/AndroidManifest.xml index 75859f5..57425cf 100644 --- a/mainActivity/src/main/AndroidManifest.xml +++ b/mainActivity/src/main/AndroidManifest.xml @@ -1,48 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/AuthorizationActivity.java b/mainActivity/src/main/java/com/sierrawireless/avphone/AuthorizationActivity.java deleted file mode 100644 index 2b28ddf..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/AuthorizationActivity.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.sierrawireless.avphone; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.webkit.CookieManager; -import android.webkit.CookieSyncManager; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.Button; -import android.widget.RadioButton; -import android.widget.RadioGroup; - -import com.sierrawireless.avphone.auth.Authentication; - -import net.airvantage.utils.AirVantageClient; -import net.airvantage.utils.AuthenticationUrlParser; -import net.airvantage.utils.AvPhonePrefs; -import net.airvantage.utils.PreferenceUtils; - -import java.util.Date; - -public class AuthorizationActivity extends Activity { - - private static final String LOGTAG = AuthorizationActivity.class.getName(); - - public static final String AUTHENTICATION_TOKEN = "token"; - public static final String AUTHENTICATION_EXPIRATION_DATE = "expirationDate"; - - public static final String AUTHENTICATION_LISTENER = "listener"; - - public static final int REQUEST_AUTHORIZATION = 1; - - - private WebView webview; - - private AuthenticationUrlParser authUrlParser = new AuthenticationUrlParser(); - - private Button btnCustom; - private Button btnEu; - private Button btnNa; - - private PreferenceUtils.Server currentServer; - - private final class OnHostClickListener implements OnClickListener { - - private final PreferenceUtils.Server server; - - public OnHostClickListener(final PreferenceUtils.Server targetServer) { - server = targetServer; - } - - @Override - public void onClick(final View v) { - if (currentServer != server) { - currentServer = server; - PreferenceUtils.setServer(server, AuthorizationActivity.this); - openAuthorizationPage(); - } - } - - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_authorization); - - btnNa = (RadioButton) this.findViewById(R.id.auth_btn_na); - btnEu = (RadioButton) this.findViewById(R.id.auth_btn_eu); - btnCustom = (RadioButton) this.findViewById(R.id.auth_btn_custom); - - btnNa.setOnClickListener(new OnHostClickListener(PreferenceUtils.Server.NA)); - btnEu.setOnClickListener(new OnHostClickListener(PreferenceUtils.Server.EU)); - btnCustom.setOnClickListener(new OnHostClickListener(PreferenceUtils.Server.CUSTOM)); - - if (PreferenceUtils.isCustomDefined(this)) { - final RadioGroup parentRadioGroup = (RadioGroup) btnCustom.getParent(); - parentRadioGroup.check(btnCustom.getId()); - } else { - btnCustom.setVisibility(Button.GONE); - } - - openAuthorizationPage(); - } - - - @SuppressLint("SetJavaScriptEnabled") - private void openAuthorizationPage() { - - AvPhonePrefs avPhonePrefs = PreferenceUtils.getAvPhonePrefs(this); - - final String serverHost = avPhonePrefs.serverHost; - final String clientId = avPhonePrefs.clientId; - - webview = (WebView) findViewById(R.id.authorization_webview); - webview.getSettings().setJavaScriptEnabled(true); - // attach WebViewClient to intercept the callback url - webview.setWebViewClient(new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - - final Authentication auth = authUrlParser.parseUrl(url, new Date()); - - if (auth != null) { - Log.d(AuthorizationActivity.class.getName(), "Access token: " + auth.getAccessToken()); - Log.d(AuthorizationActivity.class.getName(), "Expiration date : " + auth.getExpirationDate()); - - sendAuthentication(auth); - - } - - return super.shouldOverrideUrlLoading(view, url); - } - - }); - String authUrl = AirVantageClient.buildImplicitFlowURL(serverHost, clientId); - Log.d(AuthorizationActivity.class.getName(), "Auth URL: " + authUrl); - - // The 'authorize' page from AirVantage will store a cookie ; - // if this cookie is passed between calls, the 'authorize' page - // will not be displayed at all. - CookieSyncManager.createInstance(this); - CookieManager cookieManager = CookieManager.getInstance(); - cookieManager.removeAllCookie(); - - // Example : - // https://na.airvantage.net/api/oauth/authorize?client_id=54d4faa5343d49fba03f2a2ec1f210b9&response_type=token&redirect_uri=oauth://airvantage - webview.loadUrl(authUrl); - } - - private void sendAuthentication(Authentication auth) { - - Intent resultIntent = new Intent(); - - resultIntent.putExtra(AUTHENTICATION_TOKEN, auth.getAccessToken()); - resultIntent.putExtra(AUTHENTICATION_EXPIRATION_DATE, auth.getExpirationDate().getTime()); - - setResult(Activity.RESULT_OK, resultIntent); - finish(); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/AvPhoneFragment.java b/mainActivity/src/main/java/com/sierrawireless/avphone/AvPhoneFragment.java deleted file mode 100644 index 1a6e950..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/AvPhoneFragment.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.sierrawireless.avphone; - -import android.app.Activity; -import android.content.Intent; -import android.app.Fragment; -import android.text.Spanned; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; - -import com.sierrawireless.avphone.auth.AuthenticationManager; -import com.sierrawireless.avphone.message.IMessageDisplayer; -import com.sierrawireless.avphone.task.SyncWithAvListener; - -public abstract class AvPhoneFragment extends Fragment implements IMessageDisplayer { - - protected AuthenticationManager authManager; - - protected SyncWithAvListener syncListener; - - public AvPhoneFragment() { - super(); - } - - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - if (activity instanceof AuthenticationManager) { - setAuthManager((AuthenticationManager) activity); - } - - if (activity instanceof SyncWithAvListener) { - this.syncListener = (SyncWithAvListener) activity; - } - } - - public void setAuthManager(AuthenticationManager authManager) { - this.authManager = authManager; - } - - @Override - public void showError(int id, Object... params) { - this.showErrorMessage(id, params); - } - - @Override - public void showSuccess(int id, Object... params) { - this.hideErrorMessage(); - this.toast(id); - } - - public void showErrorMessage(int id, Object... params) { - showErrorMessage(getActivity().getString(id, params)); - } - - public void showErrorMessage(String message) { - TextView errorMessageView = getErrorMessageView(); - errorMessageView.setText(message); - errorMessageView.setVisibility(View.VISIBLE); - } - - public void showErrorMessage(Spanned spanned) { - TextView errorMessageView = getErrorMessageView(); - errorMessageView.setText(spanned); - errorMessageView.setVisibility(View.VISIBLE); - } - - public void hideErrorMessage() { - getErrorMessageView().setVisibility(View.GONE); - } - - private void toast(int id) { - toast(getActivity().getString(id)); - } - - private void toast(String message) { - Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); - } - - protected void requestAuthentication() { - Intent intent = new Intent(this.getActivity(), AuthorizationActivity.class); - this.startActivityForResult(intent, AuthorizationActivity.REQUEST_AUTHORIZATION); - } - - protected abstract TextView getErrorMessageView(); - -} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/AvPhoneFragment.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/AvPhoneFragment.kt new file mode 100644 index 0000000..107d035 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/AvPhoneFragment.kt @@ -0,0 +1,84 @@ +package com.sierrawireless.avphone + +import android.app.Fragment +import android.content.Context +import android.content.Intent +import android.text.Spanned +import android.view.View +import android.widget.TextView +import com.sierrawireless.avphone.activity.AuthorizationActivity +import com.sierrawireless.avphone.auth.AuthenticationManager +import com.sierrawireless.avphone.message.IMessageDisplayer +import com.sierrawireless.avphone.task.SyncWithAvListener +import org.jetbrains.anko.toast + +abstract class AvPhoneFragment : Fragment(), IMessageDisplayer { + + var authManager: AuthenticationManager? = null + + var syncListener: SyncWithAvListener? = null + + abstract var errorMessageView: TextView? + + + override fun onAttach(context: Context) { + super.onAttach(context) + + if (context is AuthenticationManager) { + authManager = context + } + + } + + + override fun showError(id: Int, vararg params: Any) { + this.showErrorMessage(id, *params) + } + + override fun showSuccess(id: Int, vararg params: Any) { + this.hideErrorMessage() + this.lToast(id) + } + + override fun showSuccess(name: String, vararg params: Any) { + this.hideErrorMessage() + this.lToast(name) + } + + private fun showErrorMessage(id: Int, vararg params: Any) { + showErrorMessage(activity.getString(id, *params)) + } + + private fun showErrorMessage(message: String) { + val errorMessageView = errorMessageView + errorMessageView?.text = message + errorMessageView?.visibility = View.VISIBLE + } + + override fun showErrorMessage(spanned: Spanned) { + val errorMessageView = errorMessageView + errorMessageView?.text = spanned + errorMessageView?.visibility = View.VISIBLE + } + + fun hideErrorMessage() { + errorMessageView?.visibility = View.GONE + } + + private fun lToast(id: Int) { + toast(activity.getString(id)) + } + + private fun lToast(name: String) { + toast(name) + } + + protected fun requestAuthentication() { + + val intent = Intent(this.activity, AuthorizationActivity::class.java) + this.startActivityForResult(intent, AuthorizationActivity.REQUEST_AUTHORIZATION) + } + + + +} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/ConfigureFragment.java b/mainActivity/src/main/java/com/sierrawireless/avphone/ConfigureFragment.java deleted file mode 100644 index 9be3362..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/ConfigureFragment.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.sierrawireless.avphone; - -import net.airvantage.utils.AvPhonePrefs; -import net.airvantage.utils.PreferenceUtils; - -import android.content.Intent; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import com.sierrawireless.avphone.auth.AuthUtils; -import com.sierrawireless.avphone.auth.Authentication; -import com.sierrawireless.avphone.message.IMessageDisplayer; -import com.sierrawireless.avphone.model.CustomDataLabels; -import com.sierrawireless.avphone.task.IAsyncTaskFactory; -import com.sierrawireless.avphone.task.SyncWithAvListener; -import com.sierrawireless.avphone.task.SyncWithAvParams; -import com.sierrawireless.avphone.task.SyncWithAvResult; -import com.sierrawireless.avphone.task.SyncWithAvTask; - -public class ConfigureFragment extends AvPhoneFragment { - - private Button saveBt; - - private EditText customData1EditText; - private EditText customData2EditText; - private EditText customData3EditText; - private EditText customData4EditText; - private EditText customData5EditText; - private EditText customData6EditText; - - private View view; - - private String deviceId; - private String imei; - - private IAsyncTaskFactory taskFactory; - - public ConfigureFragment() { - super(); - } - - public void setTaskFactory(IAsyncTaskFactory taskFactory) { - this.taskFactory = taskFactory; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - view = inflater.inflate(R.layout.fragment_configure, container, false); - - // phone identifier - deviceId = DeviceInfo.getUniqueId(this.getActivity()); - ((TextView) view.findViewById(R.id.phoneid_value)).setText(deviceId); - - // try to get the IMEI for GSM phones - imei = DeviceInfo.getIMEI(this.getActivity()); - - // Register button - saveBt = (Button) view.findViewById(R.id.save_bt); - saveBt.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - onRegisterClicked(); - } - }); - - // Fields for custom data - customData1EditText = buildCustomLabelEditText(view, R.id.custom1_value, R.string.pref_custom1_label_key, - R.string.pref_custom1_label_default); - customData2EditText = buildCustomLabelEditText(view, R.id.custom2_value, R.string.pref_custom2_label_key, - R.string.pref_custom2_label_default); - customData3EditText = buildCustomLabelEditText(view, R.id.custom3_value, R.string.pref_custom3_label_key, - R.string.pref_custom3_label_default); - customData4EditText = buildCustomLabelEditText(view, R.id.custom4_value, R.string.pref_custom4_label_key, - R.string.pref_custom4_label_default); - customData5EditText = buildCustomLabelEditText(view, R.id.custom5_value, R.string.pref_custom5_label_key, - R.string.pref_custom5_label_default); - customData6EditText = buildCustomLabelEditText(view, R.id.custom6_value, R.string.pref_custom6_label_key, - R.string.pref_custom6_label_default); - - return view; - } - - private EditText buildCustomLabelEditText(View view, int id, final int prefKeyId, int labelDefaultKeyId) { - EditText res = (EditText) view.findViewById(id); - - res.setText(PreferenceUtils.getPreference(getActivity(), prefKeyId, labelDefaultKeyId)); - - res.addTextChangedListener(new TextWatcher() { - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void afterTextChanged(Editable s) { - PreferenceUtils.setPreference(getActivity(), getActivity().getString(prefKeyId), s.toString()); - } - }); - return res; - } - - private boolean checkCredentials() { - - AvPhonePrefs prefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - - if (!prefs.checkCredentials()) { - PreferenceUtils.showMissingPrefsDialog(getActivity()); - return false; - } - - return true; - - } - - protected void onRegisterClicked() { - if (checkCredentials()) { - Authentication auth = authManager.getAuthentication(); - if (auth != null && !auth.isExpired()) { - syncWithAv(auth.getAccessToken()); - } else { - requestAuthentication(); - } - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - Authentication auth = AuthUtils.activityResultAsAuthentication(requestCode, resultCode, data); - if (auth != null) { - authManager.onAuthentication(auth); - syncWithAv(auth.getAccessToken()); - } - } - - private void syncWithAv(String token) { - - AvPhonePrefs prefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - - final IMessageDisplayer display = this; - - final SyncWithAvTask syncTask = taskFactory.syncAvTask(prefs.serverHost, token); - - SyncWithAvParams syncParams = new SyncWithAvParams(); - syncParams.deviceId = deviceId; - syncParams.imei = imei; - syncParams.mqttPassword = prefs.password; - syncParams.customData = getCustomDataLabels(); - - syncTask.execute(syncParams); - - syncTask.addProgressListener(new SyncWithAvListener() { - @Override - public void onSynced(SyncWithAvResult result) { - syncTask.showResult(result, display, getActivity()); - - if (!result.isError()) { - syncListener.onSynced(result); - } - - } - }); - - } - - protected CustomDataLabels getCustomDataLabels() { - CustomDataLabels customData = new CustomDataLabels(); - customData.customUp1Label = customData1EditText.getText().toString(); - customData.customUp2Label = customData2EditText.getText().toString(); - customData.customDown1Label = customData3EditText.getText().toString(); - customData.customDown2Label = customData4EditText.getText().toString(); - customData.customStr1Label = customData5EditText.getText().toString(); - customData.customStr2Label = customData6EditText.getText().toString(); - return customData; - } - - public TextView getErrorMessageView() { - return (TextView) view.findViewById(R.id.configure_error_message); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/ConfigureFragment.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/ConfigureFragment.kt new file mode 100644 index 0000000..5fcf5af --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/ConfigureFragment.kt @@ -0,0 +1,301 @@ +package com.sierrawireless.avphone + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.Button +import android.widget.ImageButton +import android.widget.TextView +import com.sierrawireless.avphone.activity.AuthorizationActivity +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.activity.ObjectConfigureActivity +import com.sierrawireless.avphone.adapter.ObjectAdapter +import com.sierrawireless.avphone.auth.AuthUtils +import com.sierrawireless.avphone.task.IAsyncTaskFactory +import com.sierrawireless.avphone.task.SyncWithAvParams +import com.sierrawireless.avphone.task.UpdateParams +import com.sierrawireless.avphone.tools.DeviceInfo +import kotlinx.android.synthetic.main.fragment_configure.* +import net.airvantage.utils.PreferenceUtils +import java.util.* + +open class ConfigureFragment : AvPhoneFragment() { + override var errorMessageView: TextView? = null + + private var objectsManager: ObjectsManager? = null + private var menu: ArrayList = ArrayList() + enum class Mode { + DELETE, + SYNC, + UPDATE + + } + internal var delete: Mode = Mode.SYNC + + private var lView: View? = null + + var current = 0 + + + private var taskFactory: IAsyncTaskFactory? = null + + fun setTaskFactory(taskFactory: IAsyncTaskFactory) { + this.taskFactory = taskFactory + } + + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + + + lView = inflater.inflate(R.layout.fragment_configure, container, false) + + + + return lView + } + + private fun reloadMenu(){ + menu = ArrayList() + + for (obj in objectsManager!!.objects) { + menu.add(obj.name!!) + } + + + val adapter = ObjectAdapter(activity, R.layout.menu_objects, menu) + objectConfigure.adapter = adapter + } + override fun onStart() { + instance = this + super.onStart() + objectsManager = ObjectsManager.getInstance() + errorMessageView = configure_error_message + + + reloadMenu() + + objectConfigure.onItemClickListener = AdapterView.OnItemClickListener { _, view, i, _ -> + val deleteActionBtn: Button = view.findViewById(R.id.menuDeleteActionBtn) + if (deleteActionBtn.visibility == View.VISIBLE) { + val deleteBtn:ImageButton = view.findViewById(R.id.menuDeleteBtn) + deleteBtn.visibility = View.VISIBLE + deleteActionBtn.visibility = View.GONE + } else { + startObjectConfigure(i) + } + } + + doneConfigureBtn.setOnClickListener { (activity as MainActivity).goLastFragment() } + + addConfigureBtn.setOnClickListener { _ -> + startObjectConfigure(-1) + } + + resync.setOnClickListener { _ -> + resyncAll() + } + } + + private fun startObjectConfigure(position: Int) { + + //Open a new intent with the selected Object + val intent = Intent(view.context, ObjectConfigureActivity::class.java) + intent.putExtra(INDEX, position) + + startActivityForResult(intent, CONFIGURE) + } + + override fun onStop() { + super.onStop() + instance = null + } + + private fun checkCredentials(): Boolean { + + val prefs = PreferenceUtils.getAvPhonePrefs(activity) + + if (!prefs.checkCredentials()) { + PreferenceUtils.showMissingPrefsDialog(activity) + return false + } + + return true + + } + + private fun resyncAll() { + current = 0 + // first check credential + if (checkCredentials()) { + val auth = authManager!!.authentication + if (!auth!!.isExpired) { + updateAllSystem(auth.accessToken!!) + } else { + this.delete = Mode.UPDATE + requestAuthentication() + } + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (data == null) { + Log.e(TAG, "data is null ??? why ????") + return + } + if (requestCode == AuthorizationActivity.REQUEST_AUTHORIZATION) { + + val auth = AuthUtils.activityResultAsAuthentication(requestCode, resultCode, data) + if (auth != null) { + authManager!!.onAuthentication(auth) + + when (delete) { + Mode.DELETE -> deleteSysten(auth.accessToken!!) + Mode.SYNC -> syncWithAv(auth.accessToken!!) + Mode.UPDATE -> updateAllSystem(auth.accessToken!!) + } + } + } else if (requestCode == CONFIGURE) { + if (resultCode == Activity.RESULT_OK) { + this.delete = Mode.SYNC + val position = data.getIntExtra(POS, -1) + //set current and start synchronization + + objectsManager!!.setSavedPosition(position) + + if (checkCredentials()) { + val auth = authManager!!.authentication + if (!auth!!.isExpired) { + syncWithAv(auth.accessToken!!) + } else { + this.delete = Mode.SYNC + requestAuthentication() + } + } + } + MainActivity.instance.loadMenu(false) + reloadMenu() + objectConfigure.invalidate() + + } + } + + internal fun delete() { + if (checkCredentials()) { + val auth = authManager!!.authentication + if (!auth!!.isExpired) { + deleteSysten(auth.accessToken!!) + } else { + this.delete = Mode.DELETE + requestAuthentication() + } + } + } + + private fun updateAllSystem(token: String) { + + if (current >= objectsManager!!.objects.size) return + + objectsManager!!.setSavedPosition(current) + + val prefs = PreferenceUtils.getAvPhonePrefs(activity) + + val display = this + + val updateTask = taskFactory!!.updateTask(prefs.serverHost!!, token) + + val updateParams = UpdateParams() + updateParams.deviceId = DeviceInfo.getUniqueId(activity) + updateParams.imei = DeviceInfo.getIMEI(activity) + updateParams.deviceName = DeviceInfo.deviceName + updateParams.iccid = DeviceInfo.getICCID(activity) + updateParams.mqttPassword = prefs.password + updateParams.customData = PreferenceUtils.getCustomDataLabels(activity) + + updateTask.execute(updateParams) + + updateTask.addProgressListener { result -> + + updateTask.showResult(result, objectsManager!!.savedObjectName!!, display, activity) + // Update next system + current++ + updateAllSystem(token) + + + } + + + } + + private fun deleteSysten(token: String) { + val prefs = PreferenceUtils.getAvPhonePrefs(activity) + + val display = this + + val deleteTask = taskFactory!!.deleteSystemTak(prefs.serverHost!!, token) + deleteTask.execute() + + deleteTask.addProgressListener({ result -> + if (delete == Mode.DELETE) { + objectsManager!!.removeSavedObject() + } + + deleteTask.showResult(result, display, activity) + MainActivity.instance.loadMenu(false) + reloadMenu() + objectConfigure.invalidate() + + }) + + + } + + private fun syncWithAv(token: String) { + + val prefs = PreferenceUtils.getAvPhonePrefs(activity) + + val display = this + + val syncTask = taskFactory!!.syncAvTask(prefs.serverHost!!, token) + + val syncParams = SyncWithAvParams() + syncParams.deviceId = DeviceInfo.getUniqueId(activity) + syncParams.imei = DeviceInfo.getIMEI(activity) + syncParams.deviceName = DeviceInfo.deviceName + syncParams.iccid = DeviceInfo.getICCID(activity) + syncParams.mqttPassword = prefs.password + syncParams.customData = PreferenceUtils.getCustomDataLabels(activity) + + syncTask.execute(syncParams) + + syncTask.addProgressListener { result -> + if (delete == Mode.DELETE) { + objectsManager!!.removeSavedObject() + } + + syncTask.showResult(result, display, activity) + MainActivity.instance.loadMenu(false) + + if (!result.isError) { + syncListener!!.invoke(result) + } + } + + } + + companion object { + var INDEX = "index" + var CONFIGURE = 0 + var POS = "position" + @SuppressLint("StaticFieldLeak") + var instance: ConfigureFragment? = null + private val TAG = ConfigureFragment::class.simpleName + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsListener.java b/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsListener.java deleted file mode 100644 index de3193e..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.sierrawireless.avphone; - -public interface CustomLabelsListener { - public void onCustomLabelsChanged(); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsManager.java b/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsManager.java deleted file mode 100644 index e8fd3fe..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsManager.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.sierrawireless.avphone; - -public interface CustomLabelsManager { - public void setCustomLabelsListener(CustomLabelsListener listener); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsManager.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsManager.kt new file mode 100644 index 0000000..e78736d --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/CustomLabelsManager.kt @@ -0,0 +1,7 @@ +package com.sierrawireless.avphone + +import com.sierrawireless.avphone.listener.CustomLabelsListener + +interface CustomLabelsManager { + fun setCustomLabelsListener(listener: CustomLabelsListener) +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/DataViewUpdater.java b/mainActivity/src/main/java/com/sierrawireless/avphone/DataViewUpdater.java deleted file mode 100644 index 595a18a..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/DataViewUpdater.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sierrawireless.avphone; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.view.View; -import android.widget.Switch; -import android.widget.TextView; - -import com.sierrawireless.avphone.service.LogMessage; -import com.sierrawireless.avphone.service.NewData; - -/** - * A component in charge of listening for service events (new data, logs) and updating the view accordingly. - */ -public class DataViewUpdater extends BroadcastReceiver { - - private DateFormat hourFormat = new SimpleDateFormat("HH:mm:ss", Locale.FRENCH); - - private final View view; - - public DataViewUpdater(View view) { - this.view = view; - } - - @Override - public void onReceive(Context context, Intent intent) { - - if (intent instanceof NewData) { - setNewData((NewData) intent); - } else if (intent instanceof LogMessage) { - setLogMessage(((LogMessage) intent).getMessage(), System.currentTimeMillis()); - } - } - - public void onStart(Long startedSince, NewData lastData, String logMsg, Long lastRun) { - this.setStartedSince(startedSince); - this.setNewData(lastData); - this.setLogMessage(logMsg, lastRun); - - // activate alarm button - view.findViewById(R.id.alarm_switch).setEnabled(true); - } - - public void onStop() { - this.setStartedSince(null); - - // deactivate alarm button - view.findViewById(R.id.alarm_switch).setEnabled(false); - } - - private void setLogMessage(String log, Long timestamp) { - TextView logView = findView(R.id.service_log); - if (log != null) { - logView.setText(hourFormat.format(timestamp != null ? new Date(timestamp) : new Date()) + " - " + log); - logView.setVisibility(View.VISIBLE); - } else { - logView.setVisibility(View.GONE); - } - } - - private void setStartedSince(Long startedSince) { - TextView startedTextView = findView(R.id.started_since); - if (startedSince != null) { - startedTextView.setText(view.getContext().getString(R.string.started_since) + " " - + new SimpleDateFormat("dd/MM HH:mm:ss", Locale.FRENCH).format(new Date(startedSince))); - startedTextView.setVisibility(View.VISIBLE); - } else { - startedTextView.setVisibility(View.GONE); - } - } - - private void setNewData(NewData data) { - - if (data.getRssi() != null) { - findView(R.id.signal_strength_value).setText(data.getRssi() + " dBm (RSSI)"); - } else if (data.getRsrp() != null) { - findView(R.id.signal_strength_value).setText(data.getRsrp() + " dBm (RSRP)"); - } - - if (data.getBatteryLevel() != null) { - findView(R.id.battery_value).setText((int) (data.getBatteryLevel() * 100) + "%"); - } - - if (data.getOperator() != null) { - findView(R.id.operator_value).setText(data.getOperator()); - } - - if (data.getImei() != null) { - findView(R.id.imei_value).setText(data.getImei()); - } - - if (data.getNetworkType() != null) { - findView(R.id.network_type_value).setText(data.getNetworkType()); - } - - if (data.getLatitude() != null && data.getLongitude() != null) { - findView(R.id.latitude_value).setText(data.getLatitude().toString()); - findView(R.id.longitude_value).setText(data.getLongitude().toString()); - } - - if (data.getBytesReceived() != null) { - findView(R.id.bytes_received_value).setText(((data.getBytesReceived()) / (1024F * 1024F)) + " Mo"); - } - - if (data.getBytesSent() != null) { - findView(R.id.bytes_sent_value).setText(((data.getBytesSent()) / (1024F * 1024F)) + " Mo"); - } - - if (data.getMemoryUsage() != null) { - findView(R.id.memory_usage_value).setText((int) (data.getMemoryUsage() * 100) + "%"); - } - - if (data.getRunningApps() != null) { - findView(R.id.running_apps_value).setText(data.getRunningApps().toString()); - } - - if (data.isWifiActive() != null) { - findView(R.id.active_wifi_value).setText(data.isWifiActive() ? "On" : "Off"); - } - - if (data.getAndroidVersion() != null) { - findView(R.id.android_version_value).setText(data.getAndroidVersion()); - } - - if (data.isAlarmActivated() != null) { - ((Switch) view.findViewById(R.id.alarm_switch)).setChecked(data.isAlarmActivated()); - } - - setCustomDataValues(data); - - } - - private void setCustomDataValues(NewData data) { - if (data.getCustomIntUp1() != null) { - TextView valueView = (TextView) view.findViewById(R.id.run_custom1_value); - valueView.setText(String.valueOf(data.getCustomIntUp1())); - } - - if (data.getCustomIntUp2() != null) { - TextView valueView = (TextView) view.findViewById(R.id.run_custom2_value); - valueView.setText(String.valueOf(data.getCustomIntUp2())); - } - - if (data.getCustomIntDown1() != null) { - TextView valueView = (TextView) view.findViewById(R.id.run_custom3_value); - valueView.setText(String.valueOf(data.getCustomIntDown1())); - } - - if (data.getCustomIntDown2() != null) { - TextView valueView = (TextView) view.findViewById(R.id.run_custom4_value); - valueView.setText(String.valueOf(data.getCustomIntDown2())); - } - - if (data.getCustomStr1() != null) { - TextView valueView = (TextView) view.findViewById(R.id.run_custom5_value); - valueView.setText(String.valueOf(data.getCustomStr1())); - } - - if (data.getCustomStr2() != null) { - TextView valueView = (TextView) view.findViewById(R.id.run_custom6_value); - valueView.setText(String.valueOf(data.getCustomStr2())); - } - } - - private TextView findView(int id) { - return (TextView) view.findViewById(id); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/DataViewUpdater.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/DataViewUpdater.kt new file mode 100644 index 0000000..3ffb86d --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/DataViewUpdater.kt @@ -0,0 +1,193 @@ +package com.sierrawireless.avphone + +import android.annotation.SuppressLint +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.util.Log +import android.view.View +import android.widget.ListView +import android.widget.TextView +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.adapter.RunListViewAdapter +import com.sierrawireless.avphone.model.AvPhoneObjectData +import com.sierrawireless.avphone.service.LogMessage +import com.sierrawireless.avphone.service.NewData +import com.sierrawireless.avphone.tools.Tools +import java.text.SimpleDateFormat +import java.util.* + +/** + * A component in charge of listening for service events (new data, logs) and updating the view accordingly. + */ +class DataViewUpdater(val view: View, private val activity: MainActivity) : BroadcastReceiver() { + + private val hourFormat = SimpleDateFormat("HH:mm:ss", Locale.FRENCH) + private var objectsManager: ObjectsManager? = null + + init { + objectsManager = ObjectsManager.getInstance() + } + + override fun onReceive(context: Context, intent: Intent) { + + if (intent is NewData) { + setNewData(intent) + } else if (intent is LogMessage) { + setLogMessage(intent.message, System.currentTimeMillis(), intent.alarm) + } + } + + fun onStart(startedSince: Long?, lastData: NewData, logMsg: String?, alarmLogMsg: String?, lastRun: Long?) { + this.setStartedSince(startedSince) + Log.d(TAG, "lastData " + lastData) + this.setNewData(lastData) + this.setLogMessage(logMsg, lastRun, false) + this.setLogMessage(alarmLogMsg, lastRun, true) + + // activate alarm button + //view.findViewById(R.id.alarm_switch).setEnabled(true); + } + + fun onStop() { + this.setStartedSince(null) + + // deactivate alarm button + //view.findViewById(R.id.alarm_switch).setEnabled(false); + } + + @SuppressLint("SetTextI18n") + private fun setLogMessage(log: String?, timestamp: Long?, alarm: Boolean) { + val logView: TextView = if (alarm) { + findView(R.id.alarm_log) + } else { + findView(R.id.service_log) + } + if (log != null) { + logView.text = hourFormat.format(if (timestamp != null) Date(timestamp) else Date()) + " - " + log + logView.visibility = View.VISIBLE + } else { + logView.visibility = View.GONE + } + } + + @SuppressLint("SetTextI18n") + private fun setStartedSince(startedSince: Long?) { + val startedTextView = findView(R.id.started_since) + if (startedSince != null) { + startedTextView.text = (view.context.getString(R.string.started_since) + " " + + SimpleDateFormat("dd/MM HH:mm:ss", Locale.FRENCH).format(Date(startedSince))) + startedTextView.visibility = View.VISIBLE + } else { + startedTextView.visibility = View.GONE + } + } + + fun setNewData(data: NewData) { + + val phoneListView = view.findViewById(R.id.phoneListView) + val listPhone = ArrayList>() + + val rssi: String = when { + data.rssi != null -> data.rssi!!.toString() + " dBm" + data.rsrp != null -> data.rsrp!!.toString() + " dBm" + else -> "Unknown" + } + + var temp: HashMap = HashMap() + + temp[Tools.NAME] = "RSSI" + temp[Tools.VALUE] = rssi + listPhone.add(temp) + + temp = HashMap() + temp[Tools.NAME] = "Operator" + if (data.operator == null) { + temp[Tools.VALUE] = "" + } else { + temp[Tools.VALUE] = data.operator!! + } + listPhone.add(temp) + + temp = HashMap() + temp[Tools.NAME] = "Bytes Sent" + if (data.bytesSent == null) { + temp[Tools.VALUE] = "0 Mo" + } else { + temp[Tools.VALUE] = (data.bytesSent!! / (1024f * 1024f)).toString() + " Mo" + } + listPhone.add(temp) + + temp = HashMap() + temp[Tools.NAME] = "Bytes Received" + if (data.bytesReceived == null) { + temp[Tools.VALUE] = "0 Mo" + } else { + temp[Tools.VALUE] = (data.bytesReceived!! / (1024f * 1024f)).toString() + " Mo" + } + listPhone.add(temp) + + temp = HashMap() + temp[Tools.NAME] = "Network Type" + if (data.networkType == null) { + temp[Tools.VALUE] = "" + } else { + temp[Tools.VALUE] = data.networkType!! + } + listPhone.add(temp) + + temp = HashMap() + temp[Tools.NAME] = "Latitude" + if (data.latitude == null) { + temp[Tools.VALUE] = "" + } else { + temp[Tools.VALUE] = data.latitude!!.toString() + } + listPhone.add(temp) + + temp = HashMap() + temp[Tools.NAME] = "Longitude" + if (data.longitude == null) { + temp[Tools.VALUE] = "" + } else { + temp[Tools.VALUE] = data.longitude!!.toString() + } + listPhone.add(temp) + val adapter = RunListViewAdapter(activity, listPhone) + Log.d(TAG, "set Phone data " + listPhone) + phoneListView.adapter = adapter + phoneListView.invalidateViews() + + setCustomDataValues() + } + + private fun setCustomDataValues() { + val objectListView = view.findViewById(R.id.objectLstView) + objectsManager = ObjectsManager.getInstance() + val obj = objectsManager!!.currentObject + var temp: HashMap + val listObject = ArrayList>() + for (ldata in obj!!.datas) { + temp = HashMap() + temp[Tools.NAME] = ldata.name + if (ldata.mode != AvPhoneObjectData.Mode.None) { + temp[Tools.VALUE] = ldata.current.toString() + } else { + temp[Tools.VALUE] = ldata.defaults + } + listObject.add(temp) + } + val adapter = RunListViewAdapter(activity, listObject) + objectListView.adapter = adapter + objectListView.invalidateViews() + } + + private fun findView(id: Int): TextView { + return view.findViewById(id) as TextView + } + + companion object { + private val TAG = DataViewUpdater::class.simpleName + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/DeviceInfo.java b/mainActivity/src/main/java/com/sierrawireless/avphone/DeviceInfo.java deleted file mode 100644 index a176f03..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/DeviceInfo.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.sierrawireless.avphone; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.telephony.TelephonyManager; - -public class DeviceInfo { - - - /** - * Serial number is in `syncParams.deviceId`, why not using it? - * - * - It is not available running emulator - * - It is not available to our iOs counterpart - * - * So to be AV Phone iOs compatible and able to run emulator, we use: uppercase(userUid + "-" + systemType) - */ - @SuppressLint("DefaultLocale") - public static String generateSerial(final String userUid, final String systemType) { - return (userUid + "-" + systemType).toUpperCase(); - } - - @SuppressLint("DefaultLocale") - public static String getUniqueId(final Context context) { - - if (context instanceof MainActivity) { - final MainActivity mainActivity = (MainActivity) context; - return mainActivity.getSystemSerial(); - } - - return null; - } - - /** - * Is this SN one of the common ones used by cheap phones (eg wiko)? - * - * Currently we had issues with : - * - * - "123456789ABCD" - * - "0123456789ABCDEF" - * - * We simply check if "123456789ABCD" is a substring, this should do for a while. - */ - @SuppressLint("DefaultLocale") - private static boolean isCommonSerialNumber(final String serialNumber) { - return serialNumber.toUpperCase().contains("123456789ABCD"); - } - - public static String getIMEI(final Context context) { - - final TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - if (telManager != null && telManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { - return telManager.getDeviceId(); - } - - return null; - } -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/HomeFragment.java b/mainActivity/src/main/java/com/sierrawireless/avphone/HomeFragment.java deleted file mode 100644 index fcb1a69..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/HomeFragment.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.sierrawireless.avphone; - -import net.airvantage.model.AvError; -import net.airvantage.utils.AvPhonePrefs; -import net.airvantage.utils.PreferenceUtils; - -import android.app.Activity; -import android.content.Intent; -import android.os.AsyncTask; -import android.os.Bundle; -import android.text.Html; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import com.crashlytics.android.Crashlytics; -import com.sierrawireless.avphone.auth.AuthUtils; -import com.sierrawireless.avphone.auth.Authentication; -import com.sierrawireless.avphone.message.IMessageDisplayer; -import com.sierrawireless.avphone.task.IAsyncTaskFactory; -import com.sierrawireless.avphone.task.SyncWithAvListener; -import com.sierrawireless.avphone.task.SyncWithAvParams; -import com.sierrawireless.avphone.task.SyncWithAvResult; -import com.sierrawireless.avphone.task.SyncWithAvTask; - -public class HomeFragment extends AvPhoneFragment implements IMessageDisplayer { - - private static final String LOGTAG = HomeFragment.class.getName(); - - private View view; - - private Authentication authForSync; - private boolean retrySync; - - private Button btnLogin; - private Button btnLogout; - - private IAsyncTaskFactory taskFactory; - - public HomeFragment() { - super(); - retrySync = false; - taskFactory = null; - } - - public void setTaskFactory(IAsyncTaskFactory taskFactory) { - this.taskFactory = taskFactory; - if (retrySync) { - retrySync = false; - syncWithAv(authForSync); - } - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - syncListener = (SyncWithAvListener) activity; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - view = inflater.inflate(R.layout.fragment_home, container, false); - - TextView loginMessage = (TextView) view.findViewById(R.id.home_login_message); - loginMessage.setText(Html.fromHtml(getString(R.string.home_login_message))); - - btnLogin = (Button) view.findViewById(R.id.login_btn); - - btnLogout = (Button) view.findViewById(R.id.logout_btn); - - btnLogin.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View arg0) { - requestAuthentication(); - } - }); - - btnLogout.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - logout(); - } - }); - - if (authManager.isLogged()) { - showLoggedInState(); - } else { - showLoggedOutState(); - } - - return view; - } - - @Override - public void onResume() { - super.onResume(); - - if (authManager.isLogged()) { - showLoggedInState(); - } else { - showLoggedOutState(); - } - } - - private TextView getInfoMessageView() { - TextView infoMessageView = (TextView) view.findViewById(R.id.home_info_message); - return infoMessageView; - } - - private void showCurrentServer() { - AvPhonePrefs phonePrefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - TextView infoMessageView = getInfoMessageView(); - - String message = null; - if (phonePrefs.usesNA()) { - message = getString(R.string.logged_on_na); - } else if (phonePrefs.usesEU()) { - message = getString(R.string.logged_on_eu); - } else { - message = getString(R.string.logged_on_custom, phonePrefs.serverHost); - } - - infoMessageView.setText(message); - infoMessageView.setVisibility(View.VISIBLE); - } - - private void hideCurrentServer() { - TextView infoMessageView = getInfoMessageView(); - infoMessageView.setVisibility(View.GONE); - infoMessageView.setText(""); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - Authentication auth = AuthUtils.activityResultAsAuthentication(requestCode, resultCode, data); - if (auth != null) { - syncWithAv(auth); - } - } - - private void syncWithAv(final Authentication auth) { - - hideErrorMessage(); - - AvPhonePrefs avPhonePrefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - - // Without task factory, try later - if (taskFactory == null) { - authForSync = auth; - retrySync = true; - return; - } - - final IMessageDisplayer displayer = this; - final SyncWithAvTask syncAvTask = taskFactory.syncAvTask(avPhonePrefs.serverHost, auth.getAccessToken()); - - syncAvTask.addProgressListener(new SyncWithAvListener() { - @Override - public void onSynced(SyncWithAvResult result) { - if (result.isError()) { - authManager.forgetAuthentication(); - showLoggedOutState(); - syncAvTask.showResult(result, displayer, getActivity()); - } else { - authManager.onAuthentication(auth); - showLoggedInState(); - syncListener.onSynced(result); - } - - } - }); - - final SyncWithAvParams params = new SyncWithAvParams(); - - params.deviceId = DeviceInfo.getUniqueId(getActivity()); - params.imei = DeviceInfo.getIMEI(getActivity()); - params.mqttPassword = avPhonePrefs.password; - params.customData = PreferenceUtils.getCustomDataLabels(getActivity()); - - syncAvTask.execute(params); - - } - - private void showLoggedInState() { - showCurrentServer(); - showLogoutButton(); - } - - private void showLoggedOutState() { - hideLogoutButton(); - hideCurrentServer(); - } - - private void logout() { - - AvPhonePrefs avPhonePrefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - - String accessToken = authManager.getAuthentication().getAccessToken(); - - AsyncTask logoutTask = taskFactory.logoutTask(avPhonePrefs.serverHost, accessToken); - - logoutTask.execute(); - - try { - logoutTask.get(); - } catch (Exception e) { - Log.w(LOGTAG, "Exception while logging out"); - Crashlytics.logException(e); - } finally { - authManager.forgetAuthentication(); - - showLoggedOutState(); - } - - } - - private void showLogoutButton() { - btnLogout.setVisibility(View.VISIBLE); - btnLogin.setVisibility(View.GONE); - view.findViewById(R.id.home_login_message).setVisibility(View.GONE); - } - - private void hideLogoutButton() { - btnLogout.setVisibility(View.GONE); - btnLogin.setVisibility(View.VISIBLE); - - view.findViewById(R.id.home_login_message).setVisibility(View.VISIBLE); - } - - public TextView getErrorMessageView() { - return (TextView) view.findViewById(R.id.home_error_message); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/HomeFragment.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/HomeFragment.kt new file mode 100644 index 0000000..dca3667 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/HomeFragment.kt @@ -0,0 +1,192 @@ +package com.sierrawireless.avphone + +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.text.Html +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.crashlytics.android.Crashlytics +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.auth.AuthUtils +import com.sierrawireless.avphone.auth.Authentication +import com.sierrawireless.avphone.message.IMessageDisplayer +import com.sierrawireless.avphone.task.IAsyncTaskFactory +import com.sierrawireless.avphone.task.SyncWithAvListener +import com.sierrawireless.avphone.task.SyncWithAvParams +import com.sierrawireless.avphone.tools.DeviceInfo +import kotlinx.android.synthetic.main.fragment_home.* +import net.airvantage.model.User +import net.airvantage.utils.PreferenceUtils + +class HomeFragment : AvPhoneFragment(), IMessageDisplayer { + private var lView: View? = null + private var authForSync: Authentication? = null + private var retrySync: Boolean = false + private var taskFactory: IAsyncTaskFactory? = null + private var user: User? = null + private val infoMessageView: TextView? + get() = home_info_message + + override var errorMessageView: TextView? + get() = home_error_message + set(textView) { + } + + fun setTaskFactory(taskFactory: IAsyncTaskFactory) { + this.taskFactory = taskFactory + if (retrySync) { + retrySync = false + syncWithAv(authForSync) + } + } + + override fun onAttach(context: Context) { + super.onAttach(context) + + @Suppress("UNCHECKED_CAST") + syncListener = context as SyncWithAvListener + } + + @SuppressWarnings("deprecation") + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + + lView = inflater.inflate(R.layout.fragment_home, container, false) + + return lView + } + + override fun onStart() { + super.onStart() + val loginMessage = home_login_message + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + loginMessage.text = Html.fromHtml(getString(R.string.home_login_message_str), Html.FROM_HTML_MODE_LEGACY) + }else{ + @Suppress("DEPRECATION") + loginMessage.text = Html.fromHtml(getString(R.string.home_login_message_str)) + } + + login_btn.setOnClickListener { requestAuthentication() } + logout_btn.setOnClickListener { logout() } + + showLoggedOutState() + } + + override fun onResume() { + super.onResume() + + showLoggedOutState() + } + + private fun hideCurrentServer() { + infoMessageView?.visibility = View.GONE + home_login.visibility = View.GONE + infoMessageView?.text = "" + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + + if (data != null) { + + + val auth = AuthUtils.activityResultAsAuthentication(requestCode, resultCode, data) + if (auth != null) { + syncWithAv(auth) + } + MainActivity.instance.onAuthentication(auth!!) + MainActivity.instance.readAuthenticationFromPreferences() + MainActivity.instance.loadMenu(true) + } + } + + private fun syncWithAv(auth: Authentication?) { + hideErrorMessage() + + val avPhonePrefs = PreferenceUtils.getAvPhonePrefs(activity) + + // Without task factory, try later + if (taskFactory == null) { + authForSync = auth + retrySync = true + return + } + + val displayer = this + val syncAvTask = taskFactory!!.syncAvTask(avPhonePrefs.serverHost!!, auth!!.accessToken!!) + + syncAvTask.addProgressListener { result -> + if (result.isError) { + authManager!!.forgetAuthentication() + showLoggedOutState() + syncAvTask.showResult(result, displayer, activity) + } else { + authManager!!.onAuthentication(auth) + showLoggedInState() + user = result.user + syncListener!!.invoke(result) + } + } + + val params = SyncWithAvParams() + + params.deviceId = DeviceInfo.getUniqueId(activity) + params.imei = DeviceInfo.getIMEI(activity) + params.deviceName = DeviceInfo.deviceName + params.iccid = DeviceInfo.getICCID(activity) + params.mqttPassword = avPhonePrefs.password + params.customData = PreferenceUtils.getCustomDataLabels(activity) + // params.current = ((MainActivity)getActivity()).current; + params.activity = activity as MainActivity + + syncAvTask.execute(params) + } + + private fun showLoggedInState() { + + } + + private fun showLoggedOutState() { + hideLogoutButton() + hideCurrentServer() + } + + private fun logout() { + val avPhonePrefs = PreferenceUtils.getAvPhonePrefs(activity) + + if (authManager == null || authManager!!.authentication == null || taskFactory == null) { + return + } + + val accessToken = authManager!!.authentication!!.accessToken + + val logoutTask = taskFactory!!.logoutTask(avPhonePrefs.serverHost!!, accessToken!!) + + logoutTask.execute() + try { + logoutTask.get() + } catch (e: Exception) { + Log.w(TAG, "Exception while logging out") + Crashlytics.logException(e) + } finally { + authManager!!.forgetAuthentication() + + showLoggedOutState() + } + } + + private fun hideLogoutButton() { + logout_btn.visibility = View.GONE + login_btn.visibility = View.VISIBLE + + home_login_message.visibility = View.VISIBLE + } + + companion object { + private val TAG = HomeFragment::class.simpleName + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/LoginListener.java b/mainActivity/src/main/java/com/sierrawireless/avphone/LoginListener.java deleted file mode 100644 index 546a5bc..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/LoginListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sierrawireless.avphone; - -public interface LoginListener { - - public void OnLoginChanged(boolean logged); - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/MainActivity.java b/mainActivity/src/main/java/com/sierrawireless/avphone/MainActivity.java deleted file mode 100644 index 0ef8477..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/MainActivity.java +++ /dev/null @@ -1,489 +0,0 @@ -package com.sierrawireless.avphone; - -import android.annotation.SuppressLint; -import android.app.ActionBar; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningServiceInfo; -import android.app.AlarmManager; -import android.app.Fragment; -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Configuration; -import android.os.Bundle; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.support.v4.app.FragmentActivity; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.ActionBarDrawerToggle; -import android.util.Log; -import android.view.Gravity; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ListView; - -import com.crashlytics.android.Crashlytics; -import com.sierrawireless.avphone.auth.Authentication; -import com.sierrawireless.avphone.auth.AuthenticationManager; -import com.sierrawireless.avphone.service.MonitoringService; -import com.sierrawireless.avphone.service.MonitoringService.ServiceBinder; -import com.sierrawireless.avphone.task.AsyncTaskFactory; -import com.sierrawireless.avphone.task.IAsyncTaskFactory; -import com.sierrawireless.avphone.task.SyncWithAvListener; -import com.sierrawireless.avphone.task.SyncWithAvResult; - -import net.airvantage.model.AvSystem; -import net.airvantage.model.User; -import net.airvantage.utils.AvPhonePrefs; -import net.airvantage.utils.PreferenceUtils; - -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import io.fabric.sdk.android.Fabric; - -/** - * The main activity, handling drawer and Fragments - */ -public class MainActivity extends FragmentActivity - implements LoginListener, AuthenticationManager, OnSharedPreferenceChangeListener, - MonitorServiceManager, CustomLabelsManager, SyncWithAvListener { - - private static final String PREFERENCE_SYSTEM_NAME = "systemName"; - private static final String PREFERENCE_SYSTEM_SERIAL = "systemSerial"; - private static final String PREFERENCE_USER_NAME = "userName"; - private static final String PREFERENCE_USER_UID = "userUid"; - - private static String LOGTAG = MainActivity.class.getName(); - - private ActionBar actionBar; - private AlarmManager alarmManager; - private IAsyncTaskFactory taskFactory; - private Authentication auth; - private SharedPreferences prefs; - - boolean boundToMonitoringService = false; - MonitoringService monitoringService; - private MonitorServiceListener monitoringServiceListener = null; - - private CustomLabelsListener customLabelsListener = null; - private DrawerLayout drawerLayout; - private ListView drawerListView; - private ActionBarDrawerToggle drawerToggle; - - private final static String FRAGMENT_HOME = "Home"; - private final static String FRAGMENT_RUN = "Run"; - private final static String FRAGMENT_CONFIGURE = "Configure"; - private final static String FRAGMENT_SETTINGS = "Settings"; - - private ConfigureFragment configureFragment; - private HomeFragment homeFragment; - private RunFragment runFragment; - - private final static String[] FRAGMENT_LIST = new String[]{ - FRAGMENT_HOME, - FRAGMENT_RUN, - FRAGMENT_CONFIGURE, - FRAGMENT_SETTINGS, - }; - - public void setCustomLabelsListener(CustomLabelsListener customLabelsListener) { - this.customLabelsListener = customLabelsListener; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Fabric.with(this, new Crashlytics()); - - setContentView(R.layout.activity_main); - - prefs = PreferenceManager.getDefaultSharedPreferences(this); - prefs.registerOnSharedPreferenceChangeListener(this); - - readAuthenticationFromPreferences(); - - taskFactory = new AsyncTaskFactory(MainActivity.this); - - drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - drawerListView = (ListView) findViewById(R.id.left_drawer); - drawerListView.setAdapter(new ArrayAdapter<>(this, R.layout.drawer_item, FRAGMENT_LIST)); - - // Set the list's click listener - drawerListView.setOnItemClickListener(new ListView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - selectItem(position); - } - }); - - alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); - - drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, - R.string.drawer_close); - drawerLayout.setDrawerListener(drawerToggle); - - final Map fragments = initFragments(); - final Fragment currentFragment; - if (isLogged()) { - - currentFragment = fragments.get(FRAGMENT_RUN); - unlockDrawer(); - if (isServiceRunning()) { - connectToService(); - } - - } else { - - currentFragment = fragments.get(FRAGMENT_HOME); - lockDrawer(); - if (isServiceRunning()) { - // The token is probably expired. - // We stop the service since the "stop" button is not available anymore. - this.stopMonitoringService(); - } - - } - - selectItem(currentFragment); - } - - @Override - protected void onPostCreate(@Nullable Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - drawerToggle.syncState(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return // Handle it ourselves - drawerToggle.onOptionsItemSelected(item) - // Or just go with defaults - || super.onOptionsItemSelected(item); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - drawerToggle.onConfigurationChanged(newConfig); - } - - private void lockDrawer() { - - actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(false); - actionBar.setHomeButtonEnabled(false); - } - - if (drawerLayout != null) { - drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); - } - - if (drawerToggle != null) { - drawerToggle.setDrawerIndicatorEnabled(false); - } - } - - private void unlockDrawer() { - - actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setHomeButtonEnabled(true); - } - - if (drawerLayout != null) { - drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); - drawerLayout.openDrawer(Gravity.LEFT); - } - - if (drawerToggle != null) { - drawerToggle.setDrawerIndicatorEnabled(true); - } - } - - private void readAuthenticationFromPreferences() { - this.auth = PreferenceUtils.readAuthentication(this); - } - - @Override - public void OnLoginChanged(boolean logged) { - } - - public boolean isLogged() { - return (this.auth != null && !this.auth.isExpired(new Date())); - } - - @Override - public void onAuthentication(Authentication auth) { - - this.auth = auth; - unlockDrawer(); - - saveAuthenticationInPreferences(auth); - } - - @Override - public Authentication getAuthentication() { - return this.auth; - } - - private void saveAuthenticationInPreferences(Authentication auth) { - PreferenceUtils.saveAuthentication(this, auth); - } - - public void forgetAuthentication() { - - lockDrawer(); - PreferenceUtils.resetAuthentication(this); - this.auth = null; - - if (this.isServiceRunning()) { - this.stopMonitoringService(); - } - - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - - if (PreferenceUtils.PREF_SERVER_KEY.equals(key) || PreferenceUtils.PREF_CLIENT_ID_KEY.equals(key)) { - - this.stopMonitoringService(); - this.forgetAuthentication(); - - } else if (PreferenceUtils.PREF_PERIOD_KEY.equals(key) || PreferenceUtils.PREF_PASSWORD_KEY.equals(key)) { - - this.restartMonitoringService(); - - } else if (key.indexOf("pref_data_custom") != -1) { - - if (this.customLabelsListener != null) { - this.customLabelsListener.onCustomLabelsChanged(); - } - } - - } - - public boolean isServiceRunning() { - ActivityManager manager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); - for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { - if (MonitoringService.class.getName().equals(service.service.getClassName())) { - return true; - } - } - return false; - } - - private void connectToService() { - Intent intent = new Intent(this, MonitoringService.class); - boundToMonitoringService = this.bindService(intent, connection, Context.BIND_AUTO_CREATE); - } - - private void disconnectFromService() { - if (boundToMonitoringService) { - this.unbindService(connection); - boundToMonitoringService = false; - if (monitoringServiceListener != null) { - monitoringServiceListener.onServiceStopped(monitoringService); - } - } - } - - ServiceConnection connection = new ServiceConnection() { - - @Override - public void onServiceConnected(ComponentName arg0, IBinder binder) { - Log.d(LOGTAG, "Connected to the monitoring service"); - monitoringService = ((ServiceBinder) binder).getService(); - - if (monitoringServiceListener != null) { - monitoringServiceListener.onServiceStarted(monitoringService); - } - - } - - @Override - public void onServiceDisconnected(ComponentName arg0) { - Log.d(LOGTAG, "Disconnected from the monitoring service"); - boundToMonitoringService = false; - } - - }; - - public void sendAlarmEvent(boolean activated) { - if (boundToMonitoringService && monitoringService != null) { - monitoringService.sendAlarmEvent(activated); - } - } - - @Override - public void startMonitoringService() { - AvPhonePrefs avPrefs = PreferenceUtils.getAvPhonePrefs(this); - - Intent intent = new Intent(this, MonitoringService.class); - intent.putExtra(MonitoringService.DEVICE_ID, DeviceInfo.getUniqueId(this)); - intent.putExtra(MonitoringService.SERVER_HOST, avPrefs.serverHost); - intent.putExtra(MonitoringService.PASSWORD, avPrefs.password); - - PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT); - // registering our pending intent with alarm manager - alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, - Integer.valueOf(avPrefs.period) * 60 * 1000, pendingIntent); - - connectToService(); - } - - @Override - public void stopMonitoringService() { - Intent intent = new Intent(this, MonitoringService.class); - PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT); - alarmManager.cancel(pendingIntent); - this.stopService(intent); - - disconnectFromService(); - } - - private void restartMonitoringService() { - stopMonitoringService(); - startMonitoringService(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - disconnectFromService(); - } - - @Override - public MonitoringService getMonitoringService() { - return this.monitoringService; - } - - public void setMonitoringServiceListener(MonitorServiceListener listener) { - this.monitoringServiceListener = listener; - } - - @SuppressLint("DefaultLocale") - @Override - public void onSynced(SyncWithAvResult result) { - - final AvSystem system = result.getSystem(); - prefs.edit().putString("systemUid", system.uid).apply(); - prefs.edit().putString(PREFERENCE_SYSTEM_NAME, system.name).apply(); - - final User user = result.getUser(); - prefs.edit().putString(PREFERENCE_USER_UID, user.uid).apply(); - prefs.edit().putString(PREFERENCE_USER_NAME, user.name).apply(); - - final String deviceSerial = DeviceInfo.generateSerial(user.uid, system.type); - prefs.edit().putString(PREFERENCE_SYSTEM_SERIAL, deviceSerial).apply(); - - if (runFragment != null) { - String systemUid = this.getSystemUid(); - String systemName = this.getSystemName(); - runFragment.setLinkToSystem(systemUid, systemName); - } else { - Log.w(LOGTAG, "RunFragment reference is null when onSynced is called"); - } - - } - - public String getSystemUid() { - return prefs.getString("systemUid", null); - } - - public String getSystemSerial() { - return prefs.getString(PREFERENCE_SYSTEM_SERIAL, null); - } - - public String getSystemName() { - return prefs.getString(PREFERENCE_SYSTEM_NAME, null); - } - - @SuppressLint("DefaultLocale") - public void setSystemSerial(final String serial) { - prefs.edit().putString(PREFERENCE_SYSTEM_SERIAL, serial.toUpperCase()).apply(); - } - - /** - * Swaps fragments in the main content view - */ - private void selectItem(final int position) { - - final Fragment fragment = getFragment(position); - if (fragment == null) { - return; - } - - // Insert the fragment by replacing any existing fragment - getFragmentManager() - .beginTransaction() - .replace(R.id.content_frame, fragment) - .commit(); - - // Highlight the selected item, update the title, and close the drawer - drawerListView.setItemChecked(position, true); - setTitle(FRAGMENT_LIST[position]); - drawerListView.setSelection(position); - drawerLayout.closeDrawer(drawerListView); - } - - private void selectItem(final Fragment fragment) { - final Iterator fragmentsIterator = initFragments().values().iterator(); - for (int position = 0; fragmentsIterator.hasNext(); position++) { - final Fragment currentFragment = fragmentsIterator.next(); - if (fragment.getId() == currentFragment.getId()) { - selectItem(position); - return; - } - } - } - - - private Map initFragments() { - - if (configureFragment == null) { - configureFragment = new ConfigureFragment(); - configureFragment.setTaskFactory(taskFactory); - } - - if (homeFragment == null) { - homeFragment = new HomeFragment(); - homeFragment.setTaskFactory(taskFactory); - } - - if (runFragment == null) { - runFragment = new RunFragment(); - } - - final HashMap fragmentsMapping = new HashMap<>(); - fragmentsMapping.put(FRAGMENT_CONFIGURE, configureFragment); - fragmentsMapping.put(FRAGMENT_HOME, homeFragment); - fragmentsMapping.put(FRAGMENT_SETTINGS, new SettingsActivity.SettingsFragment()); - fragmentsMapping.put(FRAGMENT_RUN, runFragment); - - return fragmentsMapping; - } - - @Nullable - private Fragment getFragment(final int fragmentPosition) { - final String fragmentName = FRAGMENT_LIST[fragmentPosition]; - final Map fragmentMap = initFragments(); - return fragmentMap.containsKey(fragmentName) ? fragmentMap.get(fragmentName) : null; - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/MonitorServiceListener.java b/mainActivity/src/main/java/com/sierrawireless/avphone/MonitorServiceListener.java deleted file mode 100644 index 2290d3a..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/MonitorServiceListener.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sierrawireless.avphone; - -import com.sierrawireless.avphone.service.MonitoringService; - -public interface MonitorServiceListener { - - public void onServiceStarted(MonitoringService service); - - public void onServiceStopped(MonitoringService service); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/MonitorServiceManager.java b/mainActivity/src/main/java/com/sierrawireless/avphone/MonitorServiceManager.java deleted file mode 100644 index eac52fd..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/MonitorServiceManager.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sierrawireless.avphone; - -import com.sierrawireless.avphone.service.MonitoringService; - - -public interface MonitorServiceManager { - public boolean isServiceRunning(); - public void stopMonitoringService(); - public void startMonitoringService(); - public void sendAlarmEvent(boolean activated); - public void setMonitoringServiceListener(MonitorServiceListener listener); - public MonitoringService getMonitoringService(); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/ObjectsManager.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/ObjectsManager.kt new file mode 100644 index 0000000..123a86f --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/ObjectsManager.kt @@ -0,0 +1,132 @@ +package com.sierrawireless.avphone + + +import android.content.Context +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.model.AvPhoneObject +import com.sierrawireless.avphone.model.AvPhoneObjectData +import com.sierrawireless.avphone.tools.MyPreference +import java.util.* + +class ObjectsManager private constructor() { + private var mainActivity: MainActivity? = null + var current: Int = 0 + private var savedPosition = -1 + + internal var objects: ArrayList + + val savecObject: AvPhoneObject + get() = objects[savedPosition] + + val savedObjectName: String? + get() = objects[savedPosition].name + + val currentObject: AvPhoneObject? + get() = if (objects.isEmpty()) { + null + } else objects[current] + + init { + objects = ArrayList() + } + + internal fun init(activity: MainActivity) { + this.mainActivity = activity + val pref = MyPreference(activity.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)) + + + objects = pref.getListObject(MODELS, AvPhoneObject::class.java) + current = pref.getInt(ACTIVE) + + if (objects.isEmpty()) { + // Create the default model here + val model = AvPhoneObject() + model.name = "Printer" + var data = AvPhoneObjectData("A6 Page Count", "page(s)", "0", AvPhoneObjectData.Mode.UP, "1", null) + model.add(data) + data = AvPhoneObjectData("A4 Page Count", "page(s)", "0", AvPhoneObjectData.Mode.UP, "2", null) + model.add(data) + data = AvPhoneObjectData("Black Cartridge S/N", "", "NTOQN-7HUL9-NEPFL-13IOA", AvPhoneObjectData.Mode.None, "3", null) + model.add(data) + data = AvPhoneObjectData("Black lnk Level", "%", "100", AvPhoneObjectData.Mode.DOWN, "4",null) + model.add(data) + data = AvPhoneObjectData("Color Cartridge S/N", "", "629U7-XLT5H-6SCGJ-@CENZ", AvPhoneObjectData.Mode.None, "5",null) + model.add(data) + data = AvPhoneObjectData("Color lnk Level", "%", "100", AvPhoneObjectData.Mode.DOWN, "6",null) + model.add(data) + objects.add(model) + current = 0 + saveOnPref() + } + if (savedPosition == -1) { + savedPosition = current + } + } + + internal fun removeSavedObject() { + objects.removeAt(savedPosition) + savedPosition = current + saveOnPref() + } + + fun saveOnPref() { + val pref = MyPreference(mainActivity!!.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)) + // Save the list for later + pref.putListObject(MODELS, objects) + pref.putInt(ACTIVE, current) + } + + internal fun reload() { + + val pref = MyPreference(mainActivity!!.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)) + + + objects = pref.getListObject(MODELS, AvPhoneObject::class.java) + current = pref.getInt(ACTIVE) + + } + + + fun changeCurrent(name: String) { + for ((index, obj) in objects.withIndex()) { + if (obj.name == name) { + current = index + saveOnPref() + return + } + } + } + + internal fun setSavedPosition(position: Int) { + savedPosition = position + } + + internal fun getObjectByIndex(position: Int): AvPhoneObject? { + return if (position > objects.size) { + null + } else objects[position] + } + + fun getObjectByName(name: String): AvPhoneObject? { + return objects.firstOrNull { it.name == name } + } + + internal fun save() { + saveOnPref() + + } + + companion object { + private var lInstance:ObjectsManager? = null + private const val SHARED_PREFS_FILE = "SavedModels" + private const val MODELS = "models" + private const val ACTIVE = "active" + + fun getInstance(): ObjectsManager { + if (lInstance == null) { + lInstance = ObjectsManager() + } + return lInstance!! + } + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/RunFragment.java b/mainActivity/src/main/java/com/sierrawireless/avphone/RunFragment.java deleted file mode 100644 index b29f063..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/RunFragment.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.sierrawireless.avphone; - -import net.airvantage.utils.AvPhonePrefs; -import net.airvantage.utils.PreferenceUtils; - -import android.app.Activity; -import android.content.IntentFilter; -import android.os.Bundle; -import android.support.v4.content.LocalBroadcastManager; -import android.support.v7.widget.SwitchCompat; -import android.text.Html; -import android.text.method.LinkMovementMethod; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.TextView; - -import com.sierrawireless.avphone.model.CustomDataLabels; -import com.sierrawireless.avphone.service.LogMessage; -import com.sierrawireless.avphone.service.MonitoringService; -import com.sierrawireless.avphone.service.NewData; - -public class RunFragment extends AvPhoneFragment implements MonitorServiceListener, CustomLabelsListener { - - private static final String LOGTAG = RunFragment.class.getName(); - - private DataViewUpdater viewUpdater; - - private View view; - - private MonitorServiceManager monitorServiceManager; - - private CustomLabelsManager customLabelsManager; - private String systemUid; - private String systemName; - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - if (activity instanceof MonitorServiceManager) { - this.setMonitorServiceManager((MonitorServiceManager) activity); - } - - if (activity instanceof CustomLabelsManager) { - this.setCustomLabelsManager((CustomLabelsManager) activity); - } - } - - protected void setMonitorServiceManager(MonitorServiceManager manager) { - this.monitorServiceManager = manager; - this.monitorServiceManager.setMonitoringServiceListener(this); - } - - protected void setCustomLabelsManager(CustomLabelsManager manager) { - this.customLabelsManager = manager; - this.customLabelsManager.setCustomLabelsListener(this); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - view = inflater.inflate(R.layout.fragment_run, container, false); - viewUpdater = new DataViewUpdater(view); - - CustomDataLabels customLabels = PreferenceUtils.getCustomDataLabels(getActivity()); - setCustomDataLabels(customLabels); - - // register service listener - LocalBroadcastManager.getInstance(getActivity()).registerReceiver(viewUpdater, - new IntentFilter(NewData.NEW_DATA)); - LocalBroadcastManager.getInstance(getActivity()).registerReceiver(viewUpdater, - new IntentFilter(LogMessage.LOG_EVENT)); - - boolean isServiceRunning = monitorServiceManager.isServiceRunning(); - - SwitchCompat serviceSwitch = (SwitchCompat) view.findViewById(R.id.service_switch); - serviceSwitch.setChecked(isServiceRunning); - - serviceSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - startMonitoringService(); - } else { - stopMonitoringService(); - } - } - }); - - if (isServiceRunning) { - MonitoringService service = monitorServiceManager.getMonitoringService(); - if (service != null) { - this.onServiceStarted(service); - } else { - // the activity is not yet connected to the service. - // as a MonitorServiceListener, this fragment will be notified when the service is available - } - } - - // Alarm button - SwitchCompat alarmButton = (SwitchCompat) view.findViewById(R.id.alarm_switch); - alarmButton.setOnCheckedChangeListener(onAlarmClick); - - // Make links clickable in info view. - TextView infoMessageView = (TextView) view.findViewById(R.id.run_info_message); - infoMessageView.setLinksClickable(true); - infoMessageView.setMovementMethod(LinkMovementMethod.getInstance()); - - // Might had those before initialization - if (systemUid != null && systemName != null) { - setLinkToSystem(systemUid, systemName); - } - - return view; - } - - public void setLinkToSystem(String systemUid, String systemName) { - - if (view == null || getActivity() == null) { - // View is unavailable, bear it in mind for later - this.systemUid = systemUid; - this.systemName = systemName; - return; - } - - final TextView infoMessageView = (TextView) view.findViewById(R.id.run_info_message); - - String infoMessage = null; - if (systemUid != null) { - - AvPhonePrefs avPhonePrefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - String link = String.format("https://%s/monitor/systems/systemDetails?uid=%s", avPhonePrefs.serverHost, - systemUid); - - infoMessage = getString(R.string.run_info_message_link, link, systemName); - infoMessageView.setText(Html.fromHtml(infoMessage)); - - } else { - infoMessage = getString(R.string.run_info_message, DeviceInfo.getUniqueId(getActivity())); - infoMessageView.setText(infoMessage); - } - - } - - @Override - public void onResume() { - super.onResume(); - - boolean isServiceRunning = monitorServiceManager.isServiceRunning(); - SwitchCompat serviceSwitch = getServiceSwitch(); - serviceSwitch.setChecked(isServiceRunning); - - String systemUid = ((MainActivity) getActivity()).getSystemUid(); - String systemName = ((MainActivity) getActivity()).getSystemName(); - - this.setLinkToSystem(systemUid, systemName); - - } - - private SwitchCompat getServiceSwitch() { - return (SwitchCompat) view.findViewById(R.id.service_switch); - } - - private void startMonitoringService() { - AvPhonePrefs avPrefs = PreferenceUtils.getAvPhonePrefs(getActivity()); - if (!avPrefs.checkCredentials()) { - PreferenceUtils.showMissingPrefsDialog(getActivity()); - SwitchCompat serviceSwitch = getServiceSwitch(); - serviceSwitch.setChecked(false); - } else { - this.monitorServiceManager.startMonitoringService(); - } - - } - - private void stopMonitoringService() { - this.monitorServiceManager.stopMonitoringService(); - } - - protected void setCustomDataLabels(CustomDataLabels customDataLabels) { - TextView labelView = (TextView) view.findViewById(R.id.run_custom1_label); - labelView.setText(customDataLabels.customUp1Label); - - labelView = (TextView) view.findViewById(R.id.run_custom2_label); - labelView.setText(customDataLabels.customUp2Label); - - labelView = (TextView) view.findViewById(R.id.run_custom3_label); - labelView.setText(customDataLabels.customDown1Label); - - labelView = (TextView) view.findViewById(R.id.run_custom4_label); - labelView.setText(customDataLabels.customDown2Label); - - labelView = (TextView) view.findViewById(R.id.run_custom5_label); - labelView.setText(customDataLabels.customStr1Label); - - labelView = (TextView) view.findViewById(R.id.run_custom6_label); - labelView.setText(customDataLabels.customStr2Label); - } - - // Alarm button - - OnCheckedChangeListener onAlarmClick = new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - Log.d(LOGTAG, "On alarm button click"); - - monitorServiceManager.sendAlarmEvent(isChecked); - - } - }; - - protected TextView getErrorMessageView() { - return (TextView) view.findViewById(R.id.run_error_message); - } - - @Override - public void onServiceStarted(MonitoringService service) { - view.findViewById(R.id.toggle_to_start).setVisibility(View.GONE); - view.findViewById(R.id.started_since).setVisibility(View.VISIBLE); - view.findViewById(R.id.service_log).setVisibility(View.VISIBLE); - viewUpdater.onStart(service.getStartedSince(), service.getLastData(), service.getLastLog(), - service.getLastRun()); - } - - @Override - public void onServiceStopped(MonitoringService service) { - view.findViewById(R.id.toggle_to_start).setVisibility(View.VISIBLE); - view.findViewById(R.id.started_since).setVisibility(View.GONE); - view.findViewById(R.id.service_log).setVisibility(View.GONE); - viewUpdater.onStop(); - } - - @Override - public void onCustomLabelsChanged() { - // The activity can be null if the change is done while the fragment is not active. - // This can wait for the activity to be resumed. - if (getActivity() != null) { - CustomDataLabels customLabels = PreferenceUtils.getCustomDataLabels(getActivity()); - setCustomDataLabels(customLabels); - } - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/RunFragment.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/RunFragment.kt new file mode 100644 index 0000000..b68d4a3 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/RunFragment.kt @@ -0,0 +1,473 @@ +package com.sierrawireless.avphone + +import android.annotation.TargetApi +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.net.Uri +import android.os.Bundle +import android.support.v4.content.ContextCompat +import android.support.v4.content.LocalBroadcastManager +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.sierrawireless.avphone.activity.AuthorizationActivity +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.adapter.RunListViewAdapter +import com.sierrawireless.avphone.auth.AuthUtils +import com.sierrawireless.avphone.listener.CustomLabelsListener +import com.sierrawireless.avphone.listener.MonitorServiceListener +import com.sierrawireless.avphone.model.AvPhoneObjectData +import com.sierrawireless.avphone.service.LogMessage +import com.sierrawireless.avphone.service.MonitorServiceManager +import com.sierrawireless.avphone.service.MonitoringService +import com.sierrawireless.avphone.service.NewData +import com.sierrawireless.avphone.task.IAsyncTaskFactory +import com.sierrawireless.avphone.task.SyncWithAvParams +import com.sierrawireless.avphone.tools.DeviceInfo +import com.sierrawireless.avphone.tools.Tools +import kotlinx.android.synthetic.main.fragment_run.* +import net.airvantage.utils.PreferenceUtils +import org.jetbrains.anko.alert +import java.util.* +import kotlin.concurrent.schedule + + +@Suppress("DEPRECATION") +open class RunFragment : AvPhoneFragment(), MonitorServiceListener, CustomLabelsListener { + private var viewUpdater: DataViewUpdater? = null + private var lView: View? = null + private var monitorServiceManager: MonitorServiceManager? = null + private var systemUid: String? = null + private var systemName: String? = null + private var taskFactory: IAsyncTaskFactory? = null + private var objectName: String? = null + private var objectsManager: ObjectsManager = ObjectsManager.getInstance() + + private var timer:TimerTask? = null + + // Alarm button + private var onAlarmClick: View.OnClickListener = View.OnClickListener { + if (this.monitorServiceManager!!.isServiceStarted(objectName!!)) { + objectsManager = ObjectsManager.getInstance() + val obj = objectsManager.currentObject!! + obj.alarm = !obj.alarm + if (!monitorServiceManager!!.sendAlarmEvent(obj.alarm)) { + obj.alarm = !obj.alarm + } else { + objectsManager.saveOnPref() + setAlarmButton() + } + }else{ + alert("A run already exist for " + MainActivity.instance.startObjectName, "Alert") { + positiveButton("OK") { + + } + }.show() + } + } + + private fun setAlarmButton() { + val obj = objectsManager.currentObject!! + alarm_btn.text = if (obj.alarm) { + getString(R.string.cancel) + }else{ + getString(R.string.reaise) + } + } + + override var errorMessageView: TextView? + get() = run_error_message + set(textView) { + + } + + fun setTaskFactory(taskFactory: IAsyncTaskFactory) { + this.taskFactory = taskFactory + } + + fun setObjectName(name: String) { + this.objectName = name + } + + @Suppress("OverridingDeprecatedMember") + override fun onAttach(activity:Activity) { + super.onAttach(activity) + + Log.d(TAG, "OnAttach Called") + + if (activity is MonitorServiceManager) { + this.setMonitorServiceManager(activity as MonitorServiceManager) + } + + if (activity is CustomLabelsManager) { + this.setCustomLabelsManager(activity as CustomLabelsManager) + } + } + + @TargetApi(23) + override fun onAttach(context: Context) { + super.onAttach(context) + + Log.d(TAG, "OnAttach Called") + + if (context is MonitorServiceManager) { + this.setMonitorServiceManager(context as MonitorServiceManager) + } + + if (context is CustomLabelsManager) { + this.setCustomLabelsManager(context as CustomLabelsManager) + } + } + + override fun onDetach() { + super.onDetach() + Log.d(TAG, "On detach called") + } + + private fun setMonitorServiceManager(manager: MonitorServiceManager) { + Log.d(TAG, "Set monitoring service") + this.monitorServiceManager = manager + this.monitorServiceManager!!.setMonitoringServiceListener(this) + } + + private fun setCustomLabelsManager(manager: CustomLabelsManager) { + manager.setCustomLabelsListener(this) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + + lView = inflater.inflate(R.layout.fragment_run, container, false) + + return lView + } + + override fun onStart() { + super.onStart() + objectsManager = ObjectsManager.getInstance() + if (objectName != null) { + objectsManager.changeCurrent(objectName!!) + }else{ + Log.d(TAG, "retrieve canceled objectName") + objectName = MainActivity.instance.fragmentsList!![MainActivity.instance.lastPosition].name + } + viewUpdater = DataViewUpdater(lView!!, activity as MainActivity) + + + // register service listener + LocalBroadcastManager.getInstance(activity).registerReceiver(viewUpdater!!, + IntentFilter(NewData.NEW_DATA)) + LocalBroadcastManager.getInstance(activity).registerReceiver(viewUpdater!!, + IntentFilter(LogMessage.LOG_EVENT)) + + /* if service is running and it's myself or that is not running */ + if (monitorServiceManager != null && + ((monitorServiceManager!!.isServiceRunning() && monitorServiceManager!!.isServiceRunning(objectName!!)) || + !monitorServiceManager!!.isServiceRunning())){ + if (!this.monitorServiceManager!!.isServiceStarted(objectName!!)) { + if (this.monitorServiceManager!!.oneServiceStarted()) { + //stop the service + this.monitorServiceManager!!.stopMonitoringService() + } + //registerNewDevice(); + this.monitorServiceManager!!.startMonitoringService(objectName!!) + } + } + val isServiceRunning = if (monitorServiceManager != null) { + monitorServiceManager!!.isServiceRunning(objectName!!) + }else{ + false + } + service_switch.isChecked = isServiceRunning + + service_switch.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + startMonitoringService() + } else { + stopMonitoringService() + } + } + + if (isServiceRunning) { + val service = monitorServiceManager!!.monitoringService + if (service != null) { + this.onServiceStarted(service) + } + } + + + // Alarm button + alarm_btn.setOnClickListener(onAlarmClick) + + // Make links clickable in info view. + + // Might had those before initialization + if (systemUid != null && systemName != null) { + setLinkToSystem(systemUid, systemName) + } + + obj.text = objectName + phone.setBackgroundColor(ContextCompat.getColor(MainActivity.instance.baseContext, R.color.grey_1)) + phoneListView.visibility = View.VISIBLE + objectLstView.visibility = View.GONE + + phone.setOnClickListener { + phoneListView.visibility = View.VISIBLE + objectLstView.visibility = View.GONE + phone.isSelected = true + phone.isPressed = true + phone.setBackgroundColor(ContextCompat.getColor(MainActivity.instance.baseContext, R.color.grey_1)) + obj.isSelected = false + obj.isPressed = false + obj.setBackgroundColor(ContextCompat.getColor(MainActivity.instance.baseContext, R.color.grey_4)) + } + + obj.setOnClickListener { + phoneListView.visibility = View.GONE + objectLstView.visibility = View.VISIBLE + phone.isSelected = false + phone.isPressed = false + phone.setBackgroundColor(ContextCompat.getColor(MainActivity.instance.baseContext, R.color.grey_4)) + obj.isSelected = true + obj.isPressed = true + obj.setBackgroundColor(ContextCompat.getColor(MainActivity.instance.baseContext, R.color.grey_1)) + } + + setCustomDataLabels() + setPhoneDataLabels() + } + + override fun onResume() { + Log.d(TAG, "On Resume Called") + super.onResume() + if (monitorServiceManager == null){ + // We have to restart monitorServiceManager + Log.d(TAG, "MonitoringServiceManager is null") + return + } + if (objectName == null) { + Log.d(TAG, "objectName is null retreive it from objectManager") + objectName = objectsManager.currentObject!!.name + } + val isServiceRunning = monitorServiceManager!!.isServiceRunning(objectName!!) + service_switch.isChecked = isServiceRunning + val systemUid = (activity as MainActivity).systemUid + val systemName = (activity as MainActivity).systemName + + this.setLinkToSystem(systemUid, systemName) + startTimer() + monitorServiceManager?.start() + setAlarmButton() + setPhoneDataLabels() + } + + override fun onPause() { + Log.d(TAG, "on Pause Called") + super.onPause() + stopTimer() + this.monitorServiceManager?.cancel() + } + + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { + super.onActivityResult(requestCode, resultCode, data) + + if (requestCode == AuthorizationActivity.REQUEST_AUTHORIZATION) { + val auth = AuthUtils.activityResultAsAuthentication(requestCode, resultCode, data) + if (auth != null) { + authManager!!.onAuthentication(auth) + syncWithAv(auth.accessToken) + } + } + } + + private fun syncWithAv(token: String?) { + + val prefs = PreferenceUtils.getAvPhonePrefs(activity) + val display = this + + val syncAvTask = taskFactory!!.syncAvTask(prefs.serverHost!!, token!!) + + + val params = SyncWithAvParams() + + params.deviceId = DeviceInfo.getUniqueId(activity) + params.imei = DeviceInfo.getIMEI(activity) + params.deviceName = DeviceInfo.deviceName + params.iccid = DeviceInfo.getICCID(activity) + params.mqttPassword = prefs.password + params.customData = PreferenceUtils.getCustomDataLabels(activity) + // params.current = ((MainActivity)getActivity()).current; + params.activity = activity as MainActivity + + syncAvTask.execute(params) + syncAvTask.addProgressListener { result -> + syncAvTask.showResult(result, display, activity) + + if (!result.isError) { + syncListener!!.invoke(result) + } + } + } + + private fun setLinkToSystem(systemUid: String?, systemName: String?) { + + if (lView == null || activity == null) { + // View is unavailable, bear it in mind for later + this.systemUid = systemUid + this.systemName = systemName + } + val avPhonePrefs = PreferenceUtils.getAvPhonePrefs(MainActivity.instance) + objectsManager = ObjectsManager.getInstance() + val obj = objectsManager.currentObject!! + val link = String.format("https://%s/monitor/systems/systemDetails?uid=%s", avPhonePrefs.serverHost, obj.systemUid) + + airvantage.setOnClickListener { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(link)) + startActivity(browserIntent) + } + + // set button to open Airvantage + + return + } + + private fun startMonitoringService() { + val avPrefs = PreferenceUtils.getAvPhonePrefs(activity) + if (!avPrefs.checkCredentials()) { + PreferenceUtils.showMissingPrefsDialog(activity) + service_switch.isChecked = false + } else { + if (this.monitorServiceManager!!.startSendData(objectName!!)) { + this.monitorServiceManager!!.monitoringService!!.startSendData() + }else{ + service_switch.isChecked = false + } + } + + } + + private fun stopMonitoringService() { + this.monitorServiceManager!!.stopSendData() + this.monitorServiceManager!!.monitoringService!!.stopSendData() + } + + + + + private fun setPhoneDataLabels() { + Log.d(TAG, "setPhoneDataLabels called for " + objectName) + val adapter = RunListViewAdapter(activity, arrayListOf( + hashMapOf(Tools.NAME to "RSSI", + Tools.VALUE to "0 dBm"), + hashMapOf(Tools.NAME to "Operator", + Tools.VALUE to "Unknown"), + hashMapOf(Tools.NAME to "Bytes Sent", + Tools.VALUE to "0 Mo"), + hashMapOf(Tools.NAME to "Bytes received", + Tools.VALUE to "0 Mo"), + hashMapOf(Tools.NAME to "Network Type", + Tools.VALUE to "Unknown"), + hashMapOf(Tools.NAME to "Latitude", + Tools.VALUE to "Unknown"), + hashMapOf(Tools.NAME to "Longitude", + Tools.VALUE to "Unknown"))) + phoneListView.adapter = adapter + phoneListView.invalidateViews() + + } + + private fun setCustomDataLabels() { + val listObject = ArrayList>() + + objectsManager = ObjectsManager.getInstance() + val obj = objectsManager.getObjectByName(objectName!!) + var temp: HashMap + for (data in obj!!.datas) { + temp = HashMap() + temp[Tools.NAME] = data.name + if (data.mode != AvPhoneObjectData.Mode.None) { + temp[Tools.VALUE] = data.current!!.toString() + } else { + temp[Tools.VALUE] = data.defaults + } + listObject.add(temp) + } + val adapter = RunListViewAdapter(activity, listObject) + objectLstView?.adapter = adapter + objectLstView?.invalidateViews() + } + + override fun onServiceStarted(service: MonitoringService) { + Log.d(TAG, "OnServiceStarted for " + objectName) + toggle_to_start?.visibility = View.GONE + started_since?.visibility = View.VISIBLE + service_log?.visibility = View.VISIBLE + alarm_log?.visibility = View.VISIBLE + viewUpdater?.onStart(service.startedSince, service.lastData, service.lastLog, service.lastAlarmLog, + service.lastRun) + } + + override fun onServiceStopped(service: MonitoringService) { + toggle_to_start?.visibility = View.VISIBLE + started_since?.visibility = View.GONE + service_log?.visibility = View.GONE + alarm_log?.visibility = View.GONE + viewUpdater?.onStop() + } + + override fun onCustomLabelsChanged() { + // The activity can be null if the change is done while the fragment is not active. + // This can wait for the activity to be resumed. + if (activity != null) { + setCustomDataLabels() + } + } + + + // Manage object data for action + + + private fun startTimer() { + // Log.i(TAG, "custom data timer started for " + objectName) + + timer = Timer().schedule(Tools.rand(1000, 5000)) { + execMode() + } + } + + private fun stopTimer() { + // Log.i(TAG, "custom data timer stopped for " + objectName) + if (timer != null) { + timer!!.cancel() + } + } + + private fun execMode() { + val obj = objectsManager.getObjectByName(objectName!!)!! + + // The return code is not used + // As for the default we don't change the value + // We don't need anything is for this the "" + for (data in obj.datas) { + @Suppress("UNUSED_EXPRESSION") + when (data.mode){ + AvPhoneObjectData.Mode.UP -> if (Tools.rand(0, 2000) > 500) data.execMode() + AvPhoneObjectData.Mode.DOWN -> if (Tools.rand(0, 2000) > 1500) data.execMode() + AvPhoneObjectData.Mode.RANDOM -> if (Tools.rand(0, 2000) > 500) data.execMode() + else -> "" + } + + } + objectsManager.saveOnPref() + startTimer() + } + + companion object { + private val TAG = RunFragment::class.simpleName + } +} + diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/SettingsActivity.java b/mainActivity/src/main/java/com/sierrawireless/avphone/SettingsActivity.java deleted file mode 100644 index ed5ba29..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/SettingsActivity.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.sierrawireless.avphone; - -import net.airvantage.utils.PreferenceUtils; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceFragment; - -public class SettingsActivity extends PreferenceActivity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); - } - - public static class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.preferences); - - onSharedPreferenceChanged(getPreferenceScreen().getSharedPreferences(), null); - } - - @Override - public void onResume() { - super.onResume(); - getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); - } - - @Override - public void onPause() { - super.onPause(); - getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - // period - ListPreference periodPref = (ListPreference) findPreference(PreferenceUtils.PREF_PERIOD_KEY); - periodPref.setSummary(periodPref.getEntry()); - } - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/activity/AuthorizationActivity.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/AuthorizationActivity.kt new file mode 100644 index 0000000..21a1642 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/AuthorizationActivity.kt @@ -0,0 +1,170 @@ +package com.sierrawireless.avphone.activity + +import android.annotation.SuppressLint +import android.annotation.TargetApi +import android.app.Activity +import android.content.Intent +import android.graphics.Bitmap +import android.os.Bundle +import android.util.Log +import android.view.View +import android.view.View.OnClickListener +import android.webkit.CookieManager +import android.webkit.WebResourceRequest +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.Button +import android.widget.RadioGroup +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.auth.Authentication +import kotlinx.android.synthetic.main.activity_authorization.* +import net.airvantage.utils.AirVantageClient +import net.airvantage.utils.AuthenticationUrlParser +import net.airvantage.utils.PreferenceUtils +import java.util.* + +class AuthorizationActivity : Activity() { + + private val authUrlParser = AuthenticationUrlParser() + private var currentServer: PreferenceUtils.Server? = null + + + private inner class OnHostClickListener (private val server: PreferenceUtils.Server) : OnClickListener { + + override fun onClick(v: View) { + if (currentServer != server) { + currentServer = server + PreferenceUtils.setServer(server, this@AuthorizationActivity) + openAuthorizationPage() + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_authorization) + + auth_btn_na.setOnClickListener(OnHostClickListener(PreferenceUtils.Server.NA)) + auth_btn_eu.setOnClickListener(OnHostClickListener(PreferenceUtils.Server.EU)) + auth_btn_custom.setOnClickListener(OnHostClickListener(PreferenceUtils.Server.CUSTOM)) + + if (PreferenceUtils.isCustomDefined(this)) { + val parentRadioGroup = auth_btn_custom.parent as RadioGroup + parentRadioGroup.check(auth_btn_custom.id) + } else { + auth_btn_custom.visibility = Button.GONE + } + + openAuthorizationPage() + } + + + @Suppress("DEPRECATION") + @SuppressLint("SetJavaScriptEnabled") + private fun openAuthorizationPage() { + + val avPhonePrefs = PreferenceUtils.getAvPhonePrefs(this) + + when { + avPhonePrefs.usesNA() -> { + auth_btn_na.isChecked = true + auth_btn_custom.isChecked = false + auth_btn_eu.isChecked = false + } + avPhonePrefs.usesEU() -> { + auth_btn_na.isChecked = false + auth_btn_custom.isChecked = false + auth_btn_eu.isChecked = true + } + else -> { + auth_btn_na.isChecked = false + auth_btn_custom.isChecked = true + auth_btn_eu.isChecked = false + } + } + + val serverHost = avPhonePrefs.serverHost + val clientId = avPhonePrefs.clientId + + val webview = findViewById(R.id.authorization_webview) + webview.settings.javaScriptEnabled = true + // attach WebViewClient to intercept the callback url + webview.webViewClient = object : WebViewClient() { + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + showProgressDialog() + super.onPageStarted(view, url, favicon) + } + + override fun onPageFinished(view: WebView?, url: String?) { + hideProgressDialog() + Log.d(TAG, "Loaded " + url.toString() ) + + super.onPageFinished(view, url) + } + + @TargetApi(24) + override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { + Log.d(TAG, "UrlLoading") + val auth = authUrlParser.parseUrl(request.url.toString(), Date()) + + if (auth != null) { + Log.i(TAG, "Access token: " + auth.accessToken!!) + Log.i(TAG, "Expiration date : " + auth.expirationDate!!) + sendAuthentication(auth) + } + return super.shouldOverrideUrlLoading(view, request) + } + + @Suppress("OverridingDeprecatedMember") + override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { + Log.d(TAG, "UrlLoading") + val auth = authUrlParser.parseUrl(url, Date()) + + if (auth != null) { + Log.i(TAG, "Access token: " + auth.accessToken!!) + Log.i(TAG, "Expiration date : " + auth.expirationDate!!) + sendAuthentication(auth) + } + return super.shouldOverrideUrlLoading(view, url) + } + } + val authUrl = AirVantageClient.buildImplicitFlowURL(serverHost!!, clientId!!) + Log.i(TAG, "Auth URL: " + authUrl) + + // The 'authorize' page from AirVantage will store a cookie ; + // if this cookie is passed between calls, the 'authorize' page + // will not be displayed at all. + val cookieManager = CookieManager.getInstance() + cookieManager.removeAllCookies(null) + + // Example : + // https://na.airvantage.net/api/oauth/authorize?client_id=54d4faa5343d49fba03f2a2ec1f210b9&response_type=token&redirect_uri=oauth://airvantage + webview.loadUrl(authUrl) + progressBar.visibility = View.GONE + } + + private fun showProgressDialog() { + progressBar.visibility = View.VISIBLE + } + + private fun hideProgressDialog() { + progressBar.visibility = View.GONE + } + + private fun sendAuthentication(auth: Authentication?) { + val resultIntent = Intent() + + resultIntent.putExtra(AUTHENTICATION_TOKEN, auth!!.accessToken) + resultIntent.putExtra(AUTHENTICATION_EXPIRATION_DATE, auth.expirationDate!!.time) + + setResult(Activity.RESULT_OK, resultIntent) + finish() + } + + companion object { + const val AUTHENTICATION_TOKEN = "token" + const val AUTHENTICATION_EXPIRATION_DATE = "expirationDate" + const val REQUEST_AUTHORIZATION = 1 + private val TAG = AuthorizationActivity::class.simpleName + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/activity/MainActivity.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/MainActivity.kt new file mode 100644 index 0000000..8597a59 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/MainActivity.kt @@ -0,0 +1,858 @@ +package com.sierrawireless.avphone.activity + +import android.Manifest +import android.annotation.SuppressLint +import android.app.ActivityManager +import android.app.AlarmManager +import android.app.Fragment +import android.app.PendingIntent +import android.content.* +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.content.pm.PackageManager +import android.content.res.Configuration +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.IBinder +import android.os.SystemClock +import android.preference.PreferenceManager +import android.support.v4.app.ActivityCompat +import android.support.v4.app.FragmentActivity +import android.support.v4.app.FragmentManager +import android.support.v4.content.ContextCompat +import android.support.v4.widget.DrawerLayout +import android.support.v7.app.ActionBarDrawerToggle +import android.util.Log +import android.view.MenuItem +import android.widget.ListView +import com.crashlytics.android.Crashlytics +import com.crashlytics.android.ndk.CrashlyticsNdk +import com.sierrawireless.avphone.* +import com.sierrawireless.avphone.adapter.MenuAdapter +import com.sierrawireless.avphone.adapter.MenuEntry +import com.sierrawireless.avphone.adapter.MenuEntryType +import com.sierrawireless.avphone.auth.Authentication +import com.sierrawireless.avphone.auth.AuthenticationManager +import com.sierrawireless.avphone.listener.CustomLabelsListener +import com.sierrawireless.avphone.listener.LoginListener +import com.sierrawireless.avphone.listener.MonitorServiceListener +import com.sierrawireless.avphone.service.MonitorServiceManager +import com.sierrawireless.avphone.service.MonitoringService +import com.sierrawireless.avphone.service.MonitoringService.ServiceBinder +import com.sierrawireless.avphone.task.* +import com.sierrawireless.avphone.tools.DeviceInfo +import io.fabric.sdk.android.Fabric +import kotlinx.android.synthetic.main.activity_main.* +import net.airvantage.model.User +import net.airvantage.utils.PreferenceUtils +import org.jetbrains.anko.alert +import org.jetbrains.anko.longToast +import java.util.* + +/** + * The main activity, handling drawer and Fragments + */ +class MainActivity : FragmentActivity(), LoginListener, AuthenticationManager, OnSharedPreferenceChangeListener, MonitorServiceManager, CustomLabelsManager, SyncWithAvListener { + override var monitoringService: MonitoringService? = null + private var objectName: String? = null + internal var startObjectName: String? = null + + private var alarmManager: AlarmManager? = null + private var taskFactory: IAsyncTaskFactory? = null + override var authentication: Authentication? = null + set(value) { + field = value + } + private var prefs: SharedPreferences? = null + + internal var boundToMonitoringService = false + private var monitoringServiceListener: MonitorServiceListener? = null + + private var customLabelsListener: CustomLabelsListener? = null + + private var drawerToggle: ActionBarDrawerToggle? = null + + private var configureFragment: ConfigureFragment? = null + private var homeFragment: HomeFragment? = null + private var runFragment: ArrayList? = null + + internal var lastPosition = 0 + internal var stopped = false + + private var serviceSendData: Boolean? = false + internal lateinit var objectsManager: ObjectsManager + var user: User? = null + private var fragmentsMapping = HashMap() + internal var fragmentsList: ArrayList? = null + + override val isLogged: Boolean + get() = this.authentication != null && !this.authentication!!.isExpired(Date()) + + private var connection: ServiceConnection = object : ServiceConnection { + + override fun onServiceConnected(arg0: ComponentName, binder: IBinder) { + monitoringService = (binder as ServiceBinder).service + + if (monitoringServiceListener != null) { + runOnUiThread { + monitoringServiceListener!!.onServiceStarted(monitoringService!!) + } + } + + } + + override fun onServiceDisconnected(arg0: ComponentName) { + boundToMonitoringService = false + } + } + + val systemUid: String? + get() = prefs!!.getString("systemUid", null) + + var systemSerial: String? + get() = prefs!!.getString(PREFERENCE_SYSTEM_SERIAL, null) + @SuppressLint("DefaultLocale") + set(serial) = prefs!!.edit().putString(PREFERENCE_SYSTEM_SERIAL, serial!!.toUpperCase()).apply() + + val systemName: String? + get() = prefs!!.getString(PREFERENCE_SYSTEM_NAME, null) + + private fun buildFragmentList(): ArrayList { + val tmp = ArrayList() + if (user != null) { + tmp.add(MenuEntry("LOGGED AS", MenuEntryType.TITLE)) + tmp.add(MenuEntry(user!!.name!!, MenuEntryType.USER, drawable = ContextCompat.getDrawable(this, R.drawable.ic_user))) + tmp.add(MenuEntry(user!!.profile!!.name!!, MenuEntryType.USER, drawable = ContextCompat.getDrawable(this, R.drawable.ic_group))) + tmp.add(MenuEntry(user!!.company!!.name!!, MenuEntryType.USER, drawable = ContextCompat.getDrawable(this, R.drawable.ic_departement))) + tmp.add(MenuEntry(user!!.server!!, MenuEntryType.USER, drawable = ContextCompat.getDrawable(this, R.drawable.ic_domain))) + } + tmp.add(MenuEntry("SIMULATED OBJECTS", MenuEntryType.TITLE, button = true)) + objectsManager.objects.mapTo(tmp) { + if (it.name != null) { + MenuEntry(it.name!!, MenuEntryType.COMMAND, drawable = ContextCompat.getDrawable(this, R.drawable.ic_object)) + }else{ + MenuEntry("KO", MenuEntryType.COMMAND, drawable = ContextCompat.getDrawable(this, R.drawable.ic_object)) + } + } + // tmp.add(MenuEntry(FRAGMENT_CONFIGURE, MenuEntryType.COMMAND)) + + //tmp.add(FRAGMENT_SETTINGS); + tmp.add(MenuEntry("NEED HELP", MenuEntryType.TITLE)) + tmp.add(MenuEntry(FRAGMENT_FAQ, MenuEntryType.COMMAND)) + tmp.add(MenuEntry("", MenuEntryType.TITLE)) + tmp.add(MenuEntry(FRAGMENT_SETTINGS, MenuEntryType.COMMAND)) + if (isLogged) { + tmp.add(MenuEntry(FRAGMENT_LOGOUT, MenuEntryType.COMMAND)) + } else { + tmp.add(MenuEntry(FRAGMENT_LOGIN, MenuEntryType.COMMAND)) + } + return tmp + } + + override fun setCustomLabelsListener(listener: CustomLabelsListener) { + this.customLabelsListener = listener + } + + //Get user + private fun syncGetUser(auth: Authentication?) { + + val avPhonePrefs = PreferenceUtils.getAvPhonePrefs(this) + + val getUserTask = taskFactory!!.getUserTak(avPhonePrefs.serverHost!!, auth!!.accessToken!!) + + getUserTask.addProgressListener { result -> + if (!result.isError) { + user = result.user + user!!.server = avPhonePrefs.serverHost + loadMenu(true) + }else{ + if (! stopped ) { + if (result.error!!.errorParameters.size == 1 && result.error!!.errorParameters[0] == "No Connection") { + stopped = true + alert("You don't have any data connection. The application will be stopped", "Alert") { + positiveButton("YES") { + finish() + } + }.show() + }else{ + logout() + } + } + } + } + val params = GetUserParams() + getUserTask.execute(params) + } + + + override fun onCreate(savedInstanceState: Bundle?) { + instance = this + // Initialization og Object Manager + objectsManager = ObjectsManager.getInstance() + objectsManager.init(this) + super.onCreate(savedInstanceState) + Fabric.with(this, Crashlytics(), CrashlyticsNdk()) + + setContentView(R.layout.activity_main) + prefs = PreferenceManager.getDefaultSharedPreferences(this) + prefs!!.registerOnSharedPreferenceChangeListener(this) + + //Auth is set here if exist + readAuthenticationFromPreferences() + + taskFactory = AsyncTaskFactory(this@MainActivity) + if (isLogged) { + if (user == null) { + syncGetUser(authentication) + } + } + + loadMenu(true) + + left_drawer.setOnItemClickListener { _, _, position, _ -> selectItem(position) } + + alarmManager = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager + + drawerToggle = ActionBarDrawerToggle(this, drawer_layout, R.string.drawer_open, + R.string.drawer_close) + drawer_layout!!.addDrawerListener(drawerToggle!!) + + // Verify Permission + + when { + ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED -> { + Log.d(TAG, "Ask for READ PHONE STATE") + ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.READ_PHONE_STATE), 1) + } + ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED -> { + Log.d(TAG, "Ask for COARSE LOCATION STATE") + ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), 2) + } + ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED -> { + Log.d(TAG, "Ask for FINE LOCATION STATE") + ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 3) + } + } + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + when (requestCode) { + 1 -> { + if (grantResults.isNotEmpty()) { + + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { + + Log.w(TAG, "onRequestPermissionsResult: READ_PHONE_STATE answer ko") + longToast("Permission not granted please grant permission") + } else { + Log.d(TAG, " for READ PHONE STATE ok") + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + Log.d(TAG, "Ask for COARSE LOCATION STATE") + ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), 2) + } else if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) { + Log.d(TAG, "Ask for FINE LOCATION STATE") + ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 3) + } + } + } + } + 2 -> { + if (grantResults.isNotEmpty()) { + + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { + + Log.w(TAG, "onRequestPermissionsResult: ACCESS_COARSE_LOCATION answer ko") + longToast("Permission not granted please grant permission") + } else { + Log.d(TAG, " for COARSE LOCATION ok") + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) { + Log.d(TAG, "Ask for FINE LOCATION STATE") + ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 3) + } + } + } + } + 3 -> { + if (grantResults.isNotEmpty()) { + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { + + Log.w(TAG, "onRequestPermissionsResult: answer ACCESS_FINE_LOCATION ko") + longToast("Permission not granted please grant permission") + }else{ + Log.d(TAG, "for FINE LOCATION STATE ok") + } + } + } + else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults) + } + } + + + fun loadMenu(changeFragment:Boolean) { + fragmentsList = buildFragmentList() + + + val adapter = MenuAdapter(this, buildFragmentList()) + + left_drawer.adapter = adapter + + left_drawer.choiceMode = ListView.CHOICE_MODE_SINGLE + // Set the list's click listener + left_drawer.invalidateViews() + + if (isLogged) { + if (user == null) { + syncGetUser(authentication) + } + + unlockDrawer() + if (isServiceRunning()) { + connectToService() + } + initFragments() + if (changeFragment) + goLastFragment() + } else { + lockDrawer() + if (isServiceRunning()) { + // The token is probably expired. + // We stop the service since the "stop" button is not available anymore. + this.stopMonitoringService() + } + initFragments() + if (changeFragment) + goHomeFragment() + } + } + + override fun onResume() { + super.onResume() + left_drawer.requestFocusFromTouch() + left_drawer.setItemChecked(lastPosition, true) + left_drawer.setSelection(lastPosition) + left_drawer.refreshDrawableState() + + } + + override fun onPostCreate(savedInstanceState: Bundle?) { + super.onPostCreate(savedInstanceState) + drawerToggle!!.syncState() + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return (drawerToggle!!.onOptionsItemSelected(item) + // Or just go with defaults + || super.onOptionsItemSelected(item)) + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + drawerToggle!!.onConfigurationChanged(newConfig) + } + + private fun lockDrawer() { + + if (actionBar != null) { + actionBar!!.setDisplayHomeAsUpEnabled(false) + actionBar!!.setHomeButtonEnabled(false) + } + + drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) + + if (drawerToggle != null) { + drawerToggle!!.isDrawerIndicatorEnabled = false + } + } + + private fun unlockDrawer() { + if (actionBar != null) { + actionBar!!.setDisplayHomeAsUpEnabled(true) + actionBar!!.setHomeButtonEnabled(true) + } + + drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) + + if (drawerToggle != null) { + drawerToggle!!.isDrawerIndicatorEnabled = true + } + } + + internal fun readAuthenticationFromPreferences() { + this.authentication = PreferenceUtils.readAuthentication(this) + } + + override fun onAuthentication(auth: Authentication) { + + this.authentication = auth + unlockDrawer() + + saveAuthenticationInPreferences(auth) + } + + private fun saveAuthenticationInPreferences(auth: Authentication) { + PreferenceUtils.saveAuthentication(this, auth) + } + + override fun forgetAuthentication() { + + lockDrawer() + PreferenceUtils.resetAuthentication(this) + this.authentication = null + + if (this.isServiceRunning()) { + this.stopMonitoringService() + } + + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + + if (PreferenceUtils.PREF_SERVER_KEY == key || PreferenceUtils.PREF_CLIENT_ID_KEY == key) { + + this.stopMonitoringService() + this.forgetAuthentication() + + } else if (PreferenceUtils.PREF_PERIOD_KEY == key || PreferenceUtils.PREF_PASSWORD_KEY == key) { + + this.restartMonitoringService() + + } else if (key.contains("pref_data_custom")) { + + if (this.customLabelsListener != null) { + this.customLabelsListener!!.onCustomLabelsChanged() + } + } + } + + override fun isServiceRunning(name: String?): Boolean { + //return serviceSendData; + + val manager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + + @Suppress("DEPRECATION") + return if (name == null) { + if (manager.getRunningServices(Integer.MAX_VALUE).any { MonitoringService::class.java.name == it.service.className }) serviceSendData!! else false + }else{ + if (manager.getRunningServices(Integer.MAX_VALUE).any { MonitoringService::class.java.name == it.service.className }) (serviceSendData!! && startObjectName == name) else false + + } + } + + override fun isServiceStarted(name: String): Boolean { + if (this.objectName == null) { + return false + } + if (this.objectName != name) { + return false + } + //return serviceSendData; + + val manager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + + @Suppress("DEPRECATION") + return manager.getRunningServices(Integer.MAX_VALUE).any { MonitoringService::class.java.name == it.service.className } + } + + override fun oneServiceStarted(): Boolean { + //return serviceSendData; + + val manager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + + @Suppress("DEPRECATION") + return manager.getRunningServices(Integer.MAX_VALUE).any { MonitoringService::class.java.name == it.service.className } + + } + + private fun connectToService() { + val intent = Intent(this, MonitoringService::class.java) + boundToMonitoringService = this.bindService(intent, connection, Context.BIND_AUTO_CREATE) + } + + private fun disconnectFromService() { + if (boundToMonitoringService) { + this.unbindService(connection) + boundToMonitoringService = false + if (monitoringServiceListener != null) { + monitoringServiceListener!!.onServiceStopped(monitoringService!!) + } + } + } + + override fun cancel() { + monitoringService?.cancel() + } + override fun start() { + monitoringService?.start() + } + + override fun sendAlarmEvent(on:Boolean):Boolean { + //if (boundToMonitoringService && monitoringService != null) { + return monitoringService!!.sendAlarmEvent(on) + // } + } + + override fun startMonitoringService(name: String) { + this.objectName = name + val avPrefs = PreferenceUtils.getAvPhonePrefs(this) + + val intent = Intent(this, MonitoringService::class.java) + intent.putExtra(MonitoringService.DEVICE_ID, DeviceInfo.getUniqueId(this)) + intent.putExtra(MonitoringService.SERVER_HOST, avPrefs.serverHost) + intent.putExtra(MonitoringService.PASSWORD, avPrefs.password) + intent.putExtra(MonitoringService.CONNECT, false) + intent.putExtra(MonitoringService.OBJECT_NAME, name) + + val pendingIntent = PendingIntent.getService(this, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT) + // registering our pending intent with alarm manager + alarmManager!!.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, pendingIntent) + + connectToService() + } + + internal fun setAlarm(timer:Int?) { + val avPrefs = PreferenceUtils.getAvPhonePrefs(this) + val intent = Intent(this, MonitoringService::class.java) + Log.d(TAG, "Set intent") + intent.putExtra(MonitoringService.DEVICE_ID, DeviceInfo.getUniqueId(this)) + intent.putExtra(MonitoringService.SERVER_HOST, avPrefs.serverHost) + intent.putExtra(MonitoringService.PASSWORD, avPrefs.password) + intent.putExtra(MonitoringService.CONNECT, true) + val pendingIntent = PendingIntent.getService(this, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT) + // registering our pending intent with alarm manager + + val wait = if (timer == null) { + SystemClock.elapsedRealtime() +(Integer.valueOf(avPrefs.period)!! * 60 * 1000).toLong() + }else { + SystemClock.elapsedRealtime() + 100 + } + alarmManager!!.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, wait, pendingIntent) + } + + override fun startSendData(name: String):Boolean { + if (startObjectName == null || name == startObjectName!!) { + setAlarm(0) + startObjectName = name + serviceSendData = true + }else{ + alert("A run already exist for $startObjectName.", "Alert") { + positiveButton("OK") { + + } + }.show() + return false + } + return true + } + + override fun stopSendData() { + val intent = Intent(this, MonitoringService::class.java) + val pendingIntent = PendingIntent.getService(this, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT) + alarmManager!!.cancel(pendingIntent) + serviceSendData = false + startObjectName = null + } + + override fun stopMonitoringService() { + val intent = Intent(this, MonitoringService::class.java) + val pendingIntent = PendingIntent.getService(this, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT) + alarmManager!!.cancel(pendingIntent) + this.stopService(intent) + + disconnectFromService() + } + + private fun restartMonitoringService() { + if (objectName != null) { + stopMonitoringService() + startMonitoringService(objectName!!) + } + } + + public override fun onDestroy() { + super.onDestroy() + disconnectFromService() + } + + override fun setMonitoringServiceListener(listener: MonitorServiceListener) { + this.monitoringServiceListener = listener + } + + @SuppressLint("DefaultLocale") + override fun invoke(result: SyncWithAvResult) { + + val system = result.system ?: return + prefs!!.edit().putString("systemUid", system.uid).apply() + prefs!!.edit().putString(PREFERENCE_SYSTEM_NAME, system.name).apply() + + val user = result.user + prefs!!.edit().putString(PREFERENCE_USER_UID, user!!.uid).apply() + prefs!!.edit().putString(PREFERENCE_USER_NAME, user.name).apply() + + val deviceSerial = DeviceInfo.generateSerial(user.uid!!) + prefs!!.edit().putString(PREFERENCE_SYSTEM_SERIAL, deviceSerial).apply() + + } + + private fun clearStack() { + //Here we are clearing back stack fragment entries + fragmentManager.popBackStack("HOME", FragmentManager.POP_BACK_STACK_INCLUSIVE) +// val backStackEntry = fragmentManager.backStackEntryCount +// if (backStackEntry > 0) { +// for (i in 0 until backStackEntry) { +// fragmentManager.popBackStackImmediate() +// } +// } + + } + + + override fun onBackPressed() { + if (isLogged) { + super.onBackPressed() + } + } + + /** + * Swaps fragments in the main content view + */ + private fun logout() { + val avPhonePrefs = PreferenceUtils.getAvPhonePrefs(this) + + // Already logout if authentication is null + if (authentication == null) { + return + } + + val accessToken = authentication!!.accessToken + + val logoutTask = taskFactory!!.logoutTask(avPhonePrefs.serverHost!!, accessToken!!) + + logoutTask.execute() + try { + logoutTask.get() + } catch (e: Exception) { + Log.w(TAG, "Exception while logging out") + Crashlytics.logException(e) + } finally { + forgetAuthentication() + + clearStack() + //fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) + + // In this case we have no menu + loadMenu(true) + + } + } + + private fun selectItem(position: Int) { + + val fragment = getFragment(position) + val entry = fragmentsList!![position] + if (fragment == null) { + //No item check if the position is valid + if (entry.name == FRAGMENT_FAQ) { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://source.sierrawireless.com/airvantage/av/avphone_faq/")) + startActivity(browserIntent) + left_drawer.setSelection(lastPosition) + drawer_layout.closeDrawer(left_drawer) + } + return + } + if (entry.name == FRAGMENT_LOGOUT) { + + alert("Are you sure ?","Logout") { + positiveButton("YES") { + logout() + } + negativeButton("NO") { + drawer_layout.closeDrawer(left_drawer) + + } + }.show() + return + } + if (entry.type == MenuEntryType.COMMAND) { + // We have not selected this fragment now do it + if (lastPosition != position) { + // Insert the fragment by replacing any existing fragment + fragmentManager + .beginTransaction() + .replace(R.id.content_frame, fragment) + .addToBackStack(null) + .commit() + // Highlight the selected item, update the title, and close the drawer + left_drawer.setItemChecked(position, true) + title = entry.name + left_drawer.setSelection(position) + lastPosition = position + left_drawer.invalidateViews() + } + drawer_layout.closeDrawer(left_drawer) + } + } + + private fun goHomeFragment() { + val fragment = if (fragmentsMapping.containsKey(FRAGMENT_LOGIN)) fragmentsMapping[FRAGMENT_LOGIN] else null + goFragment(fragment!!, FRAGMENT_LOGIN) + } + + + fun goLastFragment() { + var fragmentName = objectsManager.objects[objectsManager.current].name + var fragment = if (fragmentsMapping.containsKey(fragmentName)) fragmentsMapping[fragmentName] else null + if (fragment == null) { + fragmentName = objectsManager.objects[0].name + fragment = if (fragmentsMapping.containsKey(fragmentName)) fragmentsMapping[fragmentName] else null + } + + goFragment(fragment!!, fragmentName!!) + } + + private fun goFragment(fragment:Fragment, fragmentName:String) { + + var position:Int? = 0 + for ((current, entry) in fragmentsList!!.withIndex()) { + if (entry.name == fragmentName) { + position = current + } + } + + // Insert the fragment by replacing any existing fragment + try { + + val backStackEntry = fragmentManager.backStackEntryCount + + if (backStackEntry == 0) { + val homeFragment = fragmentsMapping[FRAGMENT_LOGIN] + if (homeFragment != null) { + Handler().post({ + fragmentManager + .beginTransaction() + .add(R.id.content_frame, homeFragment) + .addToBackStack("HOME") + .commitAllowingStateLoss() + }) + } + } + + Handler().post({ + fragmentManager + .beginTransaction() + .replace(R.id.content_frame, fragment) + .addToBackStack(null) + .commitAllowingStateLoss() + }) + // Highlight the selected item, update the title, and close the drawer + left_drawer.setItemChecked(position!!, true) + title = fragmentsList!![position].name + left_drawer.setSelection(position) + drawer_layout.closeDrawer(left_drawer) + lastPosition = position + }catch(e:IllegalStateException){ + Log.e(TAG, "GO last fragment CATCH************************", e) + } + } + + + fun goConfigureFragment() { + val fragment = fragmentsMapping[FRAGMENT_CONFIGURE] + // Insert the fragment by replacing any existing fragment + fragmentManager + .beginTransaction() + .replace(R.id.content_frame, fragment) + .addToBackStack(null) + .commit() + var position:Int? = null + fragmentsList!!.forEachIndexed { + index, menuEntry -> if (menuEntry.name == FRAGMENT_CONFIGURE) { + position = index + } + } + + if (position != null) { + // Highlight the selected item, update the title, and close the drawer + left_drawer.setItemChecked(position!!, true) + left_drawer.setItemChecked(position!!, true) + title = fragmentsList!![position!!].name + left_drawer.setSelection(position!!) + lastPosition = position!! + } + drawer_layout.closeDrawer(left_drawer) + + + } + + private fun initFragments(): Map { + + if (configureFragment == null) { + configureFragment = ConfigureFragment() + configureFragment!!.setTaskFactory(taskFactory!!) + configureFragment!!.syncListener = this + } + + if (homeFragment == null) { + homeFragment = HomeFragment() + homeFragment!!.setTaskFactory(taskFactory!!) + } + + runFragment = ArrayList() + + var tmp: RunFragment + for (obj in objectsManager.objects) { + tmp = RunFragment() + tmp.setTaskFactory(taskFactory!!) + if (obj.name != null) { + tmp.setObjectName(obj.name!!) + runFragment!!.add(tmp) + } + } + + + fragmentsMapping = HashMap() + fragmentsMapping[FRAGMENT_CONFIGURE] = configureFragment!! + if (isLogged) { + fragmentsMapping[FRAGMENT_LOGOUT] = homeFragment!! + } else { + fragmentsMapping[FRAGMENT_LOGIN] = homeFragment!! + } + fragmentsMapping[FRAGMENT_SETTINGS] = SettingsActivity.SettingsFragment() + for ((pos, obj) in objectsManager.objects.withIndex()) { + fragmentsMapping[obj.name!!] = runFragment!![pos] + } + + return fragmentsMapping + } + + private fun getFragment(fragmentPosition: Int): Fragment? { + val fragmentName = fragmentsList!![fragmentPosition].name + val fragmentMap = initFragments() + return if (fragmentMap.containsKey(fragmentName)) fragmentMap[fragmentName] else null + } + + companion object { + private const val PREFERENCE_SYSTEM_NAME = "systemName" + private const val PREFERENCE_SYSTEM_SERIAL = "systemSerial" + private const val PREFERENCE_USER_NAME = "userName" + private const val PREFERENCE_USER_UID = "userUid" + + private const val FRAGMENT_LOGOUT = "Logout" + + private const val FRAGMENT_LOGIN = "Login" + private const val FRAGMENT_CONFIGURE = "Add/Modify/Delete" + private const val FRAGMENT_SETTINGS = "Settings" + private const val FRAGMENT_FAQ = "FAQ" + + + + @SuppressLint("StaticFieldLeak") + internal lateinit var instance: MainActivity + + private val TAG = MainActivity::class.simpleName + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/activity/ObjectConfigureActivity.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/ObjectConfigureActivity.kt new file mode 100644 index 0000000..3ae8a9a --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/ObjectConfigureActivity.kt @@ -0,0 +1,153 @@ +package com.sierrawireless.avphone.activity + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.widget.AdapterView +import com.sierrawireless.avphone.ConfigureFragment +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.adapter.ObjectDataAdapter +import com.sierrawireless.avphone.model.AvPhoneObject +import kotlinx.android.synthetic.main.activity_object_configure.* +import org.jetbrains.anko.alert +import java.util.* + +class ObjectConfigureActivity : Activity() { + internal var objectsManager: ObjectsManager = ObjectsManager.getInstance() + private var menu: ArrayList = ArrayList() + private var position: Int = 0 + private var add = false + internal var obj: AvPhoneObject? = null + + private var context: Context? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_object_configure) + instance = this + + objectsManager = ObjectsManager.getInstance() + + context = this + + + + + + val intent = intent + position = intent.getIntExtra(ConfigureFragment.INDEX, -1) + add = position == -1 + + cancel.setOnClickListener { + cancel() + } + + save.setOnClickListener { + if (objectNameEdit.visibility != View.GONE || add) { + obj!!.name = objectNameEdit.text.toString() + } + if (obj!!.name!!.isEmpty()) { + // open an alert to force to define the nane before to add value + alert(getString(R.string.objectSaveConfigure), getString(R.string.alert)) { + positiveButton("OK") { + } + }.show() + }else { + obj!!.datas + .filter { it.isInteger } + .forEach { it.current = it.defaults.toInt() } + + objectsManager.save() + val i = Intent() + i.putExtra(ConfigureFragment.POS, position) + setResult(Activity.RESULT_OK, i) + finish() + } + } + + + listView.onItemClickListener = AdapterView.OnItemClickListener { _, view, i, _ -> + if (add) + obj!!.name = objectNameEdit.text.toString() + if (obj!!.name!!.isEmpty()) { + // open an alert to force to define the nane before to add value + alert(getString(R.string.nameBeforeAddObjectConfigure), getString(R.string.alert)) { + positiveButton("OK") { + } + }.show() + } else { + val lIntent = Intent(view.context, ObjectDataActivity::class.java) + lIntent.putExtra(OBJECT_POSITION, position) + lIntent.putExtra(OBJECT_NAME, obj!!.name) + lIntent.putExtra(DATA_POSITION, i) + if (i == menu.size - 1) { + lIntent.putExtra(ADD, true) + } else { + lIntent.putExtra(ADD, false) + } + startActivity(lIntent) + } + } + + } + + private fun cancel() { + //reload object from list + objectsManager.reload() + val i = Intent() + setResult(Activity.RESULT_CANCELED, i) + finish() + } + + override fun onBackPressed() = cancel() + + + override fun onDestroy() { + super.onDestroy() + instance = null + } + + override fun onResume() { + super.onResume() + if (position == -1) { + obj = AvPhoneObject() + obj!!.name = "" + titleObject.setText(R.string.add_new_object) + objectsManager.objects.add(obj!!) + position = objectsManager.objects.size - 1 + } else { + obj = objectsManager.getObjectByIndex(position) + if (!add) { + nameObject.visibility = View.GONE + objectNameEdit.visibility = View.GONE + } + titleObject.text = obj!!.name + } + menuGeneration() + } + + fun menuGeneration() { + menu = ArrayList() + for (data in obj!!.datas) { + menu.add(data.name) + } + menu.add(getString(R.string.add_new_data)) + val adapter = ObjectDataAdapter(this, R.layout.menu_objects, menu) + + listView.adapter = adapter + listView.invalidateViews() + } + + companion object { + var OBJECT_POSITION = "object_pos" + var DATA_POSITION = "data_position" + var OBJECT_NAME = "name" + var ADD = "add" + @SuppressLint("StaticFieldLeak") + var instance:ObjectConfigureActivity? = null + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/activity/ObjectDataActivity.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/ObjectDataActivity.kt new file mode 100644 index 0000000..20afda3 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/ObjectDataActivity.kt @@ -0,0 +1,172 @@ +package com.sierrawireless.avphone.activity + +import android.app.Activity +import android.os.Bundle +import android.text.TextUtils +import android.view.View +import android.widget.AdapterView +import android.widget.ArrayAdapter +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.model.AvPhoneObject +import com.sierrawireless.avphone.model.AvPhoneObjectData +import com.sierrawireless.avphone.tools.Tools +import kotlinx.android.synthetic.main.activity_object_data.* +import org.jetbrains.anko.alert + +class ObjectDataActivity : Activity(), AdapterView.OnItemSelectedListener { + + internal var objectsManager: ObjectsManager = ObjectsManager.getInstance() + private var obj: AvPhoneObject? = null + internal var data: AvPhoneObjectData? = null + private var objectPosition: Int = 0 + private var dataPosition: Int = 0 + private lateinit var objname: String + internal var add: Boolean = false + + override fun onCreate(savedInstanceState: Bundle?) { + val menuList = arrayOf("None", "Increase indefinitely", "Decrease to zero", "Random") + + + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_object_data) + val intent = intent + objectPosition = intent.getIntExtra(ObjectConfigureActivity.OBJECT_POSITION, -1) + dataPosition = intent.getIntExtra(ObjectConfigureActivity.DATA_POSITION, -1) + add = intent.getBooleanExtra(ObjectConfigureActivity.ADD, true) + objname = intent.getStringExtra(ObjectConfigureActivity.OBJECT_NAME) + + if (objectPosition == -1 || dataPosition == -1) { + return + } + + + objectsManager = ObjectsManager.getInstance() + obj = objectsManager.getObjectByIndex(objectPosition) + + // Create an ArrayAdapter using the string array and a default spinner layout + val adapter = ArrayAdapter(this, + android.R.layout.simple_spinner_item, menuList) + // Specify the layout to use when the list of choices appears + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + // Apply the adapter to the spinner + + spinner.adapter = adapter + spinner.onItemSelectedListener = this + + if (!add) { + name.visibility = View.INVISIBLE + nameText.visibility = View.GONE + data = obj!!.datas[dataPosition] + titleMenu.text = data!!.name + unitText.setText(data!!.unit) + defaultText.setText(data!!.defaults) + spinner.setSelection(data!!.modePosition(), false) + if (data!!.path != null) { + path.setText(data!!.path) + }else{ + path.setText(Tools.buildDefaultPath(objname, dataPosition)) + // path.setText("default") + } + } else { + titleMenu.setText(R.string.add_new_data) + path.setText(Tools.buildDefaultPath(objname, dataPosition)) + } + + cancelData.setOnClickListener { finish() } + + saveData.setOnClickListener { + val mode = AvPhoneObjectData.modeFromPosition(spinner.selectedItemPosition) + if (add) { + if (!validateEntry()) return@setOnClickListener + data = if (!path.text.isEmpty() && path.text.toString() == "default") { + AvPhoneObjectData( + nameText.text.toString(), + unitText.text.toString(), + defaultText.text.toString(), + mode, "1", null) + }else { + AvPhoneObjectData( + nameText.text.toString(), + unitText.text.toString(), + defaultText.text.toString(), + mode, "1", + path.text.toString()) + } + obj!!.datas.add(data!!) + } else { + if (!validateEntry()) return@setOnClickListener + data!!.unit = unitText.text.toString() + data!!.defaults = defaultText.text.toString() + data!!.mode = mode + if (!path.text.isEmpty() && path.text.toString() != "default") { + data!!.path = path.text.toString() + }else{ + data!!.path = null + } + } + + finish() + } + + } + + private fun validateEntry():Boolean { + val mode = AvPhoneObjectData.modeFromPosition(spinner.selectedItemPosition) + if (add) { + if (nameText.text.toString().isEmpty()) { + alert(getString(R.string.nameOnbjectDataEmpty), getString(R.string.alert)) { + positiveButton("OK") { + } + }.show() + return false + } + } + if (mode == AvPhoneObjectData.Mode.RANDOM) { + // Is this case we must verify the default entry + val defaults = defaultText.text.toString().split(",") + if (defaults.size != 2) { + alert(getString(R.string.InvalidRandomDefaultComma), getString(R.string.alert)) { + positiveButton("OK") { + } + }.show() + return false + } + if ((!(!defaults[0].isEmpty() && TextUtils.isDigitsOnly(defaults[0]))) or + (!(!defaults[1].isEmpty() && TextUtils.isDigitsOnly(defaults[1])))) { + alert( + getString(R.string.MinMaxRandomDataObject), + getString(R.string.alert) + ) { + positiveButton("OK") { + } + }.show() + return false + } + } + if (mode == AvPhoneObjectData.Mode.DOWN || mode == AvPhoneObjectData.Mode.UP) { + // check the default value must be a number + if (!(!defaultText.text.toString().isEmpty() && TextUtils.isDigitsOnly(defaultText.text.toString()))) { + alert(getString(R.string.InvalidDefaultUpDown), getString(R.string.alert)) { + positiveButton("OK") { + } + }.show() + return false + } + } + return true + } + + override fun onBackPressed() = finish() + + override fun onItemSelected(parent: AdapterView<*>, view: View, + pos: Int, id: Long) { + // An item was selected. You can retrieve the selected item using + // parent.getItemAtPosition(pos) + } + + override fun onNothingSelected(parent: AdapterView<*>) { + // Another interface callback + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/activity/SettingsActivity.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/SettingsActivity.kt new file mode 100644 index 0000000..d5012e5 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/SettingsActivity.kt @@ -0,0 +1,46 @@ +package com.sierrawireless.avphone.activity + +import net.airvantage.utils.PreferenceUtils +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.os.Bundle +import android.preference.ListPreference +import android.preference.PreferenceActivity +import android.preference.PreferenceFragment +import com.sierrawireless.avphone.R + +class SettingsActivity : PreferenceActivity() { + + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + fragmentManager.beginTransaction().replace(android.R.id.content, SettingsFragment()).commit() + } + + class SettingsFragment : PreferenceFragment(), OnSharedPreferenceChangeListener { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.preferences) + + onSharedPreferenceChanged(preferenceScreen.sharedPreferences, null) + } + + override fun onResume() { + super.onResume() + preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + } + + override fun onPause() { + super.onPause() + preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) { + // period + val periodPref = findPreference(PreferenceUtils.PREF_PERIOD_KEY) as ListPreference + periodPref.summary = periodPref.entry + } + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/TestFragmentActivity.java b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/TestFragmentActivity.java similarity index 76% rename from mainActivity/src/main/java/com/sierrawireless/avphone/TestFragmentActivity.java rename to mainActivity/src/main/java/com/sierrawireless/avphone/activity/TestFragmentActivity.java index 85e74f5..7082983 100644 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/TestFragmentActivity.java +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/activity/TestFragmentActivity.java @@ -1,8 +1,10 @@ -package com.sierrawireless.avphone; +package com.sierrawireless.avphone.activity; import android.os.Bundle; import android.support.v4.app.FragmentActivity; +import com.sierrawireless.avphone.R; + public class TestFragmentActivity extends FragmentActivity { @Override protected void onCreate(Bundle arg0) { diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/MenuAdapter.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/MenuAdapter.kt new file mode 100644 index 0000000..8e8dac5 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/MenuAdapter.kt @@ -0,0 +1,88 @@ +package com.sierrawireless.avphone.adapter + +import android.app.Activity +import android.graphics.Color +import android.graphics.Typeface +import android.support.v4.content.ContextCompat +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.Button +import android.widget.TextView +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.activity.MainActivity +import java.util.* + +class MenuAdapter internal constructor(private val activity: Activity, var list: ArrayList) : BaseAdapter() { + val objectsManager:ObjectsManager? = ObjectsManager.getInstance() + + override fun getCount(): Int { + return list.size + } + + override fun getItem(position: Int): Any { + return list[position] + } + + override fun getItemId(position: Int): Long { + return 0 + } + + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val lConvertView: View? + + + val inflater = activity.layoutInflater + + + val name: TextView + lConvertView = convertView ?: inflater.inflate(R.layout.menu_layout, parent, false) + val entry = list[position] + if (entry.type == MenuEntryType.TITLE) { + name = lConvertView!!.findViewById(R.id.text1) + name.text = entry.name + name.setTypeface(name.typeface, Typeface.BOLD) + name.setBackgroundColor(ContextCompat.getColor(lConvertView.context, R.color.navy)) + name.setTextColor(Color.WHITE) + // name.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(lConvertView.context, android.R.drawable.ic_lock_silent_mode), null, null, null) + + } else { + name = lConvertView!!.findViewById(R.id.text1) + name.text = entry.name + if (MainActivity.instance.lastPosition != 0 && position != list.size - 1 && position == MainActivity.instance.lastPosition) { + name.setBackgroundColor(Color.LTGRAY) + }else { + if (entry.type == MenuEntryType.COMMAND) { + name.setBackgroundColor(Color.WHITE) + }else{ + name.setTypeface(null, Typeface.ITALIC) + name.setBackgroundColor(ContextCompat.getColor(lConvertView.context, R.color.turquoise)) + } + } + name.setTextColor(ContextCompat.getColor(lConvertView.context, R.color.navy)) + if (entry.type == MenuEntryType.USER) { + name.setTypeface(null, Typeface.ITALIC) + } + } + if (entry.drawable != null) { + name.setCompoundDrawablesWithIntrinsicBounds(entry.drawable, null, null, null) + } + val menuButton:Button = lConvertView.findViewById(R.id.menu_button) + + menuButton.visibility = if (entry.button) { + View.VISIBLE + }else{ + View.GONE + } + if (entry.button) { + menuButton.setOnClickListener { + MainActivity.instance.goConfigureFragment() + } + } + + return lConvertView + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/MenuEntry.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/MenuEntry.kt new file mode 100644 index 0000000..ac7456b --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/MenuEntry.kt @@ -0,0 +1,11 @@ +package com.sierrawireless.avphone.adapter + +import android.graphics.drawable.Drawable + +internal enum class MenuEntryType { + TITLE, + USER, + COMMAND +} + +class MenuEntry internal constructor(var name: String, var type: MenuEntryType, var drawable:Drawable? = null, var button:Boolean = false) diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/ObjectAdapter.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/ObjectAdapter.kt new file mode 100644 index 0000000..1f8397b --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/ObjectAdapter.kt @@ -0,0 +1,70 @@ +package com.sierrawireless.avphone.adapter + +import android.app.Activity +import android.view.View +import android.view.ViewGroup +import android.widget.* +import com.sierrawireless.avphone.ConfigureFragment +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import java.util.* + + +class ObjectAdapter(private val activity: Activity, private val resource: Int, var list: ArrayList) : BaseAdapter() { + private var name: TextView? = null + + private val objectsManager: ObjectsManager = ObjectsManager.getInstance() + + override fun getCount(): Int { + return list.size + } + + override fun getItem(position: Int): Any { + return list[position] + } + + override fun getItemId(position: Int): Long { + return 0 + } + + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + var lConvertView = convertView + + + val inflater = activity.layoutInflater + + if (convertView == null) { + + lConvertView = inflater.inflate(resource, null) + + name = lConvertView!!.findViewById(R.id.text) + } + val deleteBtn:ImageButton = lConvertView!!.findViewById(R.id.menuDeleteBtn) + val deleteActionBtn: Button = lConvertView.findViewById(R.id.menuDeleteActionBtn) + deleteActionBtn.tag = position + deleteBtn.setOnClickListener { + deleteBtn.visibility = View.GONE + deleteActionBtn.visibility = View.VISIBLE + deleteActionBtn.setOnClickListener{ + val objectsManager = ObjectsManager.getInstance() + val lPosition = it.tag as Int + //delete + objectsManager.setSavedPosition(lPosition) + ConfigureFragment.instance!!.delete() + ConfigureFragment.instance!!.delete = ConfigureFragment.Mode.DELETE + + } + } + + if (position == objectsManager.current) { + deleteBtn.visibility = View.GONE + } else { + deleteBtn.visibility = View.VISIBLE + } + name!!.text = list[position] + + return lConvertView + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/ObjectDataAdapter.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/ObjectDataAdapter.kt new file mode 100644 index 0000000..feeeff0 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/ObjectDataAdapter.kt @@ -0,0 +1,84 @@ +package com.sierrawireless.avphone.adapter + +import android.app.Activity +import android.support.v4.content.ContextCompat +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.Button +import android.widget.ImageButton +import android.widget.TextView +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.activity.ObjectConfigureActivity +import java.util.* + + +class ObjectDataAdapter(private val activity: Activity, private val resource: Int, var list: ArrayList) : BaseAdapter() { + private var name: TextView? = null + + override fun getCount(): Int { + return list.size + } + + override fun getItem(position: Int): Any { + return list[position] + } + + override fun getItemId(position: Int): Long { + return 0 + } + + override fun getViewTypeCount(): Int { + // menu type count + return 2 + } + + override fun getItemViewType(position: Int): Int { + // current menu type + // The last item must not be deleted + return if (position == list.size - 1) { + 1 + } else { + 0 + } + } + + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + var lConvertView = convertView + + + val inflater = activity.layoutInflater + + if (convertView == null) { + + lConvertView = inflater.inflate(resource, null) + + name = lConvertView!!.findViewById(R.id.text) + } + + val deleteBtn: ImageButton = lConvertView!!.findViewById(R.id.menuDeleteBtn) + + if (position == list.size - 1) { + deleteBtn.visibility = View.GONE + name!!.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(lConvertView.context, R.drawable.ic_add_data),null) + }else { + @Suppress("NAME_SHADOWING") + val deleteBtn: ImageButton = lConvertView.findViewById(R.id.menuDeleteBtn) + val deleteActionBtn: Button = lConvertView.findViewById(R.id.menuDeleteActionBtn) + deleteActionBtn.tag = position + deleteBtn.setOnClickListener { + deleteBtn.visibility = View.GONE + deleteActionBtn.visibility = View.VISIBLE + deleteActionBtn.setOnClickListener { + ObjectConfigureActivity.instance!!.obj!!.datas.removeAt(position) + ObjectConfigureActivity.instance!!.menuGeneration() + } + } + } + + name!!.text = list[position] + + return lConvertView + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/RunListViewAdapter.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/RunListViewAdapter.kt new file mode 100644 index 0000000..7a6caf4 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/adapter/RunListViewAdapter.kt @@ -0,0 +1,48 @@ +package com.sierrawireless.avphone.adapter + +import android.app.Activity +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.TextView +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.tools.Tools +import java.util.* + +class RunListViewAdapter(private val activity: Activity, var list: ArrayList>) : BaseAdapter() { + private var name: TextView? = null + private var value: TextView? = null + + override fun getCount(): Int { + return list.size + } + + override fun getItem(position: Int): Any { + return list[position] + } + + override fun getItemId(position: Int): Long { + return 0 + } + + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + var lConvertView = convertView + + val inflater = activity.layoutInflater + + if (convertView == null) { + + lConvertView = inflater.inflate(R.layout.run_column_row, parent, false) + + name = lConvertView!!.findViewById(R.id.name) + value = lConvertView.findViewById(R.id.value) + } + + val map = list[position] + name!!.text = map[Tools.NAME] + value!!.text = map[Tools.VALUE] + + return lConvertView!! + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthUtils.java b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthUtils.java deleted file mode 100644 index 396df51..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthUtils.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sierrawireless.avphone.auth; - -import java.util.Date; - -import com.sierrawireless.avphone.AuthorizationActivity; - -import android.app.Activity; -import android.content.Intent; - -public class AuthUtils { - - public static Authentication activityResultAsAuthentication(int requestCode, int resultCode, Intent data) { - Authentication res = null; - switch (requestCode) { - case (AuthorizationActivity.REQUEST_AUTHORIZATION): { - if (resultCode == Activity.RESULT_OK) { - String accessToken = data.getStringExtra(AuthorizationActivity.AUTHENTICATION_TOKEN); - long expiresAtMs = data.getLongExtra(AuthorizationActivity.AUTHENTICATION_EXPIRATION_DATE, 0); - res = new Authentication(); - res.setAccessToken(accessToken); - res.setExpirationDate(new Date(expiresAtMs)); - } - break; - } - } - return res; - } - - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthUtils.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthUtils.kt new file mode 100644 index 0000000..c4d440d --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthUtils.kt @@ -0,0 +1,29 @@ +package com.sierrawireless.avphone.auth + +import java.util.Date + +import com.sierrawireless.avphone.activity.AuthorizationActivity + +import android.app.Activity +import android.content.Intent + +object AuthUtils { + + fun activityResultAsAuthentication(requestCode: Int, resultCode: Int, data: Intent): Authentication? { + var res: Authentication? = null + when (requestCode) { + AuthorizationActivity.REQUEST_AUTHORIZATION -> { + if (resultCode == Activity.RESULT_OK) { + val accessToken = data.getStringExtra(AuthorizationActivity.AUTHENTICATION_TOKEN) + val expiresAtMs = data.getLongExtra(AuthorizationActivity.AUTHENTICATION_EXPIRATION_DATE, 0) + res = Authentication() + res.accessToken = accessToken + res.expirationDate = Date(expiresAtMs) + } + } + } + return res + } + + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/Authentication.java b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/Authentication.java deleted file mode 100644 index 81b3a00..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/Authentication.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sierrawireless.avphone.auth; - -import java.util.Date; - -public class Authentication { - public String code; - private String accessToken; - public String refreshToken; - private Date expirationDate; - - public String getAccessToken() { - return accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public boolean isExpired(Date date) { - return date.after(this.expirationDate); - } - - public boolean isExpired() { - return isExpired(new Date()); - } - - public Date getExpirationDate() { - return this.expirationDate; - } - - public void setExpirationDate(Date date) { - this.expirationDate = date; - } -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/Authentication.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/Authentication.kt new file mode 100644 index 0000000..db19f43 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/Authentication.kt @@ -0,0 +1,15 @@ +package com.sierrawireless.avphone.auth + +import java.util.Date + +class Authentication { + var accessToken: String? = null + var expirationDate: Date? = null + + val isExpired: Boolean + get() = isExpired(Date()) + + fun isExpired(date: Date): Boolean { + return date.after(this.expirationDate) + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthenticationManager.java b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthenticationManager.java deleted file mode 100644 index ed6167b..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthenticationManager.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sierrawireless.avphone.auth; - -public interface AuthenticationManager { - public void onAuthentication(Authentication auth); - public void forgetAuthentication(); - public boolean isLogged(); - public Authentication getAuthentication(); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthenticationManager.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthenticationManager.kt new file mode 100644 index 0000000..88fc6ab --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/auth/AuthenticationManager.kt @@ -0,0 +1,8 @@ +package com.sierrawireless.avphone.auth + +interface AuthenticationManager { + val isLogged: Boolean + var authentication: Authentication? + fun onAuthentication(auth: Authentication) + fun forgetAuthentication() +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/listener/CustomLabelsListener.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/listener/CustomLabelsListener.kt new file mode 100644 index 0000000..58138c0 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/listener/CustomLabelsListener.kt @@ -0,0 +1,5 @@ +package com.sierrawireless.avphone.listener + +interface CustomLabelsListener { + fun onCustomLabelsChanged() +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/listener/LoginListener.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/listener/LoginListener.kt new file mode 100644 index 0000000..df85c5c --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/listener/LoginListener.kt @@ -0,0 +1,3 @@ +package com.sierrawireless.avphone.listener + +internal interface LoginListener diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/listener/MonitorServiceListener.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/listener/MonitorServiceListener.kt new file mode 100644 index 0000000..d5e34d1 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/listener/MonitorServiceListener.kt @@ -0,0 +1,10 @@ +package com.sierrawireless.avphone.listener + +import com.sierrawireless.avphone.service.MonitoringService + +interface MonitorServiceListener { + + fun onServiceStarted(service: MonitoringService) + + fun onServiceStopped(service: MonitoringService) +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/message/IMessageDisplayer.java b/mainActivity/src/main/java/com/sierrawireless/avphone/message/IMessageDisplayer.java deleted file mode 100644 index 17f2f94..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/message/IMessageDisplayer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sierrawireless.avphone.message; - -import android.text.Spanned; - -/** - * Generic interface for anything that can display success / error messages. - */ -public interface IMessageDisplayer { - - public void showError(int id, Object... params); - - public void showSuccess(int id, Object... params); - - public void showErrorMessage(Spanned spanned); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/message/IMessageDisplayer.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/message/IMessageDisplayer.kt new file mode 100644 index 0000000..3a31618 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/message/IMessageDisplayer.kt @@ -0,0 +1,17 @@ +package com.sierrawireless.avphone.message + +import android.text.Spanned + +/** + * Generic interface for anything that can display success / error messages. + */ +interface IMessageDisplayer { + + fun showError(id: Int, vararg params: Any) + + fun showSuccess(id: Int, vararg params: Any) + + fun showSuccess(name:String, vararg params: Any) + + fun showErrorMessage(spanned: Spanned) +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AutoResizeTextView.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AutoResizeTextView.kt new file mode 100644 index 0000000..7fe304b --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AutoResizeTextView.kt @@ -0,0 +1,276 @@ +package com.sierrawireless.avphone.model + +import android.annotation.TargetApi +import android.content.Context +import android.content.res.Resources +import android.graphics.RectF +import android.os.Build +import android.text.Layout.Alignment +import android.text.StaticLayout +import android.text.TextPaint +import android.util.AttributeSet +import android.util.Log +import android.util.SparseIntArray +import android.util.TypedValue +import android.widget.TextView + +class AutoResizeTextView : TextView { + private val mTextRect = RectF() + private var mAvailableSpaceRect: RectF? = null + private var mTextCachedSizes: SparseIntArray? = null + private var mPaint: TextPaint? = null + private var mMaxTextSize: Float = 0.toFloat() + private var mSpacingMult = 1.0f + private var mSpacingAdd = 0.0f + private var mMinTextSize = 20f + private var mWidthLimit: Int = 0 + private var mMaxLines: Int = 0 + private var mEnableSizeCache = true + private var mInitialized: Boolean = false + private val mSizeTester = object : SizeTester { + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + override fun onTestSize(suggestedSize: Int, availableSpace: RectF): Int { + mPaint!!.textSize = suggestedSize.toFloat() + val text = text.toString() + val singleline = maxLines == 1 + if (singleline) { + mTextRect.bottom = mPaint!!.fontSpacing + mTextRect.right = mPaint!!.measureText(text) + } else { + val layout = StaticLayout(text, mPaint, + mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult, + mSpacingAdd, true) + // return early if we have more lines + if (maxLines != NO_LINE_LIMIT && layout.lineCount > maxLines) { + return 1 + } + mTextRect.bottom = layout.height.toFloat() + var maxWidth = -1 + (0 until layout.lineCount) + .asSequence() + .filter { maxWidth < layout.getLineWidth(it) } + .forEach { maxWidth = layout.getLineWidth(it).toInt() } + mTextRect.right = maxWidth.toFloat() + } + + mTextRect.offsetTo(0f, 0f) + return if (availableSpace.contains(mTextRect)) { + // may be too small, don't worry we will find the best match + -1 + } else { + // too big + 1 + } + } + } + + private interface SizeTester { + /** + * + * @param suggestedSize + * Size of text to be tested + * @param availableSpace + * available space in which text must fit + * @return an integer < 0 if after applying `suggestedSize` to + * text, it takes less space than `availableSpace`, > 0 + * otherwise + */ + fun onTestSize(suggestedSize: Int, availableSpace: RectF): Int + } + + constructor(context: Context) : super(context) { + initialize() + } + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + initialize() + } + + constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { + initialize() + } + + private fun initialize() { + mPaint = TextPaint(paint) + mMaxTextSize = textSize + mAvailableSpaceRect = RectF() + mTextCachedSizes = SparseIntArray() + if (mMaxLines == 0) { + // no value was assigned during construction + mMaxLines = NO_LINE_LIMIT + } + mInitialized = true + } + + override fun setText(text: CharSequence?, type: TextView.BufferType) { + super.setText(text, type) + if (text != null) { + adjustTextSize() + } + } + + override fun setTextSize(size: Float) { + mMaxTextSize = size + mTextCachedSizes!!.clear() + adjustTextSize() + } + + override fun setMaxLines(maxlines: Int) { + super.setMaxLines(maxlines) + mMaxLines = maxlines + reAdjust() + } + + override fun getMaxLines(): Int { + return mMaxLines + } + + override fun setSingleLine() { + super.setSingleLine() + mMaxLines = 1 + reAdjust() + } + + override fun setSingleLine(singleLine: Boolean) { + super.setSingleLine(singleLine) + mMaxLines = if (singleLine) { + 1 + } else { + NO_LINE_LIMIT + } + reAdjust() + } + + override fun setLines(lines: Int) { + super.setLines(lines) + mMaxLines = lines + reAdjust() + } + + override fun setTextSize(unit: Int, size: Float) { + val c = context + val r: Resources + + r = if (c == null) + Resources.getSystem() + else + c.resources + mMaxTextSize = TypedValue.applyDimension(unit, size, + r.displayMetrics) + mTextCachedSizes!!.clear() + adjustTextSize() + } + + override fun setLineSpacing(add: Float, mult: Float) { + super.setLineSpacing(add, mult) + mSpacingMult = mult + mSpacingAdd = add + } + + /** + * Set the lower text size limit and invalidate the view + * + * @param minTextSize + */ + fun setMinTextSize(minTextSize: Float) { + mMinTextSize = minTextSize + reAdjust() + } + + private fun reAdjust() { + adjustTextSize() + } + + private fun adjustTextSize() { + if (!mInitialized) { + return + } + val startSize = mMinTextSize.toInt() + val heightLimit = (measuredHeight - compoundPaddingBottom + - compoundPaddingTop) + mWidthLimit = (measuredWidth - compoundPaddingLeft + - compoundPaddingRight) + mAvailableSpaceRect!!.right = mWidthLimit.toFloat() + mAvailableSpaceRect!!.bottom = heightLimit.toFloat() + super.setTextSize( + TypedValue.COMPLEX_UNIT_PX, + efficientTextSizeSearch(startSize, mMaxTextSize.toInt(), + mSizeTester, mAvailableSpaceRect!!).toFloat()) + } + + /** + * Enables or disables size caching, enabling it will improve performance + * where you are animating a value inside TextView. This stores the font + * size against getText().length() Be careful though while enabling it as 0 + * takes more space than 1 on some fonts and so on. + * + * @param enable + * enable font size caching + */ + fun enableSizeCache(enable: Boolean) { + mEnableSizeCache = enable + mTextCachedSizes!!.clear() + adjustTextSize() + } + + private fun efficientTextSizeSearch(start: Int, end: Int, + sizeTester: SizeTester, availableSpace: RectF): Int { + if (!mEnableSizeCache) { + return binarySearch(start, end, sizeTester, availableSpace) + } + val text = text.toString() + val key = text.length + var size = mTextCachedSizes!!.get(key) + if (size != 0) { + return size + } + size = binarySearch(start, end, sizeTester, availableSpace) + mTextCachedSizes!!.put(key, size) + return size + } + + override fun onTextChanged(text: CharSequence, start: Int, + before: Int, after: Int) { + super.onTextChanged(text, start, before, after) + reAdjust() + } + + override fun onSizeChanged(width: Int, height: Int, oldwidth: Int, + oldheight: Int) { + mTextCachedSizes!!.clear() + super.onSizeChanged(width, height, oldwidth, oldheight) + if (width != oldwidth || height != oldheight) { + reAdjust() + } + } + + companion object { + private const val NO_LINE_LIMIT = -1 + + private fun binarySearch(start: Int, end: Int, sizeTester: SizeTester, + availableSpace: RectF): Int { + var lastBest = start + var lo = start + var hi = end - 1 + var mid: Int + while (lo <= hi) { + mid = (lo + hi).ushr(1) + val midValCmp = sizeTester.onTestSize(mid, availableSpace) + when { + midValCmp < 0 -> { + lastBest = lo + lo = mid + 1 + } + midValCmp > 0 -> { + hi = mid - 1 + lastBest = hi + } + else -> return mid + } + } + // make sure to return last best + // this is what should always be returned + return lastBest + } + } +} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneApplication.java b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneApplication.java deleted file mode 100644 index 1cf7457..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneApplication.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.sierrawireless.avphone.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.airvantage.model.alert.v1.AlertRule; -import net.airvantage.model.Application; -import net.airvantage.model.ApplicationData; -import net.airvantage.model.Command; -import net.airvantage.model.alert.v1.Condition; -import net.airvantage.model.Data; -import net.airvantage.model.Parameter; -import net.airvantage.model.Protocol; -import net.airvantage.model.Variable; - -public class AvPhoneApplication { - - public static final String ALERT_RULE_NAME = "AV Phone raised an alert"; - - public static Application createApplication(final String userName) { - Application application = new Application(); - application.name = AvPhoneApplication.appName(userName); - application.type = AvPhoneApplication.appType(userName); - application.revision = "0.0.0"; - return application; - } - - public static List createProtocols() { - Protocol mqtt = new Protocol(); - mqtt.type = "MQTT"; - mqtt.commIdType = "SERIAL"; - return Arrays.asList(mqtt); - } - - public static List createApplicationData(CustomDataLabels customData) { - - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - - ApplicationData applicationData = new ApplicationData(); - applicationData.id = "0"; - applicationData.label = "AV Phone Demo"; - applicationData.encoding = "MQTT"; - applicationData.elementType = "node"; - applicationData.data = new ArrayList(); - - Data asset = new Data("phone", "Phone", "node"); - asset.data = new ArrayList(); - - asset.data.add(new Variable(AvPhoneData.RSSI, "RSSI", "int")); - asset.data.add(new Variable(AvPhoneData.RSRP, "RSRP", "int")); - asset.data.add(new Variable(AvPhoneData.SERVICE, "Service type", "string")); - asset.data.add(new Variable(AvPhoneData.OPERATOR, "Operator", "string")); - asset.data.add(new Variable(AvPhoneData.IMEI, "IMEI", "string")); - asset.data.add(new Variable(AvPhoneData.LAT, "Latitude", "double")); - asset.data.add(new Variable(AvPhoneData.LONG, "Longitude", "double")); - asset.data.add(new Variable(AvPhoneData.BATTERY, "Battery level", "double")); - asset.data.add(new Variable(AvPhoneData.BYTES_RECEIVED, "Bytes received", "double")); - asset.data.add(new Variable(AvPhoneData.BYTES_SENT, "Bytes sent", "double")); - asset.data.add(new Variable(AvPhoneData.MEMORY_USAGE, "Memory usage", "double")); - asset.data.add(new Variable(AvPhoneData.RUNNING_APPS, "Running applications", "int")); - asset.data.add(new Variable(AvPhoneData.ACTIVE_WIFI, "Active Wi-Fi", "boolean")); - asset.data.add(new Variable(AvPhoneData.ANDROID_VERSION, "Android Version", "string")); - - asset.data.add(new Variable(AvPhoneData.ALARM, "Active alarm", "boolean")); - - asset.data.add(new Variable(AvPhoneData.CUSTOM_1, customData.customUp1Label, "int")); - asset.data.add(new Variable(AvPhoneData.CUSTOM_2, customData.customUp2Label, "int")); - asset.data.add(new Variable(AvPhoneData.CUSTOM_3, customData.customDown1Label, "int")); - asset.data.add(new Variable(AvPhoneData.CUSTOM_4, customData.customDown2Label, "int")); - asset.data.add(new Variable(AvPhoneData.CUSTOM_5, customData.customStr1Label, "string")); - asset.data.add(new Variable(AvPhoneData.CUSTOM_6, customData.customStr2Label, "string")); - - Command c = new Command(AvPhoneData.NOTIFY, "Notify"); - Parameter p = new Parameter("message", "string"); - c.parameters = Arrays.asList(p); - - asset.data.add(c); - - applicationData.data.add(asset); - - return Arrays.asList(applicationData); - - } - - public static String appName(final String userName) { - return "av_phone_demo_" + userName; - } - - public static String appType(final String userName) { - return "av.phone.demo." + userName; - } - - public static AlertRule createAlertRule() { - AlertRule rule = new AlertRule(); - - rule.active = true; - rule.name = ALERT_RULE_NAME; - rule.eventType = "event.system.incoming.communication"; - - Condition alarmCondition = new Condition(); - alarmCondition.eventProperty = "communication.data.value"; - alarmCondition.eventPropertyKey = AvPhoneData.ALARM; - alarmCondition.operator = "EQUALS"; - alarmCondition.value = "true"; - - rule.conditions = Arrays.asList(alarmCondition); - - return rule; - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneApplication.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneApplication.kt new file mode 100644 index 0000000..258bfa9 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneApplication.kt @@ -0,0 +1,155 @@ +package com.sierrawireless.avphone.model + +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.tools.Tools +import net.airvantage.model.* +import net.airvantage.model.alert.v1.AlertRule +import net.airvantage.model.alert.v1.Condition + +object AvPhoneApplication { + + const val ALERT_RULE_NAME = "raised an alert" + private var objectsManager: ObjectsManager? = null + + fun createApplication(userName: String, phoneName:String): Application { + val application = Application() + application.name = AvPhoneApplication.appName(userName, phoneName) + application.type = AvPhoneApplication.appType(userName, phoneName) + application.revision = "0.0.0" + return application + } + + fun createProtocols(): List { + val mqtt = Protocol() + mqtt.type = "MQTT" + mqtt.commIdType = "SERIAL" + return listOf(mqtt) + } + + fun createApplicationData(customData: ArrayList, obj: String): List { + + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + val applicationData = ApplicationData() + applicationData.id = "0" + applicationData.label = "AV Phone Demo" + applicationData.encoding = "MQTT" + applicationData.elementType = "node" + applicationData.data = ArrayList() + + val asset = Data("phone", "Phone", "node") + asset.data = ArrayList() + + asset.data!!.add(Variable(AvPhoneData.ALARM, "Active alarm", "boolean")) + + var pos = 1 + for (data in customData) { + val type: String = if (data.mode != AvPhoneObjectData.Mode.None) { + "int" + } else { + "string" + } + + if (data.path == null) { + asset.data!!.add(Variable(obj + "." + AvPhoneData.CUSTOM + pos.toString(), data.name, type)) + }else{ + asset.data!!.add(Variable(data.path!!, data.name, type)) + } + pos++ + } + + val c = Command(AvPhoneData.NOTIFY, "Notify") + val p = Parameter("message", "string") + c.parameters = listOf(p) + + asset.data!!.add(c) + + applicationData.data!!.add(asset) + + return listOf(applicationData) + + } + + private fun appName(userName: String, phoneName: String): String { + objectsManager = ObjectsManager.getInstance() + + return phoneName.replace(" ", "_") + "_av_phone_" + objectsManager!!.savecObject.name + "_" + userName + } + + fun appType(userName: String, phoneName: String): String { + objectsManager = ObjectsManager.getInstance() + return phoneName.replace(" ", ".") + ".av.phone.demo." + objectsManager!!.savecObject.name + userName + } + + fun createAlertRule(system: AvSystem): AlertRule { + val rule = AlertRule() + + rule.active = true + rule.name = Tools.buildAlertName() + rule.eventType = "event.system.incoming.communication" + + val alarmCondition = Condition() + alarmCondition.eventProperty = "communication.data.value" + alarmCondition.eventPropertyKey = AvPhoneData.ALARM + alarmCondition.operator = "EQUALS" + alarmCondition.value = "true" + + val systemCondition = Condition() + systemCondition.eventProperty = "system.data.value" + systemCondition.eventPropertyKey = "system.id" + systemCondition.operator = "EQUALS" + systemCondition.value = system.uid + + + val tmp = ArrayList() + tmp.add(alarmCondition) + tmp.add(systemCondition) + rule.conditions = tmp + + return rule + } + + fun updateAlertRule(system: AvSystem, alertRule: AlertRule) { + + alertRule.active = true + alertRule.name = Tools.buildAlertName() + alertRule.eventType = "event.system.incoming.communication" + + val alarmCondition = Condition() + alarmCondition.eventProperty = "communication.data.value" + alarmCondition.eventPropertyKey = AvPhoneData.ALARM + alarmCondition.operator = "EQUALS" + alarmCondition.value = "true" + + val systemCondition = Condition() + systemCondition.eventProperty = "system.data.value" + systemCondition.eventPropertyKey = "system.id" + systemCondition.operator = "EQUALS" + systemCondition.value = system.uid + + + val tmp = ArrayList() + tmp.add(alarmCondition) + tmp.add(systemCondition) + alertRule.conditions = tmp + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneData.java b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneData.java deleted file mode 100644 index ece7ab9..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneData.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sierrawireless.avphone.model; - -public class AvPhoneData { - - public static final String RSSI = "phone.rssi"; - public static final String RSRP = "phone.rsrp"; - public static final String BATTERY = "phone.batterylevel"; - public static final String OPERATOR = "phone.operator"; - public static final String IMEI = "phone.imei"; - public static final String SERVICE = "phone.service"; - public static final String LAT = "phone.latitude"; - public static final String LONG = "phone.longitude"; - public static final String BYTES_RECEIVED = "phone.bytesreceived"; - public static final String BYTES_SENT = "phone.bytessent"; - public static final String ACTIVE_WIFI = "phone.activewifi"; - public static final String RUNNING_APPS = "phone.runningapps"; - public static final String MEMORY_USAGE = "phone.memoryusage"; - public static final String ANDROID_VERSION = "phone.androidversion"; - public static final String CUSTOM_1 = "phone.custom.1"; - public static final String CUSTOM_2 = "phone.custom.2"; - public static final String CUSTOM_3 = "phone.custom.3"; - public static final String CUSTOM_4 = "phone.custom.4"; - public static final String CUSTOM_5 = "phone.custom.5"; - public static final String CUSTOM_6 = "phone.custom.6"; - - public static final String ALARM = "phone.alarm"; - - public static final String NOTIFY = "phone.notify"; - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneData.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneData.kt new file mode 100644 index 0000000..3f791d9 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneData.kt @@ -0,0 +1,11 @@ +package com.sierrawireless.avphone.model + +object AvPhoneData { + + const val CUSTOM = "phone.custom." + + const val ALARM = "phone.alarm" + + internal const val NOTIFY = "phone.notify" + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneObject.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneObject.kt new file mode 100644 index 0000000..8b03ab2 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneObject.kt @@ -0,0 +1,35 @@ +package com.sierrawireless.avphone.model + +import java.util.ArrayList + +class AvPhoneObject { + var name: String? = null + var systemUid: String? = null + + var alarm: Boolean = false + var datas: ArrayList = ArrayList() + + fun add(data: AvPhoneObjectData) { + datas.add(data) + } + + override fun toString(): String { + val returned = StringBuilder("{") + returned.append("\"name\" : \"").append(name).append("\",") + returned.append("\"alarm\" : ").append(alarm).append(",") + + returned.append("\"datas\":[") + for (data in datas) { + returned.append(data.toString()).append(",") + } + returned.append("]}") + return returned.toString() + } + + fun exec() { + for (data in datas) { + data.execMode() + } + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneObjectData.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneObjectData.kt new file mode 100644 index 0000000..9b77a53 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/model/AvPhoneObjectData.kt @@ -0,0 +1,130 @@ +package com.sierrawireless.avphone.model + +import android.text.TextUtils +import com.sierrawireless.avphone.tools.Tools + + +class AvPhoneObjectData(var name: String, var unit: String, var defaults: String, mode: Mode, private val label:String?, var path: String?) { + var mode: Mode = Mode.None + var current: Int? = null + private var min: Int? = null + private var max: Int? = null + + val isInteger: Boolean + get() = !defaults.isEmpty() && TextUtils.isDigitsOnly(defaults) + + enum class Mode { + None, + UP, + DOWN, + RANDOM + } + + init { + if (isInteger) { + this.mode = mode + current = Integer.parseInt(defaults) + } else { + if (mode == Mode.RANDOM) { + val value = defaults.split(",") + if (value.size == 2) { + if (!value[0].isEmpty() && TextUtils.isDigitsOnly(value[0]) && + !value[1].isEmpty() && TextUtils.isDigitsOnly(value[1])) { + min = Integer.parseInt(value[0]) + max = Integer.parseInt(value[1]) + this.mode = mode + current = Tools.rand(min!!, max!!).toInt() + } else { + this.mode = Mode.None + } + } else { + this.mode = Mode.None + } + }else{ + this.mode = Mode.None + } + } + } + + override fun toString(): String { + var returned = "{" + returned = "$returned\"name\": \"$name\"," + returned = "$returned\"unit\": \"$unit\"," + returned = "$returned\"defaults\": \"$defaults\"," + returned = returned + "\"mode\": \"" + modeToString(mode) + "\"" + returned = if (path == null) { + returned + "}" + }else { + ",$returned\"path\": \"$path\"}" + } + return returned + } + + fun execMode(): String { + return when { + this.mode == Mode.UP -> increment() + this.mode == Mode.DOWN -> decrement() + this.mode == Mode.RANDOM -> random() + else -> defaults + } + } + + private fun modeToString(mode: Mode): String { + return when (mode) { + AvPhoneObjectData.Mode.UP -> "Increase indefinitely" + AvPhoneObjectData.Mode.DOWN -> "Decrease to zero" + AvPhoneObjectData.Mode.None -> "None" + AvPhoneObjectData.Mode.RANDOM -> "Random" + } + } + + private fun increment(): String { + if (current == null) { + current = Integer.parseInt(defaults) + } + current = current!! + 1 + return current!!.toString() + } + + private fun decrement(): String { + if (current == null) { + current = Integer.parseInt(defaults) + } + if (current!! > 0) + current = current!! - 1 + else if (current == 0) { + current = Integer.parseInt(defaults) + + } + return current!!.toString() + } + + private fun random(): String { + current = Tools.rand(min!!, max!!).toInt() + return current!!.toString() + } + + fun modePosition(): Int { + return when (mode) { + AvPhoneObjectData.Mode.None -> 0 + AvPhoneObjectData.Mode.UP -> 1 + AvPhoneObjectData.Mode.DOWN -> 2 + AvPhoneObjectData.Mode.RANDOM -> 3 + } + } + + companion object { + + fun modeFromPosition(position: Int): Mode { + when (position) { + 0 -> return Mode.None + 1 -> return Mode.UP + 2 -> return Mode.DOWN + 3 -> return Mode.RANDOM + } + return Mode.None + } + } + + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/CustomDataLabels.java b/mainActivity/src/main/java/com/sierrawireless/avphone/model/CustomDataLabels.java deleted file mode 100644 index ec78083..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/model/CustomDataLabels.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sierrawireless.avphone.model; - -public class CustomDataLabels { - - public String customUp1Label; - public String customUp2Label; - public String customDown1Label; - public String customDown2Label; - public String customStr1Label; - public String customStr2Label; -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/model/CustomDataLabels.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/model/CustomDataLabels.kt new file mode 100644 index 0000000..d7718f2 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/model/CustomDataLabels.kt @@ -0,0 +1,11 @@ +package com.sierrawireless.avphone.model + +class CustomDataLabels { + + var customUp1Label: String? = null + var customUp2Label: String? = null + var customDown1Label: String? = null + var customDown2Label: String? = null + var customStr1Label: String? = null + var customStr2Label: String? = null +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/CustomDataSource.java b/mainActivity/src/main/java/com/sierrawireless/avphone/service/CustomDataSource.java deleted file mode 100644 index 8375f04..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/service/CustomDataSource.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.sierrawireless.avphone.service; - -import java.util.Date; - -public class CustomDataSource { - - // Rate of growth (in units / seconds) - private static final float UP1_RATE = 0.2F; - private static final float UP2_RATE = 0.05F; - - // Rate of decrease (in units / seconds) ; when 0 is reached, values - // go back to 100. - private static final float DOWN1_RATE = 0.2F; - private static final float DOWN2_RATE = 0.05F; - - // How often (in seconds) should strings be changed ? - private static final int STR1_DELAY = 3600; - private static final int STR2_DELAY = 2 * 3600; - - public int customUp1 = 0; - public int customUp2 = 0; - public int customDown1 = 100; - public int customDown2 = 100; - - public String customStr1 = ""; - public String customStr2 = ""; - - public int customStr1Life = 0; - public int customStr2Life = 0; - - private long lastTick; - - public CustomDataSource(Date date) { - this.lastTick = date.getTime(); - updateStrs(); - } - - private void updateStrs() { - updateStr1(); - updateStr2(); - } - - private void updateStr1() { - customStr1 = "SN" + (lastTick / 10000); - } - - private void updateStr2() { - customStr2 = "SN" + ((lastTick / 10000) + ((int) Math.random() * 4200)); - } - - public Integer getCustomIntUp1() { - return customUp1; - } - - public Integer getCustomIntUp2() { - return customUp2; - } - - public Integer getCustomIntDown1() { - return customDown1; - } - - public Integer getCustomIntDown2() { - return customDown2; - } - - public String getCustomStr1() { - return customStr1; - } - - public String getCustomStr2() { - return customStr2; - } - - public void next(Date date) { - long now = date.getTime(); - - long delay = (long) ((now - lastTick) / 1000); - - customUp1 = customUp1 + (int) (delay * UP1_RATE); - customUp2 = customUp2 + (int) (delay * UP2_RATE); - - customDown1 = customDown1 - (int) (delay * DOWN1_RATE); - if (customDown1 < 0) { - customDown1 = 100; - } - - customDown2 = customDown2 - (int) (delay * DOWN2_RATE); - if (customDown2 < 0) { - customDown2 = 100; - } - - customStr1Life += delay; - customStr2Life += delay; - - lastTick = now; - - if (customStr1Life > STR1_DELAY) { - updateStr1(); - } - - if (customStr2Life > STR2_DELAY) { - updateStr2(); - } - - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/LocationListenerAdapter.java b/mainActivity/src/main/java/com/sierrawireless/avphone/service/LocationListenerAdapter.java deleted file mode 100644 index e48a32a..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/service/LocationListenerAdapter.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sierrawireless.avphone.service; - -import android.location.Location; -import android.location.LocationListener; -import android.os.Bundle; - -public class LocationListenerAdapter implements LocationListener { - - @Override - public void onLocationChanged(Location location) { - } - - @Override - public void onProviderDisabled(String provider) { - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/LocationListenerAdapter.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/service/LocationListenerAdapter.kt new file mode 100644 index 0000000..8a250c3 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/service/LocationListenerAdapter.kt @@ -0,0 +1,16 @@ +package com.sierrawireless.avphone.service + +import android.location.Location +import android.location.LocationListener +import android.os.Bundle + +open class LocationListenerAdapter : LocationListener { + + override fun onLocationChanged(location: Location) {} + + override fun onProviderDisabled(provider: String) {} + + override fun onProviderEnabled(provider: String) {} + + override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/LogMessage.java b/mainActivity/src/main/java/com/sierrawireless/avphone/service/LogMessage.java deleted file mode 100644 index 3109f1c..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/service/LogMessage.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.sierrawireless.avphone.service; - -import android.content.Intent; - -public class LogMessage extends Intent { - - public static final String LOG_EVENT = "com.sierrawireless.avphone.event.log"; - - // keys used for broadcasting log events - private static final String LOG = "log"; - - public LogMessage(String message) { - super(LOG_EVENT); - - this.putExtra(LOG, message); - } - - public String getMessage() { - return this.getStringExtra(LOG); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/LogMessage.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/service/LogMessage.kt new file mode 100644 index 0000000..1814beb --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/service/LogMessage.kt @@ -0,0 +1,27 @@ +package com.sierrawireless.avphone.service + +import android.content.Intent + +class LogMessage(message: String, alarm: Boolean) : Intent(LOG_EVENT) { + + val message: String + get() = this.getStringExtra(LOG) + val alarm: Boolean + get() = this.getBooleanExtra(ALARM, false) + + init { + + this.putExtra(LOG, message) + this.putExtra(ALARM, alarm) + } + + companion object { + + const val LOG_EVENT = "com.sierrawireless.avphone.event.log" + + // keys used for broadcasting log events + const val LOG = "log" + private const val ALARM = "alarm" + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitorServiceManager.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitorServiceManager.kt new file mode 100644 index 0000000..027f387 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitorServiceManager.kt @@ -0,0 +1,20 @@ +package com.sierrawireless.avphone.service + +import com.sierrawireless.avphone.listener.MonitorServiceListener + + +interface MonitorServiceManager { + //val isServiceRunning: Boolean + var monitoringService: MonitoringService? + fun isServiceStarted(name: String): Boolean + fun oneServiceStarted(): Boolean + fun stopMonitoringService() + fun startMonitoringService(name: String) + fun startSendData(name: String):Boolean + fun stopSendData() + fun sendAlarmEvent(on: Boolean):Boolean + fun setMonitoringServiceListener(listener: MonitorServiceListener) + fun isServiceRunning(name: String? = null): Boolean + fun cancel() + fun start() +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitoringService.java b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitoringService.java deleted file mode 100644 index c6daf3a..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitoringService.java +++ /dev/null @@ -1,443 +0,0 @@ -package com.sierrawireless.avphone.service; - -import android.app.ActivityManager; -import android.app.ActivityManager.MemoryInfo; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.app.TaskStackBuilder; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.location.Criteria; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.LocationProvider; -import android.net.ConnectivityManager; -import android.net.TrafficStats; -import android.os.BatteryManager; -import android.os.Binder; -import android.os.Build; -import android.os.IBinder; -import android.support.v4.content.LocalBroadcastManager; -import android.telephony.CellInfo; -import android.telephony.CellInfoGsm; -import android.telephony.CellInfoLte; -import android.telephony.CellInfoWcdma; -import android.telephony.TelephonyManager; -import android.util.Log; - -import com.crashlytics.android.Crashlytics; -import com.google.gson.Gson; -import com.sierrawireless.avphone.MainActivity; -import com.sierrawireless.avphone.R; - -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; - -public class MonitoringService extends Service { - - private static final String LOGTAG = MonitoringService.class.getName(); - - // system services - private TelephonyManager telephonyManager; - private ActivityManager activityManager; - private ConnectivityManager connManager; - - // Unique Identification Number for the Notification. - private int NOTIFICATION = R.string.notif_title; - - // Intent extra keys - public static final String DEVICE_ID = "device_id"; - public static final String SERVER_HOST = "server_host"; - public static final String PASSWORD = "password"; - - private MqttPushClient client = null; - - private Long startedSince; - - private Long lastRun; - private String lastLog; - private NewData lastData = new NewData(); - /* the date of the last location reading */ - private long lastLocation; - - private CustomDataSource customDataSource; - - // FIXME(pht) for testing, to compare with "last known location" - private Location networkLocation = null; - private Location gpsLocation = null; - private LocationListener networkLocationListener; - private LocationListener gpsLocationListener; - - @Override - public void onCreate() { - - // Display a notification icon - - // Create an intent to start the activity when clicking the notification - Intent resultIntent = new Intent(this, MainActivity.class); - TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); - stackBuilder.addParentStack(MainActivity.class); - stackBuilder.addNextIntent(resultIntent); - PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); - - Notification notification = new Notification.Builder(this.getApplicationContext()) // - .setContentTitle(getText(R.string.notif_title)) // - .setContentText(getText(R.string.notif_desc)) // - .setSmallIcon(R.drawable.ic_notif) // - .setOngoing(true) // - .setContentIntent(resultPendingIntent) // - .build(); - - startForeground(NOTIFICATION, notification); - - telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); - activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - - customDataSource = new CustomDataSource(new java.util.Date()); - - startedSince = System.currentTimeMillis(); - - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - - lastRun = System.currentTimeMillis(); - - try { - - if (this.client == null) { - - // - // Ensure intent is valid - // - final String deviceId = intent.getStringExtra(DEVICE_ID); - final String password = intent.getStringExtra(PASSWORD); - final String serverHost = intent.getStringExtra(SERVER_HOST); - - final List intentValuesList = Arrays.asList(deviceId, password, serverHost); - if (intentValuesList.contains(null)) { - // Stop service when unable to start MQTT client - stopSelfResult(startId); - return Service.START_STICKY; - } - - // Now, create client - client = new MqttPushClient(deviceId, password, serverHost, mqttCallback); - } - - if (!client.isConnected()) { - client.connect(); - } - - Location location = getLastKnownLocation(); - - // retrieve data - NewData data = new NewData(); - - List cellInfos = telephonyManager.getAllCellInfo(); - if (cellInfos != null && !cellInfos.isEmpty()) { - CellInfo cellInfo = cellInfos.get(0); - if (cellInfo instanceof CellInfoGsm) { - data.setRssi(((CellInfoGsm) cellInfo).getCellSignalStrength().getDbm()); - } else if (cellInfo instanceof CellInfoWcdma) { - // RSSI ? - // data.setRssi(((CellInfoWcdma) cellInfo).getCellSignalStrength().getDbm()); - } else if (cellInfo instanceof CellInfoLte) { - data.setRsrp(((CellInfoLte) cellInfo).getCellSignalStrength().getDbm()); - } - } - - if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { - data.setImei(telephonyManager.getDeviceId()); - } - - data.setOperator(telephonyManager.getNetworkOperatorName()); - - switch (telephonyManager.getNetworkType()) { - case TelephonyManager.NETWORK_TYPE_GPRS: - data.setNetworkType("GPRS"); - break; - case TelephonyManager.NETWORK_TYPE_EDGE: - data.setNetworkType("EDGE"); - break; - case TelephonyManager.NETWORK_TYPE_UMTS: - data.setNetworkType("UMTS"); - break; - case TelephonyManager.NETWORK_TYPE_HSDPA: - data.setNetworkType("HSDPA"); - break; - case TelephonyManager.NETWORK_TYPE_HSPAP: - data.setNetworkType("HSPA+"); - break; - case TelephonyManager.NETWORK_TYPE_HSPA: - data.setNetworkType("HSPA"); - break; - case TelephonyManager.NETWORK_TYPE_HSUPA: - data.setNetworkType("HSUPA"); - break; - case TelephonyManager.NETWORK_TYPE_LTE: - data.setNetworkType("LTE"); - break; - // to be continued - default: - } - - data.setActiveWifi(connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()); - data.setRunningApps(activityManager.getRunningAppProcesses().size()); - data.setAndroidVersion(Build.VERSION.RELEASE); - - MemoryInfo mi = new MemoryInfo(); - activityManager.getMemoryInfo(mi); - data.setMemoryUsage((float) ((mi.totalMem - mi.availMem) / ((Long) mi.totalMem).doubleValue())); - - // battery level - final IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - final Intent batteryStatus = this.registerReceiver(null, iFilter); - if (batteryStatus != null) { - final int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - final int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - data.setBatteryLevel(level / (float) scale); - } - - // location - if (location != null && location.getTime() != lastLocation) { - data.setLatitude(location.getLatitude()); - data.setLongitude(location.getLongitude()); - lastLocation = location.getTime(); - } - - // bytes sent/received - data.setBytesReceived(TrafficStats.getMobileRxBytes()); - data.setBytesSent(TrafficStats.getMobileTxBytes()); - - // Custom data - data.setCustomIntUp1(customDataSource.getCustomIntUp1()); - data.setCustomIntUp2(customDataSource.getCustomIntUp2()); - data.setCustomIntDown1(customDataSource.getCustomIntDown1()); - data.setCustomIntDown2(customDataSource.getCustomIntDown2()); - data.setCustomStr1(customDataSource.getCustomStr1()); - data.setCustomStr2(customDataSource.getCustomStr2()); - - customDataSource.next(new Date()); - - // save new data values - lastData.putExtras(data.getExtras()); - - // dispatch new data event to update the activity UI - LocalBroadcastManager.getInstance(this).sendBroadcast(data); - - this.client.push(data); - lastLog = data.size() + " data pushed to the server"; - LocalBroadcastManager.getInstance(this).sendBroadcast(new LogMessage(lastLog)); - - setUpLocationListeners(); - - - } catch (Exception e) { - Crashlytics.logException(e); - Log.e(LOGTAG, "error", e); - lastLog = "ERROR: " + e.getMessage(); - LocalBroadcastManager.getInstance(this).sendBroadcast(new LogMessage(lastLog)); - } - - - return Service.START_NOT_STICKY; - } - - @Override - public void onDestroy() { - Log.d("MonitoringService", "Stopping service"); - - if (this.client != null) { - try { - this.client.disconnect(); - } catch (MqttException e) { - Crashlytics.logException(e); - Log.e(LOGTAG, "error", e); - } - } - - // Cancel the persistent notification. - stopForeground(true); - - stopLocationListeners(); - } - - private void setUpLocationListeners() { - final LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - LocationProvider networkLocationProvider = locManager.getProvider(LocationManager.NETWORK_PROVIDER); - if (networkLocationProvider != null) { - networkLocationListener = new LocationListenerAdapter() { - @Override - public void onLocationChanged(Location location) { - Log.d(LOGTAG, "Received Network location update " + location.getLatitude() + ";" + location.getLongitude()); - networkLocation = location; - } - }; - locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60 * 1000, 5, networkLocationListener); - } - LocationProvider gpsLocationProvider = locManager.getProvider(LocationManager.GPS_PROVIDER); - if (gpsLocationProvider != null) { - gpsLocationListener = new LocationListenerAdapter() { - @Override - public void onLocationChanged(Location location) { - Log.d(LOGTAG, "Received GPS location update " + location.getLatitude() + ";" + location.getLongitude()); - gpsLocation = location; - } - }; - locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60 * 1000, 5, gpsLocationListener); - } - } - - private void stopLocationListeners() { - final LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - if (networkLocationListener != null) { - locManager.removeUpdates(networkLocationListener); - } - if (gpsLocationListener != null) { - locManager.removeUpdates(gpsLocationListener); - } - } - - - private Location getLastKnownLocation() { - final LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - final String locationProvider = locManager.getBestProvider(new Criteria(), true); - Log.d(LOGTAG, "Getting last known location from provider: " + locationProvider); - - Location location = null; - if (locationProvider != null) { - location = locManager.getLastKnownLocation(locationProvider); - if (location != null) { - Log.d(LOGTAG, "Last known location : " + location.getLatitude() + "," + location.getLongitude()); - } else { - Log.d(LOGTAG, "Read null location"); - } - if (networkLocation != null) { - Log.d(LOGTAG, "Last Network Location : " + networkLocation.getLatitude() + "," + networkLocation.getLongitude()); - } else { - Log.d(LOGTAG, "No known network location"); - } - if (gpsLocation != null) { - Log.d(LOGTAG, "Last GPS Location : " + gpsLocation.getLatitude() + "," + gpsLocation.getLongitude()); - } else { - Log.d(LOGTAG, "No known GPSlocation"); - } - } - return location; - } - - public void sendAlarmEvent(boolean activated) { - - if (this.client == null) { - // TODO: Propagate error message when client is not available yet - return; - } - - NewData data = new NewData(); - data.setAlarmActivated(activated); - - // save alarm state - lastData.putExtras(data.getExtras()); - - try { - this.client.push(data); - } catch (MqttException e) { - // TODO display something - Crashlytics.logException(e); - Log.e(LOGTAG, "Could not push the alarm event", e); - } - } - - // Service binding - - private ServiceBinder binder = new ServiceBinder(); - - @Override - public IBinder onBind(Intent arg0) { - return binder; - } - - public class ServiceBinder extends Binder { - - public MonitoringService getService() { - return MonitoringService.this; - } - } - - public long getStartedSince() { - return startedSince; - } - - public NewData getLastData() { - return lastData; - } - - public String getLastLog() { - return lastLog; - } - - public Long getLastRun() { - return lastRun; - } - - // MQTT client callback - - @SuppressWarnings("unused") - private MqttCallback mqttCallback = new MqttCallback() { - - class Message { - String uid; - long timestamp; - Command command; - } - - class Command { - String id; - Map params; - } - - @Override - public void messageArrived(String topic, MqttMessage msg) throws Exception { - Log.d(LOGTAG, "MQTT msg received: " + new String(msg.getPayload())); - - // parse json payload - Message[] messages = new Gson().fromJson(new String(msg.getPayload(), "UTF-8"), Message[].class); - - // display a new notification - Notification notification = new Notification.Builder(MonitoringService.this.getApplicationContext()) // - .setContentTitle(getText(R.string.notif_new_message)) // - .setContentText(messages[0].command.params.get("message")) // - .setSmallIcon(R.drawable.ic_notif) // - .setAutoCancel(true) // - .build(); - - NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationManager.notify((int) messages[0].timestamp, notification); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken arg0) { - // - } - - @Override - public void connectionLost(Throwable arg0) { - // - } - }; - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitoringService.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitoringService.kt new file mode 100644 index 0000000..ba90874 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MonitoringService.kt @@ -0,0 +1,540 @@ +package com.sierrawireless.avphone.service + +import android.annotation.SuppressLint +import android.app.* +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.location.Criteria +import android.location.Location +import android.location.LocationListener +import android.location.LocationManager +import android.net.ConnectivityManager +import android.net.TrafficStats +import android.os.Binder +import android.os.Build +import android.os.IBinder +import android.support.annotation.RequiresApi +import android.support.v4.app.NotificationCompat +import android.support.v4.content.LocalBroadcastManager +import android.telephony.* +import android.util.Log +import com.crashlytics.android.Crashlytics +import com.google.gson.Gson +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.task.SendDataParams +import com.sierrawireless.avphone.task.SendDataTask +import com.sierrawireless.avphone.tools.DeviceInfo +import com.sierrawireless.avphone.tools.Tools +import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken +import org.eclipse.paho.client.mqttv3.MqttCallback +import org.eclipse.paho.client.mqttv3.MqttException +import org.eclipse.paho.client.mqttv3.MqttMessage +import org.jetbrains.anko.toast +import java.nio.charset.Charset +import java.util.* +import kotlin.concurrent.fixedRateTimer + +class MonitoringService : Service() { + + // system services + private var telephonyManager: TelephonyManager? = null + private var activityManager: ActivityManager? = null + private var connManager: ConnectivityManager? = null + var set: Boolean? = false + + private var client: MqttPushClient? = null + + var startedSince: Long? = null + + var lastRun: Long? = null + private set + var lastLog: String? = null + private set + var lastAlarmLog: String? = null + private set + + val lastData = NewData() + /* the date of the last location reading */ + private var lastLocation: Long = 0 + + private var networkLocation: Location? = null + private var gpsLocation: Location? = null + private var networkLocationListener: LocationListener? = null + private var gpsLocationListener: LocationListener? = null + private var objectsManager: ObjectsManager? = null + + private var phoneStateListener: PhoneStateListener? = null + + private var dbm: Int? = null + + private var timer:Timer? = null + + + private val lastKnownLocation: Location? + @SuppressLint("MissingPermission") + get() { + val locManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + + val locationProvider = locManager.getBestProvider(Criteria(), true) + Log.i(TAG, "Getting last known location from provider: " + locationProvider!!) + + val location: Location? = locManager.getLastKnownLocation(locationProvider) + if (location != null) { + Log.i(TAG, "Last known location : " + location.latitude + "," + location.longitude) + } else { + Log.i(TAG, "Read null location") + } + if (networkLocation != null) { + Log.i(TAG, "Last Network Location : " + networkLocation!!.latitude + "," + networkLocation!!.longitude) + } else { + Log.i(TAG, "No known network location") + } + if (gpsLocation != null) { + Log.i(TAG, "Last GPS Location : " + gpsLocation!!.latitude + "," + gpsLocation!!.longitude) + } else { + Log.i(TAG, "No known GPSlocation") + } + + return location + } + + // Service binding + + private val binder = ServiceBinder() + + // MQTT client callback + + private val mqttCallback = object : MqttCallback { + + internal inner class Message { + var timestamp: Long = 0 + var command: Command? = null + } + + internal inner class Command { + var params: Map? = null + } + + @RequiresApi(Build.VERSION_CODES.O) + private fun createNotificationChannel(): String{ + val channelId = "messageArrived" + val channelName = "messageArrived" + val chan = NotificationChannel(channelId, + channelName, NotificationManager.IMPORTANCE_NONE) + chan.lightColor = Color.BLUE + chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE + val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + service.createNotificationChannel(chan) + return channelId + } + + @Throws(Exception::class) + override fun messageArrived(topic: String, msg: MqttMessage) { + Log.i(TAG, "MQTT msg received: " + String(msg.payload)) + + // parse json payload + val messages = Gson().fromJson(String(msg.payload, Charset.forName("UTF-8")), Array::class.java) + + val channelId = + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createNotificationChannel() + } else { + // If earlier version channel ID is not used + // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) + "" + } + val notification = NotificationCompat.Builder(this@MonitoringService.applicationContext, channelId) // + .setContentTitle(getText(R.string.notif_new_message)) // + .setContentText(messages[0].command!!.params!!["message"]) // + .setSmallIcon(R.drawable.ic_notif) // + .setAutoCancel(true) // + .build() + + val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + mNotificationManager.notify(messages[0].timestamp.toInt(), notification) + } + + override fun deliveryComplete(arg0: IMqttDeliveryToken) { + // + } + + override fun connectionLost(arg0: Throwable) { + // + } + } + + override fun onCreate() { + // Unique Identification Number for the Notification. + objectsManager = ObjectsManager.getInstance() + + // Display a notification icon + + + telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + connManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + phoneStateListener = object : PhoneStateListener() { + override fun onSignalStrengthsChanged(signalStrength: SignalStrength?) { + super.onSignalStrengthsChanged(signalStrength) + if (signalStrength == null) + return + if (telephonyManager!!.networkType == TelephonyManager.NETWORK_TYPE_LTE) { + val parts = signalStrength.toString().split(" ") + dbm = parts[8].toInt() - 240 + }else{ + if (signalStrength.gsmSignalStrength != 99) { + dbm = -113 + 2 * signalStrength.gsmSignalStrength + } + } + + } + + } + + + telephonyManager!!.listen(phoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) + + + startedSince = System.currentTimeMillis() + start() + + } + + fun start() { + //protect multiple start + if (timer == null) { + //periodic timer of 5 s do avoid + timer = fixedRateTimer("UItimer", false, 0, 2000L) { + setCustomDataForUi() + } + } + //setUpLocationListeners() + } + + + @RequiresApi(Build.VERSION_CODES.O) + private fun createNotificationChannel(): String{ + val channelId = "startSend" + val channelName = getText(R.string.notif_title) + val chan = NotificationChannel(channelId, + channelName, NotificationManager.IMPORTANCE_NONE) + chan.lightColor = Color.BLUE + chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE + val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + service.createNotificationChannel(chan) + return channelId + } + + fun startSendData() { + val notif = R.string.notif_title + // Create an intent to start the activity when clicking the notification + val resultIntent = Intent(this, MainActivity::class.java) + val stackBuilder = TaskStackBuilder.create(this) + stackBuilder.addParentStack(MainActivity::class.java) + stackBuilder.addNextIntent(resultIntent) + val resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) + + val channelId = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createNotificationChannel() + } else { + // If earlier version channel ID is not used + // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) + "" + } + + + val notification = NotificationCompat.Builder(this.applicationContext, channelId)// + .setContentTitle(getText(R.string.notif_title)) // + .setContentText(getText(R.string.notif_desc)) // + .setSmallIcon(R.drawable.ic_notif) // + .setOngoing(true) // + .setContentIntent(resultPendingIntent) // + .build() + + startForeground(notif, notification) + setUpLocationListeners() + + } + + fun stopSendData() { + + // Cancel the persistent notification. + stopForeground(true) + stopLocationListeners() + } + + @Suppress("DEPRECATION") + @SuppressLint("MissingPermission") + private fun setCustomDataForUi():NewData { + val location = lastKnownLocation + + // retrieve data + val data = NewData() + + if (dbm != null) { + data.rssi = dbm!! + }else { + + val cellInfos = telephonyManager!!.allCellInfo + if (cellInfos != null && !cellInfos.isEmpty()) { + val cellInfo = cellInfos[0] + if (cellInfo is CellInfoGsm) { + data.rssi = cellInfo.cellSignalStrength.dbm + // } else if (cellInfo instanceof CellInfoWcdma) { + // RSSI ? + // data.setRssi(((CellInfoWcdma) cellInfo).getCellSignalStrength().getDbm()); + } else if (cellInfo is CellInfoLte) { + data.rsrp = cellInfo.cellSignalStrength.dbm + } + } + } + + if (telephonyManager!!.phoneType == TelephonyManager.PHONE_TYPE_GSM) { + @Suppress("DEPRECATION") + data.imei = telephonyManager!!.deviceId + } + + data.operator = telephonyManager!!.networkOperatorName + + when (telephonyManager!!.networkType) { + TelephonyManager.NETWORK_TYPE_GPRS -> data.networkType = "GPRS" + TelephonyManager.NETWORK_TYPE_EDGE -> data.networkType = "EDGE" + TelephonyManager.NETWORK_TYPE_UMTS -> data.networkType = "UMTS" + TelephonyManager.NETWORK_TYPE_HSDPA -> data.networkType = "HSDPA" + TelephonyManager.NETWORK_TYPE_HSPAP -> data.networkType = "HSPA+" + TelephonyManager.NETWORK_TYPE_HSPA -> data.networkType = "HSPA" + TelephonyManager.NETWORK_TYPE_HSUPA -> data.networkType = "HSUPA" + TelephonyManager.NETWORK_TYPE_LTE -> data.networkType = "LTE" + }// to be continued + + + // location + if (location != null) { + data.latitude = location.latitude + data.longitude = location.longitude + lastLocation = location.time + } + val connManager: ConnectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) + val mMobile = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) + + when { + mWifi.isConnected -> { + // bytes sent/received + data.bytesReceived = TrafficStats.getTotalRxBytes() + data.bytesSent = TrafficStats.getTotalTxBytes() + } + mMobile.isConnected -> { + data.bytesReceived = TrafficStats.getMobileRxBytes() + data.bytesSent = TrafficStats.getMobileTxBytes() + } + else -> { + data.bytesReceived = 0 + data.bytesSent = 0 + } + } + //execute action on current object datas + //objectsManager!!.execOnCurrent() + // Custom data + data.setCustom() + + // dispatch new data event to update the activity UI + LocalBroadcastManager.getInstance(this).sendBroadcast(data) + return data + } + + @SuppressLint("HardwareIds", "MissingPermission") + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + + lastRun = System.currentTimeMillis() + objectsManager = ObjectsManager.getInstance() + val obj = objectsManager!!.currentObject + + Log.d(TAG, "alarm received") + + try { + val mustConnect = intent.getBooleanExtra(CONNECT, false) + + /* First we have to create the system if it doesn't exist */ + + if (this.client == null) { + + // + // Ensure intent is valid + // + val deviceID = intent.getStringExtra(DEVICE_ID) + if (deviceID == null) { + + } + val deviceId = Tools.buildSerialNumber(intent.getStringExtra(DEVICE_ID), obj!!.name!!, DeviceInfo.deviceName!!) + val password = intent.getStringExtra(PASSWORD) + val serverHost = intent.getStringExtra(SERVER_HOST) + + val intentValuesList = Arrays.asList(deviceId, password, serverHost) + if (intentValuesList.contains(null)) { + // Stop service when unable to start MQTT client + stopSelfResult(startId) + return Service.START_STICKY + } + + // Now, create client + client = MqttPushClient(deviceId, password, serverHost, mqttCallback) + } + + + if (mustConnect) { + + val data = setCustomDataForUi() + + + // save new data values + if (data.extras != null) { + lastData.putExtras(data.extras!!) + } + + + val sendDataTask = SendDataTask() + val params = SendDataParams() + params.client = client + params.data = data + params.context = this + params.alarm = false + + sendDataTask.execute(params) + MainActivity.instance.setAlarm(null) + + sendDataTask.addProgressListener { result -> lastLog = result.lastLog } + + // setUpLocationListeners() + } + + } catch (e: Exception) { + Crashlytics.logException(e) + Log.e(TAG, "error", e) + lastLog = "ERROR: " + e.message + LocalBroadcastManager.getInstance(this).sendBroadcast(LogMessage(lastLog!!, false)) + } + + // MainActivity.instance.setAlarm() + return Service.START_NOT_STICKY + } + + override fun onDestroy() { + try { + this.client?.disconnect() + } catch (e: MqttException) { + Crashlytics.logException(e) + Log.e(TAG, "error", e) + } + + // Cancel the persistent notification. + stopForeground(true) + + stopLocationListeners() + timer?.cancel() + } + + fun cancel(){ + timer?.cancel() + // stopLocationListeners() + timer = null + } + + @SuppressLint("MissingPermission") + private fun setUpLocationListeners() { + val locManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + + val networkLocationProvider = locManager.getProvider(LocationManager.NETWORK_PROVIDER) + if (networkLocationProvider != null) { + networkLocationListener = object : LocationListenerAdapter() { + override fun onLocationChanged(location: Location) { + Log.i(TAG, "Received Network location update " + location.latitude + ";" + location.longitude) + networkLocation = location + } + } + + locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, (60 * 1000).toLong(), 5f, networkLocationListener) + } + val gpsLocationProvider = locManager.getProvider(LocationManager.GPS_PROVIDER) + if (gpsLocationProvider != null) { + gpsLocationListener = object : LocationListenerAdapter() { + override fun onLocationChanged(location: Location) { + Log.i(TAG, "Received GPS location update " + location.latitude + ";" + location.longitude) + gpsLocation = location + } + } + locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, (60 * 1000).toLong(), 5f, gpsLocationListener) + } + } + + private fun stopLocationListeners() { + val locManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + + if (networkLocationListener != null) { + locManager.removeUpdates(networkLocationListener) + } + if (gpsLocationListener != null) { + locManager.removeUpdates(gpsLocationListener) + } + } + + fun sendAlarmEvent(on:Boolean):Boolean { + + if (this.client == null) { + toast("Alarm client is not available,wait...") + return false + } + + val data = NewData() + set = on + data.isAlarmActivated = on + + // save alarm state + // if (data.getExtras() != null) { + // lastData.putExtras(data.getExtras()); + // } + + val sendDataTask = SendDataTask() + val params = SendDataParams() + params.client = client + params.data = data + params.context = this + params.alarm = true + params.value = on + + sendDataTask.execute(params) + + + sendDataTask.addProgressListener { result -> + lastAlarmLog = result.alarmLog + } + return true + } + + override fun onBind(arg0: Intent): IBinder? { + return binder + } + + inner class ServiceBinder : Binder() { + + val service: MonitoringService + get() = this@MonitoringService + } + + companion object { + // Intent extra keys + const val DEVICE_ID = "device_id" + const val SERVER_HOST = "server_host" + const val PASSWORD = "password" + const val CONNECT = "connect" + const val OBJECT_NAME = "objname" + private val TAG = MonitoringService::class.simpleName + const val CHANNEL_ID = "Channel one" + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MqttPushClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MqttPushClient.java deleted file mode 100644 index 0752139..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MqttPushClient.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.sierrawireless.avphone.service; - -import java.io.UnsupportedEncodingException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttClient; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.MqttSecurityException; -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; - -import android.annotation.SuppressLint; -import android.util.Log; - -import com.google.gson.Gson; -import com.sierrawireless.avphone.model.AvPhoneData; - -public class MqttPushClient { - - private static final String LOGTAG = MqttPushClient.class.getName(); - - private MqttClient client; - private MqttConnectOptions opt; - - private Gson gson = new Gson(); - - @SuppressLint("DefaultLocale") - public MqttPushClient(String clientId, String password, String serverHost, MqttCallback callback) - throws MqttException { - - Log.d(LOGTAG, "new client: " + clientId + " - " + password + " - " + serverHost); - - this.client = new MqttClient("tcp://" + serverHost + ":1883", MqttClient.generateClientId(), - new MemoryPersistence()); - client.setCallback(callback); - - this.opt = new MqttConnectOptions(); - opt.setUserName(clientId.toUpperCase()); - opt.setPassword(password.toCharArray()); - opt.setKeepAliveInterval(30); - } - - public boolean isConnected() { - return client.isConnected(); - } - - public void connect() throws MqttSecurityException, MqttException { - Log.d(LOGTAG, "connecting"); - client.connect(opt); - } - - public void disconnect() throws MqttException { - if (client.isConnected()) { - client.disconnect(); - } - } - - public void push(NewData data) throws MqttException { - if (client.isConnected()) { - Log.i(LOGTAG, "Pushing data to the server : " + data); - String message = this.convertToJson(data); - - Log.d(LOGTAG, "Rest content : " + message); - - MqttMessage msg = null; - try { - msg = new MqttMessage(message.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - // won't happen, UTF-8 is available - } - msg.setQos(0); - - this.client.publish(opt.getUserName() + "/messages/json", msg); - } - } - - private String convertToJson(NewData data) { - long timestamp = System.currentTimeMillis(); - - Map> values = new HashMap>(); - - if (data.getRssi() != null) { - values.put(AvPhoneData.RSSI, Collections.singletonList(new DataValue(timestamp, data.getRssi()))); - values.put("_RSSI", Collections.singletonList(new DataValue(timestamp, data.getRssi()))); - } - - if (data.getRsrp() != null) { - values.put(AvPhoneData.RSRP, Collections.singletonList(new DataValue(timestamp, data.getRsrp()))); - values.put("_RSRP", Collections.singletonList(new DataValue(timestamp, data.getRsrp()))); - } - - if (data.getBatteryLevel() != null) { - values.put(AvPhoneData.BATTERY, - Collections.singletonList(new DataValue(timestamp, data.getBatteryLevel()))); - } - - if (data.getOperator() != null) { - values.put(AvPhoneData.OPERATOR, Collections.singletonList(new DataValue(timestamp, data.getOperator()))); - } - - if (data.getImei() != null) { - values.put(AvPhoneData.IMEI, Collections.singletonList(new DataValue(timestamp, data.getImei()))); - } - - if (data.getNetworkType() != null) { - values.put(AvPhoneData.SERVICE, Collections.singletonList(new DataValue(timestamp, data.getNetworkType()))); - // hack for data mapping - values.put("_NETWORK_SERVICE_TYPE", - Collections.singletonList(new DataValue(timestamp, data.getNetworkType()))); - } - - if (data.getLatitude() != null) { - values.put(AvPhoneData.LAT, Collections.singletonList(new DataValue(timestamp, data.getLatitude()))); - // hack for data mapping - values.put("_LATITUDE", Collections.singletonList(new DataValue(timestamp, data.getLatitude()))); - } - - if (data.getLongitude() != null) { - values.put(AvPhoneData.LONG, Collections.singletonList(new DataValue(timestamp, data.getLongitude()))); - // hack for data mapping - values.put("_LONGITUDE", Collections.singletonList(new DataValue(timestamp, data.getLongitude()))); - } - - if (data.getBytesReceived() != null) { - // hack for data mapping - values.put(AvPhoneData.BYTES_RECEIVED, - Collections.singletonList(new DataValue(timestamp, data.getBytesReceived()))); - values.put("_BYTES_RECEIVED", Collections.singletonList(new DataValue(timestamp, data.getBytesReceived()))); - } - - if (data.getBytesSent() != null) { - // hack for data mapping - values.put(AvPhoneData.BYTES_SENT, Collections.singletonList(new DataValue(timestamp, data.getBytesSent()))); - values.put("_BYTES_SENT", Collections.singletonList(new DataValue(timestamp, data.getBytesSent()))); - } - - if (data.isWifiActive() != null) { - values.put(AvPhoneData.ACTIVE_WIFI, Collections.singletonList(new DataValue(timestamp, data.isWifiActive()))); - } - - if (data.getRunningApps() != null) { - values.put(AvPhoneData.RUNNING_APPS, Collections.singletonList(new DataValue(timestamp, data.getRunningApps()))); - } - - if (data.getMemoryUsage() != null) { - values.put(AvPhoneData.MEMORY_USAGE, Collections.singletonList(new DataValue(timestamp, data.getMemoryUsage()))); - } - - if (data.getAndroidVersion() != null) { - values.put(AvPhoneData.ANDROID_VERSION, - Collections.singletonList(new DataValue(timestamp, data.getAndroidVersion()))); - // values.put("_FIRMWARE_VERSION", Collections.singletonList(new DataValue(timestamp, - // data.getAndroidVersion()))); - } - - if (data.isAlarmActivated() != null) { - values.put(AvPhoneData.ALARM, - Collections.singletonList(new DataValue(timestamp, data.isAlarmActivated()))); - } - - if (data.getCustomIntUp1() != null) { - values.put(AvPhoneData.CUSTOM_1, Collections.singletonList(new DataValue(timestamp, data.getCustomIntUp1()))); - } - if (data.getCustomIntUp2() != null) { - values.put(AvPhoneData.CUSTOM_2, Collections.singletonList(new DataValue(timestamp, data.getCustomIntUp2()))); - } - if (data.getCustomIntDown1() != null) { - values.put(AvPhoneData.CUSTOM_3, - Collections.singletonList(new DataValue(timestamp, data.getCustomIntDown1()))); - } - if (data.getCustomIntDown2() != null) { - values.put(AvPhoneData.CUSTOM_4, - Collections.singletonList(new DataValue(timestamp, data.getCustomIntDown2()))); - } - if (data.getCustomStr1() != null) { - values.put(AvPhoneData.CUSTOM_5, Collections.singletonList(new DataValue(timestamp, data.getCustomStr1()))); - } - if (data.getCustomStr2() != null) { - values.put(AvPhoneData.CUSTOM_6, Collections.singletonList(new DataValue(timestamp, data.getCustomStr2()))); - } - - return gson.toJson(Collections.singletonList(values)); - } - - class DataValue { - - DataValue(long timestamp, Object value) { - this.timestamp = timestamp; - this.value = value; - } - - long timestamp; - Object value; - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/MqttPushClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MqttPushClient.kt new file mode 100644 index 0000000..2737519 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/service/MqttPushClient.kt @@ -0,0 +1,138 @@ +package com.sierrawireless.avphone.service + +import android.annotation.SuppressLint +import android.util.Log +import com.google.gson.Gson +import com.sierrawireless.avphone.tools.DeviceInfo +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.model.AvPhoneData +import com.sierrawireless.avphone.model.AvPhoneObjectData +import org.eclipse.paho.client.mqttv3.* +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence +import java.io.UnsupportedEncodingException +import java.util.* + +class MqttPushClient @SuppressLint("DefaultLocale") +@Throws(MqttException::class) +internal constructor(clientId: String, password: String, serverHost: String, callback: MqttCallback) { + private val client: MqttClient + private val opt: MqttConnectOptions + private val gson = Gson() + private val objectsManager: ObjectsManager + val isConnected: Boolean + get() = client.isConnected + + init { + + DeviceInfo.generateSerial("") + Log.i(TAG, "new client: $clientId - $password - $serverHost") + + this.client = MqttClient("tcp://$serverHost:1883", MqttClient.generateClientId(), + MemoryPersistence()) + client.setCallback(callback) + + this.opt = MqttConnectOptions() + opt.userName = clientId.toUpperCase() + opt.password = password.toCharArray() + opt.keepAliveInterval = 30 + objectsManager = ObjectsManager.getInstance() + } + + @Throws(MqttException::class) + fun connect() { + client.connect(opt) + } + + @Throws(MqttException::class) + internal fun disconnect() { + if (client.isConnected) { + client.disconnect() + } + } + + @Throws(MqttException::class) + fun push(data: NewData) { + if (client.isConnected) { + Log.i(TAG, "Pushing data to the server : " + data) + val message = this.convertToJson(data) + Log.i(TAG, "push: message " + message) + + var msg: MqttMessage? = null + try { + msg = MqttMessage(message.toByteArray(charset("UTF-8"))) + } catch (e: UnsupportedEncodingException) { + // won't happen, UTF-8 is available + } + + if (msg != null) { + msg.qos = 0 + } + this.client.publish(opt.userName + "/messages/json", msg) + } + } + + private fun convertToJson(data: NewData): String { + val timestamp = System.currentTimeMillis() + + val values = HashMap>() + + if (data.rssi != null) { + values["_RSSI"] = listOf(DataValue(timestamp, data.rssi!!)) + } + + if (data.rsrp != null) { + values["_RSRP"] = listOf(DataValue(timestamp, data.rsrp!!)) + } + + if (data.operator != null) { + values["_NETWORK_OPERATOR"] = listOf(DataValue(timestamp, data.operator!!)) + } + + + if (data.networkType != null) { + values["_NETWORK_SERVICE_TYPE"] = listOf(DataValue(timestamp, data.networkType!!)) + } + + if (data.latitude != null) { + values["_LATITUDE"] = listOf(DataValue(timestamp, data.latitude!!)) + } + + if (data.longitude != null) { + values["_LONGITUDE"] = listOf(DataValue(timestamp, data.longitude!!)) + } + + if (data.bytesReceived != null) { + values["_BYTES_RECEIVED"] = listOf(DataValue(timestamp, data.bytesReceived!!)) + } + + if (data.bytesSent != null) { + values["_BYTES_SENT"] = listOf(DataValue(timestamp, data.bytesSent!!)) + } + + if (data.isAlarmActivated != null) { + values[AvPhoneData.ALARM] = listOf(DataValue(timestamp, data.isAlarmActivated!!)) + } else { + val obj = objectsManager.currentObject + var pos: Int? = 1 + var key: String? + for (ldata in obj!!.datas) { + key = ldata.path ?: obj.name + "." + AvPhoneData.CUSTOM + pos!!.toString() + if (ldata.mode != AvPhoneObjectData.Mode.None) { + values[key] = listOf(DataValue(timestamp, ldata.current!!)) + } else { + values[key] = listOf(DataValue(timestamp, ldata.defaults)) + } + pos = pos!! + 1 + } + } + return gson.toJson(listOf>>(values)) + } + + //timestamp is used when the massage is sent for each entry. don't remove it... + @Suppress("UNUSED") + internal inner class DataValue(var timestamp: Long, var value: Any) + + companion object { + private val TAG = MqttPushClient::class.simpleName + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/NewData.java b/mainActivity/src/main/java/com/sierrawireless/avphone/service/NewData.java deleted file mode 100644 index 8b51b67..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/service/NewData.java +++ /dev/null @@ -1,256 +0,0 @@ -package com.sierrawireless.avphone.service; - -import android.content.Intent; -import android.os.Bundle; - -public class NewData extends Intent { - - public static final String NEW_DATA = "com.sierrawireless.avphone.newdata"; - - // keys used for broadcasting new data events - private static final String NEW_DATA_PREFIX = "newdata."; - private static final String RSSI_KEY = NEW_DATA_PREFIX + "rssi"; - private static final String RSRP_KEY = NEW_DATA_PREFIX + "rsrp"; - private static final String BATTERY_KEY = NEW_DATA_PREFIX + "battery"; - private static final String OPERATOR_KEY = NEW_DATA_PREFIX + "operator"; - private static final String NETWORK_TYPE_KEY = NEW_DATA_PREFIX + "networktype"; - private static final String IMEI_KEY = NEW_DATA_PREFIX + "imei"; - private static final String LATITUDE_KEY = NEW_DATA_PREFIX + "latitude"; - private static final String LONGITUDE_KEY = NEW_DATA_PREFIX + "longitude"; - private static final String BYTES_SENT_KEY = NEW_DATA_PREFIX + "bytessent"; - private static final String BYTES_RECEIVED_KEY = NEW_DATA_PREFIX + "bytesreceived"; - private static final String ACTIVE_WIFI_KEY = NEW_DATA_PREFIX + "activewifi"; - private static final String RUNNING_APPS_KEY = NEW_DATA_PREFIX + "runningapps"; - private static final String MEMORY_USAGE_KEY = NEW_DATA_PREFIX + "memory"; - private static final String ANDROID_VERSION_KEY = NEW_DATA_PREFIX + "androidversion"; - - private static final String ALARM_KEY = NEW_DATA_PREFIX + "alarm"; - - private static final String CUSTOM_1 = NEW_DATA_PREFIX + "custom.1"; - private static final String CUSTOM_2 = NEW_DATA_PREFIX + "custom.2"; - private static final String CUSTOM_3 = NEW_DATA_PREFIX + "custom.3"; - private static final String CUSTOM_4 = NEW_DATA_PREFIX + "custom.4"; - private static final String CUSTOM_5 = NEW_DATA_PREFIX + "custom.5"; - private static final String CUSTOM_6 = NEW_DATA_PREFIX + "custom.6"; - - public NewData() { - super(NEW_DATA); - this.putExtras(new Bundle()); - } - - public Integer getRssi() { - return (Integer) this.getExtras().get(RSSI_KEY); - } - - public void setRssi(Integer rssi) { - if (rssi != null && rssi < 0) { - this.putExtra(RSSI_KEY, rssi.intValue()); - } - } - - public Integer getRsrp() { - return (Integer) this.getExtras().get(RSRP_KEY); - } - - public void setRsrp(Integer rsrp) { - if (rsrp != null && rsrp < 0) { - this.putExtra(RSRP_KEY, rsrp.intValue()); - } - } - - public String getOperator() { - return (String) this.getExtras().get(OPERATOR_KEY); - } - - public void setOperator(String operator) { - if (operator != null) { - this.putExtra(OPERATOR_KEY, operator); - } - } - - public String getImei() { - return (String) this.getExtras().get(IMEI_KEY); - } - - public void setImei(String imei) { - if (imei != null) { - this.putExtra(IMEI_KEY, imei); - } - } - - public String getNetworkType() { - return (String) this.getExtras().get(NETWORK_TYPE_KEY); - } - - public void setNetworkType(String networkType) { - if (networkType != null) { - this.putExtra(NETWORK_TYPE_KEY, networkType); - } - } - - public Boolean isWifiActive() { - return (Boolean) this.getExtras().get(ACTIVE_WIFI_KEY); - } - - public void setActiveWifi(Boolean activeWifi) { - if (activeWifi != null) { - this.putExtra(ACTIVE_WIFI_KEY, activeWifi.booleanValue()); - } - } - - public Float getBatteryLevel() { - return (Float) this.getExtras().get(BATTERY_KEY); - } - - public void setBatteryLevel(Float batteryLevel) { - if (batteryLevel != null && batteryLevel > 0F) { - this.putExtra(BATTERY_KEY, batteryLevel); - } - - } - - public Double getLatitude() { - return (Double) this.getExtras().get(LATITUDE_KEY); - } - - public void setLatitude(Double latitude) { - if (latitude != null) { - this.putExtra(LATITUDE_KEY, latitude.doubleValue()); - } - } - - public Double getLongitude() { - return (Double) this.getExtras().get(LONGITUDE_KEY); - } - - public void setLongitude(Double longitude) { - if (longitude != null) { - this.putExtra(LONGITUDE_KEY, longitude.doubleValue()); - } - } - - public void setBytesReceived(Long received) { - if (received != null && received > 0L) { - this.putExtra(BYTES_RECEIVED_KEY, received.longValue()); - } - } - - public Long getBytesReceived() { - return (Long) this.getExtras().get(BYTES_RECEIVED_KEY); - } - - public void setBytesSent(Long sent) { - if (sent != null && sent > 0L) { - this.putExtra(BYTES_SENT_KEY, sent.longValue()); - } - } - - public Long getBytesSent() { - return (Long) this.getExtras().get(BYTES_SENT_KEY); - } - - public Integer getRunningApps() { - return (Integer) this.getExtras().get(RUNNING_APPS_KEY); - } - - public void setRunningApps(Integer nbApps) { - if (nbApps != null && nbApps > 0) { - this.putExtra(RUNNING_APPS_KEY, nbApps.intValue()); - } - } - - public Float getMemoryUsage() { - return (Float) this.getExtras().get(MEMORY_USAGE_KEY); - } - - public void setMemoryUsage(Float memoryUsage) { - if (memoryUsage != null && memoryUsage > 0F) { - this.putExtra(MEMORY_USAGE_KEY, memoryUsage); - } - } - - public String getAndroidVersion() { - return (String) this.getExtras().get(ANDROID_VERSION_KEY); - } - - public void setAndroidVersion(String version) { - if (version != null) { - this.putExtra(ANDROID_VERSION_KEY, version); - } - } - - public Boolean isAlarmActivated() { - return (Boolean) this.getExtras().get(ALARM_KEY); - } - - public void setAlarmActivated(Boolean activated) { - if (activated != null) { - this.putExtra(ALARM_KEY, activated.booleanValue()); - } - } - - public int size() { - return this.getExtras().size(); - } - - public Integer getCustomIntUp1() { - return (Integer) this.getExtras().get(CUSTOM_1); - } - - public void setCustomIntUp1(Integer custom1) { - if (custom1 != null) { - this.putExtra(CUSTOM_1, custom1); - } - } - - public Integer getCustomIntUp2() { - return (Integer) this.getExtras().get(CUSTOM_2); - } - - public void setCustomIntUp2(Integer custom2) { - if (custom2 != null) { - this.putExtra(CUSTOM_2, custom2); - } - } - - public Integer getCustomIntDown2() { - return (Integer) this.getExtras().get(CUSTOM_4); - } - - public void setCustomIntDown2(Integer custom2) { - if (custom2 != null) { - this.putExtra(CUSTOM_4, custom2); - } - } - - public Integer getCustomIntDown1() { - return (Integer) this.getExtras().get(CUSTOM_3); - } - - public void setCustomIntDown1(Integer custom1) { - if (custom1 != null) { - this.putExtra(CUSTOM_3, custom1); - } - } - - public String getCustomStr1() { - return (String) this.getExtras().get(CUSTOM_5); - } - - public String getCustomStr2() { - return (String) this.getExtras().get(CUSTOM_6); - } - - public void setCustomStr1(String customStr1) { - if (customStr1 != null) { - this.putExtra(CUSTOM_5, customStr1); - } - } - - public void setCustomStr2(String customStr2) { - if (customStr2 != null) { - this.putExtra(CUSTOM_6, customStr2); - } - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/service/NewData.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/service/NewData.kt new file mode 100644 index 0000000..c44d1e2 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/service/NewData.kt @@ -0,0 +1,137 @@ +package com.sierrawireless.avphone.service + +import android.content.Intent +import android.os.Bundle +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.model.AvPhoneObjectData + +class NewData internal constructor() : Intent(NEW_DATA) { + + var rssi: Int? + get() = if (this.extras == null) null else (this.extras!!.get(RSSI_KEY) as Int?) + + internal set(rssi) { + if (rssi != null && rssi < 0) { + this.putExtra(RSSI_KEY, rssi.toInt()) + } + } + + var rsrp: Int? + get() = if (this.extras == null) null else (this.extras!!.get(RSRP_KEY) as Int?) + internal set(rsrp) { + if (rsrp != null && rsrp < 0) { + this.putExtra(RSRP_KEY, rsrp.toInt()) + } + } + + var operator: String? + get() = if (this.extras == null) null else (this.extras!!.get(OPERATOR_KEY) as String?) + internal set(operator) { + if (operator != null) { + this.putExtra(OPERATOR_KEY, operator) + } + } + + var imei: String? + get() = if (this.extras == null) null else (this.extras!!.get(IMEI_KEY) as String?) + set(imei) { + if (imei != null) { + this.putExtra(IMEI_KEY, imei) + } + } + + var networkType: String? + get() = if (this.extras == null) null else (this.extras!!.get(NETWORK_TYPE_KEY) as String?) + internal set(networkType) { + if (networkType != null) { + this.putExtra(NETWORK_TYPE_KEY, networkType) + } + } + + var latitude: Double? + get() = if (this.extras == null) null else (this.extras!!.get(LATITUDE_KEY) as Double?) + internal set(latitude) { + if (latitude != null) { + this.putExtra(LATITUDE_KEY, latitude.toDouble()) + } + } + + var longitude: Double? + get() = if (this.extras == null) null else (this.extras!!.get(LONGITUDE_KEY) as Double?) + internal set(longitude) { + if (longitude != null) { + this.putExtra(LONGITUDE_KEY, longitude.toDouble()) + } + } + + var bytesReceived: Long? + get() = if (this.extras == null) null else (this.extras!!.get(BYTES_RECEIVED_KEY) as Long?) + internal set(received) { + if (received != null && received > 0L) { + this.putExtra(BYTES_RECEIVED_KEY, received.toLong()) + } + } + + var bytesSent: Long? + get() = if (this.extras == null) null else (this.extras!!.get(BYTES_SENT_KEY) as Long?) + internal set(sent) { + if (sent != null && sent > 0L) { + this.putExtra(BYTES_SENT_KEY, sent.toLong()) + } + } + + internal var isAlarmActivated: Boolean? + get() = if (this.extras == null) null else (this.extras!!.get(ALARM_KEY) as Boolean?) + set(value) { + this.putExtra(ALARM_KEY, value) + } + + + init { + this.putExtras(Bundle()) + } + + fun size(): Int { + return this.extras!!.size() + } + + internal fun setCustom() { + val objectsManager = ObjectsManager.getInstance() + val obj = objectsManager.currentObject + var pos: Int? = 1 + for (data in obj!!.datas) { + val key:String? = if (data.path == null) { + obj.name + "." + CUSTOM + pos!!.toString() + }else{ + data.path + } + if (data.mode != AvPhoneObjectData.Mode.None) { + this.putExtra(key, data.current!!) + } else { + this.putExtra(key, data.defaults) + } + pos = pos!! + 1 + } + } + + companion object { + const val NEW_DATA = "com.sierrawireless.avphone.newdata" + + // keys used for broadcasting new data events + private const val NEW_DATA_PREFIX = "newdata." + private const val RSSI_KEY = NEW_DATA_PREFIX + "rssi" + private const val RSRP_KEY = NEW_DATA_PREFIX + "rsrp" + private const val OPERATOR_KEY = NEW_DATA_PREFIX + "operator" + private const val NETWORK_TYPE_KEY = NEW_DATA_PREFIX + "networktype" + private const val IMEI_KEY = NEW_DATA_PREFIX + "imei" + private const val LATITUDE_KEY = NEW_DATA_PREFIX + "latitude" + private const val LONGITUDE_KEY = NEW_DATA_PREFIX + "longitude" + private const val BYTES_SENT_KEY = NEW_DATA_PREFIX + "bytessent" + private const val BYTES_RECEIVED_KEY = NEW_DATA_PREFIX + "bytesreceived" + + private const val ALARM_KEY = NEW_DATA_PREFIX + "alarm" + + private const val CUSTOM = NEW_DATA_PREFIX + "custom." + } +} + diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AlertRuleClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AlertRuleClient.java deleted file mode 100644 index 08e4a6b..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AlertRuleClient.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.alert.v1.AlertRule; -import net.airvantage.utils.IAirVantageClient; - -import com.sierrawireless.avphone.model.AvPhoneApplication; - -public class AlertRuleClient implements IAlertRuleClient { - - private IAirVantageClient client; - - public AlertRuleClient(IAirVantageClient client) { - this.client = client; - } - - @Override - public AlertRule getAlertRule(String serialNumber) throws IOException, AirVantageException { - String alertRuleName = AvPhoneApplication.ALERT_RULE_NAME; - return client.getAlertRuleByName(alertRuleName); - } - - @Override - public AlertRule createAlertRule() throws IOException, AirVantageException { - AlertRule alertRule = AvPhoneApplication.createAlertRule(); - return client.createAlertRule(alertRule); - } - - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AlertRuleClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AlertRuleClient.kt new file mode 100644 index 0000000..0b2f947 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AlertRuleClient.kt @@ -0,0 +1,40 @@ +package com.sierrawireless.avphone.task + +import java.io.IOException + +import net.airvantage.model.AirVantageException +import net.airvantage.model.alert.v1.AlertRule +import net.airvantage.utils.IAirVantageClient + +import com.sierrawireless.avphone.model.AvPhoneApplication +import com.sierrawireless.avphone.tools.Tools +import net.airvantage.model.AvSystem + +class AlertRuleClient internal constructor(private val client: IAirVantageClient) : IAlertRuleClient { + + @Throws(IOException::class, AirVantageException::class) + override fun getAlertRule(serialNumber: String, system: AvSystem): AlertRule? { + return client.getAlertRuleByName(Tools.buildAlertName(), system) + } + + @Throws(IOException::class, AirVantageException::class) + override fun createAlertRule(Application: String, system: AvSystem) { + val alertRule = AvPhoneApplication.createAlertRule(system) + client.createAlertRule(alertRule, Application, system) + } + + + @Throws(IOException::class, AirVantageException::class) + override fun updateAlertRule(Application: String, system: AvSystem, alertRule: AlertRule) { + AvPhoneApplication.updateAlertRule(system, alertRule) + client.updateAlertRule(alertRule, Application, system) + } + + @Throws(IOException::class, AirVantageException::class) + override fun deleteAlertRule(alert: AlertRule) { + client.deleteAlertRule(alert) + } + + + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ApplicationClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ApplicationClient.java deleted file mode 100644 index fa6d441..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ApplicationClient.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.Application; -import net.airvantage.model.ApplicationData; -import net.airvantage.model.AvSystem; -import net.airvantage.model.Protocol; -import net.airvantage.model.User; -import net.airvantage.utils.IAirVantageClient; -import net.airvantage.utils.Utils; - -import com.sierrawireless.avphone.model.AvPhoneApplication; -import com.sierrawireless.avphone.model.CustomDataLabels; - -public class ApplicationClient implements IApplicationClient { - - private IAirVantageClient client; - private User currentUser = null; - - public ApplicationClient(IAirVantageClient client) { - this.client = client; - } - - @Override - public Application ensureApplicationExists() throws IOException, AirVantageException { - Application application = getApplication(); - if (application == null) { - application = createApplication(); - setApplicationCommunication(application.uid); - } - return application; - } - - @Override - public void setApplicationData(String applicationUid, CustomDataLabels customData) - throws IOException, AirVantageException { - List data = AvPhoneApplication.createApplicationData(customData); - client.setApplicationData(applicationUid, data); - } - - protected Application getApplication() throws IOException, AirVantageException { - List applications = client.getApplications(AvPhoneApplication.appType(getCurrentUsername())); - return Utils.first(applications); - } - - private String getCurrentUsername() { - if (currentUser == null) { - try { - currentUser = client.getCurrentUser(); - } catch (final IOException e) { - return ""; - } catch (final AirVantageException e) { - return ""; - } - } - return currentUser.email; - } - - @Override - public Application createApplication() throws IOException, AirVantageException { - Application application = AvPhoneApplication.createApplication(getCurrentUsername()); - return client.createApplication(application); - } - - @Override - public void setApplicationCommunication(String applicationUid) throws IOException, AirVantageException { - List protocols = AvPhoneApplication.createProtocols(); - client.setApplicationCommunication(applicationUid, protocols); - } - - @Override - public void addApplication(AvSystem system, Application application) throws IOException, AirVantageException { - client.updateSystem(systemWithApplication(system, application)); - } - - protected AvSystem systemWithApplication(AvSystem system, Application appToAdd) { - - AvSystem res = new AvSystem(); - res.uid = system.uid; - res.type = system.type; - res.applications = new ArrayList(); - - boolean appAlreadyLinked = false; - - if (system.applications != null) { - for (Application systemApp : system.applications) { - Application resApp = new Application(); - resApp.uid = systemApp.uid; - res.applications.add(resApp); - if (resApp.uid == appToAdd.uid) { - appAlreadyLinked = true; - } - } - } - if (!appAlreadyLinked) { - Application addedApp = new Application(); - addedApp.uid = appToAdd.uid; - res.applications.add(addedApp); - } - - return res; - - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ApplicationClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ApplicationClient.kt new file mode 100644 index 0000000..ab374f3 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ApplicationClient.kt @@ -0,0 +1,109 @@ +package com.sierrawireless.avphone.task + +import android.util.Log +import com.sierrawireless.avphone.model.AvPhoneApplication +import com.sierrawireless.avphone.model.AvPhoneObjectData +import net.airvantage.model.AirVantageException +import net.airvantage.model.Application +import net.airvantage.model.AvSystem +import net.airvantage.model.User +import net.airvantage.utils.IAirVantageClient +import net.airvantage.utils.Utils +import java.io.IOException +import java.util.* + +class ApplicationClient internal constructor(private val client: IAirVantageClient) : IApplicationClient { + private var currentUser: User? = null + private var mPhoneName: String? = null + + private val application: Application? + @Throws(IOException::class, AirVantageException::class) + get() { + val applications = client.getApplications(AvPhoneApplication.appType(currentUsername, mPhoneName!!)) + return Utils.first(applications) + } + + private val currentUsername: String + get() { + if (currentUser == null) { + try { + currentUser = client.currentUser + } catch (e: IOException) { + return "" + } catch (e: AirVantageException) { + return "" + } + + } + return currentUser!!.email!! + } + + @Throws(IOException::class, AirVantageException::class) + override fun ensureApplicationExists(phoneName: String): Application { + mPhoneName = phoneName + var application = application + + if (application == null) { + application = createApplication(phoneName) + setApplicationCommunication(application.uid!!) + } + Log.i(TAG, "ensureApplicationExists: application is " + application.uid) + return application + } + + @Throws(IOException::class, AirVantageException::class) + override fun setApplicationData(applicationUid: String, customData: ArrayList, obj: String) { + val data = AvPhoneApplication.createApplicationData(customData, obj) + client.setApplicationData(applicationUid, data) + } + + @Throws(IOException::class, AirVantageException::class) + override fun createApplication(phoneName: String): Application { + val application = AvPhoneApplication.createApplication(currentUsername, phoneName) + return client.createApplication(application) + } + + @Throws(IOException::class, AirVantageException::class) + override fun setApplicationCommunication(applicationUid: String) { + val protocols = AvPhoneApplication.createProtocols() + client.setApplicationCommunication(applicationUid, protocols) + } + + @Throws(IOException::class, AirVantageException::class) + override fun addApplication(system: AvSystem, application: Application) { + client.updateSystem(systemWithApplication(system, application)) + } + + private fun systemWithApplication(system: AvSystem, appToAdd: Application): AvSystem { + + val res = AvSystem() + res.uid = system.uid + res.type = system.type + res.applications = ArrayList() + + var appAlreadyLinked = false + + if (system.applications != null) { + for (systemApp in system.applications!!) { + val resApp = Application() + resApp.uid = systemApp.uid + res.applications!!.add(resApp) + if (resApp.uid == appToAdd.uid) { + appAlreadyLinked = true + } + } + } + if (!appAlreadyLinked) { + val addedApp = Application() + addedApp.uid = appToAdd.uid + res.applications!!.add(addedApp) + } + + return res + + } + + companion object { + private val TAG = ApplicationClient::class.simpleName + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AsyncTaskFactory.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AsyncTaskFactory.java deleted file mode 100644 index ccbb0a7..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AsyncTaskFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sierrawireless.avphone.task; - -import net.airvantage.model.AvError; -import net.airvantage.utils.AirVantageClient; -import android.content.Context; -import android.os.AsyncTask; - -public class AsyncTaskFactory implements IAsyncTaskFactory { - - private Context context; - - public AsyncTaskFactory(Context context) { - this.context = context; - } - - public SyncWithAvTask syncAvTask(String serverHost, String token) { - - AirVantageClient avClient = new AirVantageClient(serverHost, token); - - IApplicationClient appClient = new ApplicationClient(avClient); - ISystemClient systemClient = new SystemClient(avClient); - IAlertRuleClient alertRuleClient = new AlertRuleClient(avClient); - IUserClient userClient = new UserClient(avClient); - - return new ProgressSyncWithAvTask(appClient, systemClient, alertRuleClient, userClient, context); - } - - public AsyncTask logoutTask(String serverHost, String token) { - - AirVantageClient client = new AirVantageClient(serverHost, token); - - return new LogoutTask(client); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AsyncTaskFactory.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AsyncTaskFactory.kt new file mode 100644 index 0000000..c7af74e --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AsyncTaskFactory.kt @@ -0,0 +1,64 @@ +package com.sierrawireless.avphone.task + +import android.content.Context +import android.os.AsyncTask + +import net.airvantage.model.AvError +import net.airvantage.utils.AirVantageClient + +class AsyncTaskFactory(private val context: Context) : IAsyncTaskFactory { + + override fun syncAvTask(serverHost: String, token: String): SyncWithAvTask { + + val avClient = AirVantageClient(serverHost, token) + + val appClient = ApplicationClient(avClient) + val systemClient = SystemClient(avClient) + val alertRuleClient = AlertRuleClient(avClient) + val userClient = UserClient(avClient) + + return ProgressSyncWithAvTask(appClient, systemClient, alertRuleClient, userClient, context) + } + + + + override fun updateTask(serverHost: String, token: String): UpdateTask { + + val avClient = AirVantageClient(serverHost, token) + + val appClient = ApplicationClient(avClient) + val systemClient = SystemClient(avClient) + val alertRuleClient = AlertRuleClient(avClient) + val userClient = UserClient(avClient) + + return ProgressUpdateTask(appClient, systemClient, alertRuleClient, userClient, context) + } + + override fun getUserTak(serverHost: String, token: String): GetUserTask { + + val avClient = AirVantageClient(serverHost, token) + + val userClient = UserClient(avClient) + + return ProgressGetUserTask(userClient, context) + } + + override fun deleteSystemTak(serverHost: String, token: String): DeleteSystemTask { + + val avClient = AirVantageClient(serverHost, token) + val systemClient = SystemClient(avClient) + val alertRuleClient = AlertRuleClient(avClient) + + val userClient = UserClient(avClient) + + return ProgressDeleteSystemTask(systemClient, userClient, alertRuleClient, context) + } + + + override fun logoutTask(serverHost: String, token: String): AsyncTask { + + val client = AirVantageClient(serverHost, token) + + return LogoutTask(client) + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/AvPhoneTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AvPhoneTask.kt new file mode 100644 index 0000000..ffa104c --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/AvPhoneTask.kt @@ -0,0 +1,78 @@ +package com.sierrawireless.avphone.task + +import android.app.Activity +import android.os.AsyncTask +import android.os.Build +import android.text.Html +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.message.IMessageDisplayer +import com.sierrawireless.avphone.model.AvPhoneApplication +import net.airvantage.model.AvError +import net.airvantage.model.UserRights + +abstract class AvPhoneTask : AsyncTask() { + + fun displayTaskError(error: AvError, displayer: IMessageDisplayer, context: Activity, userClient: IUserClient, deviceName: String) { + + if (error.missingRights()) { + val message = missingRightsMessage(error, context) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + displayer.showErrorMessage(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY)) + }else{ + @Suppress("DEPRECATION") + displayer.showErrorMessage(Html.fromHtml(message)) + } + } else if (error.systemAlreadyExists()) { + displayer.showError(R.string.sync_error_system_exists) + } else if (error.gatewayAlreadyExists()) { + displayer.showError(R.string.sync_error_gateway_exists) + } else if (error.applicationAlreadyUsed()) { + val user = userClient.user + if (user == null) { + displayer.showError(R.string.sync_error_no_user_data) + } else { + displayer.showError(R.string.sync_error_app_exists, AvPhoneApplication.appType(user.name!!, deviceName)) + } + } else if (error.tooManyAlerRules()) { + displayer.showError(R.string.sync_error_too_many_rules) + } else if (error.cantCreateApplication()) { + displayer.showError(R.string.sync_error_no_right_create_application) + } else if (error.cantCreateSystem()) { + displayer.showError(R.string.sync_error_no_right_create_system) + } else if (error.cantCreateAlertRule()) { + displayer.showError(R.string.sync_error_no_right_create_alert_rule) + } else if (error.cantUpdateApplication()) { + displayer.showError(R.string.sync_error_no_right_update_app) + } else if (error.cantUpdateSystem()) { + displayer.showError(R.string.sync_error_no_right_update_system) + } else if (error.forbidden()) { + val method = error.errorParameters[0] + val url = error.errorParameters[1] + displayer.showError(R.string.sync_error_forbidden, method, url) + } else { + displayer.showError(R.string.sync_error_unexpected, error.error) + } + + } + + private fun missingRightsMessage(error: AvError, context: android.app.Activity): String { + val missingRights = error.errorParameters + val message = StringBuilder() + if (missingRights.size == 1 && missingRights[0] == "No Connection" ) { + message.append("We have no data connection") + } else { + message.append(context.getText(R.string.auth_not_enough_rights)) + message.append("
") + message.append(context.getText(R.string.auth_missing_rights)) + message.append("
") + + + for (missingRight in missingRights) { + message.append("• ") + message.append(UserRights.asString(missingRight, context)) + message.append("
") + } + } + return message.toString() + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemProgress.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemProgress.kt new file mode 100644 index 0000000..e1fbc7f --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemProgress.kt @@ -0,0 +1,16 @@ +package com.sierrawireless.avphone.task + +import com.sierrawireless.avphone.R + +enum class DeleteSystemProgress(val stringId: Int, val value: Int) { + // There is no "CREATING_SYSTEM', since it is done + // in the single 'ensureApplicationExists' method + CHECKING_RIGHTS(R.string.progress_checking_rights, 0), + CHECKING_SYSTEM(R.string.progress_checking_system, 1), + CHECKING_ALERTRULE(R.string.progress_checking_alert_rule, 2), + DELETING_ALERTRULE(R.string.progress_deleting_alert_rule, 3), + + DELETING_SYSTEM(R.string.progress_deleting_system, 4), + DONE(R.string.progress_done, 5) + +} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemResult.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemResult.kt new file mode 100644 index 0000000..3ab5d89 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemResult.kt @@ -0,0 +1,22 @@ +package com.sierrawireless.avphone.task + +import net.airvantage.model.AvError +import net.airvantage.model.User + +class DeleteSystemResult { + + var error: AvError? = null + + var user: User? = null + + val isError: Boolean + get() = error != null + + internal constructor(error: AvError) { + this.error = error + } + + internal constructor(user: User) { + this.user = user + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemTask.kt new file mode 100644 index 0000000..6c8cf2e --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/DeleteSystemTask.kt @@ -0,0 +1,109 @@ +package com.sierrawireless.avphone.task + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import android.util.Log +import com.crashlytics.android.Crashlytics +import com.sierrawireless.avphone.tools.DeviceInfo +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.message.IMessageDisplayer +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvError +import java.io.IOException +import java.util.* + +typealias DeleteSystemListenerAlias = (DeleteSystemResult) -> Unit + +open class DeleteSystemTask internal constructor(private val systemClient: ISystemClient, private val userClient: IUserClient, private val alertRuleClient: IAlertRuleClient,@field:SuppressLint("StaticFieldLeak") +protected val context: Context) : AvPhoneTask() { + private val syncListeners = ArrayList() + + + fun addProgressListener(listener: DeleteSystemListenerAlias) { + this.syncListeners.add(listener) + } + + + @SuppressLint("DefaultLocale") + override fun doInBackground(vararg params: Void): DeleteSystemResult { + + try { + + publishProgress(DeleteSystemProgress.CHECKING_RIGHTS) + + val missingRights = userClient.checkRights() + if (!missingRights.isEmpty()) { + return DeleteSystemResult(AvError(AvError.MISSING_RIGHTS, missingRights)) + } + + val systemType: String + val user = userClient.user + + val objectsManager = ObjectsManager.getInstance() + + systemType = objectsManager.savedObjectName!! + + // For emulator and iOs compatibility sake, using generated serial. + val serialNumber = DeviceInfo.generateSerial(user!!.uid!!) + + // Save Device serial in context + if (context is MainActivity) { + context.systemSerial = serialNumber + } + + + publishProgress(DeleteSystemProgress.CHECKING_SYSTEM) + val system = this.systemClient.getSystem(serialNumber, systemType, DeviceInfo.deviceName!!) + + publishProgress(DeleteSystemProgress.CHECKING_ALERTRULE) + + + if (system != null) { + val alertRule = this.alertRuleClient.getAlertRule(serialNumber, system) + if (alertRule != null) { + + publishProgress(DeleteSystemProgress.DELETING_ALERTRULE) + + this.alertRuleClient.deleteAlertRule(alertRule) + } + publishProgress(DeleteSystemProgress.DELETING_SYSTEM) + systemClient.deleteSystem(system) + } + publishProgress(DeleteSystemProgress.DONE) + return DeleteSystemResult(user) + + + } catch (e: AirVantageException) { + publishProgress(DeleteSystemProgress.DONE) + return DeleteSystemResult(e.error!!) + } catch (e: IOException) { + Crashlytics.logException(e) + Log.e(MainActivity::class.java.name, "Error when trying to synchronize with server", e) + publishProgress(DeleteSystemProgress.DONE) + return DeleteSystemResult(AvError("unkown.error")) + } + + } + + override fun onPostExecute(result: DeleteSystemResult) { + super.onPostExecute(result) + for (listener in syncListeners) { + listener.invoke(result) + } + } + + fun showResult(result: DeleteSystemResult, displayer: IMessageDisplayer, context: Activity) { + + if (result.isError) { + val error = result.error!! + displayTaskError(error, displayer, context, userClient, "") + + } else { + displayer.showSuccess(R.string.sync_success) + } + } +} + diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserParams.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserParams.kt new file mode 100644 index 0000000..74a8421 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserParams.kt @@ -0,0 +1,8 @@ +package com.sierrawireless.avphone.task + +import com.sierrawireless.avphone.activity.MainActivity + +class GetUserParams { + var imei: String? = null + var activity: MainActivity? = null +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserResult.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserResult.kt new file mode 100644 index 0000000..9ce9a24 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserResult.kt @@ -0,0 +1,22 @@ +package com.sierrawireless.avphone.task + +import net.airvantage.model.AvError +import net.airvantage.model.User + +class GetUserResult { + + var error: AvError? = null + + var user: User? = null + + val isError: Boolean + get() = error != null + + constructor(error: AvError) { + this.error = error + } + + constructor(user: User) { + this.user = user + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserTask.kt new file mode 100644 index 0000000..6e439e8 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/GetUserTask.kt @@ -0,0 +1,63 @@ +package com.sierrawireless.avphone.task + + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.message.IMessageDisplayer +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvError +import java.util.* + +typealias GetUserListener = (GetUserResult) -> Unit + +open class GetUserTask internal constructor(private val userClient: IUserClient, @field:SuppressLint("StaticFieldLeak") +protected val context: Context) : AvPhoneTask() { + + + private val syncListeners = ArrayList() + + fun addProgressListener(listener: GetUserListener) { + this.syncListeners.add(listener) + } + + @SuppressLint("DefaultLocale") + override fun doInBackground(vararg params: GetUserParams): GetUserResult { + + try { + + + val missingRights = userClient.checkRights() + if (!missingRights.isEmpty()) { + return GetUserResult(AvError(AvError.MISSING_RIGHTS, missingRights)) + } + + val user = userClient.user!! + + return GetUserResult(user) + } catch (e: AirVantageException) { + + return GetUserResult(e.error!!) + } + + } + + override fun onPostExecute(result: GetUserResult) { + super.onPostExecute(result) + for (listener in syncListeners) { + listener.invoke(result) + } + } + + fun showResult(result: GetUserResult, displayer: IMessageDisplayer, context: Activity) { + + if (result.isError) { + val error = result.error + displayTaskError(error!!, displayer, context, userClient, "") + + } else { + displayer.showSuccess(R.string.sync_success) + } + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAlertRuleClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAlertRuleClient.java deleted file mode 100644 index 93e8cb0..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAlertRuleClient.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.alert.v1.AlertRule; - -public interface IAlertRuleClient { - - AlertRule getAlertRule(String serialNumber) throws IOException, AirVantageException; - - AlertRule createAlertRule() throws IOException, AirVantageException; - - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAlertRuleClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAlertRuleClient.kt new file mode 100644 index 0000000..c732a9c --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAlertRuleClient.kt @@ -0,0 +1,24 @@ +package com.sierrawireless.avphone.task + +import java.io.IOException + +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvSystem +import net.airvantage.model.alert.v1.AlertRule + +interface IAlertRuleClient { + + @Throws(IOException::class, AirVantageException::class) + fun getAlertRule(serialNumber: String, system: AvSystem): AlertRule? + + @Throws(IOException::class, AirVantageException::class) + fun createAlertRule(Application: String, system: AvSystem) + + @Throws(IOException::class, AirVantageException::class) + fun updateAlertRule(Application: String, system: AvSystem, alertRule: AlertRule) + + + @Throws(IOException::class, AirVantageException::class) + fun deleteAlertRule(alert:AlertRule) + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IApplicationClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IApplicationClient.java deleted file mode 100644 index 25877f9..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IApplicationClient.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.Application; -import net.airvantage.model.AvSystem; - -import com.sierrawireless.avphone.model.CustomDataLabels; - -public interface IApplicationClient { - - Application ensureApplicationExists() throws IOException, AirVantageException; - - void setApplicationData(String applicationUid, CustomDataLabels customData) throws IOException, AirVantageException; - - Application createApplication() throws IOException, AirVantageException; - - void setApplicationCommunication(String applicationUid) throws IOException, AirVantageException; - - void addApplication(AvSystem system, Application application) throws IOException, AirVantageException; - -} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IApplicationClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IApplicationClient.kt new file mode 100644 index 0000000..8be260f --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IApplicationClient.kt @@ -0,0 +1,28 @@ +package com.sierrawireless.avphone.task + +import java.io.IOException +import java.util.ArrayList + +import net.airvantage.model.AirVantageException +import net.airvantage.model.Application +import net.airvantage.model.AvSystem + +import com.sierrawireless.avphone.model.AvPhoneObjectData + +interface IApplicationClient { + + @Throws(IOException::class, AirVantageException::class) + fun ensureApplicationExists(phoneName:String): Application + + @Throws(IOException::class, AirVantageException::class) + fun setApplicationData(applicationUid: String, customData: ArrayList, obj: String) + + @Throws(IOException::class, AirVantageException::class) + fun createApplication(phoneName: String): Application + + @Throws(IOException::class, AirVantageException::class) + fun setApplicationCommunication(applicationUid: String) + + @Throws(IOException::class, AirVantageException::class) + fun addApplication(system: AvSystem, application: Application) +} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAsyncTaskFactory.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAsyncTaskFactory.java deleted file mode 100644 index b1746d5..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAsyncTaskFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sierrawireless.avphone.task; - -import net.airvantage.model.AvError; -import android.os.AsyncTask; - -public interface IAsyncTaskFactory { - public SyncWithAvTask syncAvTask(String serverHost, String token); - public AsyncTask logoutTask(String serverHost, String token); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAsyncTaskFactory.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAsyncTaskFactory.kt new file mode 100644 index 0000000..0e159c3 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IAsyncTaskFactory.kt @@ -0,0 +1,14 @@ +package com.sierrawireless.avphone.task + +import net.airvantage.model.AvError +import android.os.AsyncTask + +interface IAsyncTaskFactory { + fun syncAvTask(serverHost: String, token: String): SyncWithAvTask + fun getUserTak(serverHost: String, token: String): GetUserTask + fun deleteSystemTak(serverHost: String, token: String): DeleteSystemTask + + fun logoutTask(serverHost: String, token: String): AsyncTask + + fun updateTask(serverHost: String, token: String): UpdateTask +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ISystemClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ISystemClient.java deleted file mode 100644 index da6a5c2..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ISystemClient.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.AvSystem; - -public interface ISystemClient { - - AvSystem getSystem(String serialNumber) throws IOException, AirVantageException; - - AvSystem createSystem(String serialNumber, String imei, String type, String mqttPassword, String applicationUid) - throws IOException, AirVantageException; - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ISystemClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ISystemClient.kt new file mode 100644 index 0000000..f3b6bf6 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ISystemClient.kt @@ -0,0 +1,20 @@ +package com.sierrawireless.avphone.task + +import java.io.IOException + +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvSystem + +interface ISystemClient { + + @Throws(IOException::class, AirVantageException::class) + fun getSystem(serialNumber: String, type: String, deviceName: String): AvSystem? + + @Throws(IOException::class, AirVantageException::class) + fun deleteSystem(system: AvSystem) + + @Throws(IOException::class, AirVantageException::class) + fun createSystem(serialNumber: String, iccid: String, type: String, mqttPassword: String, applicationUid: String, deviceName: String, userName: String, imei: String): AvSystem + fun updateSystem(system:AvSystem, serialNumber: String, iccid: String, type: String, mqttPassword: String, applicationUid: String, deviceName: String, userName: String, imei: String ) + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IUserClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IUserClient.java deleted file mode 100644 index af54188..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IUserClient.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.util.List; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.User; - -public interface IUserClient { - - public List checkRights() throws AirVantageException; - - public User getUser(); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/IUserClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IUserClient.kt new file mode 100644 index 0000000..3ac441e --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/IUserClient.kt @@ -0,0 +1,12 @@ +package com.sierrawireless.avphone.task + +import net.airvantage.model.AirVantageException +import net.airvantage.model.User + +interface IUserClient { + + val user: User? + + @Throws(AirVantageException::class) + fun checkRights(): List +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/LogoutTask.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/LogoutTask.java deleted file mode 100644 index 14de663..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/LogoutTask.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.AvError; -import net.airvantage.utils.IAirVantageClient; -import android.os.AsyncTask; - -public class LogoutTask extends AsyncTask { - - private IAirVantageClient client; - - public LogoutTask(IAirVantageClient client) { - this.client = client; - } - - @Override - protected AvError doInBackground(String... arg0) { - AvError res = null; - try { - this.client.logout(); - } catch (IOException e) { - res = new AvError("unexpected.error"); - } catch (AirVantageException e) { - res = e.getError(); - } - return res; - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/LogoutTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/LogoutTask.kt new file mode 100644 index 0000000..020e57f --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/LogoutTask.kt @@ -0,0 +1,25 @@ +package com.sierrawireless.avphone.task + +import java.io.IOException + +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvError +import net.airvantage.utils.IAirVantageClient +import android.os.AsyncTask + +class LogoutTask internal constructor(private val client: IAirVantageClient) : AsyncTask() { + + override fun doInBackground(vararg arg0: String): AvError? { + var res: AvError? = null + try { + this.client.logout() + } catch (e: IOException) { + res = AvError("unexpected.error") + } catch (e: AirVantageException) { + res = e.error + } + + return res + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressDeleteSystemTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressDeleteSystemTask.kt new file mode 100644 index 0000000..9299b7f --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressDeleteSystemTask.kt @@ -0,0 +1,75 @@ +@file:Suppress("DEPRECATION") + +package com.sierrawireless.avphone.task + +import android.app.ProgressDialog +import android.content.Context +import android.os.Build +import android.support.v4.content.ContextCompat +import android.text.Html +import android.view.View +import android.widget.TextView +import com.sierrawireless.avphone.R + +class ProgressDeleteSystemTask internal constructor(systemClient: ISystemClient, userClient: IUserClient, private val alertRuleClient: IAlertRuleClient, context: Context) : DeleteSystemTask(systemClient, userClient, alertRuleClient, context) { + + + private var dialog: ProgressDialog? = null + + override fun onPreExecute() { + super.onPreExecute() + + val maxProgress = SyncProgress.values().size + dialog = ProgressDialog(context) + dialog!!.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + dialog!!.isIndeterminate = false + dialog!!.max = maxProgress + dialog!!.setCancelable(false) + dialog!!.setTitle(R.string.progress_syncing) + + dialog!!.setMessage(context.getString(R.string.progress_starting)) + dialog!!.setProgressDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_horizontal_holo_light, context.theme)) + + dialog!!.setIndeterminateDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_indeterminate_horizontal_holo_light, context.theme)) + + dialog!!.show() + + // Color has to be set *after* the dialog is shown (see + // http://blog.supenta.com/2014/07/02/how-to-style-alertdialogs-like-a-pro/) + val titleDividerId = context.resources.getIdentifier("titleDivider", "id", "android") + val titleDivider = dialog!!.findViewById(titleDividerId) + titleDivider?.setBackgroundColor(ContextCompat.getColor(context, R.color.sierrared)) + + // See http://stackoverflow.com/questions/15271500/how-to-change-alert-dialog-header-divider-color-android + val alertTitleId = context.resources.getIdentifier("alertTitle", "id", "android") + val windows = dialog!!.window + if (windows != null) { + val alertTitle = windows.decorView.findViewById(alertTitleId) + alertTitle.setTextColor(ContextCompat.getColor(context, R.color.sierrared)) // change title text color + } + } + + + public override fun onProgressUpdate(vararg progress: DeleteSystemProgress) { + dialog!!.progress = progress[0].value + val stepMessage = context.getString(progress[0].stringId) + val htmlMessage = context.getString(R.string.progress_syncing_message, stepMessage) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + dialog!!.setMessage(Html.fromHtml(htmlMessage, Html.FROM_HTML_MODE_LEGACY)) + }else{ + @Suppress("DEPRECATION") + dialog!!.setMessage(Html.fromHtml(htmlMessage)) + } + + } + + override fun onPostExecute(result: DeleteSystemResult) { + if (dialog!!.isShowing) { + dialog!!.dismiss() + } + super.onPostExecute(result) + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressGetUserTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressGetUserTask.kt new file mode 100644 index 0000000..5797b65 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressGetUserTask.kt @@ -0,0 +1,59 @@ +@file:Suppress("DEPRECATION") + +package com.sierrawireless.avphone.task + +import android.app.ProgressDialog +import android.content.Context +import android.support.v4.content.ContextCompat +import android.view.View +import android.widget.TextView +import com.sierrawireless.avphone.R + +class ProgressGetUserTask internal constructor(userClient: IUserClient, context: Context) : GetUserTask(userClient, context) { + + private var dialog: ProgressDialog? = null + + override fun onPreExecute() { + super.onPreExecute() + + val maxProgress = SyncProgress.values().size + dialog = ProgressDialog(context) + dialog!!.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + dialog!!.isIndeterminate = false + dialog!!.max = maxProgress + dialog!!.setCancelable(false) + dialog!!.setTitle(R.string.progress_syncing) + + dialog!!.setMessage(context.getString(R.string.progress_starting)) + dialog!!.setProgressDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_horizontal_holo_light, context.theme)) + + dialog!!.setIndeterminateDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_indeterminate_horizontal_holo_light, context.theme)) + + dialog!!.show() + + // Color has to be set *after* the dialog is shown (see + // http://blog.supenta.com/2014/07/02/how-to-style-alertdialogs-like-a-pro/) + val titleDividerId = context.resources.getIdentifier("titleDivider", "id", "android") + val titleDivider = dialog!!.findViewById(titleDividerId) + titleDivider?.setBackgroundColor(ContextCompat.getColor(context, R.color.sierrared)) + + // See http://stackoverflow.com/questions/15271500/how-to-change-alert-dialog-header-divider-color-android + val alertTitleId = context.resources.getIdentifier("alertTitle", "id", "android") + val windows = dialog!!.window + if (windows != null) { + val alertTitle = windows.decorView.findViewById(alertTitleId) + alertTitle.setTextColor(ContextCompat.getColor(context, R.color.sierrared)) // change title text color + } + } + + + override fun onPostExecute(result: GetUserResult) { + if (dialog!!.isShowing) { + dialog!!.dismiss() + } + super.onPostExecute(result) + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressSyncWithAvTask.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressSyncWithAvTask.java deleted file mode 100644 index 016e610..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressSyncWithAvTask.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.sierrawireless.avphone.task; - -import com.sierrawireless.avphone.R; - -import android.app.ProgressDialog; -import android.content.Context; -import android.text.Html; -import android.view.View; -import android.widget.TextView; - -public class ProgressSyncWithAvTask extends SyncWithAvTask { - - private ProgressDialog dialog; - - public ProgressSyncWithAvTask(IApplicationClient applicationClient, ISystemClient systemClient, - IAlertRuleClient alertRuleClient, IUserClient userClient, Context context) { - super(applicationClient, systemClient, alertRuleClient, userClient, context); - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - - int maxProgress = SyncProgress.values().length; - dialog = new ProgressDialog(getContext()); - dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - dialog.setIndeterminate(false); - dialog.setMax(maxProgress); - dialog.setCancelable(false); - dialog.setTitle(R.string.progress_syncing); - - dialog.setMessage(getContext().getString(R.string.progress_starting)); - dialog.setProgressDrawable(getContext().getResources().getDrawable( - R.drawable.apptheme_progress_horizontal_holo_light)); - dialog.setIndeterminateDrawable(getContext().getResources().getDrawable( - R.drawable.apptheme_progress_indeterminate_horizontal_holo_light)); - dialog.show(); - - // Color has to be set *after* the dialog is shown (see - // http://blog.supenta.com/2014/07/02/how-to-style-alertdialogs-like-a-pro/) - int titleDividerId = getContext().getResources().getIdentifier("titleDivider", "id", "android"); - View titleDivider = dialog.findViewById(titleDividerId); - if (titleDivider != null) - titleDivider.setBackgroundColor(getContext().getResources().getColor(R.color.sierrared)); - - // See http://stackoverflow.com/questions/15271500/how-to-change-alert-dialog-header-divider-color-android - int alertTitleId = getContext().getResources().getIdentifier("alertTitle", "id", "android"); - TextView alertTitle = (TextView) dialog.getWindow().getDecorView().findViewById(alertTitleId); - alertTitle.setTextColor(getContext().getResources().getColor(R.color.sierrared)); // change title text color - - } - - @Override - public void onProgressUpdate(SyncProgress... progress) { - dialog.setProgress(progress[0].value); - String stepMessage = getContext().getString(progress[0].stringId); - String htmlMessage = getContext().getString(R.string.progress_syncing_message, stepMessage); - dialog.setMessage(Html.fromHtml(htmlMessage)); - } - - @Override - protected void onPostExecute(SyncWithAvResult result) { - if (dialog.isShowing()) { - dialog.dismiss(); - } - super.onPostExecute(result); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressSyncWithAvTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressSyncWithAvTask.kt new file mode 100644 index 0000000..7100931 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressSyncWithAvTask.kt @@ -0,0 +1,73 @@ +@file:Suppress("DEPRECATION") + +package com.sierrawireless.avphone.task + +import android.app.ProgressDialog +import android.content.Context +import android.os.Build +import android.support.v4.content.ContextCompat +import android.text.Html +import android.view.View +import android.widget.TextView +import com.sierrawireless.avphone.R + +class ProgressSyncWithAvTask internal constructor(applicationClient: IApplicationClient, systemClient: ISystemClient, + alertRuleClient: IAlertRuleClient, userClient: IUserClient, context: Context) : SyncWithAvTask(applicationClient, systemClient, alertRuleClient, userClient, context) { + + private var dialog: ProgressDialog? = null + + override fun onPreExecute() { + super.onPreExecute() + + val maxProgress = SyncProgress.values().size + dialog = ProgressDialog(context) + dialog!!.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + dialog!!.isIndeterminate = false + dialog!!.max = maxProgress + dialog!!.setCancelable(false) + dialog!!.setTitle(R.string.progress_syncing) + + dialog!!.setMessage(context.getString(R.string.progress_starting)) + dialog!!.setProgressDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_horizontal_holo_light, context.theme)) + + dialog!!.setIndeterminateDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_indeterminate_horizontal_holo_light, context.theme)) + + dialog!!.show() + + // Color has to be set *after* the dialog is shown (see + // http://blog.supenta.com/2014/07/02/how-to-style-alertdialogs-like-a-pro/) + val titleDividerId = context.resources.getIdentifier("titleDivider", "id", "android") + val titleDivider = dialog!!.findViewById(titleDividerId) + titleDivider?.setBackgroundColor(ContextCompat.getColor(context, R.color.sierrared)) + + // See http://stackoverflow.com/questions/15271500/how-to-change-alert-dialog-header-divider-color-android + val alertTitleId = context.resources.getIdentifier("alertTitle", "id", "android") + val windows = dialog!!.window + if (windows != null) { + val alertTitle = windows.decorView.findViewById(alertTitleId) + alertTitle.setTextColor(ContextCompat.getColor(context, R.color.sierrared)) // change title text color + } + } + + public override fun onProgressUpdate(vararg progress: SyncProgress) { + dialog!!.progress = progress[0].value + val stepMessage = context.getString(progress[0].stringId) + val htmlMessage = context.getString(R.string.progress_syncing_message, stepMessage) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + dialog!!.setMessage(Html.fromHtml(htmlMessage, Html.FROM_HTML_MODE_LEGACY)) + }else{ + @Suppress("DEPRECATION") + dialog!!.setMessage(Html.fromHtml(htmlMessage)) + } + } + + override fun onPostExecute(result: SyncWithAvResult) { + if (dialog!!.isShowing) { + dialog!!.dismiss() + } + super.onPostExecute(result) + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressUpdateTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressUpdateTask.kt new file mode 100644 index 0000000..30a9d38 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/ProgressUpdateTask.kt @@ -0,0 +1,71 @@ +package com.sierrawireless.avphone.task + +import android.app.ProgressDialog +import android.content.Context +import android.os.Build +import android.support.v4.content.ContextCompat +import android.text.Html +import android.view.View +import android.widget.TextView +import com.sierrawireless.avphone.R + +class ProgressUpdateTask internal constructor(applicationClient: IApplicationClient, systemClient: ISystemClient, + alertRuleClient: IAlertRuleClient, userClient: IUserClient, context: Context) : UpdateTask(applicationClient, systemClient, alertRuleClient, userClient, context) { + + private var dialog: ProgressDialog? = null + + override fun onPreExecute() { + super.onPreExecute() + + val maxProgress = UpdateProgress.values().size + dialog = ProgressDialog(context) + dialog!!.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + dialog!!.isIndeterminate = false + dialog!!.max = maxProgress + dialog!!.setCancelable(false) + dialog!!.setTitle(R.string.progress_syncing) + + dialog!!.setMessage(context.getString(R.string.progress_starting)) + dialog!!.setProgressDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_horizontal_holo_light, context.theme)) + + dialog!!.setIndeterminateDrawable(context.resources.getDrawable( + R.drawable.apptheme_progress_indeterminate_horizontal_holo_light, context.theme)) + + dialog!!.show() + + // Color has to be set *after* the dialog is shown (see + // http://blog.supenta.com/2014/07/02/how-to-style-alertdialogs-like-a-pro/) + val titleDividerId = context.resources.getIdentifier("titleDivider", "id", "android") + val titleDivider = dialog!!.findViewById(titleDividerId) + titleDivider?.setBackgroundColor(ContextCompat.getColor(context, R.color.sierrared)) + + // See http://stackoverflow.com/questions/15271500/how-to-change-alert-dialog-header-divider-color-android + val alertTitleId = context.resources.getIdentifier("alertTitle", "id", "android") + val windows = dialog!!.window + if (windows != null) { + val alertTitle = windows.decorView.findViewById(alertTitleId) + alertTitle.setTextColor(ContextCompat.getColor(context, R.color.sierrared)) // change title text color + } + } + + public override fun onProgressUpdate(vararg progress: UpdateProgress) { + dialog!!.progress = progress[0].value + val stepMessage = context.getString(progress[0].stringId) + val htmlMessage = context.getString(R.string.progress_syncing_message, stepMessage) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + dialog!!.setMessage(Html.fromHtml(htmlMessage, Html.FROM_HTML_MODE_LEGACY)) + }else{ + @Suppress("DEPRECATION") + dialog!!.setMessage(Html.fromHtml(htmlMessage)) + } + } + + override fun onPostExecute(result: UpdateResult) { + if (dialog!!.isShowing) { + dialog!!.dismiss() + } + super.onPostExecute(result) + } + +} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataParams.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataParams.kt new file mode 100644 index 0000000..38fd612 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataParams.kt @@ -0,0 +1,14 @@ +package com.sierrawireless.avphone.task + +import android.content.Context + +import com.sierrawireless.avphone.service.MqttPushClient +import com.sierrawireless.avphone.service.NewData + +class SendDataParams { + var client: MqttPushClient? = null + var data: NewData? = null + var alarm: Boolean = false + var value: Boolean = false + var context: Context? = null +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataResult.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataResult.kt new file mode 100644 index 0000000..5d0211f --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataResult.kt @@ -0,0 +1,25 @@ +package com.sierrawireless.avphone.task + + +class SendDataResult { + var isError: Boolean = false + private set + var lastLog: String? = null + private set + var alarmLog: String? = null + private set + + + + constructor(lastLog: String?, alarmLog: String?, error: Boolean) { + this.isError = error + this.lastLog = lastLog + this.alarmLog = alarmLog + } + + constructor(lastLog: String?, alarmLog: String?) { + this.lastLog = lastLog + this.isError = false + this.alarmLog = alarmLog + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataTask.kt new file mode 100644 index 0000000..c8190be --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SendDataTask.kt @@ -0,0 +1,110 @@ +package com.sierrawireless.avphone.task + +import android.os.AsyncTask +import android.support.v4.content.LocalBroadcastManager +import android.util.Log +import com.crashlytics.android.Crashlytics +import com.sierrawireless.avphone.service.LogMessage +import org.eclipse.paho.client.mqttv3.MqttException +import java.util.* + +typealias SendDataListener = (SendDataResult) -> Unit +class SendDataTask : AsyncTask() { + + + private val syncListeners = ArrayList() + + + fun addProgressListener(listener: SendDataListener) { + this.syncListeners.add(listener) + } + + override fun doInBackground(vararg params: SendDataParams): SendDataResult { + var lastLog: String + + val sendParams = params[0] + val client = sendParams.client + val data = sendParams.data + val alarm = sendParams.alarm + val context = sendParams.context + val value = sendParams.value + try { + if (!client!!.isConnected) { + client.connect() + } + + if (!alarm) + // dispatch new data event to update the activity UI + LocalBroadcastManager.getInstance(context!!).sendBroadcast(data!!) + + client.push(data!!) + lastLog = if (!alarm) + data.size().toString() + " data pushed to the server" + else if (value) + "Alarm on sent to server" + else + "Alarm off sent to server" + + + LocalBroadcastManager.getInstance(context!!).sendBroadcast(LogMessage(lastLog, alarm)) + return if (!alarm) { + SendDataResult(lastLog, null) + }else{ + SendDataResult(null, lastLog) + } + }catch (e: MqttException) { + lastLog = "MQTT ERROR: " + when (e.reasonCode.toShort()){ + MqttException.REASON_CODE_BROKER_UNAVAILABLE -> "The broker was not available to handle the request" + MqttException.REASON_CODE_CLIENT_ALREADY_DISCONNECTED -> "The client is already disconnected." + MqttException.REASON_CODE_CLIENT_CLOSED -> "The client is closed - no operations are permitted on the client in this state" + MqttException.REASON_CODE_CLIENT_CONNECTED -> "The client is already connected" + MqttException.REASON_CODE_CLIENT_DISCONNECT_PROHIBITED -> "Thrown when an attempt to call MqttClient.disconnect() has been made from within a method on MqttCallback" + MqttException.REASON_CODE_CLIENT_DISCONNECTING -> "The client is currently disconnecting and cannot accept any new work" + MqttException.REASON_CODE_CLIENT_EXCEPTION -> "Client encountered an exception, can't connect to server. port closed by firewall ???" + MqttException.REASON_CODE_CLIENT_NOT_CONNECTED -> "The client is not connected to the server" + MqttException.REASON_CODE_CLIENT_TIMEOUT -> "Client timed out while waiting for a response from the server" + MqttException.REASON_CODE_CONNECT_IN_PROGRESS -> "A connect operation in already in progress, only one connect can happen at a time" + MqttException.REASON_CODE_CONNECTION_LOST -> "The client has been unexpectedly disconnected from the server" + MqttException.REASON_CODE_FAILED_AUTHENTICATION -> "Authentication with the server has failed, due to a bad user name or password" + MqttException.REASON_CODE_INVALID_CLIENT_ID -> "The server has rejected the supplied client ID" + MqttException.REASON_CODE_INVALID_MESSAGE -> "Protocol error: the message was not recognized as a valid MQTT packet" + MqttException.REASON_CODE_INVALID_PROTOCOL_VERSION -> "The protocol version requested is not supported by the server" + MqttException.REASON_CODE_MAX_INFLIGHT -> "A request has been made to send a message but the maximum number of inflight messages has already been reached" + MqttException.REASON_CODE_NO_MESSAGE_IDS_AVAILABLE -> "Internal error, caused by no new message IDs being available" + MqttException.REASON_CODE_NOT_AUTHORIZED -> "Not authorized to perform the requested operation" + MqttException.REASON_CODE_SERVER_CONNECT_ERROR -> "Unable to connect to server" + MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH -> "Server URI and supplied SocketFactory do not match" + MqttException.REASON_CODE_SSL_CONFIG_ERROR -> "SSL configuration error" + MqttException.REASON_CODE_SUBSCRIBE_FAILED -> "Error from subscribe - returned from the server" + MqttException.REASON_CODE_TOKEN_INUSE -> "A request has been made to use a token that is already associated with another action" + MqttException.REASON_CODE_UNEXPECTED_ERROR -> "An unexpected error has occurred" + MqttException.REASON_CODE_WRITE_TIMEOUT -> "Client timed out while waiting to write messages to the server" + else -> "Unkown reason code "+ e.reasonCode + } + Log.w("SendDataTasK", "Mqtt error " + lastLog ) + LocalBroadcastManager.getInstance(context!!).sendBroadcast(LogMessage(lastLog, alarm)) + return if (!alarm) { + SendDataResult(lastLog, null,true) + }else{ + SendDataResult(null, lastLog, true) + } + } catch (e: Exception) { + Crashlytics.logException(e) + lastLog = "ERROR: " + e.message + LocalBroadcastManager.getInstance(context!!).sendBroadcast(LogMessage(lastLog, alarm)) + return if (!alarm) { + SendDataResult(lastLog, null,true) + }else{ + SendDataResult(null, lastLog, true) + } + } + } + + override fun onPostExecute(result: SendDataResult) { + super.onPostExecute(result) + for (listener in syncListeners) { + listener.invoke(result) + } + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncProgress.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncProgress.kt similarity index 65% rename from mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncProgress.java rename to mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncProgress.kt index c7fec26..2e6a85f 100644 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncProgress.java +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncProgress.kt @@ -1,8 +1,8 @@ -package com.sierrawireless.avphone.task; +package com.sierrawireless.avphone.task -import com.sierrawireless.avphone.R; +import com.sierrawireless.avphone.R -public enum SyncProgress { +enum class SyncProgress(val stringId: Int, val value: Int) { // There is no "CREATING_SYSTEM', since it is done // in the single 'ensureApplicationExists' method CHECKING_RIGHTS(R.string.progress_checking_rights, 0), @@ -13,13 +13,5 @@ public enum SyncProgress { CREATING_ALERT_RULE(R.string.progress_creating_alert_rule, 5), UPDATING_APPLICATION(R.string.progress_updating_application, 6), ADDING_APPLICATION(R.string.progress_adding_application, 7), - DONE(R.string.progress_done, 8); - - public final int stringId; - public final int value; - SyncProgress(int stringId, int value) { - this.stringId = stringId; - this.value = value; - } - + DONE(R.string.progress_done, 8) } \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvListener.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvListener.java deleted file mode 100644 index 1625254..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvListener.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.sierrawireless.avphone.task; - - -public interface SyncWithAvListener { - public void onSynced(SyncWithAvResult result); -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvParams.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvParams.java deleted file mode 100644 index cd75c1e..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvParams.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sierrawireless.avphone.task; - -import com.sierrawireless.avphone.model.CustomDataLabels; - -public class SyncWithAvParams { - public String deviceId; - public String imei; - public String mqttPassword; - public CustomDataLabels customData; -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvParams.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvParams.kt new file mode 100644 index 0000000..ddd310b --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvParams.kt @@ -0,0 +1,14 @@ +package com.sierrawireless.avphone.task + +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.model.CustomDataLabels + +class SyncWithAvParams { + var deviceId: String? = null + var imei: String? = null + var mqttPassword: String? = null + var iccid: String? = null + var deviceName: String? = null + var customData: CustomDataLabels? = null + var activity: MainActivity? = null +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvResult.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvResult.java deleted file mode 100644 index 74724fb..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvResult.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.sierrawireless.avphone.task; - -import net.airvantage.model.AvError; -import net.airvantage.model.AvSystem; -import net.airvantage.model.User; - -public class SyncWithAvResult { - - private AvError error; - - private AvSystem system; - - private User user; - - public SyncWithAvResult(AvError error) { - this.error = error; - } - - public SyncWithAvResult(final AvSystem system, final User user) { - this.system = system; - this.user = user; - } - - public boolean isError() { - return error != null; - } - - public AvSystem getSystem() { - return system; - } - - public User getUser() { - return user; - } - - public AvError getError() { - return error; - } -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvResult.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvResult.kt new file mode 100644 index 0000000..80ba954 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvResult.kt @@ -0,0 +1,26 @@ +package com.sierrawireless.avphone.task + +import net.airvantage.model.AvError +import net.airvantage.model.AvSystem +import net.airvantage.model.User + +class SyncWithAvResult { + + var error: AvError? = null + + var system: AvSystem? = null + + var user: User? = null + + val isError: Boolean + get() = error != null + + constructor(error: AvError) { + this.error = error + } + + constructor(system: AvSystem, user: User) { + this.system = system + this.user = user + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvTask.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvTask.java deleted file mode 100644 index c66d344..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvTask.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.crashlytics.android.Crashlytics; -import com.sierrawireless.avphone.DeviceInfo; -import com.sierrawireless.avphone.MainActivity; -import com.sierrawireless.avphone.R; -import com.sierrawireless.avphone.message.IMessageDisplayer; -import com.sierrawireless.avphone.model.AvPhoneApplication; -import com.sierrawireless.avphone.model.CustomDataLabels; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Context; -import android.os.AsyncTask; -import android.text.Html; -import android.util.Log; -import net.airvantage.model.AirVantageException; -import net.airvantage.model.Application; -import net.airvantage.model.AvError; -import net.airvantage.model.AvSystem; -import net.airvantage.model.User; -import net.airvantage.model.UserRights; -import net.airvantage.model.alert.v1.AlertRule; - -public class SyncWithAvTask extends AsyncTask { - - private IApplicationClient applicationClient; - - private ISystemClient systemClient; - - private IAlertRuleClient alertRuleClient; - - private List syncListeners = new ArrayList(); - - private IUserClient userClient; - - private Context context; - - public SyncWithAvTask(IApplicationClient applicationClient, ISystemClient systemClient, - IAlertRuleClient alertRuleClient, IUserClient userClient, Context context) { - this.applicationClient = applicationClient; - this.systemClient = systemClient; - this.alertRuleClient = alertRuleClient; - this.userClient = userClient; - this.context = context; - } - - public void addProgressListener(SyncWithAvListener listener) { - this.syncListeners.add(listener); - } - - @Override - @SuppressLint("DefaultLocale") - protected SyncWithAvResult doInBackground(SyncWithAvParams... params) { - - try { - - publishProgress(SyncProgress.CHECKING_RIGHTS); - - final List missingRights = userClient.checkRights(); - if (!missingRights.isEmpty()) { - return new SyncWithAvResult(new AvError(AvError.MISSING_RIGHTS, missingRights)); - } - - final String systemType = "Android"; - final SyncWithAvParams syncParams = params[0]; - final User user = userClient.getUser(); - final String imei = syncParams.imei; - final String mqttPassword = syncParams.mqttPassword; - final CustomDataLabels customData = syncParams.customData; - - // For emulator and iOs compatibility sake, using generated serial. - final String serialNumber = DeviceInfo.generateSerial(user.uid ,systemType); - - // Save Device serial in context - if (context instanceof MainActivity) { - final MainActivity mainActivity = (MainActivity) context; - mainActivity.setSystemSerial(serialNumber); - } - - publishProgress(SyncProgress.CHECKING_APPLICATION); - - Application application = this.applicationClient.ensureApplicationExists(); - - publishProgress(SyncProgress.CHECKING_SYSTEM); - - net.airvantage.model.AvSystem system = this.systemClient.getSystem(serialNumber); - if (system == null) { - - publishProgress(SyncProgress.CREATING_SYSTEM); - - system = systemClient.createSystem(serialNumber, imei, systemType, mqttPassword, application.uid); - } - - publishProgress(SyncProgress.CHECKING_ALERT_RULE); - - AlertRule alertRule = this.alertRuleClient.getAlertRule(serialNumber); - if (alertRule == null) { - - publishProgress(SyncProgress.CREATING_ALERT_RULE); - - this.alertRuleClient.createAlertRule(); - } - - publishProgress(SyncProgress.UPDATING_APPLICATION); - - this.applicationClient.setApplicationData(application.uid, customData); - - if (!hasApplication(system, application)) { - - publishProgress(SyncProgress.ADDING_APPLICATION); - - this.applicationClient.addApplication(system, application); - } - - publishProgress(SyncProgress.DONE); - - return new SyncWithAvResult(system, user); - - } catch (AirVantageException e) { - publishProgress(SyncProgress.DONE); - return new SyncWithAvResult(e.getError()); - } catch (IOException e) { - Crashlytics.logException(e); - Log.e(MainActivity.class.getName(), "Error when trying to synchronize with server", e); - publishProgress(SyncProgress.DONE); - return new SyncWithAvResult(new AvError("unkown.error")); - } - - } - - @Override - protected void onPostExecute(SyncWithAvResult result) { - super.onPostExecute(result); - for (SyncWithAvListener listener : syncListeners) { - listener.onSynced(result); - } - } - - private boolean hasApplication(AvSystem system, Application application) { - boolean found = false; - if (system.applications != null) { - for (Application app : system.applications) { - if (app.uid.equals(application.uid)) { - found = true; - } - } - } - return found; - } - - public void showResult(SyncWithAvResult result, IMessageDisplayer displayer, Activity context) { - - if (result.isError()) { - AvError error = result.getError(); - if (error.missingRights()) { - String message = missingRightsMessage(error, context); - displayer.showErrorMessage(Html.fromHtml(message)); - } else if (error.systemAlreadyExists()) { - displayer.showError(R.string.sync_error_system_exists); - } else if (error.gatewayAlreadyExists()) { - displayer.showError(R.string.sync_error_gateway_exists); - } else if (error.applicationAlreadyUsed()) { - final User user = userClient.getUser(); - if (user == null) { - displayer.showError(R.string.sync_error_no_user_data); - } else { - displayer.showError(R.string.sync_error_app_exists, AvPhoneApplication.appType(user.name)); - } - } else if (error.tooManyAlerRules()) { - displayer.showError(R.string.sync_error_too_many_rules); - } else if (error.cantCreateApplication()) { - displayer.showError(R.string.sync_error_no_right_create_application); - } else if (error.cantCreateSystem()) { - displayer.showError(R.string.sync_error_no_right_create_system); - } else if (error.cantCreateAlertRule()) { - displayer.showError(R.string.sync_error_no_right_create_alert_rule); - } else if (error.cantUpdateApplication()) { - displayer.showError(R.string.sync_error_no_right_update_app); - } else if (error.cantUpdateSystem()) { - displayer.showError(R.string.sync_error_no_right_update_system); - } else if (error.forbidden()) { - String method = error.errorParameters.get(0); - String url = error.errorParameters.get(1); - displayer.showError(R.string.sync_error_forbidden, method, url); - } else { - displayer.showError(R.string.sync_error_unexpected, error.error); - } - } else { - displayer.showSuccess(R.string.sync_success); - } - } - - protected Context getContext() { - return this.context; - } - - private String missingRightsMessage(AvError error, Activity context) { - List missingRights = error.errorParameters; - StringBuilder message = new StringBuilder(); - message.append(context.getText(R.string.auth_not_enough_rights)); - message.append("
"); - message.append(context.getText(R.string.auth_missing_rights)); - message.append("
"); - - for (String missingRight : missingRights) { - message.append("• "); - message.append(UserRights.asString(missingRight, context)); - message.append("
"); - } - return message.toString(); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvTask.kt new file mode 100644 index 0000000..291ff20 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SyncWithAvTask.kt @@ -0,0 +1,156 @@ +package com.sierrawireless.avphone.task + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import android.util.Log +import com.crashlytics.android.Crashlytics +import com.sierrawireless.avphone.tools.DeviceInfo +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.message.IMessageDisplayer +import net.airvantage.model.AirVantageException +import net.airvantage.model.Application +import net.airvantage.model.AvError +import net.airvantage.model.AvSystem +import org.jetbrains.anko.longToast +import java.io.IOException +import java.util.* + + +typealias SyncWithAvListener = (SyncWithAvResult) -> Unit + +open class SyncWithAvTask internal constructor(private val applicationClient: IApplicationClient, private val systemClient: ISystemClient, + private val alertRuleClient: IAlertRuleClient, private val userClient: IUserClient, @field:SuppressLint("StaticFieldLeak") + protected val context: Context) : AvPhoneTask() { + + private val syncListeners = ArrayList() + var deviceName:String? = null + + fun addProgressListener(listener: SyncWithAvListener) { + this.syncListeners.add(listener) + } + + @SuppressLint("DefaultLocale") + override fun doInBackground(vararg params: SyncWithAvParams): SyncWithAvResult { + + try { + + publishProgress(SyncProgress.CHECKING_RIGHTS) + + + val systemType: String? + val syncParams = params[0] + val user = userClient.user + val imei = syncParams.imei + val iccid = syncParams.iccid + deviceName = syncParams.deviceName + val mqttPassword = syncParams.mqttPassword + val objectsManager = ObjectsManager.getInstance() + + val missingRights = userClient.checkRights() + if (!missingRights.isEmpty()) { + return SyncWithAvResult(AvError(AvError.MISSING_RIGHTS, missingRights)) + } + + + systemType = objectsManager.savedObjectName + + // For emulator and iOs compatibility sake, using generated serial. + val serialNumber = DeviceInfo.generateSerial(user!!.uid!!) + + // Save Device serial in context + if (context is MainActivity) { + context.systemSerial = serialNumber + } + + publishProgress(SyncProgress.CHECKING_APPLICATION) + + val application = this.applicationClient.ensureApplicationExists(deviceName!!) + + publishProgress(SyncProgress.CHECKING_SYSTEM) + + var system: net.airvantage.model.AvSystem? = this.systemClient.getSystem(serialNumber, systemType!!, deviceName!!) + if (system == null) { + + publishProgress(SyncProgress.CREATING_SYSTEM) + + system = systemClient.createSystem(serialNumber, iccid!!, systemType, mqttPassword!!, application.uid!!, deviceName!!, user.name!!, imei!!) + } + objectsManager.savecObject.systemUid = system.uid + objectsManager.saveOnPref() + + + publishProgress(SyncProgress.CHECKING_ALERT_RULE) + + val alertRule = this.alertRuleClient.getAlertRule(serialNumber, system) + if (alertRule == null) { + + publishProgress(SyncProgress.CREATING_ALERT_RULE) + + this.alertRuleClient.createAlertRule(application.uid!!, system) + } + + publishProgress(SyncProgress.UPDATING_APPLICATION) + + this.applicationClient.setApplicationData(application.uid!!, objectsManager.savecObject.datas, objectsManager.savecObject.name!!) + + if (!hasApplication(system, application)) { + + publishProgress(SyncProgress.ADDING_APPLICATION) + + this.applicationClient.addApplication(system, application) + } + + publishProgress(SyncProgress.DONE) + + return SyncWithAvResult(system, user) + + } catch (e: AirVantageException) { + publishProgress(SyncProgress.DONE) + return SyncWithAvResult(e.error!!) + } catch (e: IOException) { + Crashlytics.logException(e) + Log.e(MainActivity::class.java.name, "Error when trying to synchronize with server", e) + publishProgress(SyncProgress.DONE) + return SyncWithAvResult(AvError("unkown.error")) + } + + } + + override fun onPostExecute(result: SyncWithAvResult) { + super.onPostExecute(result) + for (listener in syncListeners) { + listener.invoke(result) + } + } + + private fun hasApplication(system: AvSystem, application: Application): Boolean { + var found = false + if (system.applications != null) { + system.applications!! + .filter { it.uid == application.uid } + .forEach { found = true } + } + return found + } + + fun showResult(result: SyncWithAvResult, displayer: IMessageDisplayer, context: Activity) { + + if (result.isError) { + var error = result.error + if (error == null) { + error = AvError("Internal Error") + } + if (error!!.errorParameters.size == 1 && error!!.errorParameters[0] == "No Connection") { + context.longToast("Resync error\nYou don't have any data connection") + } + + displayTaskError(error, displayer, context, userClient, deviceName!!) + } else { + displayer.showSuccess(R.string.sync_success) + } + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SystemClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SystemClient.java deleted file mode 100644 index 3f594b2..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SystemClient.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.Application; -import net.airvantage.model.AvSystem; -import net.airvantage.model.MqttCommunication; -import net.airvantage.utils.AirVantageClient; -import net.airvantage.utils.Utils; - -public class SystemClient implements ISystemClient { - - private AirVantageClient client; - - public SystemClient(AirVantageClient client) { - this.client = client; - } - - @Override - public net.airvantage.model.AvSystem getSystem(final String serialNumber) throws IOException, AirVantageException { - List systems = client.getSystemsBySerialNumber(serialNumber); - - return Utils.firstWhere(systems, AvSystem.hasSerialNumber(serialNumber)); - } - - @Override - public net.airvantage.model.AvSystem createSystem(String serialNumber, String imei, String type, String mqttPassword, - String applicationUid) throws IOException, AirVantageException { - net.airvantage.model.AvSystem system = new net.airvantage.model.AvSystem(); - - net.airvantage.model.AvSystem.Gateway gateway = new net.airvantage.model.AvSystem.Gateway(); - gateway.serialNumber = serialNumber; - gateway.imei = imei; - - system.gateway = gateway; - - system.state = "READY"; - - Application application = new Application(); - application.uid = applicationUid; - system.applications = Arrays.asList(application); - - MqttCommunication mqtt = new MqttCommunication(); - mqtt.password = mqttPassword; - - system.communication = new HashMap(); - system.communication.put("mqtt", mqtt); - system.type = type; - - return client.createSystem(system); - } - -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/SystemClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SystemClient.kt new file mode 100644 index 0000000..9336143 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/SystemClient.kt @@ -0,0 +1,102 @@ +package com.sierrawireless.avphone.task + +import com.sierrawireless.avphone.tools.Tools +import net.airvantage.model.AirVantageException +import net.airvantage.model.Application +import net.airvantage.model.AvSystem +import net.airvantage.model.MqttCommunication +import net.airvantage.utils.AirVantageClient +import net.airvantage.utils.Utils +import java.io.IOException +import java.util.HashMap +import kotlin.collections.ArrayList +import kotlin.collections.set + +class SystemClient internal constructor(private val client: AirVantageClient) : ISystemClient { + + @Throws(IOException::class, AirVantageException::class) + override fun getSystem(serialNumber: String, type: String, deviceName: String): net.airvantage.model.AvSystem? { + val systems = client.getSystemsBySerialNumber(Tools.buildSerialNumber(serialNumber, type, deviceName)) + + return Utils.firstWhere(systems, AvSystem.hasSerialNumber(Tools.buildSerialNumber(serialNumber, type, deviceName))) + } + + @Throws(IOException::class, AirVantageException::class) + override fun createSystem(serialNumber: String, iccid: String, type: String, mqttPassword: String, + applicationUid: String, deviceName: String, userName: String, imei: String): net.airvantage.model.AvSystem { + val system = net.airvantage.model.AvSystem() + + val uid = client.getGateway((serialNumber + "-ANDROID-" + type + "-" + deviceName.replace(" ", "_")).toUpperCase()) + val gateway = net.airvantage.model.AvSystem.Gateway() + + if (uid == null) { + gateway.serialNumber = (serialNumber + "-ANDROID-" + type + "-" + deviceName.replace(" ", "_")).toUpperCase() + // gateway.imei = imei + type; + gateway.type = type + } else { + gateway.uid = uid + } + system.name = Tools.buildSystemName(deviceName, userName, type) + + system.gateway = gateway + + system.state = "READY" + + val application = Application() + application.uid = applicationUid + val tmp = ArrayList() + tmp.add(application) + system.applications = tmp + + val mqtt = MqttCommunication() + mqtt.password = mqttPassword + + system.communication = HashMap() + system.communication!!["mqtt"] = mqtt + system.type = type + + return client.createSystem(system) + } + + @Throws(IOException::class, AirVantageException::class) + override fun updateSystem(system: AvSystem, serialNumber: String, iccid: String, type: String, mqttPassword: String, + applicationUid: String, deviceName: String, userName: String, imei: String) { + + + val uid = client.getGateway((serialNumber + "-ANDROID-" + type + "-" + deviceName.replace(" ", "_")).toUpperCase()) + val gateway = net.airvantage.model.AvSystem.Gateway() + + if (uid == null) { + gateway.serialNumber = (serialNumber + "-ANDROID-" + type + "-" + deviceName.replace(" ", "_")).toUpperCase() + // gateway.imei = imei + type; + gateway.type = type + } else { + gateway.uid = uid + } + system.name = Tools.buildSystemName(deviceName, userName, type) + + system.gateway = gateway + + system.state = "READY" + + val application = Application() + application.uid = applicationUid + val tmp = ArrayList() + tmp.add(application) + system.applications = tmp + + val mqtt = MqttCommunication() + mqtt.password = mqttPassword + + system.communication = HashMap() + system.communication!!["mqtt"] = mqtt + system.type = type + + client.updateSystem(system) + } + + @Throws(IOException::class, AirVantageException::class) + override fun deleteSystem(system: net.airvantage.model.AvSystem) { + client.deleteSystem(system) + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateParams.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateParams.kt new file mode 100644 index 0000000..764cb2e --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateParams.kt @@ -0,0 +1,15 @@ +package com.sierrawireless.avphone.task + +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.model.CustomDataLabels + +class UpdateParams { + var deviceId: String? = null + var imei: String? = null + var mqttPassword: String? = null + var iccid: String? = null + var deviceName: String? = null + var customData: CustomDataLabels? = null + var activity: MainActivity? = null + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateProgress.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateProgress.kt new file mode 100644 index 0000000..8237ed4 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateProgress.kt @@ -0,0 +1,17 @@ +package com.sierrawireless.avphone.task + +import com.sierrawireless.avphone.R + +enum class UpdateProgress(val stringId: Int, val value: Int) { + // There is no "CREATING_SYSTEM', since it is done + // in the single 'ensureApplicationExists' method + CHECKING_RIGHTS(R.string.progress_checking_rights, 0), + CHECKING_APPLICATION(R.string.progress_checking_application, 1), + CHECKING_SYSTEM(R.string.progress_checking_system, 2), + UPDATING_SYSTEM(R.string.progress_updating_system, 3), + CHECKING_ALERT_RULE(R.string.progress_checking_alert_rule, 4), + UPDATING_ALERT_RULE(R.string.progress_updating_alert_rule, 5), + UPDATING_APPLICATION(R.string.progress_updating_application, 6), + ADDING_APPLICATION(R.string.progress_adding_application, 7), + DONE(R.string.progress_done, 8) +} \ No newline at end of file diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateResult.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateResult.kt new file mode 100644 index 0000000..72b9a16 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateResult.kt @@ -0,0 +1,26 @@ +package com.sierrawireless.avphone.task + +import net.airvantage.model.AvError +import net.airvantage.model.AvSystem +import net.airvantage.model.User + +class UpdateResult { + + var error: AvError? = null + + var system: AvSystem? = null + + var user: User? = null + + val isError: Boolean + get() = error != null + + constructor(error: AvError) { + this.error = error + } + + constructor(system: AvSystem, user: User) { + this.system = system + this.user = user + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateTask.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateTask.kt new file mode 100644 index 0000000..71dd7b2 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UpdateTask.kt @@ -0,0 +1,160 @@ +package com.sierrawireless.avphone.task + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import android.util.Log +import com.crashlytics.android.Crashlytics +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.activity.MainActivity +import com.sierrawireless.avphone.message.IMessageDisplayer +import com.sierrawireless.avphone.tools.DeviceInfo +import net.airvantage.model.AirVantageException +import net.airvantage.model.Application +import net.airvantage.model.AvError +import net.airvantage.model.AvSystem +import org.jetbrains.anko.longToast +import java.io.IOException +import java.util.ArrayList + +typealias UpdateListener = (UpdateResult) -> Unit + +open class UpdateTask internal constructor(private val applicationClient: IApplicationClient, private val systemClient: ISystemClient, + private val alertRuleClient: IAlertRuleClient, private val userClient: IUserClient, @field:SuppressLint("StaticFieldLeak") + protected val context: Context) : AvPhoneTask() { + + private val syncListeners = ArrayList() + var deviceName:String? = null + + fun addProgressListener(listener: UpdateListener) { + this.syncListeners.add(listener) + } + + @SuppressLint("DefaultLocale") + override fun doInBackground(vararg params: UpdateParams): UpdateResult { + + try { + + publishProgress(UpdateProgress.CHECKING_RIGHTS) + + + + val systemType: String? + val syncParams = params[0] + val user = userClient.user + val imei = syncParams.imei + val iccid = syncParams.iccid + deviceName = syncParams.deviceName + val mqttPassword = syncParams.mqttPassword + val objectsManager = ObjectsManager.getInstance() + + systemType = objectsManager.savedObjectName + + val missingRights = userClient.checkRights() + if (!missingRights.isEmpty()) { + return UpdateResult(AvError(AvError.MISSING_RIGHTS, missingRights)) + } + + + // For emulator and iOs compatibility sake, using generated serial. + val serialNumber = DeviceInfo.generateSerial(user!!.uid!!) + + // Save Device serial in context + if (context is MainActivity) { + context.systemSerial = serialNumber + } + + + publishProgress(UpdateProgress.CHECKING_APPLICATION) + + val application = this.applicationClient.ensureApplicationExists(deviceName!!) + + publishProgress(UpdateProgress.CHECKING_SYSTEM) + + var system: net.airvantage.model.AvSystem? = this.systemClient.getSystem(serialNumber, systemType!!, deviceName!!) + publishProgress(UpdateProgress.UPDATING_SYSTEM) + + if (system != null) { + systemClient.updateSystem(system, serialNumber, iccid!!, systemType, mqttPassword!!, application.uid!!, deviceName!!, user.name!!, imei!!) + }else{ + system = systemClient.createSystem(serialNumber, iccid!!, systemType, mqttPassword!!, application.uid!!, deviceName!!, user.name!!, imei!!) + } + + objectsManager.savecObject.systemUid = system.uid + objectsManager.saveOnPref() + + publishProgress(UpdateProgress.CHECKING_ALERT_RULE) + + val alertRule = this.alertRuleClient.getAlertRule(serialNumber, system) + publishProgress(UpdateProgress.UPDATING_ALERT_RULE) + + if (alertRule != null) { + this.alertRuleClient.updateAlertRule(application.uid!!, system, alertRule) + }else{ + this.alertRuleClient.createAlertRule(application.uid!!, system) + } + + publishProgress(UpdateProgress.UPDATING_APPLICATION) + + this.applicationClient.setApplicationData(application.uid!!, objectsManager.savecObject.datas, objectsManager.savecObject.name!!) + + if (!hasApplication(system, application)) { + + publishProgress(UpdateProgress.ADDING_APPLICATION) + + this.applicationClient.addApplication(system, application) + } + + publishProgress(UpdateProgress.DONE) + + return UpdateResult(system, user) + + } catch (e: AirVantageException) { + Log.d("TODO", "Airvantage exception e.error " + e.error) + publishProgress(UpdateProgress.DONE) + return UpdateResult(e.error!!) + } catch (e: IOException) { + Crashlytics.logException(e) + Log.e(MainActivity::class.java.name, "Error when trying to synchronize with server", e) + publishProgress(UpdateProgress.DONE) + return UpdateResult(AvError("unkown.error")) + } + } + + override fun onPostExecute(result: UpdateResult) { + super.onPostExecute(result) + for (listener in syncListeners) { + listener.invoke(result) + } + } + + private fun hasApplication(system: AvSystem, application: Application): Boolean { + var found = false + if (system.applications != null) { + system.applications!! + .filter { it.uid == application.uid } + .forEach { found = true } + } + return found + } + + fun showResult(result: UpdateResult, name: String, displayer: IMessageDisplayer, context: Activity) { + + if (result.isError) { + var error = result.error + if (error == null) { + error = AvError("Internal Error") + } + + if (error!!.errorParameters.size == 1 && error!!.errorParameters[0] == "No Connection") { + context.longToast("Resync Error\nYou don't have any data connection") + } + + displayTaskError(error, displayer, context, userClient, deviceName!!) + } else { + displayer.showSuccess(name + " updated with AirVantage") + } + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UserClient.java b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UserClient.java deleted file mode 100644 index 69d29b2..0000000 --- a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UserClient.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.sierrawireless.avphone.task; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.crashlytics.android.Crashlytics; - -import android.util.Log; -import net.airvantage.model.AirVantageException; -import net.airvantage.model.User; -import net.airvantage.model.UserRights; -import net.airvantage.utils.IAirVantageClient; - -public class UserClient implements IUserClient { - - private static final String LOGTAG = UserClient.class.getName(); - - private IAirVantageClient client; - - public UserClient(IAirVantageClient client) { - this.client = client; - } - - @Override - public List checkRights() throws AirVantageException { - - List requiredRights = new ArrayList(Arrays.asList("entities.applications.view", - "entities.applications.create", "entities.applications.edit", "entities.systems.view", - "entities.systems.create", "entities.systems.edit", "entities.alerts.rule.view", - "entities.alerts.rule.create.edit.delete")); - - try { - UserRights rights = client.getUserRights(); - requiredRights.removeAll(rights); - } catch (Exception e) { - Crashlytics.logException(e); - Log.e(LOGTAG, "Could not get user rights", e); - } - - return requiredRights; - - } - - @Override - public User getUser() { - try { - return this.client.getCurrentUser(); - } catch (final Exception e) { - Crashlytics.logException(e); - Log.e(LOGTAG, "Could not get user name", e); - return null; - } - } -} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/task/UserClient.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UserClient.kt new file mode 100644 index 0000000..7fff292 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/task/UserClient.kt @@ -0,0 +1,50 @@ +package com.sierrawireless.avphone.task + +import android.util.Log +import android.widget.Toast +import com.crashlytics.android.Crashlytics +import com.sierrawireless.avphone.activity.MainActivity +import net.airvantage.model.AirVantageException +import net.airvantage.model.User +import net.airvantage.utils.IAirVantageClient +import java.net.UnknownHostException +import java.util.* + +class UserClient internal constructor(private val client: IAirVantageClient) : IUserClient { + override val user: User? + get() { + return try { + this.client.currentUser + } catch (e: Exception) { + Crashlytics.logException(e) + Log.e(TAG, "Could not get user name", e) + null + } + + } + + @Throws(AirVantageException::class) + override fun checkRights(): List { + var requiredRights = ArrayList(Arrays.asList("entities.applications.view", + "entities.applications.create", "entities.applications.edit", "entities.systems.view", + "entities.systems.create", "entities.systems.edit", "entities.alerts.rule.view", + "entities.alerts.rule.create.edit.delete")) + try { + val rights = client.userRights + requiredRights.removeAll(rights) + } catch (e: UnknownHostException) { + requiredRights.clear() + requiredRights = ArrayList(Arrays.asList("No Connection")) + } + catch (e: Exception) { + Crashlytics.logException(e) + Log.e(TAG, "Could not get user rights", e) + } + return requiredRights + } + + companion object { + private val TAG = UserClient::class.simpleName + } + +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/tools/DeviceInfo.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/tools/DeviceInfo.kt new file mode 100644 index 0000000..6548f4e --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/tools/DeviceInfo.kt @@ -0,0 +1,89 @@ +package com.sierrawireless.avphone.tools + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Build +import android.telephony.SubscriptionManager +import android.telephony.TelephonyManager +import android.text.TextUtils +import com.sierrawireless.avphone.activity.MainActivity + +object DeviceInfo { + + /** Returns the consumer friendly device name */ + val deviceName: String? + get() { + val manufacturer = Build.MANUFACTURER + val model = Build.MODEL + return if (model.toUpperCase().startsWith(manufacturer.toUpperCase())) { + capitalize(model) + } else capitalize(manufacturer) + " " + model + } + + private fun capitalize(str: String): String? { + if (TextUtils.isEmpty(str)) { + return str + } + val arr = str.toCharArray() + var capitalizeNext = true + + val phrase = StringBuilder() + for (c in arr) { + if (capitalizeNext && Character.isLetter(c)) { + phrase.append(Character.toUpperCase(c)) + capitalizeNext = false + continue + } else if (Character.isWhitespace(c)) { + capitalizeNext = true + } + phrase.append(c) + } + + return phrase.toString() + } + + /** + * Serial number is in `syncParams.deviceId`, why not using it? + * + * - It is not available running emulator + * - It is not available to our iOs counterpart + * + * So to be AV Phone iOs compatible and able to run emulator, we use: uppercase(userUid + "-" + systemType) + */ + @SuppressLint("DefaultLocale") + fun generateSerial(userUid: String): String { + return userUid + } + + @SuppressLint("DefaultLocale") + fun getUniqueId(context: Context): String? { + + return (context as? MainActivity)?.systemSerial + + } + + + @SuppressLint("HardwareIds", "MissingPermission") + fun getIMEI(context: Context): String? { + + val telManager: TelephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + return if (telManager.phoneType == TelephonyManager.PHONE_TYPE_GSM) { + @Suppress("DEPRECATION") + telManager.deviceId + } else null + + } + + fun getICCID(context: Context): String { + val sm = SubscriptionManager.from(context) + val sis = sm.activeSubscriptionInfoList + return if (sis != null) { + val si = sis[0] + si.iccId + }else{ + "" + } + + + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/tools/MyPreference.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/tools/MyPreference.kt new file mode 100644 index 0000000..e58b7af --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/tools/MyPreference.kt @@ -0,0 +1,87 @@ +package com.sierrawireless.avphone.tools + +import android.content.SharedPreferences +import android.text.TextUtils + +import com.google.gson.Gson +import com.sierrawireless.avphone.model.AvPhoneObject + +import java.util.ArrayList +import java.util.Arrays + +class MyPreference(private val preferences: SharedPreferences) { + + /** + * Get String value from SharedPreferences at 'key'. If key not found, return "" + * @param key SharedPreferences key + * @return String value at 'key' or "" (empty String) if key not found + */ + fun getString(key: String): String { + return preferences.getString(key, "") + } + + /** + * Get parsed ArrayList of String from SharedPreferences at 'key' + * @param key SharedPreferences key + * @return ArrayList of String + */ + private fun getListString(key: String): ArrayList { + return ArrayList(Arrays.asList(*TextUtils.split(preferences.getString(key, ""), "‚‗‚"))) + } + + fun getListObject(key: String, mClass: Class): ArrayList { + val gson = Gson() + + val objStrings = getListString(key) + return objStrings.mapTo(ArrayList()) { gson.fromJson(it, mClass) } + + } + + + /** + * Get int value from SharedPreferences at 'key'. If key not found, return 'defaultValue' + * @param key SharedPreferences key + * @return int value at 'key' or 'defaultValue' if key not found + */ + fun getInt(key: String): Int { + return preferences.getInt(key, 0) + } + + /** + * Put int value into SharedPreferences with 'key' and save + * @param key SharedPreferences key + * @param value int value to be added + */ + fun putInt(key: String, value: Int) { + checkForNullKey(key) + preferences.edit().putInt(key, value).apply() + } + + /** + * null keys would corrupt the shared pref file and make them unreadable this is a preventive measure + * @param key pref key + */ + private fun checkForNullKey(key: String?) { + if (key == null) { + throw NullPointerException() + } + } + + /** + * Put ArrayList of String into SharedPreferences with 'key' and save + * @param key SharedPreferences key + * @param stringList ArrayList of String to be added + */ + private fun putListString(key: String, stringList: ArrayList) { + checkForNullKey(key) + val myStringList = stringList.toTypedArray() + preferences.edit().putString(key, TextUtils.join("‚‗‚", myStringList)).apply() + } + + fun putListObject(key: String, objArray: ArrayList) { + checkForNullKey(key) + val gson = Gson() + val objStrings = objArray.mapTo(ArrayList()) { gson.toJson(it) } + putListString(key, objStrings) + } +} diff --git a/mainActivity/src/main/java/com/sierrawireless/avphone/tools/Tools.kt b/mainActivity/src/main/java/com/sierrawireless/avphone/tools/Tools.kt new file mode 100644 index 0000000..6053aa7 --- /dev/null +++ b/mainActivity/src/main/java/com/sierrawireless/avphone/tools/Tools.kt @@ -0,0 +1,42 @@ +package com.sierrawireless.avphone.tools + +import android.content.Context +import com.sierrawireless.avphone.ObjectsManager +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.model.AvPhoneApplication +import com.sierrawireless.avphone.model.AvPhoneData + +import java.util.* +import org.jetbrains.anko.alert + +object Tools { + const val NAME = "name" + const val VALUE = "value" + + fun buildSerialNumber(serial: String, type: String, deviceName:String): String { + return (serial + "-ANDROID-" + type + "-" + deviceName.replace(" ", "_")).toUpperCase() + } + + fun dp2px(context: Context): Float { + val scale = context.resources.displayMetrics.density + return 90 * scale + 0.5f + } + + fun ClosedRange.random() = + (Random().nextInt(endInclusive - start) + start).toLong() + + fun rand(min:Int, max:Int):Long { + return (min..max).random() + } + + fun buildAlertName():String { + val objectsManager = ObjectsManager.getInstance() + val systemType = objectsManager.savedObjectName + return systemType + " " + AvPhoneApplication.ALERT_RULE_NAME + " on " + DeviceInfo.deviceName + "..." + } + + fun buildDefaultPath(name:String, pos:Int):String = name + "." + AvPhoneData.CUSTOM + pos.toString() + + fun buildSystemName(deviceName: String, userName: String, type: String) = "$type for $deviceName ($userName)" + +} diff --git a/mainActivity/src/main/java/net/airvantage/model/AccessToken.java b/mainActivity/src/main/java/net/airvantage/model/AccessToken.java deleted file mode 100644 index 7068e3d..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/AccessToken.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.airvantage.model; - -public class AccessToken { - public String access_token; - public String refresh_token; - public long expires_in; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/AirVantageException.java b/mainActivity/src/main/java/net/airvantage/model/AirVantageException.java deleted file mode 100644 index d5af12a..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/AirVantageException.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.airvantage.model; - -public class AirVantageException extends Exception { - - private static final long serialVersionUID = 1L; - private AvError error; - - public AirVantageException(net.airvantage.model.AvError error) { - super(); - this.error = error; - } - - public AvError getError() { - return error; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/model/AirVantageException.kt b/mainActivity/src/main/java/net/airvantage/model/AirVantageException.kt new file mode 100644 index 0000000..cb29774 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/AirVantageException.kt @@ -0,0 +1,14 @@ +package net.airvantage.model + +class AirVantageException(error: net.airvantage.model.AvError) : Exception() { + var error: AvError? = null + + init { + this.error = error + } + + companion object { + + private const val serialVersionUID = 1L + } +} diff --git a/mainActivity/src/main/java/net/airvantage/model/Application.java b/mainActivity/src/main/java/net/airvantage/model/Application.java deleted file mode 100644 index e6b0072..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Application.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.airvantage.model; - -public class Application { - public String uid; - public String name; - public String revision; - public String type; - public String category; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Application.kt b/mainActivity/src/main/java/net/airvantage/model/Application.kt new file mode 100644 index 0000000..bc1a192 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Application.kt @@ -0,0 +1,8 @@ +package net.airvantage.model + +class Application { + var uid: String? = null + var name: String? = null + var revision: String? = null + var type: String? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/ApplicationData.java b/mainActivity/src/main/java/net/airvantage/model/ApplicationData.java deleted file mode 100644 index 6ec1cfa..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/ApplicationData.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.airvantage.model; - -import java.util.List; - -public class ApplicationData { - public String id; - public String label; - public String description; - public String elementType; - public String encoding; - public List data; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/ApplicationData.kt b/mainActivity/src/main/java/net/airvantage/model/ApplicationData.kt new file mode 100644 index 0000000..1783fe8 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/ApplicationData.kt @@ -0,0 +1,9 @@ +package net.airvantage.model + +class ApplicationData { + var id: String? = null + var label: String? = null + var elementType: String? = null + var encoding: String? = null + var data: MutableList? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/ApplicationsList.java b/mainActivity/src/main/java/net/airvantage/model/ApplicationsList.java deleted file mode 100644 index 0902dbf..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/ApplicationsList.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.airvantage.model; - -public class ApplicationsList extends EntityList { - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/ApplicationsList.kt b/mainActivity/src/main/java/net/airvantage/model/ApplicationsList.kt new file mode 100644 index 0000000..abc011d --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/ApplicationsList.kt @@ -0,0 +1,3 @@ +package net.airvantage.model + +class ApplicationsList : EntityList() diff --git a/mainActivity/src/main/java/net/airvantage/model/AvError.java b/mainActivity/src/main/java/net/airvantage/model/AvError.java deleted file mode 100644 index dbb2c0a..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/AvError.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.airvantage.model; - -import java.util.Arrays; -import java.util.List; - -public class AvError { - - public static final String SYSTEM_EXISTS = "system.not.unique.identifiers"; - public static final String GATEWAY_EXISTS = "gateway.not.unique.identifiers"; - public static final String GATEWAY_ASSIGNED = "gateway.assigned"; - public static final String FORBIDDEN = "forbidden"; - public static final String APPLICATION_TYPE_EXISTS = "application.type.already.used"; - public static final String ALERT_RULES_TOO_MANY = "alert.rule.too.many"; - public static final String MISSING_RIGHTS = "missing.rights"; - - public String error; - public List errorParameters; - - public AvError(String error) { - this.error = error; - this.errorParameters = Arrays.asList(); - } - - public AvError(String error, List errorParameters) { - super(); - this.error = error; - this.errorParameters = errorParameters; - } - - public boolean systemAlreadyExists() { - return (SYSTEM_EXISTS.equals(error) || GATEWAY_EXISTS.equals(error)); - } - - public boolean gatewayAlreadyExists() { - return (GATEWAY_ASSIGNED.equals(error)); - } - - public boolean applicationAlreadyUsed() { - return (APPLICATION_TYPE_EXISTS.equals(error)); - } - - public boolean tooManyAlerRules() { - return (ALERT_RULES_TOO_MANY.equals(error)); - } - - public boolean forbidden() { - return FORBIDDEN.equals(error); - } - - public boolean cantCreateApplication() { - return isForbiddenAction("POST", "application"); - } - - public boolean cantCreateSystem() { - return isForbiddenAction("POST", "system"); - } - - public boolean cantCreateAlertRule() { - return isForbiddenAction("POST", "alerts/rules"); - } - - public boolean cantUpdateApplication() { - return isForbiddenAction("PUT", "application"); - } - - public boolean cantUpdateSystem() { - return isForbiddenAction("PUT", "system"); - } - - protected boolean isForbiddenAction(String method, String entity) { - if (forbidden()) { - String requestMethod = errorParameters.get(0); - String requestUrl = errorParameters.get(1); - return method.equalsIgnoreCase(requestMethod) && requestUrl.contains(entity); - } else { - return false; - } - } - - public boolean missingRights() { - return MISSING_RIGHTS.equals(error); - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/AvError.kt b/mainActivity/src/main/java/net/airvantage/model/AvError.kt new file mode 100644 index 0000000..be69c2b --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/AvError.kt @@ -0,0 +1,83 @@ +package net.airvantage.model + +class AvError { + + var error: String + var errorParameters: List + + constructor(error: String) { + this.error = error + this.errorParameters = emptyList() + } + + constructor(error: String, errorParameters: List) : super() { + this.error = error + this.errorParameters = errorParameters + } + + fun systemAlreadyExists(): Boolean { + return SYSTEM_EXISTS == error || GATEWAY_EXISTS == error + } + + fun gatewayAlreadyExists(): Boolean { + return GATEWAY_ASSIGNED == error + } + + fun applicationAlreadyUsed(): Boolean { + return APPLICATION_TYPE_EXISTS == error + } + + fun tooManyAlerRules(): Boolean { + return ALERT_RULES_TOO_MANY == error + } + + fun forbidden(): Boolean { + return FORBIDDEN == error + } + + fun cantCreateApplication(): Boolean { + return isForbiddenAction("POST", "application") + } + + fun cantCreateSystem(): Boolean { + return isForbiddenAction("POST", "system") + } + + fun cantCreateAlertRule(): Boolean { + return isForbiddenAction("POST", "alerts/rules") + } + + fun cantUpdateApplication(): Boolean { + return isForbiddenAction("PUT", "application") + } + + fun cantUpdateSystem(): Boolean { + return isForbiddenAction("PUT", "system") + } + + private fun isForbiddenAction(method: String, entity: String): Boolean { + return if (forbidden()) { + val requestMethod = errorParameters[0] + val requestUrl = errorParameters[1] + method.equals(requestMethod, ignoreCase = true) && requestUrl.contains(entity) + } else { + false + } + } + + fun missingRights(): Boolean { + return MISSING_RIGHTS == error + } + + companion object { + + private const val SYSTEM_EXISTS = "system.not.unique.identifiers" + private const val GATEWAY_EXISTS = "gateway.not.unique.identifiers" + private const val GATEWAY_ASSIGNED = "gateway.assigned" + const val FORBIDDEN = "forbidden" + private const val APPLICATION_TYPE_EXISTS = "application.type.already.used" + private const val ALERT_RULES_TOO_MANY = "alert.rule.too.many" + const val MISSING_RIGHTS = "missing.rights" + } + +} diff --git a/mainActivity/src/main/java/net/airvantage/model/AvSystem.java b/mainActivity/src/main/java/net/airvantage/model/AvSystem.java deleted file mode 100644 index 652533b..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/AvSystem.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.airvantage.model; - -import java.util.List; -import java.util.Map; - -import net.airvantage.utils.Predicate; - - -public class AvSystem { - public String uid; - public String name; - public String commStatus; - public Long lastCommDate; - public String type; - public String state; - public String activityState; - public Long lastSyncDate; - public String syncStatus; - public Gateway gateway; - public Data data; - public List applications; - public Map communication; - - public static class Data { - public Double rssi; - public String rssiLevel; - public String networkServiceType; - public Double latitude; - public Double longitude; - } - - public static class Gateway { - public String uid; - public String imei; - public String macAddress; - public String serialNumber; - public String type; - } - - public static Predicate hasSerialNumber(final String serialNumber) { - return new Predicate() { - @Override - public boolean matches(AvSystem item) { - return (serialNumber != null && serialNumber.equals(item.gateway.serialNumber)); - } - }; - } - - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/AvSystem.kt b/mainActivity/src/main/java/net/airvantage/model/AvSystem.kt new file mode 100644 index 0000000..1126853 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/AvSystem.kt @@ -0,0 +1,40 @@ +package net.airvantage.model + +import net.airvantage.utils.Predicate + + +class AvSystem { + var uid: String? = null + var name: String? = null + var type: String? = null + var state: String? = null + var gateway: Gateway? = null + var data: Data? = null + var applications: MutableList? = null + var communication: MutableMap? = null + + class Data { + var rssi: Double? = null + var rssiLevel: String? = null + var networkServiceType: String? = null + var latitude: Double? = null + var longitude: Double? = null + } + + class Gateway { + var uid: String? = null + var imei: String? = null + var serialNumber: String? = null + var type: String? = null + } + + companion object { + + + fun hasSerialNumber(serialNumber: String?): Predicate { + return { item -> serialNumber != null && serialNumber == item.gateway!!.serialNumber } + } + } + + +} diff --git a/mainActivity/src/main/java/net/airvantage/model/Command.java b/mainActivity/src/main/java/net/airvantage/model/Command.java deleted file mode 100644 index b4b2427..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Command.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.airvantage.model; - -import java.util.List; - -public class Command extends Data { - - public List parameters; - - public Command(String id, String label) { - super(id, label, "command"); - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Command.kt b/mainActivity/src/main/java/net/airvantage/model/Command.kt new file mode 100644 index 0000000..680dcee --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Command.kt @@ -0,0 +1,7 @@ +package net.airvantage.model + +class Command(id: String, label: String) : Data(id, label, "command") { + + var parameters: List? = null + +} diff --git a/mainActivity/src/main/java/net/airvantage/model/Data.java b/mainActivity/src/main/java/net/airvantage/model/Data.java deleted file mode 100644 index 4ca7ac8..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Data.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.airvantage.model; - -import java.util.List; - -public class Data { - public String id; - public String label; - public String type; - public String description; - public String elementType; - public List data; - - public Data(String id, String label, String elementType) { - this.id = id; - this.label = label; - this.elementType = elementType; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Data.kt b/mainActivity/src/main/java/net/airvantage/model/Data.kt new file mode 100644 index 0000000..c95d16c --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Data.kt @@ -0,0 +1,6 @@ +package net.airvantage.model + +open class Data(var id: String, private val label: String, private val elementType: String) { + var type: String? = null + var data: MutableList? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/Datapoint.java b/mainActivity/src/main/java/net/airvantage/model/Datapoint.java deleted file mode 100644 index abb371d..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Datapoint.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.airvantage.model; - -public class Datapoint { - - public long timestamp; - public double value; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Datapoint.kt b/mainActivity/src/main/java/net/airvantage/model/Datapoint.kt new file mode 100644 index 0000000..ae553bd --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Datapoint.kt @@ -0,0 +1,6 @@ +package net.airvantage.model + +class Datapoint { + + var value: Double = 0.toDouble() +} diff --git a/mainActivity/src/main/java/net/airvantage/model/EntityList.java b/mainActivity/src/main/java/net/airvantage/model/EntityList.java deleted file mode 100644 index 639d0fe..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/EntityList.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.airvantage.model; - -import java.util.List; - -public class EntityList { - public List items; - public Integer count; - public Integer size; - public Integer offset; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/EntityList.kt b/mainActivity/src/main/java/net/airvantage/model/EntityList.kt new file mode 100644 index 0000000..1ad561d --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/EntityList.kt @@ -0,0 +1,6 @@ +package net.airvantage.model + +open class EntityList { + var items: List? = null + var size: Int? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/MqttCommunication.java b/mainActivity/src/main/java/net/airvantage/model/MqttCommunication.java deleted file mode 100644 index 7d8fdc9..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/MqttCommunication.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.airvantage.model; - -public class MqttCommunication { - public String password; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/MqttCommunication.kt b/mainActivity/src/main/java/net/airvantage/model/MqttCommunication.kt new file mode 100644 index 0000000..d874db8 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/MqttCommunication.kt @@ -0,0 +1,5 @@ +package net.airvantage.model + +class MqttCommunication { + var password: String? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/OperationResult.java b/mainActivity/src/main/java/net/airvantage/model/OperationResult.java deleted file mode 100644 index cc2bd37..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/OperationResult.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.airvantage.model; - -public class OperationResult { - public String operationUid; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Parameter.java b/mainActivity/src/main/java/net/airvantage/model/Parameter.java deleted file mode 100644 index 8882d44..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Parameter.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.airvantage.model; - -public class Parameter { - - public String id; - public String type; - - public Parameter(String id, String type) { - super(); - this.id = id; - this.type = type; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Parameter.kt b/mainActivity/src/main/java/net/airvantage/model/Parameter.kt new file mode 100644 index 0000000..12f2105 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Parameter.kt @@ -0,0 +1,3 @@ +package net.airvantage.model + +class Parameter(var id: String, var type: String) diff --git a/mainActivity/src/main/java/net/airvantage/model/Protocol.java b/mainActivity/src/main/java/net/airvantage/model/Protocol.java deleted file mode 100644 index 8deaca5..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Protocol.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.airvantage.model; - -public class Protocol { - public String type; - public String commIdType; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Protocol.kt b/mainActivity/src/main/java/net/airvantage/model/Protocol.kt new file mode 100644 index 0000000..fcd00a5 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Protocol.kt @@ -0,0 +1,6 @@ +package net.airvantage.model + +class Protocol { + var type: String? = null + var commIdType: String? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/Setting.java b/mainActivity/src/main/java/net/airvantage/model/Setting.java deleted file mode 100644 index 0455b03..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Setting.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.airvantage.model; - -public class Setting extends Data { - - public Setting(String id, String label, String type) { - super(id, label, "setting"); - this.type = type; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/SystemsList.java b/mainActivity/src/main/java/net/airvantage/model/SystemsList.java deleted file mode 100644 index 2458c5b..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/SystemsList.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.airvantage.model; - -public class SystemsList extends EntityList { -} diff --git a/mainActivity/src/main/java/net/airvantage/model/SystemsList.kt b/mainActivity/src/main/java/net/airvantage/model/SystemsList.kt new file mode 100644 index 0000000..423fcbe --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/SystemsList.kt @@ -0,0 +1,3 @@ +package net.airvantage.model + +class SystemsList : EntityList() diff --git a/mainActivity/src/main/java/net/airvantage/model/User.java b/mainActivity/src/main/java/net/airvantage/model/User.java deleted file mode 100644 index e3d8243..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/User.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.airvantage.model; - -public class User { - - public String uid; - public String email; - public Pictures picture; - public String name; - - public static class Pictures { - public String normal; - public String small; - public String icon; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/model/User.kt b/mainActivity/src/main/java/net/airvantage/model/User.kt new file mode 100644 index 0000000..493b1fb --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/User.kt @@ -0,0 +1,23 @@ +package net.airvantage.model + +class User { + + var uid: String? = null + var email: String? = null + var name: String? = null + var profile: Profile? = null + var company: Company? = null + var server: String? = null + + inner class Profile { + var uid: String? = null + var name: String? = null + } + + inner class Company { + var uid: String? = null + var name: String? = null + } + + +} diff --git a/mainActivity/src/main/java/net/airvantage/model/UserRights.java b/mainActivity/src/main/java/net/airvantage/model/UserRights.java deleted file mode 100644 index d2bf8e7..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/UserRights.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.airvantage.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import android.content.Context; - -import com.sierrawireless.avphone.R; - -public class UserRights extends ArrayList { - - private static final long serialVersionUID = 1L; - - private static Map AS_STRING_ID = new HashMap(); - - static { - AS_STRING_ID.put("entities.systems.view", R.string.entities_systems_view); - AS_STRING_ID.put("entities.systems.create", R.string.entities_systems_create); - AS_STRING_ID.put("entities.systems.edit", R.string.entities_systems_edit); - AS_STRING_ID.put("entities.applications.view", R.string.entities_applications_view); - AS_STRING_ID.put("entities.applications.create", R.string.entities_applications_create); - AS_STRING_ID.put("entities.applications.edit", R.string.entities_applications_edit); - AS_STRING_ID.put("entities.alerts.rule.view", R.string.entities_alerts_rule_view); - AS_STRING_ID.put("entities.alerts.rule.create.edit.delete", R.string.entities_alerts_rule_create_edit_delete); - } - - public static String asString(String rightKey, Context context) { - String res = null; - Integer stringId = AS_STRING_ID.get(rightKey); - if (stringId != null) { - res = context.getString(stringId); - } - return res; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/UserRights.kt b/mainActivity/src/main/java/net/airvantage/model/UserRights.kt new file mode 100644 index 0000000..b10e9d6 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/UserRights.kt @@ -0,0 +1,38 @@ +package net.airvantage.model + +import java.util.ArrayList +import java.util.HashMap + +import android.content.Context + +import com.sierrawireless.avphone.R + +class UserRights : ArrayList() { + companion object { + + private const val serialVersionUID = 1L + + private val AS_STRING_ID = HashMap() + + init { + AS_STRING_ID["entities.systems.view"] = R.string.entities_systems_view + AS_STRING_ID["entities.systems.create"] = R.string.entities_systems_create + AS_STRING_ID["entities.systems.edit"] = R.string.entities_systems_edit + AS_STRING_ID["entities.applications.view"] = R.string.entities_applications_view + AS_STRING_ID["entities.applications.create"] = R.string.entities_applications_create + AS_STRING_ID["entities.applications.edit"] = R.string.entities_applications_edit + AS_STRING_ID["entities.alerts.rule.view"] = R.string.entities_alerts_rule_view + AS_STRING_ID["entities.alerts.rule.create.edit.delete"] = R.string.entities_alerts_rule_create_edit_delete + } + + fun asString(rightKey: String, context: Context): String? { + var res: String? = null + val stringId = AS_STRING_ID[rightKey] + if (stringId != null) { + res = context.getString(stringId) + } + return res + } + } + +} diff --git a/mainActivity/src/main/java/net/airvantage/model/Variable.java b/mainActivity/src/main/java/net/airvantage/model/Variable.java deleted file mode 100644 index d9ba239..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/Variable.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.airvantage.model; - -public class Variable extends Data { - - public Variable(String id, String label, String type) { - super(id, label, "variable"); - this.type = type; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/Variable.kt b/mainActivity/src/main/java/net/airvantage/model/Variable.kt new file mode 100644 index 0000000..c57241e --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/Variable.kt @@ -0,0 +1,8 @@ +package net.airvantage.model + +class Variable(id: String, label: String, type: String) : Data(id, label, "variable") { + + init { + this.type = type + } +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/Alert.java b/mainActivity/src/main/java/net/airvantage/model/alert/v1/Alert.java deleted file mode 100644 index 9569620..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v1/Alert.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.airvantage.model.alert.v1; - -public class Alert { - - public String target; - public long date; - public String eventType; - public String uid; - public long acknowledgedAt; - public String acknowledgedBy; - public Rule rule; - public int nbOccurrence; - public long lastDate; - - public static class Rule { - public String name; - public String message; - public String uid; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/Alert.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v1/Alert.kt new file mode 100644 index 0000000..cb1ab19 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v1/Alert.kt @@ -0,0 +1,13 @@ +package net.airvantage.model.alert.v1 + +class Alert { + + var date: Long = 0 + var uid: String? = null + + class Rule { + var name: String? = null + var message: String? = null + var uid: String? = null + } +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRule.java b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRule.java deleted file mode 100644 index 0332c71..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRule.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.airvantage.model.alert.v1; - -import java.util.List; -import java.util.Map; - -import net.airvantage.utils.Predicate; - -public class AlertRule { - public String uid; - public boolean active = true; - public String name; - public String eventType; - public List conditions; - public Map metadata; - - public static Predicate isNamed(final String name) { - return new Predicate() { - @Override - public boolean matches(AlertRule item) { - return name.equals(item.name); - } - }; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRule.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRule.kt new file mode 100644 index 0000000..20ab279 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRule.kt @@ -0,0 +1,19 @@ +package net.airvantage.model.alert.v1 + + +class AlertRule { + var uid: String? = null + var active = true + var name: String? = null + var eventType: String? = null + var conditions: MutableList? = null + + + + companion object { + + fun isNamed(name: String): net.airvantage.utils.Predicate { + return { item -> name == item.name } + } + } +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRuleList.java b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRuleList.java deleted file mode 100644 index 06e506d..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRuleList.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.airvantage.model.alert.v1; - -import net.airvantage.model.EntityList; -import net.airvantage.model.alert.v1.AlertRule; - -public class AlertRuleList extends EntityList { - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRuleList.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRuleList.kt new file mode 100644 index 0000000..11dd17d --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertRuleList.kt @@ -0,0 +1,5 @@ +package net.airvantage.model.alert.v1 + +import net.airvantage.model.EntityList + +class AlertRuleList : EntityList() diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertsList.java b/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertsList.java deleted file mode 100644 index 6cd6244..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v1/AlertsList.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.airvantage.model.alert.v1; - -import net.airvantage.model.EntityList; -import net.airvantage.model.alert.v1.Alert; - -public class AlertsList extends EntityList { -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/Condition.java b/mainActivity/src/main/java/net/airvantage/model/alert/v1/Condition.java deleted file mode 100644 index c2bda42..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v1/Condition.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.airvantage.model.alert.v1; - -public class Condition { - public String eventProperty; - public String eventPropertyKey; - public String operator; - public String value; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v1/Condition.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v1/Condition.kt new file mode 100644 index 0000000..b6c25de --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v1/Condition.kt @@ -0,0 +1,8 @@ +package net.airvantage.model.alert.v1 + +class Condition { + var eventProperty: String? = null + var eventPropertyKey: String? = null + var operator: String? = null + var value: String? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/AlertRuleList.java b/mainActivity/src/main/java/net/airvantage/model/alert/v2/AlertRuleList.java deleted file mode 100644 index 5476c2b..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v2/AlertRuleList.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.airvantage.model.alert.v2; - -import net.airvantage.model.alert.v2.alertrule.AlertRule; - -import java.util.ArrayList; - -public class AlertRuleList extends ArrayList { - -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/AlertRuleList.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v2/AlertRuleList.kt new file mode 100644 index 0000000..5b93a20 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v2/AlertRuleList.kt @@ -0,0 +1,7 @@ +package net.airvantage.model.alert.v2 + +import net.airvantage.model.alert.v2.alertrule.AlertRule + +import java.util.ArrayList + +class AlertRuleList : ArrayList() diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AlertRule.java b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AlertRule.java deleted file mode 100644 index bb9670c..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AlertRule.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.airvantage.model.alert.v2.alertrule; - - -import net.airvantage.utils.Predicate; - -import java.util.List; -import java.util.Map; - -public class AlertRule { - - public String id; - public boolean active; - public List emails; - - public String companyId; - public String message; - public String name; - public String notifMode; - public String targetType; - - public List conditions; - - public Map metadata; - - - public static Predicate isNamed(final String name) { - return new Predicate() { - @Override - public boolean matches(AlertRule item) { - return name.equals(item.name); - } - }; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AlertRule.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AlertRule.kt new file mode 100644 index 0000000..956d9f2 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AlertRule.kt @@ -0,0 +1,24 @@ +package net.airvantage.model.alert.v2.alertrule + +import net.airvantage.utils.Predicate + + +class AlertRule { + + var id: String? = null + var active: Boolean = false + + var message: String? = null + var name: String? = null + var targetType: String? = null + + var conditions: MutableList? = null + var metadata: MutableMap? = null + + companion object { + + fun isNamed(name: String): Predicate { + return { item -> name == item.name } + } + } +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AttributeId.java b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AttributeId.java deleted file mode 100644 index a664ef6..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AttributeId.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.airvantage.model.alert.v2.alertrule; - - -public class AttributeId { - public String targetId; - public String name; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AttributeId.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AttributeId.kt new file mode 100644 index 0000000..84dfd89 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/AttributeId.kt @@ -0,0 +1,6 @@ +package net.airvantage.model.alert.v2.alertrule + + +class AttributeId { + var name: String? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Condition.java b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Condition.java deleted file mode 100644 index 8b38c7c..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Condition.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.airvantage.model.alert.v2.alertrule; - -import java.util.List; - -public class Condition { - public String operator; - public List operands; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Condition.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Condition.kt new file mode 100644 index 0000000..ea3c60b --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Condition.kt @@ -0,0 +1,6 @@ +package net.airvantage.model.alert.v2.alertrule + +class Condition { + var operator: String? = null + var operands: List? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Operand.java b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Operand.java deleted file mode 100644 index 08c4a0c..0000000 --- a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Operand.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.airvantage.model.alert.v2.alertrule; - -import java.util.List; - -public class Operand { - - public AttributeId attributeId; - public String function; - public String functionParam; - public String valueStr; - public Number valueNum; - public List valuesStr; -} diff --git a/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Operand.kt b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Operand.kt new file mode 100644 index 0000000..90f1e34 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/model/alert/v2/alertrule/Operand.kt @@ -0,0 +1,8 @@ +package net.airvantage.model.alert.v2.alertrule + +class Operand { + + var attributeId: AttributeId? = null + var valueStr: String? = null + var valueNum: Number? = null +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/AirVantageClient.java b/mainActivity/src/main/java/net/airvantage/utils/AirVantageClient.java deleted file mode 100644 index a2cb6bb..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/AirVantageClient.java +++ /dev/null @@ -1,318 +0,0 @@ -package net.airvantage.utils; - -import android.util.Log; - -import com.crashlytics.android.Crashlytics; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.squareup.okhttp.OkHttpClient; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.ApplicationData; -import net.airvantage.model.ApplicationsList; -import net.airvantage.model.AvError; -import net.airvantage.model.AvSystem; -import net.airvantage.model.Datapoint; -import net.airvantage.model.Protocol; -import net.airvantage.model.SystemsList; -import net.airvantage.model.User; -import net.airvantage.model.UserRights; -import net.airvantage.model.alert.v1.AlertRule; -import net.airvantage.utils.alert.AlertAdapterFactory; -import net.airvantage.utils.alert.IAlertAdapterFactoryListener; -import net.airvantage.utils.alert.DefaultAlertAdapter; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.lang.reflect.Type; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class AirVantageClient implements IAirVantageClient, IAlertAdapterFactoryListener { - - private static final String SCHEME = "https://"; - - private static final String API_PREFIX = "/api/v1"; - - private final String access_token; - - private DefaultAlertAdapter alertAdapter = null; - - private final String server; - - private Gson gson; - - private OkHttpClient client; - - public AirVantageClient(String server, String token) { - this.server = server; - this.access_token = token; - this.gson = new Gson(); - this.client = new OkHttpClient(); - new AlertAdapterFactory(server, token, this); - - } - - @Override - public void alertAdapterAvailable(DefaultAlertAdapter adapter) { - alertAdapter = adapter; - } - - public static String buildImplicitFlowURL(String server, String clientId) { - return SCHEME + server + "/api/oauth/authorize?client_id=" + clientId - + "&response_type=token&redirect_uri=oauth://airvantage"; - } - - private String buildPath(String api) { - return server + API_PREFIX + api + "?access_token=" + access_token; - } - - private String buildEndpoint(String api) { - return SCHEME + buildPath(api); - } - - protected InputStream readResponse(HttpURLConnection connection) throws IOException, AirVantageException { - InputStream in; - if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - in = connection.getInputStream(); - } else if (connection.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST) { - in = connection.getErrorStream(); - InputStreamReader isr = new InputStreamReader(in); - - net.airvantage.model.AvError error = gson.fromJson(isr, net.airvantage.model.AvError.class); - - Log.e(AirVantageClient.class.getName(), "AirVantage Error : " + error.error + "," + error.errorParameters); - - throw new AirVantageException(error); - } else if (connection.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) { - String method = connection.getRequestMethod(); - String url = connection.getURL().toString(); - AvError error = new AvError(AvError.FORBIDDEN, Arrays.asList(method, url)); - throw new AirVantageException(error); - } else { - throw new IOException("Unexpected HTTP response: " + connection.getResponseCode() + " " - + connection.getResponseMessage()); - } - return in; - } - - protected InputStream sendString(String method, URL url, String bodyString) - throws IOException, AirVantageException { - - OutputStream out = null; - try { - - // Create request for remote resource. - HttpURLConnection connection = client.open(url); - connection.addRequestProperty("Cache-Control", "no-cache"); - connection.addRequestProperty("Content-Type", "application/json"); - - // Write the request. - connection.setRequestMethod(method); - out = connection.getOutputStream(); - out.write(bodyString.getBytes()); - return readResponse(connection); - - } finally { - if (out != null) - out.close(); - } - - } - - protected InputStream post(URL url, Object body) throws IOException, AirVantageException { - String bodyString = gson.toJson(body); - return sendString("POST", url, bodyString); - } - - protected InputStream put(URL url, Object body) throws IOException, AirVantageException { - String bodyString = gson.toJson(body); - return sendString("PUT", url, bodyString); - } - - protected InputStream get(URL url) throws IOException, AirVantageException { - // Create request for remote resource. - HttpURLConnection connection = client.open(url); - connection.addRequestProperty("Cache-Control", "no-cache"); - - return readResponse(connection); - } - - @Override - public User getCurrentUser() throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/users/current")); - InputStream in = get(url); - return gson.fromJson(new InputStreamReader(in), User.class); - } - - public void expire() throws IOException, AirVantageException { - URL url = new URL(server + "/api/oauth/expire?access_token=" + access_token); - this.get(url); - } - - public List getLast24Hours(String systemUid, String data) throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/systems/" + systemUid + "/data/" + data + "/aggregated") + "&fn=mean&from=" - + (System.currentTimeMillis() - 23 * 60 * 60 * 1000) + "&to=" - + (System.currentTimeMillis() + 1 * 60 * 60 * 1000)); - - InputStream in = this.get(url); - - // Deserialize HTTP response to concrete type. - Type collectionType = new TypeToken>() { - }.getType(); - return gson.fromJson(new InputStreamReader(in), collectionType); - - } - - public Map getLast24HoursOccurences(String systemUid, String data) - throws IOException, AirVantageException { - - URL url = new URL(buildEndpoint("/systems/" + systemUid + "/data/" + data + "/aggregated") - + "&fn=occ&interval=24hour&from=" + (System.currentTimeMillis() - 23 * 60 * 60 * 1000) + "&to=" - + (System.currentTimeMillis() + 1 * 60 * 60 * 1000)); - - InputStream in = this.get(url); - - Map values = new HashMap(); - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - StringBuilder sb = new StringBuilder(); - String line = null; - - while ((line = reader.readLine()) != null) { - sb.append(line); - } - - in.close(); - JSONArray json = new JSONArray(sb.toString()); - JSONObject jsonValues = json.getJSONObject(0).getJSONObject("value"); - for (int i = 0; i < jsonValues.names().length(); i++) { - values.put(jsonValues.names().getString(i).trim(), jsonValues.getInt(jsonValues.names().getString(i))); - } - } catch (JSONException e) { - Log.e(AirVantageClient.class.getName(), "Unable to parse json", e); - Crashlytics.logException(e); - } - - return values; - - } - - public net.airvantage.model.AvSystem getSystemByUid(String uid) throws IOException, AirVantageException { - URL url = new URL( - buildEndpoint("/systems") + "&fields=uid,name,commStatus,lastCommDate,data,applications&uid=" + uid); - InputStream in = get(url); - List items = gson.fromJson(new InputStreamReader(in), SystemsList.class).items; - if (items.size() > 0) { - return items.get(0); - } else { - return null; - } - } - - public List getSystems() throws IOException, AirVantageException { - return getSystemsBySerialNumber(null); - } - - public List getSystemsBySerialNumber(String serialNumber) - throws IOException, AirVantageException { - String urlString = buildEndpoint("/systems") - + "&fields=uid,name,commStatus,lastCommDate,data,applications,gateway,type"; - if (serialNumber != null) { - urlString += "&gateway=serialNumber:" + serialNumber; - } - URL url = new URL(urlString); - InputStream in = this.get(url); - return gson.fromJson(new InputStreamReader(in), SystemsList.class).items; - } - - public net.airvantage.model.AvSystem createSystem(net.airvantage.model.AvSystem system) - throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/systems")); - InputStream in = post(url, system); - return gson.fromJson(new InputStreamReader(in), net.airvantage.model.AvSystem.class); - } - - @Override - public void updateSystem(AvSystem system) throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/systems/") + system.uid); - put(url, system); - } - - public List getApplications(String type) throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/applications") + "&type=" + type + "&fields=uid,name,revision,type,category"); - InputStream in = this.get(url); - try { - return gson.fromJson(new InputStreamReader(in), ApplicationsList.class).items; - } finally { - if (in != null) { - in.close(); - } - } - } - - public net.airvantage.model.Application createApplication(net.airvantage.model.Application application) - throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/applications")); - InputStream in = post(url, application); - return gson.fromJson(new InputStreamReader(in), net.airvantage.model.Application.class); - } - - public void setApplicationData(String applicationUid, List data) - throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/applications/" + applicationUid + "/data")); - put(url, data); - } - - public void setApplicationCommunication(String applicationUid, List protocols) - throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/applications/" + applicationUid + "/communication")); - put(url, protocols); - } - - private void checkAlertAdapter() throws AirVantageException { - if (this.alertAdapter == null) - throw new AirVantageException(new AvError("Response pending")); - } - - @Override - public AlertRule getAlertRuleByName(final String name) throws IOException, AirVantageException { - checkAlertAdapter(); - return this.alertAdapter.getAlertRuleByName(name); - } - - @Override - public AlertRule createAlertRule(AlertRule alertRule) throws IOException, AirVantageException { - checkAlertAdapter(); - return this.alertAdapter.createAlertRule(alertRule); - } - - @Override - public AlertRule updateAlertRule(AlertRule alertRule) throws IOException, AirVantageException { - checkAlertAdapter(); - return this.alertAdapter.updateAlertRule(alertRule); - } - - @Override - public void logout() throws IOException, AirVantageException { - URL url = new URL(SCHEME + server + "/api/oauth/expire?access_token=" + access_token); - get(url); - } - - public UserRights getUserRights() throws IOException, AirVantageException { - URL url = new URL(buildEndpoint("/users/rights")); - InputStream in = get(url); - return gson.fromJson(new InputStreamReader(in), UserRights.class); - } -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/AirVantageClient.kt b/mainActivity/src/main/java/net/airvantage/utils/AirVantageClient.kt new file mode 100644 index 0000000..17d7d88 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/AirVantageClient.kt @@ -0,0 +1,276 @@ +package net.airvantage.utils + +import android.util.Log +import com.google.gson.Gson +import com.squareup.okhttp.OkHttpClient +import net.airvantage.model.* +import net.airvantage.model.alert.v1.AlertRule +import net.airvantage.utils.alert.AlertAdapterFactory +import net.airvantage.utils.alert.DefaultAlertAdapter +import net.airvantage.utils.alert.IAlertAdapterFactoryListener +import org.json.JSONException +import org.json.JSONObject +import java.io.* +import java.net.HttpURLConnection +import java.net.URL +import java.util.* + +class AirVantageClient(private val server: String, private val access_token: String) : IAirVantageClient, IAlertAdapterFactoryListener { + private var alertAdapter: DefaultAlertAdapter? = null + private val gson: Gson = Gson() + private val client: OkHttpClient = OkHttpClient() + init { + AlertAdapterFactory(server, access_token, this) + } + + override fun alertAdapterAvailable(adapter: DefaultAlertAdapter) { + alertAdapter = adapter + } + + private fun buildPath(api: String): String { + return server + API_PREFIX + api + "?access_token=" + access_token + } + + private fun buildEndpoint(api: String): String { + return SCHEME + buildPath(api) + } + + @Throws(IOException::class, AirVantageException::class) + private fun readResponse(connection: HttpURLConnection): InputStream { + val inputStream: InputStream + when { + connection.responseCode == HttpURLConnection.HTTP_OK -> inputStream = connection.inputStream + connection.responseCode == HttpURLConnection.HTTP_BAD_REQUEST -> { + inputStream = connection.errorStream + val isr = InputStreamReader(inputStream) + + val error = gson.fromJson(isr, net.airvantage.model.AvError::class.java) + + Log.e(AirVantageClient::class.java.name, "AirVantage Error : " + error.error + "," + error.errorParameters) + + throw AirVantageException(error) + } + connection.responseCode == HttpURLConnection.HTTP_FORBIDDEN -> { + val method = connection.requestMethod + val url = connection.url.toString() + val error = AvError(AvError.FORBIDDEN, Arrays.asList(method, url)) + throw AirVantageException(error) + } + else -> throw IOException("Unexpected HTTP response: " + connection.responseCode + " " + + connection.responseMessage) + } + return inputStream + } + + @Throws(IOException::class, AirVantageException::class) + private fun sendString(method: String, url: URL, bodyString: String): InputStream { + Log.d("**********", url.toString()) + + var out: OutputStream? = null + try { + + // Create request for remote resource. + val connection = client.open(url) + connection.addRequestProperty("Cache-Control", "no-cache") + connection.addRequestProperty("Content-Type", "application/json") + + // Write the request. + connection.requestMethod = method + out = connection.outputStream + out!!.write(bodyString.toByteArray()) + return readResponse(connection) + + } finally { + if (out != null) + out.close() + } + } + + @Throws(IOException::class, AirVantageException::class) + private fun post(url: URL, body: Any): InputStream { + val bodyString = gson.toJson(body) + return sendString("POST", url, bodyString) + } + + @Throws(IOException::class, AirVantageException::class) + private fun put(url: URL, body: Any): InputStream { + val bodyString = gson.toJson(body) + return sendString("PUT", url, bodyString) + } + + @Throws(IOException::class, AirVantageException::class) + private fun delete(url: URL) { + + + val connection = client.open(url) + + connection.addRequestProperty("Cache-Control", "no-cache") + connection.requestMethod = "DELETE" + readResponse(connection) + } + + @Throws(IOException::class, AirVantageException::class) + private + operator fun get(url: URL): InputStream? { + // Create request for remote resource. + val connection = client.open(url) + connection.addRequestProperty("Cache-Control", "no-cache") + + return readResponse(connection) + } + + override val currentUser: User + get() { + val url = URL(buildEndpoint("/users/current")) + val inputStream = get(url) + return gson.fromJson(InputStreamReader(inputStream!!), User::class.java) + } + + + + @Throws(IOException::class, AirVantageException::class) + fun getSystemsBySerialNumber(serialNumber: String?): List? { + var urlString = buildEndpoint("/systems") + "&fields=uid,name,commStatus,lastCommDate,data,applications,gateway,type" + if (serialNumber != null) { + urlString += "&gateway=serialNumber:" + serialNumber + } + val url = URL(urlString) + val inputStream = this[url] + return gson.fromJson(InputStreamReader(inputStream!!), SystemsList::class.java).items + } + + @Throws(IOException::class, AirVantageException::class) + fun getGateway(serialNumber: String): String? { + val urlString = buildEndpoint("/gateways") + val url = URL(urlString) + val inputStream = this[url] + val reader = BufferedReader(InputStreamReader(inputStream!!)) + val sb = StringBuilder() + var line = reader.readLine() + + while (line != null) { + sb.append(line) + line = reader.readLine() + } + inputStream.close() + + try { + val json = JSONObject(sb.toString()) + val jsonValues = json.getJSONArray("items") + for (i in 0 until jsonValues.length()) { + val entry = jsonValues.getJSONObject(i) + val name = entry.getString("serialNumber") + if (name == serialNumber) { + return entry.getString("uid") + } + } + } catch (e: JSONException) { + return null + } + + return null + } + + @Throws(IOException::class, AirVantageException::class) + fun createSystem(system: net.airvantage.model.AvSystem): net.airvantage.model.AvSystem { + val url = URL(buildEndpoint("/systems")) + val inputStream = post(url, system) + return gson.fromJson(InputStreamReader(inputStream), net.airvantage.model.AvSystem::class.java) + } + + @Throws(IOException::class, AirVantageException::class) + override fun updateSystem(system: AvSystem) { + val url = URL(buildEndpoint("/systems/" + system.uid!!)) + put(url, system) + } + + + @Throws(IOException::class, AirVantageException::class) + fun deleteSystem(system: net.airvantage.model.AvSystem) { + val url = URL(buildEndpoint("/systems/" + system.uid!!) + "&deleteGateway=true") + delete(url) + } + + @Throws(IOException::class, AirVantageException::class) + override fun getApplications(appType: String): List? { + val url = URL(buildEndpoint("/applications") + "&type=" + appType + "&fields=uid,name,revision,type,category") + val inputStream = this[url] + inputStream.use { inStream -> + return gson.fromJson(InputStreamReader(inStream!!), ApplicationsList::class.java).items + } + } + + @Throws(IOException::class, AirVantageException::class) + override fun createApplication(application: net.airvantage.model.Application): net.airvantage.model.Application { + val url = URL(buildEndpoint("/applications")) + val inputStream = post(url, application) + return gson.fromJson(InputStreamReader(inputStream), net.airvantage.model.Application::class.java) + } + + @Throws(IOException::class, AirVantageException::class) + override fun setApplicationData(applicationUid: String, data: List) { + val url = URL(buildEndpoint("/applications/$applicationUid/data")) + put(url, data) + } + + @Throws(IOException::class, AirVantageException::class) + override fun setApplicationCommunication(applicationUid: String, protocols: List) { + val url = URL(buildEndpoint("/applications/$applicationUid/communication")) + put(url, protocols) + } + + @Throws(AirVantageException::class) + private fun checkAlertAdapter() { + if (this.alertAdapter == null) + throw AirVantageException(AvError("Response pending")) + } + + @Throws(IOException::class, AirVantageException::class) + override fun getAlertRuleByName(name: String, system: AvSystem): AlertRule? { + checkAlertAdapter() + return this.alertAdapter!!.getAlertRuleByName(name, system) + } + + @Throws(IOException::class, AirVantageException::class) + override fun createAlertRule(alertRule: AlertRule, application: String, system: AvSystem) { + checkAlertAdapter() + this.alertAdapter!!.createAlertRule(alertRule, application, system) + } + + + @Throws(IOException::class, AirVantageException::class) + override fun updateAlertRule(alertRule: AlertRule, application: String, system: AvSystem) { + checkAlertAdapter() + this.alertAdapter!!.updateAlertRule(alertRule, application, system) + } + + @Throws(IOException::class, AirVantageException::class) + override fun deleteAlertRule(alertRule: AlertRule) { + checkAlertAdapter() + this.alertAdapter!!.deleteAlertRule(alertRule) + } + + + @Throws(IOException::class, AirVantageException::class) + override fun logout() { + val url = URL(SCHEME + server + "/api/oauth/expire?access_token=" + access_token) + get(url) + } + + override val userRights: UserRights + get() { + val url = URL(buildEndpoint("/users/rights")) + val inputStream = get(url) + return gson.fromJson(InputStreamReader(inputStream!!), UserRights::class.java) + } + + companion object { + private const val SCHEME = "https://" + private const val API_PREFIX = "/api/v1" + + fun buildImplicitFlowURL(server: String, clientId: String): String { + return (SCHEME + server + "/api/oauth/authorize?client_id=" + clientId + + "&response_type=token&redirect_uri=oauth://airvantage") + } + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/AuthenticationUrlParser.java b/mainActivity/src/main/java/net/airvantage/utils/AuthenticationUrlParser.java deleted file mode 100644 index 8aca1fc..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/AuthenticationUrlParser.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.airvantage.utils; - -import java.util.Date; - -import android.net.Uri; -import android.util.Log; - -import com.sierrawireless.avphone.auth.Authentication; - -public class AuthenticationUrlParser { - - public Authentication parseUrl(String url, Date parsingDate) { - - Authentication auth = null; - - if (url.startsWith("oauth")) { - Log.d(AuthenticationUrlParser.class.getName(), "Callback URL: " + url); - // Example - // oauth://airvantage#access_token=430ad00a-2737-4673-bfa4-48c6710d748f&token_type=bearer&expires_in=86399&scope= - Uri uri = Uri.parse(url); - - if (uri.getHost().equals("airvantage")) { - auth = new Authentication(); - - String fragment = uri.getFragment(); - if (fragment != null) { - - String[] params = fragment.split("&"); - for (String param : params) { - String[] kv = param.split("="); - if (kv != null && kv.length == 2) { - String key = kv[0]; - String value = kv[1]; - - if ("access_token".equals(key)) { - auth.setAccessToken(value); - } else if ("expires_in".equals(key)) { - int expiresInSeconds = Integer.parseInt(value); - Date expirationDate = new Date(parsingDate.getTime() + expiresInSeconds * 1000); - auth.setExpirationDate(expirationDate); - } - } - } - } - } - - } - - return auth; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/AuthenticationUrlParser.kt b/mainActivity/src/main/java/net/airvantage/utils/AuthenticationUrlParser.kt new file mode 100644 index 0000000..ff2a845 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/AuthenticationUrlParser.kt @@ -0,0 +1,52 @@ +package net.airvantage.utils + +import java.util.Date + +import android.net.Uri +import android.util.Log + +import com.sierrawireless.avphone.auth.Authentication + +class AuthenticationUrlParser { + + fun parseUrl(url: String, parsingDate: Date): Authentication? { + + var auth: Authentication? = null + + if (url.startsWith("oauth")) { + Log.i(TAG, "Callback URL: " + url) + // Example + // oauth://airvantage#access_token=430ad00a-2737-4673-bfa4-48c6710d748f&token_type=bearer&expires_in=86399&scope= + val uri = Uri.parse(url) + + if (uri.host == "airvantage") { + auth = Authentication() + + val fragment = uri.fragment + if (fragment != null) { + + val params = fragment.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + for (param in params) { + val kv = param.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + if (kv.size == 2) { + val key = kv[0] + val value = kv[1] + + if ("access_token" == key) { + auth.accessToken = value + } else if ("expires_in" == key) { + val expiresInSeconds = Integer.parseInt(value) + val expirationDate = Date(parsingDate.time + expiresInSeconds * 1000) + auth.expirationDate = expirationDate + } + } + } + } + } + } + return auth + } + companion object { + private val TAG = AuthenticationUrlParser::class.simpleName + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/AvPhonePrefs.java b/mainActivity/src/main/java/net/airvantage/utils/AvPhonePrefs.java deleted file mode 100644 index c2f686f..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/AvPhonePrefs.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.airvantage.utils; - -public class AvPhonePrefs { - - public String serverHost; - public String clientId; - - public String password; - public String period; - - public PreferenceUtils.Server usesServer; - - public boolean checkCredentials() { - return !(password == null || password.isEmpty() || serverHost == null || serverHost.isEmpty()); - } - - public boolean usesNA() { - return usesServer == PreferenceUtils.Server.NA; - } - - public boolean usesEU() { - return usesServer == PreferenceUtils.Server.EU; - } - - public boolean usesCustomServer() { - return usesServer == PreferenceUtils.Server.CUSTOM; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/AvPhonePrefs.kt b/mainActivity/src/main/java/net/airvantage/utils/AvPhonePrefs.kt new file mode 100644 index 0000000..f169909 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/AvPhonePrefs.kt @@ -0,0 +1,24 @@ +package net.airvantage.utils + +class AvPhonePrefs { + + var serverHost: String? = null + var clientId: String? = null + + var password: String? = null + var period: String? = null + + var usesServer: PreferenceUtils.Server? = null + + fun checkCredentials(): Boolean { + return !(password == null || password!!.isEmpty() || serverHost == null || serverHost!!.isEmpty()) + } + + fun usesNA(): Boolean { + return usesServer == PreferenceUtils.Server.NA + } + + fun usesEU(): Boolean { + return usesServer == PreferenceUtils.Server.EU + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/IAirVantageClient.java b/mainActivity/src/main/java/net/airvantage/utils/IAirVantageClient.java deleted file mode 100644 index ad3b103..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/IAirVantageClient.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.airvantage.utils; - -import java.io.IOException; -import java.util.List; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.alert.v1.AlertRule; -import net.airvantage.model.Application; -import net.airvantage.model.ApplicationData; -import net.airvantage.model.AvSystem; -import net.airvantage.model.Protocol; -import net.airvantage.model.User; -import net.airvantage.model.UserRights; - -public interface IAirVantageClient { - - AlertRule createAlertRule(AlertRule alertRule) throws IOException, AirVantageException; - - AlertRule updateAlertRule(AlertRule alertRule) throws IOException, AirVantageException; - - AlertRule getAlertRuleByName(String name) throws IOException, AirVantageException; - - void setApplicationData(String applicationUid, List data) throws IOException, AirVantageException; - - List getApplications(String appType) throws IOException, AirVantageException; - - Application createApplication(Application application) throws IOException, AirVantageException; - - void setApplicationCommunication(String applicationUid, List protocols) throws IOException, AirVantageException; - - void updateSystem(AvSystem system) throws IOException, AirVantageException; - - void logout() throws IOException, AirVantageException; - - UserRights getUserRights() throws IOException, AirVantageException; - - User getCurrentUser() throws IOException, AirVantageException; - -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/IAirVantageClient.kt b/mainActivity/src/main/java/net/airvantage/utils/IAirVantageClient.kt new file mode 100644 index 0000000..4dff37a --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/IAirVantageClient.kt @@ -0,0 +1,49 @@ +package net.airvantage.utils + +import java.io.IOException + +import net.airvantage.model.AirVantageException +import net.airvantage.model.alert.v1.AlertRule +import net.airvantage.model.Application +import net.airvantage.model.ApplicationData +import net.airvantage.model.AvSystem +import net.airvantage.model.Protocol +import net.airvantage.model.User +import net.airvantage.model.UserRights + +interface IAirVantageClient { + + val userRights: UserRights + + val currentUser: User + + @Throws(IOException::class, AirVantageException::class) + fun createAlertRule(alertRule: AlertRule, application: String, system: AvSystem) + + @Throws(IOException::class, AirVantageException::class) + fun updateAlertRule(alertRule: AlertRule, application: String, system: AvSystem) + + @Throws(IOException::class, AirVantageException::class) + fun getAlertRuleByName(name: String, system: AvSystem): AlertRule? + + @Throws(IOException::class, AirVantageException::class) + fun deleteAlertRule(alertRule: AlertRule) + + @Throws(IOException::class, AirVantageException::class) + fun setApplicationData(applicationUid: String, data: List) + + @Throws(IOException::class, AirVantageException::class) + fun getApplications(appType: String): List? + + @Throws(IOException::class, AirVantageException::class) + fun createApplication(application: Application): Application + + @Throws(IOException::class, AirVantageException::class) + fun setApplicationCommunication(applicationUid: String, protocols: List) + + @Throws(IOException::class, AirVantageException::class) + fun updateSystem(system: AvSystem) + + @Throws(IOException::class, AirVantageException::class) + fun logout() +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/Predicate.java b/mainActivity/src/main/java/net/airvantage/utils/Predicate.java deleted file mode 100644 index 9a6f79b..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/Predicate.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.airvantage.utils; - -public interface Predicate { - public boolean matches(T item); -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/PreferenceUtils.java b/mainActivity/src/main/java/net/airvantage/utils/PreferenceUtils.java deleted file mode 100644 index 790cd48..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/PreferenceUtils.java +++ /dev/null @@ -1,207 +0,0 @@ -package net.airvantage.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.util.Log; - -import com.sierrawireless.avphone.R; -import com.sierrawireless.avphone.auth.Authentication; -import com.sierrawireless.avphone.model.CustomDataLabels; - -public class PreferenceUtils { - - private static String LOGTAG = PreferenceUtils.class.getName(); - - public enum Server { - NA, EU, CUSTOM - } - - private static final String DEFAULT_COMM_PERIOD = "2"; - - public static final String PREF_SERVER_KEY = "pref_server_key"; - - public static final String PREF_CLIENT_ID_KEY = "pref_client_id_key"; - - public static final String PREF_PASSWORD_KEY = "pref_password_key"; - - public static final String PREF_PERIOD_KEY = "pref_period_key"; - - public static final String PREF_ACCESS_TOKEN = "pref_access_token"; - - public static final String PREF_TOKEN_EXPIRES_AT = "pref_token_expires_at"; - - protected static Properties properties; - - public static AvPhonePrefs getAvPhonePrefs(Context context) { - AvPhonePrefs res = new AvPhonePrefs(); - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - res.serverHost = prefs.getString(PREF_SERVER_KEY, context.getString(R.string.pref_server_na_value)); - - res.clientId = prefs.getString(PREF_CLIENT_ID_KEY, getNaClientId(context)); - - HashMap serverMapping = new HashMap(); - serverMapping.put(context.getString(R.string.pref_server_eu_value), Server.EU); - serverMapping.put(context.getString(R.string.pref_server_na_value), Server.NA); - serverMapping.put(context.getString(R.string.pref_server_custom_value), Server.CUSTOM); - res.usesServer = serverMapping.get(res.serverHost); - - res.password = prefs.getString(PREF_PASSWORD_KEY, context.getString(R.string.pref_password_default)); - res.period = prefs.getString(PREF_PERIOD_KEY, DEFAULT_COMM_PERIOD); - - return res; - } - - private static Properties getPropertiesFile(Context context) { - if (properties == null) { - try { - InputStream in = context.getAssets().open("avphone.properties"); - properties = new Properties(); - properties.load(in); - } catch (IOException e) { - e.printStackTrace(); - } - } - return properties; - } - - private static String getNaClientId(Context context) { - Properties properties = getPropertiesFile(context); - return properties.getProperty("clientid.na"); - } - - private static String getEuClientId(Context context) { - Properties properties = getPropertiesFile(context); - return properties.getProperty("clientid.eu"); - } - - private static String getCustomClientId(Context context) { - Properties properties = getPropertiesFile(context); - return properties.getProperty("clientid.custom"); - } - - public static boolean isCustomDefined(Context context) { - return getCustomClientId(context) != null; - } - - public static String getPreference(Context context, int prefKeyId, int defaultValueKeyId) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - String prefKey = context.getString(prefKeyId); - String defaultValueKey = context.getString(defaultValueKeyId); - return prefs.getString(prefKey, defaultValueKey); - } - - public static void setPreference(Context context, String prefKey, String value) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - prefs.edit().putString(prefKey, value).commit(); - } - - public static void showMissingPrefsDialog(Activity activity) { - new AlertDialog.Builder(activity).setTitle(R.string.invalid_prefs).setMessage(R.string.prefs_missing) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // do nothing - } - }).show(); - } - - public static CustomDataLabels getCustomDataLabels(Context context) { - CustomDataLabels labels = new CustomDataLabels(); - labels.customUp1Label = getPreference(context, R.string.pref_custom1_label_key, - R.string.pref_custom1_label_default); - labels.customUp2Label = getPreference(context, R.string.pref_custom2_label_key, - R.string.pref_custom2_label_default); - labels.customDown1Label = getPreference(context, R.string.pref_custom3_label_key, - R.string.pref_custom3_label_default); - labels.customDown2Label = getPreference(context, R.string.pref_custom4_label_key, - R.string.pref_custom4_label_default); - labels.customStr1Label = getPreference(context, R.string.pref_custom5_label_key, - R.string.pref_custom5_label_default); - labels.customStr2Label = getPreference(context, R.string.pref_custom6_label_key, - R.string.pref_custom6_label_default); - - return labels; - } - - public static void setServer(Server server, Context context) { - switch (server) { - case NA: - setPreference(context, PREF_SERVER_KEY, context.getString(R.string.pref_server_na_value)); - setPreference(context, PREF_CLIENT_ID_KEY, getNaClientId(context)); - break; - case EU: - setPreference(context, PREF_SERVER_KEY, context.getString(R.string.pref_server_eu_value)); - setPreference(context, PREF_CLIENT_ID_KEY, getEuClientId(context)); - break; - case CUSTOM: - setPreference(context, PREF_SERVER_KEY, context.getString(R.string.pref_server_custom_value)); - setPreference(context, PREF_CLIENT_ID_KEY, getCustomClientId(context)); - break; - default: - throw new IllegalArgumentException("Should be NA or EU"); - } - } - - public static void saveAuthentication(Context context, Authentication auth) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - - prefs.edit().putString(PREF_ACCESS_TOKEN, auth.getAccessToken()) - .putLong(PREF_TOKEN_EXPIRES_AT, auth.getExpirationDate().getTime()).commit(); - } - - public static void resetAuthentication(Context context) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - - prefs.edit().remove(PREF_ACCESS_TOKEN).remove(PREF_TOKEN_EXPIRES_AT).commit(); - - } - - public static Authentication readAuthentication(Context context) { - - Authentication auth = null; - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - - String accessToken = prefs.getString(PREF_ACCESS_TOKEN, null); - - Long expiresAtMs = null; - - try { - expiresAtMs = prefs.getLong(PREF_TOKEN_EXPIRES_AT, 0); - } catch (ClassCastException e) { - // An earlier version might have stored the token as a string - String expiresAtSt = null; - try { - expiresAtSt = prefs.getString(PREF_TOKEN_EXPIRES_AT, null); - if (expiresAtSt != null) { - expiresAtMs = Long.parseLong(expiresAtSt); - } - } catch (NumberFormatException nfe) { - // The string was not even a valid one, we'll ignore it. - Log.w(LOGTAG, "pref_token_expires_at stored as invalid String : '" + expiresAtSt + "'", nfe); - } - } - - if (accessToken != null && expiresAtMs != null && expiresAtMs != 0) { - Date expiresAt = new Date(expiresAtMs); - auth = new Authentication(); - auth.setAccessToken(accessToken); - auth.setExpirationDate(expiresAt); - } - - return auth; - - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/PreferenceUtils.kt b/mainActivity/src/main/java/net/airvantage/utils/PreferenceUtils.kt new file mode 100644 index 0000000..1553498 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/PreferenceUtils.kt @@ -0,0 +1,189 @@ +package net.airvantage.utils + +import android.app.Activity +import android.app.AlertDialog +import android.content.Context +import android.preference.PreferenceManager +import android.util.Log +import com.sierrawireless.avphone.R +import com.sierrawireless.avphone.auth.Authentication +import com.sierrawireless.avphone.model.CustomDataLabels +import java.io.IOException +import java.util.* + +object PreferenceUtils { + + private val TAG = PreferenceUtils::class.simpleName + + private const val DEFAULT_COMM_PERIOD = "2" + const val PREF_SERVER_KEY = "pref_server_key" + const val PREF_CLIENT_ID_KEY = "pref_client_id_key" + const val PREF_PASSWORD_KEY = "pref_password_key" + const val PREF_PERIOD_KEY = "pref_period_key" + private const val PREF_ACCESS_TOKEN = "pref_access_token" + private const val PREF_TOKEN_EXPIRES_AT = "pref_token_expires_at" + private var properties: Properties? = null + + enum class Server { + NA, EU, CUSTOM + } + + fun getAvPhonePrefs(context: Context): AvPhonePrefs { + val res = AvPhonePrefs() + + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + res.serverHost = prefs.getString(PREF_SERVER_KEY, context.getString(R.string.pref_server_na_value)) + + res.clientId = prefs.getString(PREF_CLIENT_ID_KEY, getNaClientId(context)) + + val serverMapping = HashMap() + serverMapping[context.getString(R.string.pref_server_eu_value)] = Server.EU + serverMapping[context.getString(R.string.pref_server_na_value)] = Server.NA + serverMapping[context.getString(R.string.pref_server_custom_value)] = Server.CUSTOM + res.usesServer = serverMapping[res.serverHost!!] + + res.password = prefs.getString(PREF_PASSWORD_KEY, context.getString(R.string.pref_password_default)) + res.period = prefs.getString(PREF_PERIOD_KEY, DEFAULT_COMM_PERIOD) + + return res + } + + private fun getPropertiesFile(context: Context): Properties? { + if (properties == null) { + try { + val `in` = context.assets.open("avphone.properties") + properties = Properties() + properties!!.load(`in`) + } catch (e: IOException) { + e.printStackTrace() + } + + } + return properties + } + + private fun getNaClientId(context: Context): String { + val properties = getPropertiesFile(context) + return properties!!.getProperty("clientid.na") + } + + private fun getEuClientId(context: Context): String { + val properties = getPropertiesFile(context) + return properties!!.getProperty("clientid.eu") + } + + private fun getCustomClientId(context: Context): String? { + val properties = getPropertiesFile(context) + return properties!!.getProperty("clientid.custom") + } + + fun isCustomDefined(context: Context): Boolean { + return getCustomClientId(context) != null + } + + private fun getPreference(context: Context, prefKeyId: Int, defaultValueKeyId: Int): String { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + val prefKey = context.getString(prefKeyId) + val defaultValueKey = context.getString(defaultValueKeyId) + return prefs.getString(prefKey, defaultValueKey) + } + + private fun setPreference(context: Context, prefKey: String, value: String?) { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + prefs.edit().putString(prefKey, value).apply() + } + + fun showMissingPrefsDialog(activity: Activity) { + AlertDialog.Builder(activity).setTitle(R.string.invalid_prefs).setMessage(R.string.prefs_missing) + .setPositiveButton(android.R.string.yes) { _, _ -> + // do nothing + }.show() + } + + fun getCustomDataLabels(context: Context): CustomDataLabels { + val labels = CustomDataLabels() + labels.customUp1Label = getPreference(context, R.string.pref_custom1_label_key, + R.string.pref_custom1_label_default) + labels.customUp2Label = getPreference(context, R.string.pref_custom2_label_key, + R.string.pref_custom2_label_default) + labels.customDown1Label = getPreference(context, R.string.pref_custom3_label_key, + R.string.pref_custom3_label_default) + labels.customDown2Label = getPreference(context, R.string.pref_custom4_label_key, + R.string.pref_custom4_label_default) + labels.customStr1Label = getPreference(context, R.string.pref_custom5_label_key, + R.string.pref_custom5_label_default) + labels.customStr2Label = getPreference(context, R.string.pref_custom6_label_key, + R.string.pref_custom6_label_default) + + return labels + } + + fun setServer(server: Server, context: Context) { + when (server) { + PreferenceUtils.Server.NA -> { + setPreference(context, PREF_SERVER_KEY, context.getString(R.string.pref_server_na_value)) + setPreference(context, PREF_CLIENT_ID_KEY, getNaClientId(context)) + } + PreferenceUtils.Server.EU -> { + setPreference(context, PREF_SERVER_KEY, context.getString(R.string.pref_server_eu_value)) + setPreference(context, PREF_CLIENT_ID_KEY, getEuClientId(context)) + } + PreferenceUtils.Server.CUSTOM -> { + setPreference(context, PREF_SERVER_KEY, context.getString(R.string.pref_server_custom_value)) + setPreference(context, PREF_CLIENT_ID_KEY, getCustomClientId(context)) + } + } + } + + fun saveAuthentication(context: Context, auth: Authentication) { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + prefs.edit().putString(PREF_ACCESS_TOKEN, auth.accessToken) + .putLong(PREF_TOKEN_EXPIRES_AT, auth.expirationDate!!.time).apply() + } + + fun resetAuthentication(context: Context) { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + prefs.edit().remove(PREF_ACCESS_TOKEN).remove(PREF_TOKEN_EXPIRES_AT).apply() + + } + + fun readAuthentication(context: Context): Authentication? { + + var auth: Authentication? = null + + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + val accessToken = prefs.getString(PREF_ACCESS_TOKEN, null) + + var expiresAtMs: Long? = null + + try { + expiresAtMs = prefs.getLong(PREF_TOKEN_EXPIRES_AT, 0) + } catch (e: ClassCastException) { + // An earlier version might have stored the token as a string + var expiresAtSt: String? = null + try { + expiresAtSt = prefs.getString(PREF_TOKEN_EXPIRES_AT, null) + if (expiresAtSt != null) { + expiresAtMs = java.lang.Long.parseLong(expiresAtSt) + } + } catch (nfe: NumberFormatException) { + // The string was not even a valid one, we'll ignore it. + Log.w(TAG, "pref_token_expires_at stored as invalid String : '$expiresAtSt'", nfe) + } + + } + + if (accessToken != null && expiresAtMs != null && (expiresAtMs) != 0L) { + val expiresAt = Date(expiresAtMs) + auth = Authentication() + auth.accessToken = accessToken + auth.expirationDate = expiresAt + } + + return auth + } + +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/Utils.java b/mainActivity/src/main/java/net/airvantage/utils/Utils.java deleted file mode 100644 index ede4f9d..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/Utils.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.airvantage.utils; - -import java.util.List; - -public class Utils { - - public static T first(List list) { - return (list == null || list.isEmpty()) ? null : list.get(0); - } - - public static T firstWhere(List list, Predicate predicate) { - - if (list != null) { - for (T item : list) { - if (predicate.matches(item)) { - return item; - } - } - } - return null; - } - -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/Utils.kt b/mainActivity/src/main/java/net/airvantage/utils/Utils.kt new file mode 100644 index 0000000..24f8f83 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/Utils.kt @@ -0,0 +1,24 @@ +package net.airvantage.utils + + +typealias Predicate = (T) -> Boolean + +object Utils { + + fun first(list: List?): T? { + return if (list == null || list.isEmpty()) null else list[0] + } + + fun firstWhere(list: List?, predicate: Predicate): T? { + + if (list != null) { + for (item in list) { + val match = predicate.invoke(item) + if (match) { + return item + } + } + } + return null + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterFactory.java b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterFactory.java deleted file mode 100644 index 5c3829a..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.airvantage.utils.alert; - -import android.os.AsyncTask; -import android.util.Log; - -import com.squareup.okhttp.OkHttpClient; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; - -public class AlertAdapterFactory extends AsyncTask { - - private static final String ALERT_V1_API_PREFIX = "/api/v1/alerts/rules?size=0&access_token="; - private static final String ALERT_V2_API_PREFIX = "/api/v2/alertstates?access_token="; - private final IAlertAdapterFactoryListener listener; - - private final String server; - private final String accessToken; - private final OkHttpClient client; - - public AlertAdapterFactory(String server, String token, IAlertAdapterFactoryListener adapterListener) { - this.accessToken = token; - this.client = new OkHttpClient(); - this.listener = adapterListener; - this.server = server; - this.execute(); - } - - @Override - protected DefaultAlertAdapter doInBackground(Void... params) { - - // Mapping of _Alert APIs_ -> Functions handling them - HashMap urls = new HashMap(); - urls.put(ALERT_V1_API_PREFIX, new AlertAdapterV1(server, accessToken)); - urls.put(ALERT_V2_API_PREFIX, new AlertAdapterV2(server, accessToken)); - - // We using first available - for (HashMap.Entry entry : urls.entrySet()) { - try { - - String urlString = "https://" + server + entry.getKey() + accessToken; - URL url = new URL(urlString); - HttpURLConnection connection = client.open(url); - connection.setRequestMethod("GET"); - if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - Log.d(this.getClass().getName(), "Using Alerts from " + urlString); - return entry.getValue(); - } - - } catch (MalformedURLException e) { - Log.e(this.getClass().getName(), "Bad Url generated for " + entry.getKey(), e); - } catch (IOException e) { - Log.e(this.getClass().getName(), "Connection problem", e); - } - } - - // Neither is available? - // This adapter provides error messages at each call - return new DefaultAlertAdapter(server, accessToken); - } - - @Override - protected void onPostExecute(DefaultAlertAdapter adapter) { - this.listener.alertAdapterAvailable(adapter); - } -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterFactory.kt b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterFactory.kt new file mode 100644 index 0000000..9986409 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterFactory.kt @@ -0,0 +1,66 @@ +package net.airvantage.utils.alert + +import android.os.AsyncTask +import android.util.Log + +import com.squareup.okhttp.OkHttpClient + +import java.io.IOException +import java.net.HttpURLConnection +import java.net.MalformedURLException +import java.net.URL +import java.util.HashMap + +class AlertAdapterFactory(private val server: String, private val accessToken: String, private val listener: IAlertAdapterFactoryListener) : AsyncTask() { + private val client: OkHttpClient = OkHttpClient() + private val TAG = this.javaClass.name + + init { + this.execute() + } + + override fun doInBackground(vararg params: Void): DefaultAlertAdapter { + + // Mapping of _Alert APIs_ -> Functions handling them set V2 in first preferred + val urls = HashMap() + urls[ALERT_V2_API_PREFIX] = AlertAdapterV2(server, accessToken) + urls[ALERT_V1_API_PREFIX] = AlertAdapterV1(server, accessToken) + val founds = HashMap() + + // We using first available + for ((key) in urls) { + try { + + val urlString = "https://" + server + key + accessToken + val url = URL(urlString) + val connection = client.open(url) + connection.requestMethod = "GET" + founds[key] = connection.responseCode == HttpURLConnection.HTTP_OK + + } catch (e: MalformedURLException) { + Log.e(TAG, "Bad Url generated for " + key, e) + } catch (e: IOException) { + Log.e(TAG, "Connection problem", e) + } + } + + if (founds[ALERT_V2_API_PREFIX] != null && founds[ALERT_V2_API_PREFIX]!!) { + return urls[ALERT_V2_API_PREFIX]!! + } else if (founds[ALERT_V1_API_PREFIX] != null && founds[ALERT_V1_API_PREFIX]!!) { + return urls[ALERT_V1_API_PREFIX]!! + } + + // Neither is available? + // This adapter provides error messages at each call + return DefaultAlertAdapter(server, accessToken) + } + + override fun onPostExecute(adapter: DefaultAlertAdapter) { + this.listener.alertAdapterAvailable(adapter) + } + + companion object { + private const val ALERT_V1_API_PREFIX = "/api/v1/alerts/rules?size=0&access_token=" + private const val ALERT_V2_API_PREFIX = "/api/v2/alertstates?access_token=" + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV1.java b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV1.java deleted file mode 100644 index 21594e0..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV1.java +++ /dev/null @@ -1,60 +0,0 @@ -package net.airvantage.utils.alert; - -import android.net.Uri; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.alert.v1.AlertRule; -import net.airvantage.model.alert.v1.AlertRuleList; -import net.airvantage.utils.Utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; - - -public class AlertAdapterV1 extends DefaultAlertAdapter { - - private static String API_PATH ="/alerts/rules"; - - public AlertAdapterV1(String server, String accessToken) { - super(server, accessToken); - } - - @Override - public String getPrefix() { - return "/api/v1"; - } - - @Override - public AlertRule getAlertRuleByName(final String name) throws IOException, AirVantageException { - - String str = Uri.parse(buildEndpoint(API_PATH)) - .buildUpon() - .appendQueryParameter("access_token", access_token) - .appendQueryParameter("fields", "uid,name") - .appendQueryParameter("name", name) - .build() - .toString(); - - URL url = new URL(str); - InputStream in = get(url); - AlertRuleList rules = gson.fromJson(new InputStreamReader(in), AlertRuleList.class); - return Utils.firstWhere(rules.items, AlertRule.isNamed(name)); - } - - @Override - public AlertRule createAlertRule(AlertRule alertRule) throws IOException, AirVantageException { - URL url = new URL(buildEndpoint(API_PATH)); - InputStream in = post(url, alertRule); - return gson.fromJson(new InputStreamReader(in), AlertRule.class); - } - - @Override - public AlertRule updateAlertRule(AlertRule alertRule) throws IOException, AirVantageException { - URL url = new URL(buildEndpoint(API_PATH + alertRule.uid)); - put(url, alertRule); - InputStream in = put(url, alertRule); - return gson.fromJson(new InputStreamReader(in), AlertRule.class); - } -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV1.kt b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV1.kt new file mode 100644 index 0000000..5235586 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV1.kt @@ -0,0 +1,64 @@ +package net.airvantage.utils.alert + +import android.net.Uri +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvSystem +import net.airvantage.model.alert.v1.AlertRule +import net.airvantage.model.alert.v1.AlertRuleList +import net.airvantage.utils.Utils +import java.io.IOException +import java.io.InputStreamReader +import java.net.URL + + +class AlertAdapterV1 internal constructor(server: String, accessToken: String) : DefaultAlertAdapter(server, accessToken) { + + override val prefix: String + get() = "/api/v1/" + + + @Throws(IOException::class, AirVantageException::class) + override fun getAlertRuleByName(name: String, system:AvSystem): AlertRule? { + + val str = Uri.parse(buildEndpoint(API_PATH)) + .buildUpon() + .appendQueryParameter("access_token", access_token) + .appendQueryParameter("fields", "uid,name") + .appendQueryParameter("name", name) + .build() + .toString() + + val url = URL(str) + val `in` = get(url) + val rules = gson.fromJson(InputStreamReader(`in`), AlertRuleList::class.java) + return Utils.firstWhere(rules.items, AlertRule.isNamed(name)) + } + + @Throws(IOException::class, AirVantageException::class) + override fun createAlertRule(alertRule: AlertRule, application: String, system:AvSystem) { + val url = URL(buildEndpoint(API_PATH)) + val `in` = post(url, alertRule) + gson.fromJson(InputStreamReader(`in`), AlertRule::class.java) + } + + + + @Throws(IOException::class, AirVantageException::class) + override fun updateAlertRule(alertRule: AlertRule, application: String, system:AvSystem) { + val url = URL(buildEndpoint(API_PATH + "/" + alertRule.uid)) + val `in` = put(url, alertRule) + gson.fromJson(InputStreamReader(`in`), AlertRule::class.java) + } + override fun deleteAlertRule(alertRule: AlertRule) { + + val url = URL(buildEndpoint(API_PATH + alertRule.uid)) + delete(url) + + } + + companion object { + + private const val API_PATH = "/alerts/rules" + } + +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV2.java b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV2.java deleted file mode 100644 index c128126..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV2.java +++ /dev/null @@ -1,175 +0,0 @@ -package net.airvantage.utils.alert; - -import android.net.Uri; -import android.util.Log; - -import com.google.gson.JsonIOException; -import com.sierrawireless.avphone.model.AvPhoneData; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.alert.v2.AlertRuleList; -import net.airvantage.model.alert.v2.alertrule.AlertRule; -import net.airvantage.model.alert.v2.alertrule.AttributeId; -import net.airvantage.model.alert.v2.alertrule.Condition; -import net.airvantage.model.alert.v2.alertrule.Operand; -import net.airvantage.utils.Utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - - -public class AlertAdapterV2 extends DefaultAlertAdapter { - - private static String LOG_TAG = AlertAdapterV2.class.getName(); - - private static String API_PATH = "alertrules"; - private URL alertRuleUrl = null; - - public AlertAdapterV2(String server, String accessToken) { - super(server, accessToken); - } - - @Override - public String getPrefix() { - return "/api/v2/"; - } - - @Override - public net.airvantage.model.alert.v1.AlertRule getAlertRuleByName(final String name) - throws IOException, AirVantageException { - try { - InputStream in = get(alertRuleUrl()); - AlertRuleList rules = gson.fromJson(new InputStreamReader(in), AlertRuleList.class); - AlertRule alertRuleV2 = Utils.firstWhere(rules, AlertRule.isNamed(name)); - if (alertRuleV2 != null) { - convert(alertRuleV2); - } - } catch (final JsonIOException e) { - Log.e(LOG_TAG, "Unable to read Alert Rules", e); - } - return null; - } - - @Override - public net.airvantage.model.alert.v1.AlertRule createAlertRule(net.airvantage.model.alert.v1.AlertRule alertRule) - throws IOException, AirVantageException { - try { - AlertRule alertRuleV2 = new AlertRule(); - alertRuleV2.targetType = "SYSTEM"; - alertRuleV2.name = alertRule.name; - alertRuleV2.message = "Alarm is ON"; - alertRuleV2.conditions = new ArrayList(); - for (net.airvantage.model.alert.v1.Condition condition : alertRule.conditions) { - alertRuleV2.conditions.add(convert(condition)); - } - InputStream in = post(alertRuleUrl(), alertRuleV2); - alertRuleV2 = gson.fromJson(new InputStreamReader(in), AlertRule.class); - if (alertRuleV2 != null) { - return convert(alertRuleV2); - } - } catch (final JsonIOException e) { - Log.e(LOG_TAG, "Unable to create Alert Rule", e); - } - return null; - } - - private static Condition convert(net.airvantage.model.alert.v1.Condition condition) { - - final Condition conditionV2 = new Condition(); - conditionV2.operator = condition.operator; - - final Operand leftOperand = new Operand(); - leftOperand.attributeId = new AttributeId(); - leftOperand.attributeId.name = "communication.data.value"; - - final Operand rightOperand = new Operand(); - rightOperand.valueStr = condition.value; - - conditionV2.operands = new ArrayList(Arrays.asList(leftOperand, rightOperand)); - return conditionV2; - } - - @Override - public net.airvantage.model.alert.v1.AlertRule updateAlertRule( - net.airvantage.model.alert.v1.AlertRule alertRule) - throws IOException, AirVantageException { - try { - InputStream in = put(alertRuleUrl(), alertRule); - AlertRule alertRuleV2 = gson.fromJson(new InputStreamReader(in), AlertRule.class); - if (alertRuleV2 != null) { - return convert(alertRuleV2); - } - } catch (final JsonIOException e) { - Log.e(LOG_TAG, "Unable to update Alert Rule", e); - } - return null; - } - - private URL alertRuleUrl() throws IOException { - - if (alertRuleUrl != null) - return alertRuleUrl; - - String urlString = Uri.parse(buildEndpoint(API_PATH)).toString(); - try { - alertRuleUrl = new URL(urlString); - } catch (MalformedURLException e) { - Log.e(this.getClass().getName(), "Sure of URL?", e); - throw e; - } - - return alertRuleUrl; - } - - private static net.airvantage.model.alert.v1.AlertRule convert(AlertRule alertRule) { - net.airvantage.model.alert.v1.AlertRule alertRuleV1; - alertRuleV1 = new net.airvantage.model.alert.v1.AlertRule(); - - // Assign similar fields - alertRuleV1.uid = alertRule.id; - alertRuleV1.active = alertRule.active; - alertRuleV1.name = alertRule.name; - // alertRuleV1.metadata = alertRule.metadata; - - // Only event created in AV Phone - alertRuleV1.eventType = "event.system.incoming.communication"; - - // Translating conditions - alertRuleV1.conditions = new ArrayList(); - for (final Condition condition : alertRule.conditions) { - alertRuleV1.conditions.add(convert(condition)); - } - return alertRuleV1; - } - - private static net.airvantage.model.alert.v1.Condition convert(Condition condition) { - net.airvantage.model.alert.v1.Condition conditionV1; - conditionV1 = new net.airvantage.model.alert.v1.Condition(); - conditionV1.eventProperty = "communication.data.value"; - conditionV1.eventPropertyKey = AvPhoneData.ALARM; - conditionV1.operator = condition.operator; - - // Finding values - Operand operand = Utils.first(condition.operands); - List values = new ArrayList(); - values.add(operand.valueStr); - values.add(operand.valueNum); - values.add(Utils.first(operand.valuesStr)); - - // Trimming nulls - values.removeAll(Collections.singleton(null)); - values.removeAll(Collections.singleton("")); - - // Pick first one - conditionV1.value = values.isEmpty() ? "" : Utils.first(values).toString(); - return conditionV1; - } -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV2.kt b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV2.kt new file mode 100644 index 0000000..f5ece6b --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/alert/AlertAdapterV2.kt @@ -0,0 +1,204 @@ +package net.airvantage.utils.alert + +import android.net.Uri +import android.util.Log +import com.google.gson.JsonIOException +import com.sierrawireless.avphone.model.AvPhoneData +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvSystem +import net.airvantage.model.alert.v2.AlertRuleList +import net.airvantage.model.alert.v2.alertrule.AlertRule +import net.airvantage.model.alert.v2.alertrule.AttributeId +import net.airvantage.model.alert.v2.alertrule.Condition +import net.airvantage.model.alert.v2.alertrule.Operand +import net.airvantage.utils.Utils +import java.io.IOException +import java.io.InputStreamReader +import java.io.Serializable +import java.net.MalformedURLException +import java.net.URL +import java.util.* + + +class AlertAdapterV2 internal constructor(server: String, accessToken: String) : DefaultAlertAdapter(server, accessToken) { + + private var alertRuleUrl: URL? = null + + override val prefix: String + get() = "/api/v2/" + + @Throws(IOException::class, AirVantageException::class) + override fun getAlertRuleByName(name: String, system:AvSystem): net.airvantage.model.alert.v1.AlertRule? { + try { + val inp = get(alertRuleUrl()) + val rules = gson.fromJson(InputStreamReader(inp), AlertRuleList::class.java) + val alertRuleV2 = Utils.firstWhere(rules, AlertRule.isNamed(name)) + if (alertRuleV2 != null) { + return convert(alertRuleV2) + } + } catch (e: JsonIOException) { + Log.e(TAG, "Unable to read Alert Rules", e) + } + + return null + } + + @Throws(IOException::class, AirVantageException::class) + override fun createAlertRule(alertRule: net.airvantage.model.alert.v1.AlertRule, application: String, system: AvSystem) { + try { + var alertRuleV2: AlertRule? = AlertRule() + alertRuleV2!!.targetType = "SYSTEM" + alertRuleV2.name = alertRule.name + alertRuleV2.message = "Alarm for " + system.name + " is ON" + alertRuleV2.active = true + alertRuleV2.conditions = ArrayList() + val metadata = HashMap() + metadata["templateId"] = "alertrule.template.custom" + + val condi = HashMap() + condi["application"] = application + metadata["condition_0"] = condi + alertRuleV2.metadata = metadata + for (condition in alertRule.conditions!!) { + alertRuleV2.conditions!!.add(convert(condition)) + } + val inp = post(alertRuleUrl(), alertRuleV2) + alertRuleV2 = gson.fromJson(InputStreamReader(inp), AlertRule::class.java) + convert(alertRuleV2) + + } catch (e: JsonIOException) { + Log.e(TAG, "Unable to create Alert Rule", e) + } + + } + + @Throws(IOException::class, AirVantageException::class) + override fun updateAlertRule(alertRule: net.airvantage.model.alert.v1.AlertRule, application: String, system: AvSystem) { + try { + var alertRuleV2: AlertRule? = AlertRule() + alertRuleV2!!.targetType = "SYSTEM" + alertRuleV2.name = alertRule.name + alertRuleV2.message = "Alarm for " + system.name + " is ON" + alertRuleV2.active = true + alertRuleV2.conditions = ArrayList() + val metadata = HashMap() + metadata["templateId"] = "alertrule.template.custom" + + val condi = HashMap() + condi["application"] = application + metadata["condition_0"] = condi + alertRuleV2.metadata = metadata + for (condition in alertRule.conditions!!) { + alertRuleV2.conditions!!.add(convert(condition)) + } + val inp = put(alertRuleUrl("/" + alertRule.uid), alertRuleV2) + alertRuleV2 = gson.fromJson(InputStreamReader(inp), AlertRule::class.java) + convert(alertRuleV2) + + } catch (e: JsonIOException) { + Log.e(TAG, "Unable to create Alert Rule", e) + } + + } + + @Throws(IOException::class, AirVantageException::class) + override fun deleteAlertRule(alertRule: net.airvantage.model.alert.v1.AlertRule) { + delete(alertRuleUrl("/" + alertRule.uid)) + } + + + @Throws(IOException::class) + private fun alertRuleUrl(data:String? = null): URL { + + if (alertRuleUrl != null && data != null) + return alertRuleUrl!! + + val apiPath = "alertrules" + + val urlString = if (data == null) { + Uri.parse(buildEndpoint(apiPath)).toString() + }else{ + Uri.parse(buildEndpoint(apiPath + data)).toString() + } + var tmp: URL? + try { + tmp = URL(urlString) + } catch (e: MalformedURLException) { + Log.e(TAG, "Sure of URL?", e) + throw e + } + if (data != null) { + alertRuleUrl = tmp + } + + return tmp + } + + companion object { + private const val TAG = "AlertAdapterV2" + + private fun convert(condition: net.airvantage.model.alert.v1.Condition): Condition { + + val conditionV2 = Condition() + conditionV2.operator = condition.operator + + val leftOperand = Operand() + leftOperand.attributeId = AttributeId() + if (condition.eventProperty == "communication.data.value") { + leftOperand.attributeId!!.name = "DATA." + condition.eventPropertyKey + }else{ + leftOperand.attributeId!!.name = condition.eventPropertyKey + } + val rightOperand = Operand() + rightOperand.valueStr = condition.value + + conditionV2.operands = ArrayList(Arrays.asList(leftOperand, rightOperand)) + return conditionV2 + } + + private fun convert(alertRule: AlertRule): net.airvantage.model.alert.v1.AlertRule { + val alertRuleV1: net.airvantage.model.alert.v1.AlertRule = net.airvantage.model.alert.v1.AlertRule() + + // Assign similar fields + alertRuleV1.uid = alertRule.id + alertRuleV1.active = alertRule.active + alertRuleV1.name = alertRule.name + // alertRuleV1.metadata = alertRule.metadata; + + // Only event created in AV Phone + alertRuleV1.eventType = "event.system.incoming.communication" + + // Translating conditions + alertRuleV1.conditions = ArrayList() + for (condition in alertRule.conditions!!) { + alertRuleV1.conditions!!.add(convert(condition)) + } + return alertRuleV1 + } + + private fun convert(condition: Condition): net.airvantage.model.alert.v1.Condition { + val conditionV1: net.airvantage.model.alert.v1.Condition = net.airvantage.model.alert.v1.Condition() + conditionV1.eventProperty = "phone.alarm" + conditionV1.eventPropertyKey = AvPhoneData.ALARM + conditionV1.operator = condition.operator + + // Finding values + //Operand operand = Utils.first(condition.operands); + val values = ArrayList() + for (operand in condition.operands!!) { + if (operand.attributeId == null) { + if (operand.valueStr != null) values.add(operand.valueStr!!) + if (operand.valueNum != null) values.add(operand.valueNum!!) + } + }//values.add(Utils.first(operand.valuesStr)); + + // Trimming nulls + // values.removeAll(Collections.singleton(null)); + values.removeAll(setOf("")) + + // Pick first one + conditionV1.value = if (values.isEmpty()) "" else Utils.first(values).toString() + return conditionV1 + } + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/DefaultAlertAdapter.java b/mainActivity/src/main/java/net/airvantage/utils/alert/DefaultAlertAdapter.java deleted file mode 100644 index 0b56da8..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/alert/DefaultAlertAdapter.java +++ /dev/null @@ -1,139 +0,0 @@ -package net.airvantage.utils.alert; - -import android.util.Log; - -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; -import com.squareup.okhttp.OkHttpClient; - -import net.airvantage.model.AirVantageException; -import net.airvantage.model.AvError; -import net.airvantage.model.alert.v1.AlertRule; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Arrays; - -public class DefaultAlertAdapter { - - protected final String access_token; - protected final Gson gson; - protected final OkHttpClient client; - protected final String server; - - public DefaultAlertAdapter(String server, String token) { - this.access_token = token; - this.client = new OkHttpClient(); - this.gson = new Gson(); - this.server = server; - } - - public AlertRule createAlertRule(AlertRule alertRule) throws IOException, AirVantageException { - throw new AirVantageException(new AvError(AvError.FORBIDDEN)); - } - - public AlertRule updateAlertRule(AlertRule alertRule) throws IOException, AirVantageException { - throw new AirVantageException(new AvError(AvError.FORBIDDEN)); - } - - public AlertRule getAlertRuleByName(String name) throws IOException, AirVantageException { - throw new AirVantageException(new AvError(AvError.FORBIDDEN)); - } - - // - // After alert v2 migration, everything below this line HAVE TO GO: it is DUPLICATION. - // - - protected String buildPath(String api) { - final String path = server + getPrefix() + api + "?access_token=" + access_token; - Log.d(this.getClass().toString(), "About to call: " + path); - return path; - } - - protected String getPrefix() { - return "Override me"; - } - - protected String buildEndpoint(String api) { - return "https://" + buildPath(api); - } - - protected InputStream readResponse(HttpURLConnection connection) throws IOException, AirVantageException { - InputStream in; - if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - in = connection.getInputStream(); - Log.d(this.getClass().getName(), "Just read : " + connection.getURL().toString() - + " with status " + HttpURLConnection.HTTP_OK); - } else if (connection.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST) { - in = connection.getErrorStream(); - InputStreamReader isr = new InputStreamReader(in); - - net.airvantage.model.AvError error = gson.fromJson(isr, net.airvantage.model.AvError.class); - Log.e(this.getClass().getName(), "AirVantage Error : " + error.error + "," + error.errorParameters); - - throw new AirVantageException(error); - } else if (connection.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) { - String method = connection.getRequestMethod(); - String url = connection.getURL().toString(); - AvError error = new AvError(AvError.FORBIDDEN, Arrays.asList(method, url)); - throw new AirVantageException(error); - } else { - String message = "Reading " + connection.getURL().toString() - + " got unexpected HTTP response " + connection.getResponseCode() + ", " - + connection.getResponseMessage(); - IOException ioException = new IOException(message); - Log.e(this.getClass().getName(), message, ioException); - throw ioException; - } - return in; - } - - protected InputStream sendString(String method, URL url, String bodyString) - throws IOException, AirVantageException { - - OutputStream out = null; - try { - - // Create request for remote resource. - HttpURLConnection connection = client.open(url); - connection.addRequestProperty("Cache-Control", "no-cache"); - connection.addRequestProperty("Content-Type", "application/json"); - // Write the request. - connection.setRequestMethod(method); - - final String message = method +" on " + url.toString() + "\n" + bodyString; - Log.d(this.getClass().getName(), message); - - out = connection.getOutputStream(); - out.write(bodyString.getBytes()); - return readResponse(connection); - } finally { - if (out != null) - out.close(); - - } - - } - - protected InputStream post(URL url, Object body) throws IOException, AirVantageException { - String bodyString = gson.toJson(body); - return sendString("POST", url, bodyString); - } - - protected InputStream put(URL url, Object body) throws IOException, AirVantageException { - String bodyString = gson.toJson(body); - return sendString("PUT", url, bodyString); - } - - protected InputStream get(URL url) throws IOException, AirVantageException { - // Create request for remote resource. - HttpURLConnection connection = client.open(url); - connection.addRequestProperty("Cache-Control", "no-cache"); - - return readResponse(connection); - } -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/DefaultAlertAdapter.kt b/mainActivity/src/main/java/net/airvantage/utils/alert/DefaultAlertAdapter.kt new file mode 100644 index 0000000..9c36187 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/alert/DefaultAlertAdapter.kt @@ -0,0 +1,153 @@ +package net.airvantage.utils.alert + +import android.util.Log + +import com.google.gson.Gson +import com.squareup.okhttp.OkHttpClient + +import net.airvantage.model.AirVantageException +import net.airvantage.model.AvError +import net.airvantage.model.AvSystem +import net.airvantage.model.alert.v1.AlertRule + +import java.io.IOException +import java.io.InputStream +import java.io.InputStreamReader +import java.io.OutputStream +import java.net.HttpURLConnection +import java.net.URL +import java.util.Arrays + +open class DefaultAlertAdapter internal constructor(protected val server: String, internal val access_token: String) { + internal val gson: Gson = Gson() + protected val client: OkHttpClient = OkHttpClient() + private val TAG = this.javaClass.name + + open val prefix: String + get() = "Override me" + + @Throws(IOException::class, AirVantageException::class) + open fun createAlertRule(alertRule: AlertRule, application: String, system: AvSystem) { + throw AirVantageException(AvError(AvError.FORBIDDEN)) + } + + + @Throws(IOException::class, AirVantageException::class) + open fun updateAlertRule(alertRule: AlertRule, application: String, system: AvSystem) { + throw AirVantageException(AvError(AvError.FORBIDDEN)) + } + + + @Throws(IOException::class, AirVantageException::class) + open fun deleteAlertRule(alertRule: AlertRule) { + throw AirVantageException(AvError(AvError.FORBIDDEN)) + } + + + @Throws(IOException::class, AirVantageException::class) + open fun getAlertRuleByName(name: String, system: AvSystem): AlertRule? { + throw AirVantageException(AvError(AvError.FORBIDDEN)) + } + + // + // After alert v2 migration, everything below this line HAVE TO GO: it is DUPLICATION. + // + + private fun buildPath(api: String): String { + return server + prefix + api + "?access_token=" + access_token + } + + internal fun buildEndpoint(api: String): String { + return "https://" + buildPath(api) + } + + @Throws(IOException::class, AirVantageException::class) + private fun readResponse(connection: HttpURLConnection): InputStream { + val inp: InputStream + when { + connection.responseCode == HttpURLConnection.HTTP_OK -> { + inp = connection.inputStream + Log.i(TAG, "Just read : " + connection.url.toString() + + " with status " + HttpURLConnection.HTTP_OK) + } + connection.responseCode == HttpURLConnection.HTTP_BAD_REQUEST -> { + inp = connection.errorStream + val isr = InputStreamReader(inp) + + val error = gson.fromJson(isr, net.airvantage.model.AvError::class.java) + Log.e(TAG, "AirVantage Error : " + error.error + "," + error.errorParameters) + + throw AirVantageException(error) + } + connection.responseCode == HttpURLConnection.HTTP_FORBIDDEN -> { + val method = connection.requestMethod + val url = connection.url.toString() + val error = AvError(AvError.FORBIDDEN, Arrays.asList(method, url)) + throw AirVantageException(error) + } + else -> { + val message = ("Reading " + connection.url.toString() + + " got unexpected HTTP response " + connection.responseCode + ", " + + connection.responseMessage) + val ioException = IOException(message) + Log.e(TAG, message, ioException) + throw ioException + } + } + return inp + } + + @Throws(IOException::class, AirVantageException::class) + private fun sendString(method: String, url: URL, bodyString: String): InputStream { + var out: OutputStream? = null + try { + + // Create request for remote resource. + val connection = client.open(url) + connection.addRequestProperty("Cache-Control", "no-cache") + connection.addRequestProperty("Content-Type", "application/json") + // Write the request. + connection.requestMethod = method + + //val message = method + " on " + url.toString() + "\n" + bodyString + out = connection.outputStream + out!!.write(bodyString.toByteArray()) + return readResponse(connection) + } finally { + if (out != null) + out.close() + + } + + } + + @Throws(IOException::class, AirVantageException::class) + internal fun post(url: URL, body: Any): InputStream { + val bodyString = gson.toJson(body) + return sendString("POST", url, bodyString) + } + + @Throws(IOException::class, AirVantageException::class) + internal fun put(url: URL, body: Any): InputStream { + val bodyString = gson.toJson(body) + return sendString("PUT", url, bodyString) + } + + @Throws(IOException::class, AirVantageException::class) + internal fun delete(url: URL) { + val connection = client.open(url) + + connection.addRequestProperty("Cache-Control", "no-cache") + connection.requestMethod = "DELETE" + readResponse(connection) + } + + @Throws(IOException::class, AirVantageException::class) + protected operator fun get(url: URL): InputStream { + // Create request for remote resource. + val connection = client.open(url) + connection.addRequestProperty("Cache-Control", "no-cache") + + return readResponse(connection) + } +} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/IAlertAdapterFactoryListener.java b/mainActivity/src/main/java/net/airvantage/utils/alert/IAlertAdapterFactoryListener.java deleted file mode 100644 index e30c89c..0000000 --- a/mainActivity/src/main/java/net/airvantage/utils/alert/IAlertAdapterFactoryListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.airvantage.utils.alert; - -public interface IAlertAdapterFactoryListener { - void alertAdapterAvailable(DefaultAlertAdapter adapter); -} diff --git a/mainActivity/src/main/java/net/airvantage/utils/alert/IAlertAdapterFactoryListener.kt b/mainActivity/src/main/java/net/airvantage/utils/alert/IAlertAdapterFactoryListener.kt new file mode 100644 index 0000000..5dc60e5 --- /dev/null +++ b/mainActivity/src/main/java/net/airvantage/utils/alert/IAlertAdapterFactoryListener.kt @@ -0,0 +1,5 @@ +package net.airvantage.utils.alert + +interface IAlertAdapterFactoryListener { + fun alertAdapterAvailable(adapter: DefaultAlertAdapter) +} diff --git a/mainActivity/src/main/res/anim/enter.xml b/mainActivity/src/main/res/anim/enter.xml new file mode 100644 index 0000000..531a155 --- /dev/null +++ b/mainActivity/src/main/res/anim/enter.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/mainActivity/src/main/res/anim/exit.xml b/mainActivity/src/main/res/anim/exit.xml new file mode 100644 index 0000000..0f7f76d --- /dev/null +++ b/mainActivity/src/main/res/anim/exit.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/mainActivity/src/main/res/anim/pop_enter.xml b/mainActivity/src/main/res/anim/pop_enter.xml new file mode 100644 index 0000000..4e5df22 --- /dev/null +++ b/mainActivity/src/main/res/anim/pop_enter.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/mainActivity/src/main/res/anim/pop_exit.xml b/mainActivity/src/main/res/anim/pop_exit.xml new file mode 100644 index 0000000..fb3a3fa --- /dev/null +++ b/mainActivity/src/main/res/anim/pop_exit.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_add_data.png b/mainActivity/src/main/res/drawable-hdpi/ic_add_data.png new file mode 100644 index 0000000..6dad203 Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_add_data.png differ diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_delete.png b/mainActivity/src/main/res/drawable-hdpi/ic_delete.png new file mode 100644 index 0000000..e10a57b Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_delete.png differ diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_departement.png b/mainActivity/src/main/res/drawable-hdpi/ic_departement.png new file mode 100644 index 0000000..5ddb0dd Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_departement.png differ diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_domain.png b/mainActivity/src/main/res/drawable-hdpi/ic_domain.png new file mode 100644 index 0000000..86d7bbb Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_domain.png differ diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_group.png b/mainActivity/src/main/res/drawable-hdpi/ic_group.png new file mode 100644 index 0000000..d97185d Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_group.png differ diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_object.png b/mainActivity/src/main/res/drawable-hdpi/ic_object.png new file mode 100644 index 0000000..a1aa960 Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_object.png differ diff --git a/mainActivity/src/main/res/drawable-hdpi/ic_user.png b/mainActivity/src/main/res/drawable-hdpi/ic_user.png new file mode 100644 index 0000000..1549845 Binary files /dev/null and b/mainActivity/src/main/res/drawable-hdpi/ic_user.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_add_data.png b/mainActivity/src/main/res/drawable-mdpi/ic_add_data.png new file mode 100644 index 0000000..98ba6f3 Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_add_data.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_delete.png b/mainActivity/src/main/res/drawable-mdpi/ic_delete.png new file mode 100644 index 0000000..dabf6fb Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_delete.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_departement.png b/mainActivity/src/main/res/drawable-mdpi/ic_departement.png new file mode 100644 index 0000000..0671c60 Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_departement.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_domain.png b/mainActivity/src/main/res/drawable-mdpi/ic_domain.png new file mode 100644 index 0000000..7ba7119 Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_domain.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_group.png b/mainActivity/src/main/res/drawable-mdpi/ic_group.png new file mode 100644 index 0000000..c6a39b3 Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_group.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_object.png b/mainActivity/src/main/res/drawable-mdpi/ic_object.png new file mode 100644 index 0000000..276034d Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_object.png differ diff --git a/mainActivity/src/main/res/drawable-mdpi/ic_user.png b/mainActivity/src/main/res/drawable-mdpi/ic_user.png new file mode 100644 index 0000000..e288873 Binary files /dev/null and b/mainActivity/src/main/res/drawable-mdpi/ic_user.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_add_data.png b/mainActivity/src/main/res/drawable-xhdpi/ic_add_data.png new file mode 100644 index 0000000..c0f38fe Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_add_data.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_delete.png b/mainActivity/src/main/res/drawable-xhdpi/ic_delete.png new file mode 100644 index 0000000..ce20dfe Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_delete.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_departement.png b/mainActivity/src/main/res/drawable-xhdpi/ic_departement.png new file mode 100644 index 0000000..ee9619f Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_departement.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_domain.png b/mainActivity/src/main/res/drawable-xhdpi/ic_domain.png new file mode 100644 index 0000000..5932057 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_domain.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_group.png b/mainActivity/src/main/res/drawable-xhdpi/ic_group.png new file mode 100644 index 0000000..0416730 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_group.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_object.png b/mainActivity/src/main/res/drawable-xhdpi/ic_object.png new file mode 100644 index 0000000..932a700 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_object.png differ diff --git a/mainActivity/src/main/res/drawable-xhdpi/ic_user.png b/mainActivity/src/main/res/drawable-xhdpi/ic_user.png new file mode 100644 index 0000000..94f97a8 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xhdpi/ic_user.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_add_data.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_add_data.png new file mode 100644 index 0000000..fdf5fcf Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_add_data.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_delete.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_delete.png new file mode 100644 index 0000000..2d14234 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_delete.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_departement.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_departement.png new file mode 100644 index 0000000..0ed374e Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_departement.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_domain.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_domain.png new file mode 100644 index 0000000..45cd2f8 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_domain.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_group.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_group.png new file mode 100644 index 0000000..54fae32 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_group.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_object.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_object.png new file mode 100644 index 0000000..429cd7d Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_object.png differ diff --git a/mainActivity/src/main/res/drawable-xxhdpi/ic_user.png b/mainActivity/src/main/res/drawable-xxhdpi/ic_user.png new file mode 100644 index 0000000..be0fa39 Binary files /dev/null and b/mainActivity/src/main/res/drawable-xxhdpi/ic_user.png differ diff --git a/mainActivity/src/main/res/drawable/apptheme_switch_inner_holo_light.xml b/mainActivity/src/main/res/drawable/apptheme_switch_inner_holo_light.xml index afb2823..bd47e8b 100644 --- a/mainActivity/src/main/res/drawable/apptheme_switch_inner_holo_light.xml +++ b/mainActivity/src/main/res/drawable/apptheme_switch_inner_holo_light.xml @@ -17,6 +17,7 @@ + diff --git a/mainActivity/src/main/res/drawable/listitem_selector.xml b/mainActivity/src/main/res/drawable/listitem_selector.xml new file mode 100644 index 0000000..9e287cb --- /dev/null +++ b/mainActivity/src/main/res/drawable/listitem_selector.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mainActivity/src/main/res/layout/activity_authorization.xml b/mainActivity/src/main/res/layout/activity_authorization.xml index 056f517..7e194c3 100644 --- a/mainActivity/src/main/res/layout/activity_authorization.xml +++ b/mainActivity/src/main/res/layout/activity_authorization.xml @@ -1,50 +1,82 @@ - + android:orientation="horizontal" + android:paddingTop="10dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + android:layout_height="wrap_content" + android:buttonTint="@color/sierrared" + android:text="@string/auth_login_na" /> + android:layout_height="wrap_content" + android:buttonTint="@color/sierrared" + android:text="@string/auth_login_eu" /> + android:layout_height="wrap_content" + android:buttonTint="@color/sierrared" + android:text="@string/auth_login_custom" /> + android:layout_height="0dp" + android:background="@android:color/darker_gray" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/radioGroup" /> + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@+id/view"> + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/mainActivity/src/main/res/layout/activity_fortests.xml b/mainActivity/src/main/res/layout/activity_fortests.xml index 7b5bb0c..b2dbe92 100644 --- a/mainActivity/src/main/res/layout/activity_fortests.xml +++ b/mainActivity/src/main/res/layout/activity_fortests.xml @@ -9,5 +9,5 @@ android:layout_height="fill_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="true" - /> + android:orientation="horizontal" /> \ No newline at end of file diff --git a/mainActivity/src/main/res/layout/activity_main.xml b/mainActivity/src/main/res/layout/activity_main.xml index f804c0d..143e49b 100644 --- a/mainActivity/src/main/res/layout/activity_main.xml +++ b/mainActivity/src/main/res/layout/activity_main.xml @@ -10,12 +10,11 @@ + android:dividerHeight="0dp" /> diff --git a/mainActivity/src/main/res/layout/activity_object_configure.xml b/mainActivity/src/main/res/layout/activity_object_configure.xml new file mode 100644 index 0000000..b311ba1 --- /dev/null +++ b/mainActivity/src/main/res/layout/activity_object_configure.xml @@ -0,0 +1,78 @@ + + + +