Skip to content

Commit

Permalink
Various fixes for Android 4
Browse files Browse the repository at this point in the history
  • Loading branch information
Alberto Geniola committed Jun 27, 2021
1 parent 784a69a commit f5b9b07
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;

Expand All @@ -23,6 +24,7 @@

public class AndroidPreferencesManager {
private static String PREFS_CONFS = "com.albertogeniola.merossconf.shared_preferences";
private static String PREFS_WIFI_CREDS = "com.albertogeniola.merossconf.shared_preferences.wifi_creds";
private static String KEY_MQTT_CONF = "mqtt";
private static String KEY_HTTP_CONF = "http";
private static Gson g = Utils.getGson();
Expand Down Expand Up @@ -76,11 +78,21 @@ public static void removeHttpCredentials(Context c) {

@Nullable
public static String getWifiStoredPassword(@NonNull Context c, @NonNull String bssid) {
return SecurePreferences.getStringValue(bssid.trim().toLowerCase(), c, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
return SecurePreferences.getStringValue(bssid.trim().toLowerCase(), c, null);
} else {
return c.getSharedPreferences(PREFS_WIFI_CREDS, Context.MODE_PRIVATE).getString(bssid.trim().toLowerCase(), null);
}
}

public static void storeWifiStoredPassword(@NonNull Context c, @NonNull String bssid, @NonNull String password) {
SecurePreferences.setValue(bssid.trim().toLowerCase(), password, c);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
SecurePreferences.setValue(bssid.trim().toLowerCase(), password, c);
} else {
SharedPreferences.Editor e = c.getSharedPreferences(PREFS_WIFI_CREDS, Context.MODE_PRIVATE).edit();
e.putString(bssid.trim().toLowerCase(), password);
e.apply();
}
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,6 @@ public void onDiscoveryStarted(String serviceType) {
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success" + service);
/*
if (mDiscoveryInProgress)
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
*/
mNsdManager.resolveService(service, mResolveListener);
}

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.albertogeniola.merossconf.ui.fragments.pair;

import android.app.AlertDialog;
import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
Expand Down Expand Up @@ -35,13 +36,16 @@
import com.albertogeniola.merossconf.model.WifiConfiguration;
import com.albertogeniola.merossconf.model.exception.PermissionNotGrantedException;
import com.albertogeniola.merossconf.ui.PairActivityViewModel;
import com.albertogeniola.merossconf.ui.fragments.login.LoginFragment;
import com.albertogeniola.merosslib.model.Encryption;
import com.albertogeniola.merosslib.model.protocol.payloads.GetConfigWifiListEntry;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.textfield.TextInputLayout;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import lombok.SneakyThrows;

Expand All @@ -50,6 +54,7 @@ public class ConfigureWifiFragment extends AbstractWifiFragment {
private static final String TAG = "ConfigureWifiFragment";
private NsdManager mNsdManager;
private static final String SERVICE_TYPE = "_meross-mqtt._tcp.";
private static final int WIFI_CONNECT_DELAY = 5000;

private Handler mUiHandler;
private PairActivityViewModel pairActivityViewModel;
Expand All @@ -64,6 +69,8 @@ public class ConfigureWifiFragment extends AbstractWifiFragment {
private boolean mResolveInProgress = false;
private WifiConfiguration mSelectedWifi = null;

private Timer mTimer;

private static final String VALIDATE_AND_PROCEED = "Validate and proceed";
private static final String DISCOVERY_MQTT = "MQTT discovery...";
private static final String MQTT_RESOLVE = "Resolving service...";
Expand Down Expand Up @@ -98,7 +105,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
mSkipButton = view.findViewById(R.id.next_no_validation_button);
mLinearProgressBar = view.findViewById(R.id.wifi_progress_bar);

configureUi(true, VALIDATE_AND_PROCEED);
configureUi(true, VALIDATE_AND_PROCEED, null);
mNextButton.setOnClickListener(nextButtonClick);
mSkipButton.setOnClickListener(skipButtonClick);
CheckBox showPasswordButton = view.findViewById(R.id.showPasswordCheckbox);
Expand Down Expand Up @@ -141,14 +148,14 @@ public void onDestroy() {
}

@Override
protected void onWifiConnected(String ssid, String bssid) {
protected void onWifiConnected(String ssid) {
// If the wifi connection succeeds, store the wifi info into the parent model
mUiHandler.post(new Runnable() {
mUiHandler.postDelayed(new Runnable() {
@Override
public void run() {
pairActivityViewModel.setMerossWifiConfiguration(mSelectedWifi);
}
});
}, WIFI_CONNECT_DELAY);

// Store the password, if required
if (mSaveWifiPasswordCheckBox.isChecked())
Expand All @@ -164,44 +171,63 @@ public void run() {
Log.e(TAG, "Resolve in progress. Cannot issue discovery.");
} else {
Log.i(TAG, "Wifi connected, issuing discovery.");
configureUi(false, DISCOVERY_MQTT);
startApiDiscovery();
}
}

private void startApiDiscovery() {
// Setup UI
configureUi(false, DISCOVERY_MQTT, null);

// Start mDNS discovery
if (!mDiscoveryInProgress) {
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}

// Start a timer for aborting discovery after 10 seconds if nothing is found.
if (mTimer == null) {
mTimer = new Timer();
mTimer.schedule(new ConfigureWifiFragment.TimeoutTask(), 5000);
}
}

@Override
protected void onWifiUnavailable(String ssid, String bssid) {
Toast.makeText(requireContext(), "Wifi validation failed. Please double check credentials and try again.", Toast.LENGTH_LONG).show();
configureUi(true, VALIDATE_AND_PROCEED);
protected void onWifiUnavailable(String ssid) {
configureUi(true, VALIDATE_AND_PROCEED, "Wifi validation failed. Please double check credentials and try again.");
}

@Override
protected void onMissingWifiPermissions(String ssid, String bssid) {
Toast.makeText(requireContext(), "Please grant Wifi and Location permissions to this app. It won't work without them.", Toast.LENGTH_LONG).show();
configureUi(true, VALIDATE_AND_PROCEED);
protected void onMissingWifiPermissions(String ssid) {
configureUi(true, VALIDATE_AND_PROCEED, "Please grant Wifi and Location permissions to this app. It won't work without them.");
}

@SneakyThrows(PermissionNotGrantedException.class)
@Override
protected void onWifiPermissionsGranted(String ssid, String bssid) {
startWifiConnection(ssid, bssid, mSelectedWifi.getClearWifiPassword(), null, 20000);
protected void onWifiPermissionsGranted(String ssid) {
startWifiConnection(ssid, mSelectedWifi.getClearWifiPassword(), null, 20000);
}

@UiThread
private void configureUi(final Boolean uiEnabled,
final String nextButtonText) {
final String nextButtonText,
@Nullable final String textMessage) {
Runnable r = new Runnable() {
@Override
public void run() {
wifiSpinner.setEnabled(uiEnabled);
mNextButton.setEnabled(uiEnabled);
mSkipButton.setEnabled(uiEnabled);
mSaveWifiPasswordCheckBox.setEnabled(uiEnabled);
mNextButton.setText(nextButtonText);
mLinearProgressBar.setVisibility(uiEnabled ? View.GONE : View.VISIBLE);
mWifiPasswordTextView.setEnabled(uiEnabled);

if (textMessage != null) {
Toast.makeText(requireContext(), textMessage, Toast.LENGTH_SHORT).show();
}
}
};
if (Looper.getMainLooper().isCurrentThread())
if (Looper.getMainLooper().getThread()==Thread.currentThread())
r.run();
else
mUiHandler.post(r);
Expand Down Expand Up @@ -251,7 +277,7 @@ public void onClick(View v) {
private void notifyResolveCompleted(@Nullable final String hostname,
@Nullable final Integer port) {

configureUi(false, COMPLETED);
configureUi(false, COMPLETED, null);

// In case the discovery found a valid service, put it into a parcel for the next fragment
final Bundle args = new Bundle();
Expand All @@ -274,11 +300,11 @@ public void run() {

private void startWifiConnectionValidation(WifiConfiguration selectedWifi) {
mSelectedWifi = selectedWifi;
configureUi(false, "Connecting to wifi...");
configureUi(false, "Connecting to wifi...", null);

// Start wifi connection
try {
startWifiConnection(mSelectedWifi.getScannedWifi().getSsid(), mSelectedWifi.getScannedWifi().getBssid(), mSelectedWifi.getClearWifiPassword(), null, 20000);
startWifiConnection(mSelectedWifi.getScannedWifi().getSsid(), mSelectedWifi.getClearWifiPassword(), null, 20000);
// The flow starts back from on onWifiConnected / onWifiUnavailable().
} catch (PermissionNotGrantedException e) {
// The flow starts back from onWifiPermissionsGranted()
Expand Down Expand Up @@ -351,46 +377,32 @@ public View getDropDownView(int position, View convertView,
@Override
public void onDiscoveryStarted(String serviceType) {
Log.d(TAG, "Service discovery started");

mDiscoveryInProgress = true;
}

@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success" + service);
synchronized (this) {
if (!mResolveInProgress) {
mResolveInProgress = true;
configureUi(false, MQTT_RESOLVE);
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
mNsdManager.resolveService(service, mResolveListener);
}
}
mNsdManager.resolveService(service, mResolveListener);
}

@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mDiscoveryInProgress = false;
configureUi(true, VALIDATE_AND_PROCEED);
configureUi(true, VALIDATE_AND_PROCEED, "Discovery failed");
mNsdManager.stopServiceDiscovery(this);
}

@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}

@Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, "Discovery stopped: " + serviceType);
mDiscoveryInProgress = false;

// We need to check the availability of the context. This appers to be a bug:
// it is not possible to unregister a discovery listener.
// So, we just check for the presence of the Context. If that's null, we assume this
// must not run.
if (ConfigureWifiFragment.this.getContext()!=null)
configureUi(false, VALIDATE_AND_PROCEED);
}

@Override
Expand All @@ -408,14 +420,41 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {

Log.e(TAG, "Resolve failed" + errorCode);
mResolveInProgress = false;
configureUi(false, VALIDATE_AND_PROCEED);
configureUi(false, VALIDATE_AND_PROCEED, "mDNSResolve failed");
}
@Override
public void onServiceResolved(final NsdServiceInfo serviceInfo) {
Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
mResolveInProgress = false;
configureUi(false, VALIDATE_AND_PROCEED);
configureUi(false, VALIDATE_AND_PROCEED, null);
notifyResolveCompleted(serviceInfo.getHost().getHostName(), serviceInfo.getPort());
}
};

private class TimeoutTask extends TimerTask {
@Override
public void run() {
mTimer = null;
if (mDiscoveryInProgress)
mNsdManager.stopServiceDiscovery(mDiscoveryListener);

mUiHandler.post(new Runnable() {
@Override
public void run() {
// Just store the current configuration and proceed to the next fragment
pairActivityViewModel.setMerossWifiConfiguration(mSelectedWifi);

// Store the password, if required
if (mSaveWifiPasswordCheckBox.isChecked())
AndroidPreferencesManager.storeWifiStoredPassword(requireContext(), mSelectedWifi.getScannedWifi().getBssid(), mWifiPasswordTextView.getEditText().toString());

// Launch the next fragment
NavController ctrl = NavHostFragment.findNavController(ConfigureWifiFragment.this);
ctrl.navigate(R.id.action_configureWifi_to_configureMqtt, null, new NavOptions.Builder().setEnterAnim(android.R.animator.fade_in).setExitAnim(android.R.animator.fade_out).build());

configureUi(true, VALIDATE_AND_PROCEED, "Failed to locate MQTT endpoint via mDNS");
}
});
}
}
}
Loading

0 comments on commit f5b9b07

Please sign in to comment.