/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.waz.zclient.pages.main.profile.preferences;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.widget.Toast;
import com.waz.api.Fingerprint;
import com.waz.api.NetworkMode;
import com.waz.api.OtrClient;
import com.waz.api.Subscriber;
import com.waz.api.Subscription;
import com.waz.api.UiSignal;
import com.waz.api.UpdateListener;
import com.waz.api.Verification;
import com.waz.zclient.BaseActivity;
import com.waz.zclient.R;
import com.waz.zclient.controllers.tracking.events.otr.RemovedOwnOtrClientEvent;
import com.waz.zclient.controllers.tracking.events.otr.UnverifiedOwnOtrClientEvent;
import com.waz.zclient.controllers.tracking.events.otr.VerifiedOwnOtrClientEvent;
import com.waz.zclient.core.stores.network.NetworkAction;
import com.waz.zclient.pages.BasePreferenceFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.RemoveDevicePreferenceDialogFragment;
import com.waz.zclient.tracking.GlobalTrackingController;
import com.waz.zclient.utils.ViewUtils;
import net.xpece.android.support.preference.PreferenceCategory;
import net.xpece.android.support.preference.SwitchPreference;
import timber.log.Timber;
public class DeviceDetailPreferences extends BasePreferenceFragment<DeviceDetailPreferences.Container>
implements RemoveDevicePreferenceDialogFragment.Container {
public static final String TAG = DeviceDetailPreferences.class.getName();
public static final String PREFS_OTR_CLIENT = "PREFS_OTR_CLIENT";
public static final String PREFS_CURRENT_DEVICE = "PREFS_CURRENT_DEVICE";
private OtrClient otrClient;
private final UpdateListener otrClientUpdateListener = new UpdateListener() {
@Override
public void updated() {
updateOtrClientDetails();
}
};
private Subscription fingerprintSubscription;
private UiSignal<Fingerprint> fingerprint;
private boolean currentDevice;
public static DeviceDetailPreferences newInstance(String rootKey, Bundle extras) {
DeviceDetailPreferences f = new DeviceDetailPreferences();
Bundle args = new Bundle(extras);
args.putString(ARG_PREFERENCE_ROOT, rootKey);
f.setArguments(args);
return f;
}
@Override
public void onCreatePreferences2(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences2(savedInstanceState, rootKey);
addPreferencesFromResource(R.xml.preferences_device_details);
currentDevice = getArguments().getBoolean(PREFS_CURRENT_DEVICE, false);
otrClient = getArguments().getParcelable(PREFS_OTR_CLIENT);
otrClient.addUpdateListener(otrClientUpdateListener);
updateOtrClientDetails();
}
@Override
public void onStop() {
if (fingerprintSubscription != null) {
fingerprintSubscription.cancel();
fingerprintSubscription = null;
}
fingerprint = null;
if (otrClient != null) {
otrClient.removeUpdateListener(otrClientUpdateListener);
otrClient = null;
}
super.onStop();
}
private void updateOtrClientDetails() {
// Name
Preference preference = findPreference(getString(R.string.pref_device_details_device_key));
preference.setTitle(DevicesPreferencesUtil.getTitle(getActivity(), otrClient));
preference.setSummary(DevicesPreferencesUtil.getSummary(getActivity(), otrClient, true));
// Fingerprint
final FingerprintPreference fingerPrintPreference = (FingerprintPreference) findPreference(getString(R.string.pref_device_details_fingerprint_key));
if (fingerprint == null) {
fingerprint = otrClient.getFingerprint();
fingerprintSubscription = fingerprint.subscribe(new Subscriber<Fingerprint>() {
@Override
public void next(Fingerprint fingerprint) {
fingerPrintPreference.setFingerprint(fingerprint);
}
});
}
//Trust
final SwitchPreference verifySwitchPreference = (SwitchPreference) findPreference(getString(R.string.pref_device_details_trust_key));
if (currentDevice) {
PreferenceCategory group = (PreferenceCategory) findPreference(getString(R.string.pref_device_details_fingerprint_category_key));
group.removePreference(verifySwitchPreference);
} else {
verifySwitchPreference.setChecked(otrClient.getVerified() == Verification.VERIFIED);
// Note: Using OnPreferenceClickListener as it was some issues with getting
// OnPreferenceChangeListener to work.
verifySwitchPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
boolean newVerifiredValue = otrClient.getVerified() != Verification.VERIFIED;
otrClient.setVerified(newVerifiredValue);
verifySwitchPreference.setChecked(newVerifiredValue);
trackVerified(newVerifiredValue);
return true;
}
});
}
// Remove
if (currentDevice) {
Preference actionsPreference = findPreference(getString(R.string.pref_device_details_actions_category_key));
PreferenceScreen screen = (PreferenceScreen) findPreference(getString(R.string.pref_device_details_screen_key));
screen.removePreference(actionsPreference);
} else {
Preference resetSessionPreference = findPreference(getString(R.string.pref_device_details_reset_session_key));
resetSessionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
resetSession();
return true;
}
});
preference = findPreference(getString(R.string.pref_device_details_remove_key));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
getStoreFactory().getNetworkStore().doIfHasInternetOrNotifyUser(new NetworkAction() {
@Override
public void execute(NetworkMode networkMode) {
if (otrClient == null) {
return;
}
if (getControllerFactory().getPasswordController().hasPassword()) {
deleteCurrentDevice();
} else {
showRemoveDeviceDialog();
}
}
@Override
public void onNoNetwork() {
ViewUtils.showAlertDialog(DeviceDetailPreferences.this.getActivity(),
R.string.otr__remove_device__no_internet__title,
R.string.otr__remove_device__no_internet__message,
R.string.otr__remove_device__no_internet__button,
null,
true);
}
});
return true;
}
});
}
}
private void deleteCurrentDevice() {
otrClient.delete(getControllerFactory().getPasswordController().getPassword(),
new OtrClient.DeleteCallback() {
@Override
public void onClientDeleted(OtrClient otrClient) {
if (getActivity() == null ||
getControllerFactory() == null ||
getControllerFactory().isTornDown()) {
return;
}
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new RemovedOwnOtrClientEvent());
onCurrentDeviceDeleted();
}
@Override
public void onDeleteFailed(String error) {
Timber.e("Remove client failed: %s", error);
if (getActivity() == null ||
getControllerFactory() == null ||
getControllerFactory().isTornDown() ||
otrClient == null) {
return;
}
showRemoveDeviceDialog();
}
});
}
private void showRemoveDeviceDialog() {
getChildFragmentManager().beginTransaction()
.add(RemoveDevicePreferenceDialogFragment.newInstance(otrClient.getModel()),
RemoveDevicePreferenceDialogFragment.TAG)
.addToBackStack(RemoveDevicePreferenceDialogFragment.TAG)
.commit();
}
private void trackVerified(boolean verified) {
if (getControllerFactory() == null || getControllerFactory().isTornDown()) {
return;
}
if (verified) {
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new VerifiedOwnOtrClientEvent());
} else {
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new UnverifiedOwnOtrClientEvent());
}
}
private void resetSession() {
otrClient.resetSession(new OtrClient.ResetCallback() {
@Override
public void onSessionReset(OtrClient otrClient) {
Toast.makeText(getActivity(), R.string.otr__reset_session__message_ok, Toast.LENGTH_SHORT).show();
}
@Override
public void onSessionResetFailed(int i, String s, String s1) {
ViewUtils.showAlertDialog(getActivity(),
R.string.empty_string,
R.string.otr__reset_session__message_fail,
R.string.otr__reset_session__button_ok,
R.string.otr__reset_session__button_fail, null, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
resetSession();
}
});
}
});
}
@Override
public OtrClient getOtrClient() {
return otrClient;
}
@Override
public void onCurrentDeviceDeleted() {
getActivity().onBackPressed();
}
public interface Container {
}
}