im.neon.fragments.VectorUnknownDevicesFragment.java Source code

Java tutorial

Introduction

Here is the source code for im.neon.fragments.VectorUnknownDevicesFragment.java

Source

/*
 * Copyright 2017 Vector Creations Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package im.neon.fragments;

import android.app.AlertDialog;
import android.app.Dialog;
import android.support.v4.app.DialogFragment;

import android.content.DialogInterface;
import android.os.Bundle;

import org.matrix.androidsdk.crypto.data.MXUsersDevicesMap;

import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;

import android.widget.ExpandableListView;

import org.matrix.androidsdk.MXSession;
import org.matrix.androidsdk.crypto.data.MXDeviceInfo;
import org.matrix.androidsdk.rest.callback.ApiCallback;
import org.matrix.androidsdk.rest.model.MatrixError;

import java.util.ArrayList;
import java.util.List;

import im.neon.Matrix;
import im.neon.R;
import im.neon.activity.CommonActivityUtils;
import im.neon.adapters.VectorUnknownDevicesAdapter;

public class VectorUnknownDevicesFragment extends DialogFragment {
    private static final String ARG_SESSION_ID = "VectorUnknownDevicesFragment.ARG_SESSION_ID";

    /**
     * Define the SendAnyway button listener
     */
    public interface IUnknownDevicesSendAnywayListener {
        // the "Send Anyway" button has been tapped
        void onSendAnyway();
    }

    private static MXUsersDevicesMap<MXDeviceInfo> mUnknownDevicesMap = null;

    private static IUnknownDevicesSendAnywayListener mListener = null;

    public static VectorUnknownDevicesFragment newInstance(String sessionId,
            MXUsersDevicesMap<MXDeviceInfo> unknownDevicesMap, IUnknownDevicesSendAnywayListener listener) {
        VectorUnknownDevicesFragment f = new VectorUnknownDevicesFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putString(ARG_SESSION_ID, sessionId);
        // cannot serialize unknownDevicesMap if it is too large
        mUnknownDevicesMap = unknownDevicesMap;
        // idem for the listener
        mListener = listener;
        f.setArguments(args);
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSession = Matrix.getMXSession(getActivity(), getArguments().getString(ARG_SESSION_ID));
    }

    // current session
    private MXSession mSession;
    // list view
    private ExpandableListView mExpandableListView;
    // Devices list
    private List<Pair<String, List<MXDeviceInfo>>> mDevicesList;
    // Tells if the dialog has been closed by tapping on the "Send anyway" button
    private boolean mIsSendAnywayTapped = false;

    /**
     * Convert a MXUsersDevicesMap to a list of List
     *
     * @return the list of list
     */
    private static List<Pair<String, List<MXDeviceInfo>>> getDevicesList() {
        List<Pair<String, List<MXDeviceInfo>>> res = new ArrayList<>();

        List<String> userIds = mUnknownDevicesMap.getUserIds();

        for (String userId : userIds) {
            List<MXDeviceInfo> deviceInfos = new ArrayList<>();
            List<String> deviceIds = mUnknownDevicesMap.getUserDeviceIds(userId);

            for (String deviceId : deviceIds) {
                deviceInfos.add(mUnknownDevicesMap.getObject(deviceId, userId));
            }
            res.add(new Pair<>(userId, deviceInfos));
        }

        return res;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        View v = inflater.inflate(R.layout.dialog_unknown_devices, null);
        mExpandableListView = (ExpandableListView) v.findViewById(R.id.unknown_devices_list_view);

        mDevicesList = getDevicesList();
        final VectorUnknownDevicesAdapter adapter = new VectorUnknownDevicesAdapter(getContext(), mDevicesList);

        adapter.setListener(new VectorUnknownDevicesAdapter.IVerificationAdapterListener() {
            /**
             * Refresh the adapter
             */
            private void refresh() {
                adapter.notifyDataSetChanged();
            }

            /**
             * Common callback
             */
            final ApiCallback<Void> mCallback = new ApiCallback<Void>() {
                @Override
                public void onSuccess(Void info) {
                    refresh();
                }

                @Override
                public void onNetworkError(Exception e) {
                    refresh();
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    refresh();
                }

                @Override
                public void onUnexpectedError(Exception e) {
                    refresh();
                }
            };

            @Override
            public void OnVerifyDeviceClick(MXDeviceInfo aDeviceInfo) {
                switch (aDeviceInfo.mVerified) {
                case MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED:
                    mSession.getCrypto().setDeviceVerification(MXDeviceInfo.DEVICE_VERIFICATION_UNVERIFIED,
                            aDeviceInfo.deviceId, aDeviceInfo.userId, mCallback);
                    break;

                case MXDeviceInfo.DEVICE_VERIFICATION_UNVERIFIED:
                default: // Blocked
                    CommonActivityUtils.displayDeviceVerificationDialog(aDeviceInfo, aDeviceInfo.userId, mSession,
                            getActivity(), mCallback);
                    break;
                }
            }

            @Override
            public void OnBlockDeviceClick(MXDeviceInfo aDeviceInfo) {
                if (aDeviceInfo.mVerified == MXDeviceInfo.DEVICE_VERIFICATION_BLOCKED) {
                    mSession.getCrypto().setDeviceVerification(MXDeviceInfo.DEVICE_VERIFICATION_UNVERIFIED,
                            aDeviceInfo.deviceId, aDeviceInfo.userId, mCallback);
                } else {
                    mSession.getCrypto().setDeviceVerification(MXDeviceInfo.DEVICE_VERIFICATION_BLOCKED,
                            aDeviceInfo.deviceId, aDeviceInfo.userId, mCallback);
                }
                refresh();
            }
        });

        mExpandableListView.addHeaderView(inflater.inflate(R.layout.dialog_unknown_devices_header, null));
        mExpandableListView.setGroupIndicator(null);
        mExpandableListView.setAdapter(adapter);
        // expand each group by default
        mExpandableListView.post(new Runnable() {
            @Override
            public void run() {
                int count = adapter.getGroupCount();

                for (int i = 0; i < count; i++) {
                    mExpandableListView.expandGroup(i);
                }
            }
        });

        builder.setView(v).setTitle(R.string.unknown_devices_alert_title);

        if (null != mListener) {
            // Add action buttons
            builder.setPositiveButton(R.string.send_anyway, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int id) {
                    mIsSendAnywayTapped = true;
                }
            });
            builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int id) {
                    // nothing : everything will be done on onDismiss()
                }
            });

        } else {
            // Add action buttons
            builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int id) {
                    // nothing : everything will be done on onDismiss()
                }
            });
        }

        return builder.create();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        // whatever the user clicks
        // we assume that the devices are now known because they have been displayed.
        setDevicesKnown(mDevicesList);
    }

    /**
     * Update the devices verifications status.
     *
     * @param devicesList the devices list.
     */
    private void setDevicesKnown(List<Pair<String, List<MXDeviceInfo>>> devicesList) {
        if (null != mUnknownDevicesMap) {
            List<MXDeviceInfo> dis = new ArrayList<>();

            for (Pair<String, List<MXDeviceInfo>> item : devicesList) {
                dis.addAll(item.second);
            }

            mSession.getCrypto().setDevicesKnown(dis, new ApiCallback<Void>() {
                // common method
                private void onDone() {
                    if (mIsSendAnywayTapped && (null != mListener)) {
                        mListener.onSendAnyway();
                    }
                    mUnknownDevicesMap = null;
                    mListener = null;
                }

                @Override
                public void onSuccess(Void info) {
                    onDone();
                }

                @Override
                public void onNetworkError(Exception e) {
                    onDone();
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    onDone();
                }

                @Override
                public void onUnexpectedError(Exception e) {
                    onDone();
                }
            });
        }
    }
}