/** * 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.participants; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.TextView; 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.User; import com.waz.api.Verification; import com.waz.zclient.BaseActivity; import com.waz.zclient.OnBackPressedListener; import com.waz.zclient.R; import com.waz.zclient.controllers.accentcolor.AccentColorObserver; import com.waz.zclient.controllers.tracking.events.otr.UnverifiedOtherOtrClientEvent; import com.waz.zclient.controllers.tracking.events.otr.VerifiedOtherOtrClientEvent; import com.waz.zclient.pages.BaseFragment; import com.waz.zclient.pages.main.profile.ZetaPreferencesActivity; import com.waz.zclient.tracking.GlobalTrackingController; import com.waz.zclient.ui.utils.TextViewUtils; import com.waz.zclient.ui.views.e2ee.OtrSwitch; import com.waz.zclient.utils.LayoutSpec; import com.waz.zclient.utils.ViewUtils; import com.waz.zclient.utils.OtrUtils; import com.waz.zclient.views.LoadingIndicatorView; import com.waz.zclient.views.e2ee.FingerprintView; import java.util.Locale; public class SingleOtrClientFragment extends BaseFragment<SingleOtrClientFragment.Container> implements View.OnClickListener, OnBackPressedListener, UpdateListener, AccentColorObserver, CompoundButton.OnCheckedChangeListener { public static final String TAG = SingleOtrClientFragment.class.getName(); private static final String ARG_OTR_CLIENT = "ARG_OTR_CLIENT"; private static final String ARG_USER = "ARG_USER"; private TextView backButton; private TextView closeButton; private TextView myFingerprintButton; private TextView resetSessionButton; private TextView howToLinkButton; private OtrSwitch verifySwitch; private TextView myDevicesButton; private TextView descriptionTextview; private TextView typeTextView; private FingerprintView idTextView; private FingerprintView fingerprintView; private OtrClient otrClient; private UiSignal<OtrClient> otrClientUiSignal; private Subscription otrClientSubscription; private User user; private boolean isSelf; public static SingleOtrClientFragment newInstance() { return new SingleOtrClientFragment(); } public static SingleOtrClientFragment newInstance(OtrClient otrClient, User user) { SingleOtrClientFragment fragment = new SingleOtrClientFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_OTR_CLIENT, otrClient); args.putParcelable(ARG_USER, user); fragment.setArguments(args); return fragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_single_otr_client, viewGroup, false); backButton = ViewUtils.getView(view, R.id.gtv__single_otr_client__back); closeButton = ViewUtils.getView(view, R.id.gtv__single_otr_client__close); myFingerprintButton = ViewUtils.getView(view, R.id.ttv__single_otr_client__my_fingerprint); resetSessionButton = ViewUtils.getView(view, R.id.ttv__single_otr_client__reset); howToLinkButton = ViewUtils.getView(view, R.id.ttv__single_otr_client__how_to_link); verifySwitch = ViewUtils.getView(view, R.id.os__single_otr_client__verify); myDevicesButton = ViewUtils.getView(view, R.id.ttv__single_otr_client__my_devices); descriptionTextview = ViewUtils.getView(view, R.id.ttv__single_otr_client__description); typeTextView = ViewUtils.getView(view, R.id.ttv__single_otr_client__type); idTextView = ViewUtils.getView(view, R.id.ttv__single_otr_client__id); if (otrClient != null) { idTextView.setOtrClient(otrClient, FingerprintView.DisplayType.DEVICE_ID); } fingerprintView = ViewUtils.getView(view, R.id.ttv__single_otr_client__fingerprint); if (otrClient != null) { fingerprintView.setOtrClient(otrClient, FingerprintView.DisplayType.FINGERPRINT); } if (LayoutSpec.isTablet(getActivity())) { view.setBackgroundResource(R.drawable.rounded_corner_background_white); } view.setOnClickListener(this); updated(); return view; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() == null || getArguments().getParcelable(ARG_USER) == null) { isSelf = true; } else { otrClient = getArguments().getParcelable(ARG_OTR_CLIENT); user = getArguments().getParcelable(ARG_USER); isSelf = false; } } @Override public void onStart() { super.onStart(); getControllerFactory().getAccentColorController().addAccentColorObserver(this); howToLinkButton.setText( TextViewUtils.getHighlightText(getActivity(), getActivity().getString(R.string.otr__participant__single_device__how_to_link), getControllerFactory().getAccentColorController().getColor(), false)); if (isSelf) { user = getStoreFactory().getProfileStore().getSelfUser(); otrClientUiSignal = getStoreFactory().getZMessagingApiStore().getApi().getSelf().getOtrClient(); subscribeToOtrClient(); resetSessionButton.setVisibility(View.GONE); howToLinkButton.setVisibility(View.GONE); } else { otrClient.addUpdateListener(this); resetSessionButton.setVisibility(View.VISIBLE); howToLinkButton.setVisibility(View.VISIBLE); } user.addUpdateListener(this); } @Override public void onResume() { super.onResume(); backButton.setOnClickListener(this); closeButton.setOnClickListener(this); myFingerprintButton.setOnClickListener(this); resetSessionButton.setOnClickListener(this); verifySwitch.setOnCheckedListener(this); myDevicesButton.setOnClickListener(this); fingerprintView.setOnClickListener(this); howToLinkButton.setOnClickListener(this); } @Override public void onPause() { super.onPause(); backButton.setOnClickListener(null); closeButton.setOnClickListener(null); myFingerprintButton.setOnClickListener(null); resetSessionButton.setOnClickListener(null); verifySwitch.setOnCheckedListener(null); myDevicesButton.setOnClickListener(null); fingerprintView.setOnClickListener(null); howToLinkButton.setOnClickListener(null); } @Override public void onStop() { if (otrClient != null) { otrClient.removeUpdateListener(this); } if (user != null) { user.removeUpdateListener(this); } if (otrClientSubscription != null) { otrClientSubscription.cancel(); otrClientSubscription = null; } if (otrClientUiSignal != null) { otrClientUiSignal = null; } getControllerFactory().getAccentColorController().removeAccentColorObserver(this); super.onStop(); } @Override public void onDestroyView() { backButton = null; closeButton = null; myFingerprintButton = null; resetSessionButton = null; verifySwitch = null; myDevicesButton = null; descriptionTextview = null; typeTextView = null; idTextView = null; fingerprintView = null; super.onDestroyView(); } @Override public void onDestroy() { super.onDestroy(); otrClient = null; user = null; } @Override public void onClick(View view) { if (view == null) { return; } switch (view.getId()) { case R.id.gtv__single_otr_client__back: case R.id.gtv__single_otr_client__close: getControllerFactory().getConversationScreenController().hideOtrClient(); break; case R.id.ttv__single_otr_client__my_fingerprint: getControllerFactory().getConversationScreenController().showCurrentOtrClient(); break; case R.id.ttv__single_otr_client__reset: resetSession(); break; case R.id.ttv__single_otr_client__fingerprint: ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText(getString(R.string.pref_dev_avs_last_call_session_id_title), fingerprintView.getText().toString()); clipboard.setPrimaryClip(clip); break; case R.id.ttv__single_otr_client__my_devices: startActivity(ZetaPreferencesActivity.getOtrDevicesPreferencesIntent(getActivity())); break; case R.id.ttv__single_otr_client__how_to_link: getContainer().onOpenUrl(getString(R.string.url_otr_learn_how)); break; } } private void subscribeToOtrClient() { otrClientSubscription = otrClientUiSignal.subscribe(new Subscriber<OtrClient>() { @Override public void next(OtrClient otrClient) { SingleOtrClientFragment.this.otrClient = otrClient; idTextView.setOtrClient(otrClient, FingerprintView.DisplayType.DEVICE_ID); fingerprintView.setOtrClient(otrClient, FingerprintView.DisplayType.FINGERPRINT); updated(); } }); } private void resetSession() { getContainer().getLoadingViewIndicator().show(LoadingIndicatorView.SPINNER_WITH_DIMMED_BACKGROUND, getControllerFactory().getThemeController().isDarkTheme()); resetSessionButton.setEnabled(false); otrClient.resetSession(new OtrClient.ResetCallback() { @Override public void onSessionReset(OtrClient otrClient) { resetSessionButton.setEnabled(true); getContainer().getLoadingViewIndicator().hide(); ViewUtils.showAlertDialog(getActivity(), R.string.empty_string, R.string.otr__reset_session__message_ok, R.string.otr__reset_session__button_ok, null, true); } @Override public void onSessionResetFailed(int i, String s, String s1) { resetSessionButton.setEnabled(true); getContainer().getLoadingViewIndicator().hide(); 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 void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { otrClient.setVerified(isChecked); trackVerified(isChecked); } // For Otr Client and User updates @Override public void updated() { updateViewVisibility(); if (isSelf) { descriptionTextview.setText(getString(R.string.otr__participant__my_device__description)); } else { descriptionTextview.setText(getString(R.string.otr__participant__single_device__description, user.getDisplayName())); verifySwitch.setChecked(otrClient != null && otrClient.getVerified() == Verification.VERIFIED); } typeTextView.setText(OtrUtils.getDeviceClassName(getActivity(), otrClient).toUpperCase(Locale.getDefault())); } private void updateViewVisibility() { if (isSelf) { verifySwitch.setVisibility(View.GONE); backButton.setVisibility(View.GONE); myFingerprintButton.setVisibility(View.GONE); closeButton.setVisibility(View.VISIBLE); myDevicesButton.setVisibility(View.VISIBLE); howToLinkButton.setVisibility(View.GONE); } else { verifySwitch.setVisibility(View.VISIBLE); backButton.setVisibility(View.VISIBLE); myFingerprintButton.setVisibility(View.VISIBLE); closeButton.setVisibility(View.GONE); myDevicesButton.setVisibility(View.GONE); howToLinkButton.setVisibility(View.VISIBLE); } } @Override public boolean onBackPressed() { return false; } @Override public void onAccentColorHasChanged(Object sender, int color) { myFingerprintButton.setTextColor(color); resetSessionButton.setTextColor(color); myDevicesButton.setTextColor(color); howToLinkButton.setText( TextViewUtils.getHighlightText(getActivity(), getActivity().getString(R.string.otr__participant__single_device__how_to_link), color, false)); } private void trackVerified(boolean verified) { if (getControllerFactory() == null || getControllerFactory().isTornDown()) { return; } if (verified) { ((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new VerifiedOtherOtrClientEvent()); } else { ((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new UnverifiedOtherOtrClientEvent()); } } public interface Container { LoadingIndicatorView getLoadingViewIndicator(); void onOpenUrl(String url); } }