Add IpAddressCallbacks

Refactor Flowable using Interval
Shift Flowable code to WebServerHelper
This commit is contained in:
Adeel 2019-08-30 16:02:05 +05:00
parent b2409a0aa9
commit 6c75fefdb7
8 changed files with 93 additions and 50 deletions

View File

@ -13,6 +13,7 @@ import org.kiwix.kiwixmobile.di.ServiceScope
import org.kiwix.kiwixmobile.webserver.WebServerHelper import org.kiwix.kiwixmobile.webserver.WebServerHelper
import org.kiwix.kiwixmobile.wifi_hotspot.HotspotNotificationManager import org.kiwix.kiwixmobile.wifi_hotspot.HotspotNotificationManager
import org.kiwix.kiwixmobile.wifi_hotspot.HotspotStateListener import org.kiwix.kiwixmobile.wifi_hotspot.HotspotStateListener
import org.kiwix.kiwixmobile.wifi_hotspot.IpAddressCallbacks
import org.kiwix.kiwixmobile.wifi_hotspot.WifiHotspotManager import org.kiwix.kiwixmobile.wifi_hotspot.WifiHotspotManager
@Module @Module
@ -22,8 +23,9 @@ class ServiceModule {
@ServiceScope @ServiceScope
fun providesWebServerHelper( fun providesWebServerHelper(
jniKiwixLibrary: JNIKiwixLibrary, jniKiwixLibrary: JNIKiwixLibrary,
kiwixServer: JNIKiwixServer kiwixServer: JNIKiwixServer,
): WebServerHelper = WebServerHelper(jniKiwixLibrary, kiwixServer) ipAddressCallbacks: IpAddressCallbacks
): WebServerHelper = WebServerHelper(jniKiwixLibrary, kiwixServer, ipAddressCallbacks)
@Provides @Provides
@ServiceScope @ServiceScope
@ -38,6 +40,11 @@ class ServiceModule {
fun providesHotspotStateListener(service: Service): HotspotStateListener = fun providesHotspotStateListener(service: Service): HotspotStateListener =
service as HotspotStateListener service as HotspotStateListener
@Provides
@ServiceScope
fun providesIpAddressCallbacks(service: Service): IpAddressCallbacks =
service as IpAddressCallbacks
@Provides @Provides
@ServiceScope @ServiceScope
fun providesJNIKiwixLibrary(): JNIKiwixLibrary = JNIKiwixLibrary() fun providesJNIKiwixLibrary(): JNIKiwixLibrary = JNIKiwixLibrary()

View File

@ -1,6 +1,7 @@
package org.kiwix.kiwixmobile.utils; package org.kiwix.kiwixmobile.utils;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
@ -9,9 +10,10 @@ import java.util.Enumeration;
public class ServerUtils { public class ServerUtils {
public static int port; public static int port;
public static boolean isServerStarted; public static boolean isServerStarted;
public static final String INVALID_IP = "-1";
// get Ip address of the device's wireless access point i.e. wifi hotspot OR wifi network // get Ip address of the device's wireless access point i.e. wifi hotspot OR wifi network
public static String getIpAddress() { @Nullable public static String getIpAddress() {
String ip = ""; String ip = "";
try { try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
@ -51,10 +53,10 @@ public class ServerUtils {
return address; return address;
} }
public static String getIp() { @Nullable public static String getIp() {
String ip = getIpAddress(); String ip = getIpAddress();
ip = ip.replaceAll("\n", ""); ip = ip.replaceAll("\n", "");
if (ip.length() == 0) throw new IllegalStateException(); if (ip.length() == 0) return INVALID_IP;
return ip; return ip;
} }
} }

View File

@ -2,12 +2,18 @@ package org.kiwix.kiwixmobile.webserver;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import org.kiwix.kiwixlib.JNIKiwixException; import org.kiwix.kiwixlib.JNIKiwixException;
import org.kiwix.kiwixlib.JNIKiwixLibrary; import org.kiwix.kiwixlib.JNIKiwixLibrary;
import org.kiwix.kiwixlib.JNIKiwixServer; import org.kiwix.kiwixlib.JNIKiwixServer;
import org.kiwix.kiwixmobile.utils.ServerUtils; import org.kiwix.kiwixmobile.utils.ServerUtils;
import org.kiwix.kiwixmobile.wifi_hotspot.IpAddressCallbacks;
import static org.kiwix.kiwixmobile.utils.ServerUtils.INVALID_IP;
/** /**
* WebServerHelper class is used to set up the suitable environment i.e. getting the * WebServerHelper class is used to set up the suitable environment i.e. getting the
@ -19,11 +25,13 @@ public class WebServerHelper {
private static final String TAG = "WebServerHelper"; private static final String TAG = "WebServerHelper";
private JNIKiwixLibrary kiwixLibrary; private JNIKiwixLibrary kiwixLibrary;
private JNIKiwixServer kiwixServer; private JNIKiwixServer kiwixServer;
private IpAddressCallbacks ipAddressCallbacks;
@Inject public WebServerHelper(@NonNull JNIKiwixLibrary kiwixLibrary, @Inject public WebServerHelper(@NonNull JNIKiwixLibrary kiwixLibrary,
@NonNull JNIKiwixServer kiwixServer) { @NonNull JNIKiwixServer kiwixServer, @NonNull IpAddressCallbacks ipAddressCallbacks) {
this.kiwixLibrary = kiwixLibrary; this.kiwixLibrary = kiwixLibrary;
this.kiwixServer = kiwixServer; this.kiwixServer = kiwixServer;
this.ipAddressCallbacks = ipAddressCallbacks;
} }
public boolean startServerHelper(@NonNull ArrayList<String> selectedBooksPath) { public boolean startServerHelper(@NonNull ArrayList<String> selectedBooksPath) {
@ -63,4 +71,25 @@ public class WebServerHelper {
} }
return ServerUtils.isServerStarted; return ServerUtils.isServerStarted;
} }
//Keeps checking if hotspot has been turned using the ip address with an interval of 1 sec
//If no ip is found after 15 seconds, dismisses the progress dialog
public void pollForValidIpAddress() {
Flowable.interval(1, TimeUnit.SECONDS)
.map(__ -> ServerUtils.getIp())
.filter(s -> s != INVALID_IP)
.timeout(15, TimeUnit.SECONDS)
.take(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
s -> {
ipAddressCallbacks.onIpAddressValid();
Log.d(TAG, "onSuccess: " + s);
}, //success stuff
e -> {
Log.d(TAG, "Unable to turn on server", e);
ipAddressCallbacks.onIpAddressInvalid();
} //failure stuff
);
}
} }

View File

@ -22,14 +22,9 @@ import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView; import butterknife.BindView;
import io.reactivex.Flowable;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import kotlin.Unit; import kotlin.Unit;
import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function0;
@ -44,6 +39,7 @@ import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BookOnDiskDeleg
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter; import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter;
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem; import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem;
import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_CHECK_IP_ADDRESS;
import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_LOCATION_ACCESS_GRANTED; import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_LOCATION_ACCESS_GRANTED;
import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_START_SERVER; import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_START_SERVER;
import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_STOP_SERVER; import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotService.ACTION_STOP_SERVER;
@ -70,15 +66,15 @@ public class ZimHostActivity extends BaseActivity implements
private static final String TAG = "ZimHostActivity"; private static final String TAG = "ZimHostActivity";
private static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 102; private static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 102;
public static final String SELECTED_ZIM_PATHS_KEY = "selected_zim_paths";
private static final String IP_STATE_KEY = "ip_state_key"; private static final String IP_STATE_KEY = "ip_state_key";
private ProgressDialog progressDialog; public static final String SELECTED_ZIM_PATHS_KEY = "selected_zim_paths";
private BooksOnDiskAdapter booksAdapter; private BooksOnDiskAdapter booksAdapter;
private BookOnDiskDelegate.BookDelegate bookDelegate; private BookOnDiskDelegate.BookDelegate bookDelegate;
private HotspotService hotspotService; private HotspotService hotspotService;
private String ip; private String ip;
private ServiceConnection serviceConnection; private ServiceConnection serviceConnection;
private ProgressDialog progressDialog;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -280,43 +276,15 @@ public class ZimHostActivity extends BaseActivity implements
null, null,
() -> { () -> {
progressDialog = progressDialog =
ProgressDialog.show(ZimHostActivity.this, ProgressDialog.show(this,
getString(R.string.progress_dialog_starting_server), "", getString(R.string.progress_dialog_starting_server), "",
true); true);
pollForValidIpAddress(); startService(createHotspotIntent(ACTION_CHECK_IP_ADDRESS));
return Unit.INSTANCE; return Unit.INSTANCE;
} }
); );
} }
//Keeps checking if hotspot has been turned using the ip address with an interval of 1 sec
//If no ip is found after 15 seconds, dismisses the progress dialog
private void pollForValidIpAddress() {
Flowable.fromCallable(ServerUtils::getIp)
.retryWhen(error -> error.delay(1, TimeUnit.SECONDS))
.timeout(15, TimeUnit.SECONDS)
.firstOrError()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<String>() {
@Override public void onSubscribe(Disposable d) {
}
@Override public void onSuccess(String s) {
progressDialog.dismiss();
startService(createHotspotIntent(ACTION_START_SERVER).putStringArrayListExtra(
SELECTED_ZIM_PATHS_KEY, getSelectedBooksPath()));
Log.d(TAG, "onSuccess: " + s);
}
@Override public void onError(Throwable e) {
progressDialog.dismiss();
Toast.makeText(ZimHostActivity.this, R.string.server_failed_message, Toast.LENGTH_SHORT)
.show();
Log.d(TAG, "Unable to turn on server", e);
}
});
}
private Intent createHotspotIntent(String action) { private Intent createHotspotIntent(String action) {
return new Intent(this, HotspotService.class).setAction(action); return new Intent(this, HotspotService.class).setAction(action);
} }
@ -338,10 +306,10 @@ public class ZimHostActivity extends BaseActivity implements
alertDialogShower.show(new KiwixDialog.ShowHotspotDetails(wifiConfiguration), alertDialogShower.show(new KiwixDialog.ShowHotspotDetails(wifiConfiguration),
(Function0<Unit>) () -> { (Function0<Unit>) () -> {
progressDialog = progressDialog =
ProgressDialog.show(ZimHostActivity.this, ProgressDialog.show(this,
getString(R.string.progress_dialog_starting_server), "", getString(R.string.progress_dialog_starting_server), "",
true); true);
pollForValidIpAddress(); startService(createHotspotIntent(ACTION_CHECK_IP_ADDRESS));
return Unit.INSTANCE; return Unit.INSTANCE;
}); });
} }
@ -383,4 +351,16 @@ public class ZimHostActivity extends BaseActivity implements
@Override public void onLocationSet() { @Override public void onLocationSet() {
startService(createHotspotIntent(ACTION_LOCATION_ACCESS_GRANTED)); startService(createHotspotIntent(ACTION_LOCATION_ACCESS_GRANTED));
} }
@Override public void provideBooksAndStartServer() {
startService(createHotspotIntent(ACTION_START_SERVER).putStringArrayListExtra(
SELECTED_ZIM_PATHS_KEY, getSelectedBooksPath()));
}
@Override public void dismissProgressDialog() {
progressDialog.dismiss();
Toast.makeText(this, R.string.server_failed_message,
Toast.LENGTH_SHORT)
.show();
}
} }

View File

@ -16,4 +16,8 @@ public interface ZimHostCallbacks {
void onHotspotFailedToStart(); void onHotspotFailedToStart();
void requestLocationAccess(); void requestLocationAccess();
void provideBooksAndStartServer();
void dismissProgressDialog();
} }

View File

@ -27,12 +27,13 @@ import static org.kiwix.kiwixmobile.wifi_hotspot.HotspotNotificationManager.HOTS
* Created by Adeel Zafar on 07/01/2019. * Created by Adeel Zafar on 07/01/2019.
*/ */
public class HotspotService extends Service implements HotspotStateListener { public class HotspotService extends Service implements HotspotStateListener, IpAddressCallbacks {
public static final String ACTION_TOGGLE_HOTSPOT = "toggle_hotspot"; public static final String ACTION_TOGGLE_HOTSPOT = "toggle_hotspot";
public static final String ACTION_LOCATION_ACCESS_GRANTED = "location_access_granted"; public static final String ACTION_LOCATION_ACCESS_GRANTED = "location_access_granted";
public static final String ACTION_START_SERVER = "start_server"; public static final String ACTION_START_SERVER = "start_server";
public static final String ACTION_STOP_SERVER = "stop_server"; public static final String ACTION_STOP_SERVER = "stop_server";
public static final String ACTION_CHECK_IP_ADDRESS = "check_ip_address";
public static final String ACTION_STOP = "hotspot_stop"; public static final String ACTION_STOP = "hotspot_stop";
private static final String TAG = "HotspotService"; private static final String TAG = "HotspotService";
@ -111,6 +112,11 @@ public class HotspotService extends Service implements HotspotStateListener {
case ACTION_STOP_SERVER: case ACTION_STOP_SERVER:
stopHotspotAndDismissNotification(); stopHotspotAndDismissNotification();
break; break;
case ACTION_CHECK_IP_ADDRESS:
webServerHelper.pollForValidIpAddress();
break;
default: default:
break; break;
} }
@ -169,6 +175,15 @@ public class HotspotService extends Service implements HotspotStateListener {
hotspotNotificationManager.dismissNotification(); hotspotNotificationManager.dismissNotification();
} }
@Override public void onIpAddressValid() {
zimHostCallbacks.dismissProgressDialog();
zimHostCallbacks.provideBooksAndStartServer();
}
@Override public void onIpAddressInvalid() {
zimHostCallbacks.dismissProgressDialog();
}
public class HotspotBinder extends Binder { public class HotspotBinder extends Binder {
@NonNull public HotspotService getService() { @NonNull public HotspotService getService() {

View File

@ -0,0 +1,8 @@
package org.kiwix.kiwixmobile.wifi_hotspot;
public interface IpAddressCallbacks {
void onIpAddressValid();
void onIpAddressInvalid();
}

View File

@ -17,15 +17,13 @@ import javax.inject.Inject;
public class WifiHotspotManager { public class WifiHotspotManager {
private static final String TAG = "WifiHotspotManager"; private static final String TAG = "WifiHotspotManager";
private WifiManager wifiManager;
private WifiManager.LocalOnlyHotspotReservation hotspotReservation; private WifiManager.LocalOnlyHotspotReservation hotspotReservation;
private HotspotStateListener hotspotStateListener; private HotspotStateListener hotspotStateListener;
@Inject
WifiManager wifiManager;
@Inject @Inject
public WifiHotspotManager(@NonNull WifiManager wifiManager, public WifiHotspotManager(@NonNull WifiManager wifiManager,
HotspotStateListener hotspotStateListener) { @NonNull HotspotStateListener hotspotStateListener) {
this.wifiManager = wifiManager; this.wifiManager = wifiManager;
this.hotspotStateListener = hotspotStateListener; this.hotspotStateListener = hotspotStateListener;
} }