org.strongswan.android.ui.TrustedCertificateListFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.strongswan.android.ui.TrustedCertificateListFragment.java

Source

/*
 * Copyright (C) 2012-2015 Tobias Brunner
 * Hochschule fuer Technik Rapperswil
 *
 * 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 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * 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.
 */

package org.strongswan.android.ui;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;

import org.strongswan.android.R;
import org.strongswan.android.logic.TrustedCertificateManager;
import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource;
import org.strongswan.android.security.TrustedCertificateEntry;
import org.strongswan.android.ui.adapter.TrustedCertificateAdapter;

import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map.Entry;
import java.util.Observable;
import java.util.Observer;

public class TrustedCertificateListFragment extends ListFragment
        implements LoaderCallbacks<List<TrustedCertificateEntry>>, OnQueryTextListener {
    public static final String EXTRA_CERTIFICATE_SOURCE = "certificate_source";
    private OnTrustedCertificateSelectedListener mListener;
    private TrustedCertificateAdapter mAdapter;
    private TrustedCertificateSource mSource = TrustedCertificateSource.SYSTEM;

    /**
     * The activity containing this fragment should implement this interface
     */
    public interface OnTrustedCertificateSelectedListener {
        public void onTrustedCertificateSelected(TrustedCertificateEntry selected);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);

        setEmptyText(getString(R.string.no_certificates));

        mAdapter = new TrustedCertificateAdapter(getActivity());
        setListAdapter(mAdapter);

        setListShown(false);

        Bundle arguments = getArguments();
        if (arguments != null) {
            mSource = (TrustedCertificateSource) arguments.getSerializable(EXTRA_CERTIFICATE_SOURCE);
        }

        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if (context instanceof OnTrustedCertificateSelectedListener) {
            mListener = (OnTrustedCertificateSelectedListener) context;
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        MenuItem item = menu.add(R.string.search);
        item.setIcon(android.R.drawable.ic_menu_search);
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

        SearchView sv = new SearchView(getActivity());
        sv.setOnQueryTextListener(this);
        item.setActionView(sv);
    }

    @Override
    public boolean onQueryTextSubmit(String query) { /* already handled when the text changes */
        return true;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        String search = TextUtils.isEmpty(newText) ? null : newText;
        mAdapter.getFilter().filter(search);
        return true;
    }

    @Override
    public Loader<List<TrustedCertificateEntry>> onCreateLoader(int id,
            Bundle args) { /* we don't need the id as we have only one loader */
        return new CertificateListLoader(getActivity(), mSource);
    }

    @Override
    public void onLoadFinished(Loader<List<TrustedCertificateEntry>> loader, List<TrustedCertificateEntry> data) {
        mAdapter.setData(data);

        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
    }

    @Override
    public void onLoaderReset(Loader<List<TrustedCertificateEntry>> loader) {
        mAdapter.setData(null);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        if (mListener != null) {
            mListener.onTrustedCertificateSelected(mAdapter.getItem(position));
        }
    }

    public static class CertificateListLoader extends AsyncTaskLoader<List<TrustedCertificateEntry>> {
        private List<TrustedCertificateEntry> mData;
        private final TrustedCertificateSource mSource;
        private TrustedCertificateManagerObserver mObserver;

        public CertificateListLoader(Context context, TrustedCertificateSource source) {
            super(context);
            mSource = source;
        }

        @Override
        public List<TrustedCertificateEntry> loadInBackground() {
            TrustedCertificateManager certman = TrustedCertificateManager.getInstance().load();
            Hashtable<String, X509Certificate> certificates = certman.getCACertificates(mSource);
            List<TrustedCertificateEntry> selected;

            selected = new ArrayList<TrustedCertificateEntry>();
            for (Entry<String, X509Certificate> entry : certificates.entrySet()) {
                selected.add(new TrustedCertificateEntry(entry.getKey(), entry.getValue()));
            }
            Collections.sort(selected);
            return selected;
        }

        @Override
        protected void onStartLoading() {
            if (mData != null) { /* if we have data ready, deliver it directly */
                deliverResult(mData);
            }
            if (takeContentChanged() || mData == null) {
                forceLoad();
            }
        }

        @Override
        public void deliverResult(List<TrustedCertificateEntry> data) {
            if (isReset()) {
                return;
            }
            mData = data;
            if (isStarted()) { /* if it is started we deliver the data directly,
                               * otherwise this is handled in onStartLoading */
                if (mObserver == null) {
                    mObserver = new TrustedCertificateManagerObserver();
                    TrustedCertificateManager.getInstance().addObserver(mObserver);
                }
                super.deliverResult(data);
            }
        }

        @Override
        protected void onReset() {
            if (mObserver != null) {
                TrustedCertificateManager.getInstance().deleteObserver(mObserver);
                mObserver = null;
            }
            mData = null;
            super.onReset();
        }

        @Override
        protected void onAbandon() {
            if (mObserver != null) {
                TrustedCertificateManager.getInstance().deleteObserver(mObserver);
                mObserver = null;
            }
        }

        private class TrustedCertificateManagerObserver implements Observer {
            private ForceLoadContentObserver mContentObserver = new ForceLoadContentObserver();

            @Override
            public void update(Observable observable, Object data) {
                mContentObserver.onChange(false);
            }
        }
    }
}