/* * Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.davdroid.ui; import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.LoaderManager; import android.support.v4.content.AsyncTaskLoader; import android.support.v4.content.Loader; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.Html; import android.text.Spanned; import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.time.DateFormatUtils; import java.io.IOException; import java.io.InputStream; import java.util.logging.Level; import at.bitfire.davdroid.App; import at.bitfire.davdroid.BuildConfig; import at.bitfire.davdroid.R; import ezvcard.Ezvcard; import lombok.Cleanup; import lombok.RequiredArgsConstructor; public class AboutActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); setSupportActionBar((Toolbar)findViewById(R.id.toolbar)); getSupportActionBar().setDisplayHomeAsUpEnabled(true); ViewPager viewPager = (ViewPager)findViewById(R.id.viewpager); viewPager.setAdapter(new TabsAdapter(getSupportFragmentManager())); TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); } @RequiredArgsConstructor private static class ComponentInfo { final String title, version, website, copyright; final int licenseInfo; final String licenseTextFile; } private final static ComponentInfo components[] = { new ComponentInfo( "DAVdroid", BuildConfig.VERSION_NAME, "https://davdroid.bitfire.at", DateFormatUtils.format(BuildConfig.buildTime, "yyyy") + " Ricki Hirner, Bernhard Stockmann (bitfire web engineering)", R.string.about_license_info_no_warranty, "gpl-3.0-standalone.html" ), new ComponentInfo( "AmbilWarna", null, "https://github.com/yukuku/ambilwarna", "Yuku", R.string.about_license_info_no_warranty, "apache2.html" ), new ComponentInfo( "Apache Commons", null, "http://commons.apache.org/", "Apache Software Foundation", R.string.about_license_info_no_warranty, "apache2.html" ), new ComponentInfo( "dnsjava", null, "http://dnsjava.org/", "Brian Wellington", R.string.about_license_info_no_warranty, "bsd.html" ), new ComponentInfo( "ez-vcard", Ezvcard.VERSION, "https://github.com/mangstadt/ez-vcard", "Michael Angstadt", R.string.about_license_info_no_warranty, "bsd.html" ), new ComponentInfo( "ical4j", "2.x", "https://ical4j.github.io/", "Ben Fortuna", R.string.about_license_info_no_warranty, "bsd-3clause.html" ), new ComponentInfo( "OkHttp", null, "https://square.github.io/okhttp/", "Square, Inc.", R.string.about_license_info_no_warranty, "apache2.html" ), new ComponentInfo( "Project Lombok", null, "https://projectlombok.org/", "The Project Lombok Authors", R.string.about_license_info_no_warranty, "mit.html" ) }; private static class TabsAdapter extends FragmentPagerAdapter { public TabsAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return components.length; } @Override public CharSequence getPageTitle(int position) { return components[position].title; } @Override public Fragment getItem(int position) { return ComponentFragment.instantiate(position); } } public static class ComponentFragment extends Fragment implements LoaderManager.LoaderCallbacks { private static final String KEY_POSITION = "position", KEY_FILE_NAME = "fileName"; public static ComponentFragment instantiate(int position) { ComponentFragment frag = new ComponentFragment(); Bundle args = new Bundle(1); args.putInt(KEY_POSITION, position); frag.setArguments(args); return frag; } @Nullable @Override @SuppressLint("SetTextI18n") public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ComponentInfo info = components[getArguments().getInt(KEY_POSITION)]; View v = inflater.inflate(R.layout.about_component, container, false); TextView tv = (TextView)v.findViewById(R.id.title); tv.setText(info.title + (info.version != null ? (" " + info.version) : "")); tv = (TextView)v.findViewById(R.id.website); tv.setAutoLinkMask(Linkify.WEB_URLS); tv.setText(info.website); tv = (TextView)v.findViewById(R.id.copyright); tv.setText("© " + info.copyright); tv = (TextView)v.findViewById(R.id.license_info); tv.setText(info.licenseInfo); // load and format license text Bundle args = new Bundle(1); args.putString(KEY_FILE_NAME, info.licenseTextFile); getLoaderManager().initLoader(0, args, this); return v; } @Override public Loader onCreateLoader(int id, Bundle args) { return new LicenseLoader(getContext(), args.getString(KEY_FILE_NAME)); } @Override public void onLoadFinished(Loader loader, Spanned license) { if (getView() != null) { TextView tv = (TextView)getView().findViewById(R.id.license_text); if (tv != null) { tv.setAutoLinkMask(Linkify.EMAIL_ADDRESSES | Linkify.WEB_URLS); tv.setText(license); } } } @Override public void onLoaderReset(Loader loader) { } } private static class LicenseLoader extends AsyncTaskLoader { final String fileName; Spanned content; LicenseLoader(Context context, String fileName) { super(context); this.fileName = fileName; } @Override protected void onStartLoading() { if (content == null) forceLoad(); else deliverResult(content); } @Override public Spanned loadInBackground() { App.log.fine("Loading license file " + fileName); try { @Cleanup InputStream is = getContext().getResources().getAssets().open(fileName); byte[] raw = IOUtils.toByteArray(is); return content = Html.fromHtml(new String(raw)); } catch (IOException e) { App.log.log(Level.SEVERE, "Couldn't read license file", e); return null; } } } }