Skip to content

Commit

Permalink
Merge pull request #233 from mycelium-com/modulesSettingsFix
Browse files Browse the repository at this point in the history
#872 Implemented logic to support contract versions in settings.
  • Loading branch information
Giszmo authored Apr 30, 2018
2 parents 4c4eef8 + bf6eba3 commit df8b1b5
Show file tree
Hide file tree
Showing 20 changed files with 338 additions and 108 deletions.
36 changes: 9 additions & 27 deletions mbw/src/main/java/com/mycelium/wallet/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -705,34 +705,16 @@ public void onClick(DialogInterface dialog, int id) {
}
}

/**
* Shows one AlertDialog per module that runs under a different SpvApiVersion, advising to upgrade the lower between wallet and module.
*/
public static void notifyWrongModuleVersion(final Activity parent) {
for(WalletApplication.ModuleVersionError moduleVersionError: WalletApplication.getInstance().moduleVersionErrors) {
Module module = GooglePlayModuleCollection.getModuleByPackage(parent, moduleVersionError.moduleId);
Module wallet = new Module(BuildConfig.APPLICATION_ID, "<b>Mycelium Wallet</b>", "");
final Module needsUpdate;
if (moduleVersionError.expected > com.mycelium.spvmodulecontract.BuildConfig.SpvApiVersion) {
needsUpdate = wallet;
} else {
needsUpdate = module;
}
new AlertDialog.Builder(parent)
.setTitle(Html.fromHtml(parent.getString(R.string.update_required_for, needsUpdate.getName())))
.setMessage(Html.fromHtml(parent.getString(R.string.update_required_details, wallet.getName(), module.getName(), needsUpdate.getName())))
.setPositiveButton(Html.fromHtml(parent.getString(R.string.update, needsUpdate.getName())), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent installIntent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("https://play.google.com/store/apps/details?id=" + needsUpdate.getModulePackage()));
parent.startActivity(installIntent);
}
})
.setNegativeButton(Html.fromHtml(parent.getString(R.string.continue_without, module.getName())), null)
.create()
.show();
public static boolean isAppInstalled(Context context, String uri) {
PackageManager pm = context.getPackageManager();
boolean installed;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
installed = true;
} catch (PackageManager.NameNotFoundException e) {
installed = false;
}
return installed;
}

public static void pinProtectedBackup(final Activity activity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import com.mycelium.wallet.event.TorStateChanged;
import com.mycelium.wallet.event.TransactionBroadcasted;
import com.mycelium.wallet.modularisation.BCHHelper;
import com.mycelium.wallet.modularisation.ModularisationVersionHelper;
import com.mycelium.wapi.api.response.Feature;
import com.mycelium.wapi.wallet.AesKeyCipher;
import com.mycelium.wapi.wallet.KeyCipher;
Expand Down Expand Up @@ -204,7 +205,7 @@ public BitmapDrawable call() throws Exception {
BCHHelper.firstBCHPages(this);
_mbwManager.importLabelsToBch(_mbwManager.getWalletManager(false));

Utils.notifyWrongModuleVersion(this);
ModularisationVersionHelper.notifyWrongModuleVersion(this);
}

private void checkGapBug() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatEditText;
import android.text.Html;
import android.text.InputType;
Expand Down Expand Up @@ -82,6 +83,7 @@
import com.mycelium.wallet.activity.export.VerifyBackupActivity;
import com.mycelium.wallet.activity.modern.Toaster;
import com.mycelium.wallet.activity.view.ButtonPreference;
import com.mycelium.wallet.activity.view.TwoButtonsPreference;
import com.mycelium.wallet.event.SpvSyncChanged;
import com.mycelium.wallet.external.BuySellServiceDescriptor;
import com.mycelium.wallet.lt.LocalTraderEventSubscriber;
Expand All @@ -90,6 +92,7 @@
import com.mycelium.wallet.lt.api.SetNotificationMail;
import com.mycelium.wallet.modularisation.BCHHelper;
import com.mycelium.wallet.modularisation.GooglePlayModuleCollection;
import com.mycelium.wallet.modularisation.ModularisationVersionHelper;
import com.mycelium.wapi.wallet.WalletAccount;
import com.mycelium.wapi.wallet.single.SingleAddressAccount;
import com.squareup.otto.Subscribe;
Expand Down Expand Up @@ -517,64 +520,113 @@ public boolean onPreferenceChange(Preference preference, Object newValue) {

final PreferenceCategory modulesPrefs = (PreferenceCategory) findPreference("modulesPrefs");
if (!CommunicationManager.getInstance().getPairedModules().isEmpty()) {
for (final Module module : CommunicationManager.getInstance().getPairedModules()) {
final ButtonPreference preference = new ButtonPreference(this);
preference.setLayoutResource(R.layout.preference_layout);
preference.setTitle(Html.fromHtml(module.getName()));
preference.setKey("Module_" + module.getModulePackage());
updateModulePreference(preference, module, BCHHelper.getBCHSyncProgress(this));
preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(com.mycelium.modularizationtools.Constants.getSETTINGS());
intent.setPackage(module.getModulePackage());
intent.putExtra("callingPackage", getPackageName());
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e("SettingsActivity", "Something wrong with module", e);
}
return true;
}
});
preference.setButtonText(getString(R.string.uninstall));
preference.setButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri packageUri = Uri.parse("package:" + module.getModulePackage());
preference.setEnabled(false);
startActivityForResult(new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
.putExtra(Intent.EXTRA_RETURN_RESULT, true), REQUEST_CODE_UNINSTALL);
}
});
modulesPrefs.addPreference(preference);
}
processPairedModules(modulesPrefs);
} else {
Preference preference = new Preference(this);
preference.setTitle(R.string.no_connected_modules);
modulesPrefs.addPreference(preference);
}
processUnpairedModules(modulesPrefs);
}

private void processPairedModules(PreferenceCategory modulesPrefs) {
for (final Module module : CommunicationManager.getInstance().getPairedModules()) {
final ButtonPreference preference = createUninstallableModulePreference(module);
modulesPrefs.addPreference(preference);
}
}

private void processUnpairedModules(PreferenceCategory modulesPrefs) {
for (final Module module : GooglePlayModuleCollection.getModules(this).values()) {
if (!CommunicationManager.getInstance().getPairedModules().contains(module)) {
ButtonPreference installPreference = new ButtonPreference(this);
installPreference.setButtonText(getString(R.string.install));
installPreference.setButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent installIntent = new Intent(Intent.ACTION_VIEW);
installIntent.setData(Uri.parse("https://play.google.com/store/apps/details?id=" +
module.getModulePackage()));
startActivity(installIntent);
}
});
installPreference.setTitle(Html.fromHtml(module.getName()));
installPreference.setSummary(module.getDescription());
modulesPrefs.addPreference(installPreference);
if (Utils.isAppInstalled(this, module.getModulePackage()) && ModularisationVersionHelper.isUpdateRequired(this, module.getModulePackage())) {
TwoButtonsPreference preference = createUpdateRequiredPreference( module);
modulesPrefs.addPreference(preference);
preference.setEnabled(false, true, true);
} else if (Utils.isAppInstalled(this, module.getModulePackage())) {
final ButtonPreference preference = createUninstallableModulePreference(module);
preference.setEnabled(false);
preference.setButtonEnabled(true);
modulesPrefs.addPreference(preference);
} else {
ButtonPreference installPreference = new ButtonPreference(this);
installPreference.setButtonText(getString(R.string.install));
installPreference.setButtonClickListener(getInstallClickListener(module));
installPreference.setTitle(Html.fromHtml(module.getName()));
installPreference.setSummary(module.getDescription());
modulesPrefs.addPreference(installPreference);
}
}
}
}

@NonNull
private ButtonPreference createUninstallableModulePreference(final Module module) {
final ButtonPreference preference = new ButtonPreference(this);
preference.setLayoutResource(R.layout.preference_layout);
preference.setTitle(Html.fromHtml(module.getName()));
preference.setKey("Module_" + module.getModulePackage());
updateModulePreference(preference, module, BCHHelper.getBCHSyncProgress(this));
preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(com.mycelium.modularizationtools.Constants.getSETTINGS());
intent.setPackage(module.getModulePackage());
intent.putExtra("callingPackage", getPackageName());
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e("SettingsActivity", "Something wrong with module", e);
}
return true;
}
});
preference.setButtonText(getString(R.string.uninstall));
preference.setButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri packageUri = Uri.parse("package:" + module.getModulePackage());
preference.setEnabled(false);
startActivityForResult(new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
.putExtra(Intent.EXTRA_RETURN_RESULT, true), REQUEST_CODE_UNINSTALL);
}
});
return preference;
}

private TwoButtonsPreference createUpdateRequiredPreference(final Module module) {
final TwoButtonsPreference preference = new TwoButtonsPreference(this);
preference.setLayoutResource(R.layout.preference_layout);
preference.setTitle(Html.fromHtml(module.getName()));
preference.setKey("Module_" + module.getModulePackage());
updateModulePreference(preference, module, BCHHelper.getBCHSyncProgress(this));
preference.setButtonsText(getString(R.string.uninstall), getString(R.string.update));
preference.setTopButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri packageUri = Uri.parse("package:" + module.getModulePackage());
preference.setEnabled(false, false, false);
startActivityForResult(new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
.putExtra(Intent.EXTRA_RETURN_RESULT, true), REQUEST_CODE_UNINSTALL);
}
});
preference.setBottomButtonClickListener(getInstallClickListener(module));
return preference;
}

@NonNull
private View.OnClickListener getInstallClickListener(final Module module) {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent installIntent = new Intent(Intent.ACTION_VIEW);
installIntent.setData(Uri.parse("https://play.google.com/store/apps/details?id=" +
module.getModulePackage()));
startActivity(installIntent);
}
};
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_UNINSTALL) {
Expand All @@ -585,8 +637,13 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_CANCELED) {
pleaseWait.dismiss();
for (int index = 0; index < modulesPrefs.getPreferenceCount(); index++) {
ButtonPreference preferenceButton = (ButtonPreference) modulesPrefs.getPreference(index);
preferenceButton.setEnabled(true);
Preference preferenceButton = modulesPrefs.getPreference(index);
if (preferenceButton instanceof ButtonPreference) {
if (ModularisationVersionHelper.isUpdateRequired(this, preferenceButton.getKey().replace("Module_", "")))
preferenceButton.setEnabled(true);
} else if (preferenceButton instanceof TwoButtonsPreference) {
((TwoButtonsPreference) preferenceButton).setEnabled(false, true, true);
}
}
}
}
Expand All @@ -599,7 +656,7 @@ private void updateModulePreference(Preference preference, Module module, float
String syncStatus = progress == 100F ? getString(R.string.fully_synced)
: getString(R.string.sync_progress, format.format(progress));
preference.setSummary(Html.fromHtml(module.getDescription()
+ "<br/>"
+ "<br/><br/>"
+ addColorHtmlTag(syncStatus, "#00CC00")));

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.content.Context;
import android.preference.Preference;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.mycelium.wallet.R;
Expand All @@ -19,6 +18,7 @@ public class ButtonPreference extends Preference {

private View.OnClickListener buttonClickListener;
private String buttonText;
private boolean buttonEnabled = true;

public ButtonPreference(Context context) {
super(context);
Expand All @@ -30,12 +30,15 @@ protected void onBindView(final View view) {
super.onBindView(view);
ButterKnife.bind(this, view);
button.setText(buttonText);
setButtonEnabled(buttonEnabled);
}

@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
button.setEnabled(enabled);
if (button != null) {
button.setEnabled(enabled);
}
}

@OnClick(R.id.preference_button)
Expand All @@ -57,7 +60,10 @@ public void setButtonText(String text) {
}

public void setButtonEnabled(boolean enabled) {
button.setClickable(enabled);
button.setEnabled(enabled);
buttonEnabled = enabled;
if (button != null) {
button.setClickable(enabled);
button.setEnabled(enabled);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.mycelium.wallet.activity.view;


import android.content.Context;
import android.preference.Preference;
import android.view.View;
import android.widget.Button;

import com.mycelium.wallet.R;

import butterknife.BindView;
import butterknife.ButterKnife;

public class TwoButtonsPreference extends Preference {
@BindView(R.id.top_button)
Button topButton;

@BindView(R.id.bottom_button)
Button bottomButton;

private View.OnClickListener topButtonClickListener;
private View.OnClickListener bottomButtonClickListener;
private String topButtonText;
private String bottomButtonText;
private boolean topButtonEnabled;
private boolean bottomButtonEnabled;

public TwoButtonsPreference(Context context) {
super(context);
setWidgetLayoutResource(R.layout.two_button_preference);
}

@Override
protected void onBindView(final View view) {
super.onBindView(view);
ButterKnife.bind(this, view);
topButton.setText(topButtonText);
bottomButton.setText(bottomButtonText);
topButton.setEnabled(topButtonEnabled);
bottomButton.setEnabled(bottomButtonEnabled);
topButton.setOnClickListener(topButtonClickListener);
bottomButton.setOnClickListener(bottomButtonClickListener);
}

public void setTopButtonClickListener(View.OnClickListener buttonClickListener) {
topButtonClickListener = buttonClickListener;
}

public void setBottomButtonClickListener(View.OnClickListener buttonClickListener) {
bottomButtonClickListener = buttonClickListener;
}

public void setEnabled(boolean preferenceEnabled, boolean topButtonEnabled, boolean bottomButtonEnabled) {
this.topButtonEnabled = topButtonEnabled;
this.bottomButtonEnabled = bottomButtonEnabled;
this.setEnabled(preferenceEnabled);
if (topButton != null) {
topButton.setEnabled(topButtonEnabled);
}
if (bottomButton != null) {
bottomButton.setEnabled(bottomButtonEnabled);
}
}

public void setButtonsText(String topButtonText, String bottomButtonText) {
this.bottomButtonText = bottomButtonText;
this.topButtonText = topButtonText;

if (bottomButton != null) {
bottomButton.setText(bottomButtonText);
}

if (topButton != null) {
topButton.setText(topButtonText);
}
}
}
Loading

0 comments on commit df8b1b5

Please sign in to comment.