package com.nutomic.syncthingandroid.activities;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.service.SyncthingServiceBinder;
import java.util.LinkedList;
/**
* Connects to {@link SyncthingService} and provides access to it.
*/
public abstract class SyncthingActivity extends ToolbarBindingActivity implements ServiceConnection {
public static final String EXTRA_FIRST_START = "com.nutomic.syncthing-android.SyncthingActivity.FIRST_START";
private SyncthingService mSyncthingService;
private AlertDialog mLoadingDialog;
private final LinkedList<OnServiceConnectedListener> mServiceConnectedListeners = new LinkedList<>();
/**
* To be used for Fragments.
*/
public interface OnServiceConnectedListener {
void onServiceConnected();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, SyncthingService.class));
}
@Override
protected void onPause() {
unbindService(this);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
bindService(new Intent(this, SyncthingService.class), this, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
dismissLoadingDialog();
if (getService() != null) {
getService().unregisterOnApiChangeListener(this::onApiChange);
}
}
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
SyncthingServiceBinder binder = (SyncthingServiceBinder) iBinder;
mSyncthingService = binder.getService();
mSyncthingService.registerOnApiChangeListener(this::onApiChange);
for (OnServiceConnectedListener listener : mServiceConnectedListeners) {
listener.onServiceConnected();
}
mServiceConnectedListeners.clear();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mSyncthingService = null;
}
private void onApiChange(SyncthingService.State currentState) {
switch (currentState) {
case INIT: // fallthrough
case STARTING:
showLoadingDialog();
break;
case ACTIVE: // fallthrough
case DISABLED:
dismissLoadingDialog();
break;
}
}
/**
* Used for Fragments to use the Activity's service connection.
*/
public void registerOnServiceConnectedListener(OnServiceConnectedListener listener) {
if (mSyncthingService != null) {
listener.onServiceConnected();
} else {
mServiceConnectedListeners.addLast(listener);
}
}
/**
* Returns service object (or null if not bound).
*/
public SyncthingService getService() {
return mSyncthingService;
}
/**
* Returns RestApi instance, or null if SyncthingService is not yet connected.
*/
public RestApi getApi() {
return (getService() != null)
? getService().getApi()
: null;
}
/**
* Shows the loading dialog with the correct text ("creating keys" or "loading").
*/
private void showLoadingDialog() {
if (isFinishing() || mLoadingDialog != null)
return;
LayoutInflater inflater = getLayoutInflater();
@SuppressLint("InflateParams")
View dialogLayout = inflater.inflate(R.layout.dialog_loading, null);
TextView loadingText = (TextView) dialogLayout.findViewById(R.id.loading_text);
loadingText.setText((getIntent().getBooleanExtra(EXTRA_FIRST_START, false))
? R.string.web_gui_creating_key
: R.string.api_loading);
mLoadingDialog = new AlertDialog.Builder(this)
.setCancelable(false)
.setView(dialogLayout)
.show();
}
private void dismissLoadingDialog() {
if (mLoadingDialog != null) {
mLoadingDialog.dismiss();
mLoadingDialog = null;
}
}
}