org.rm3l.ddwrt.fragments.status.StatusWirelessFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.rm3l.ddwrt.fragments.status.StatusWirelessFragment.java

Source

/*
 * DD-WRT Companion is a mobile app that lets you connect to,
 * monitor and manage your DD-WRT routers on the go.
 *
 * Copyright (C) 2014  Armel Soro
 *
 * 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/>.
 *
 * Contact Info: Armel Soro <apps+ddwrt@rm3l.org>
 */

package org.rm3l.ddwrt.fragments.status;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.rm3l.ddwrt.R;
import org.rm3l.ddwrt.fragments.DDWRTBaseFragment;
import org.rm3l.ddwrt.resources.conn.NVRAMInfo;
import org.rm3l.ddwrt.tiles.DDWRTTile;
import org.rm3l.ddwrt.tiles.status.wireless.WirelessClientsTile;
import org.rm3l.ddwrt.tiles.status.wireless.WirelessIfaceTile;
import org.rm3l.ddwrt.tiles.status.wireless.WirelessIfacesTile;
import org.rm3l.ddwrt.utils.DDWRTCompanionConstants;
import org.rm3l.ddwrt.utils.SSHUtils;
import org.rm3l.ddwrt.utils.Utils;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static org.rm3l.ddwrt.utils.Utils.getThemeBackgroundColor;
import static org.rm3l.ddwrt.utils.Utils.isThemeLight;

/**
 *
 */
public class StatusWirelessFragment extends DDWRTBaseFragment<Collection<DDWRTTile>> {

    private static final String LOG_TAG = StatusWirelessFragment.class.getSimpleName();
    public static final Splitter SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults();

    @Nullable
    private Collection<DDWRTTile> mIfaceTiles = null;

    @Nullable
    @Override
    protected List<DDWRTTile> getTiles(@Nullable Bundle savedInstanceState) {
        return Arrays.<DDWRTTile>asList(new WirelessIfacesTile(this, savedInstanceState, router));
    }

    @Nullable
    @Override
    protected Loader<Collection<DDWRTTile>> getLoader(final int id, @NotNull final Bundle args) {

        return new AsyncTaskLoader<Collection<DDWRTTile>>(getSherlockActivity()) {

            @Nullable
            @Override
            public Collection<DDWRTTile> loadInBackground() {

                try {
                    Log.d(LOG_TAG, "Init background loader for " + StatusWirelessFragment.class + ": routerInfo="
                            + router);

                    final SherlockFragment parentFragment = StatusWirelessFragment.this;

                    if (DDWRTCompanionConstants.TEST_MODE) {
                        return Arrays.<DDWRTTile>asList(
                                new WirelessIfaceTile("eth0.test", parentFragment, args, router),
                                new WirelessIfaceTile("eth1.test", parentFragment, args, router),
                                new WirelessIfaceTile("eth2.test", parentFragment, args, router));
                    }

                    @Nullable
                    final NVRAMInfo nvramInfo = SSHUtils.getNVRamInfoFromRouter(StatusWirelessFragment.this.router,
                            getSherlockActivity().getSharedPreferences(
                                    DDWRTCompanionConstants.DEFAULT_SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE),
                            NVRAMInfo.LANDEVS);

                    if (nvramInfo == null) {
                        return null;
                    }

                    final String landevs = nvramInfo.getProperty(NVRAMInfo.LANDEVS);
                    if (landevs == null) {
                        return null;
                    }

                    final List<String> splitToList = SPLITTER.splitToList(landevs);
                    if (splitToList == null || splitToList.isEmpty()) {
                        return null;
                    }

                    final List<DDWRTTile> tiles = Lists.newArrayList();

                    for (@Nullable
                    final String landev : splitToList) {
                        if (landev == null || !(landev.startsWith("wl") || landev.startsWith("ath"))) {
                            continue;
                        }
                        tiles.add(new WirelessIfaceTile(landev, parentFragment, args, router));
                        //Also get Virtual Interfaces
                        try {
                            final String landevVifsKeyword = landev + "_vifs";
                            final NVRAMInfo landevVifsNVRAMInfo = SSHUtils.getNVRamInfoFromRouter(
                                    StatusWirelessFragment.this.router,
                                    getSherlockActivity().getSharedPreferences(
                                            DDWRTCompanionConstants.DEFAULT_SHARED_PREFERENCES_KEY,
                                            Context.MODE_PRIVATE),
                                    landevVifsKeyword);
                            if (landevVifsNVRAMInfo == null) {
                                continue;
                            }
                            final String landevVifsNVRAMInfoProp = landevVifsNVRAMInfo
                                    .getProperty(landevVifsKeyword, DDWRTCompanionConstants.EMPTY_STRING);
                            if (landevVifsNVRAMInfoProp == null) {
                                continue;
                            }
                            final List<String> list = SPLITTER.splitToList(landevVifsNVRAMInfoProp);
                            if (list == null) {
                                continue;
                            }
                            for (final String landevVif : list) {
                                if (landevVif == null || landevVif.isEmpty()) {
                                    continue;
                                }
                                tiles.add(new WirelessIfaceTile(landevVif, landev, parentFragment, args, router));
                            }
                        } catch (final Exception e) {
                            e.printStackTrace();
                            //No worries
                        }
                    }

                    if (tiles.isEmpty()) {
                        return null;
                    }

                    return tiles;

                } catch (@NotNull final Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
        };

    }

    /**
     * Called when a previously created loader has finished its load.  Note
     * that normally an application is <em>not</em> allowed to commit fragment
     * transactions while in this call, since it can happen after an
     * activity's state is saved.  See {@link android.support.v4.app.FragmentManager#beginTransaction()
     * FragmentManager.openTransaction()} for further discussion on this.
     * <p/>
     * <p>This function is guaranteed to be called prior to the release of
     * the last data that was supplied for this Loader.  At this point
     * you should remove all use of the old data (since it will be released
     * soon), but should not do your own release of the data since its Loader
     * owns it and will take care of that.  The Loader will take care of
     * management of its data so you don't have to.  In particular:
     * <p/>
     * <ul>
     * <li> <p>The Loader will monitor for changes to the data, and report
     * them to you through new calls here.  You should not monitor the
     * data yourself.  For example, if the data is a {@link android.database.Cursor}
     * and you place it in a {@link android.widget.CursorAdapter}, use
     * the {@link android.widget.CursorAdapter#CursorAdapter(android.content.Context,
     * android.database.Cursor, int)} constructor <em>without</em> passing
     * in either {@link android.widget.CursorAdapter#FLAG_AUTO_REQUERY}
     * or {@link android.widget.CursorAdapter#FLAG_REGISTER_CONTENT_OBSERVER}
     * (that is, use 0 for the flags argument).  This prevents the CursorAdapter
     * from doing its own observing of the Cursor, which is not needed since
     * when a change happens you will get a new Cursor throw another call
     * here.
     * <li> The Loader will release the data once it knows the application
     * is no longer using it.  For example, if the data is
     * a {@link android.database.Cursor} from a {@link android.content.CursorLoader},
     * you should not call close() on it yourself.  If the Cursor is being placed in a
     * {@link android.widget.CursorAdapter}, you should use the
     * {@link android.widget.CursorAdapter#swapCursor(android.database.Cursor)}
     * method so that the old Cursor is not closed.
     * </ul>
     *
     * @param loader The Loader that has finished.
     * @param tiles  The data generated by the Loader.
     */
    @Override
    public void onLoadFinished(final Loader<Collection<DDWRTTile>> loader,
            @Nullable final Collection<DDWRTTile> tiles) {
        Log.d(LOG_TAG, "Done loading background task for " + StatusWirelessFragment.class.getCanonicalName());
        this.mIfaceTiles = tiles;

        if (viewGroup == null || tiles == null || tiles.isEmpty()) {
            return;
        }

        final SherlockFragmentActivity sherlockActivity = getSherlockActivity();

        final int themeBackgroundColor = getThemeBackgroundColor(sherlockActivity, router.getUuid());
        final boolean isThemeLight = isThemeLight(sherlockActivity, themeBackgroundColor);

        final LinearLayout dynamicTilessViewGroup = (LinearLayout) viewGroup
                .findViewById(R.id.tiles_container_scrollview_layout_dynamic_items);

        //Remove everything first
        dynamicTilessViewGroup.removeAllViews();

        for (@NotNull
        final DDWRTTile tile : tiles) {
            @Nullable
            final ViewGroup tileViewGroupLayout = tile.getViewGroupLayout();
            if (tileViewGroupLayout == null) {
                continue;
            }

            if (isThemeLight) {
                final View titleView = tileViewGroupLayout.findViewById(tile.getTileTitleViewId());
                if (titleView instanceof TextView) {
                    ((TextView) titleView).setTextColor(getResources().getColor(android.R.color.holo_blue_dark));
                }
            }

            tileViewGroupLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));

            //Init loaders for these tiles
            getSherlockActivity().getSupportLoaderManager()
                    .initLoader(Long.valueOf(Utils.getNextLoaderId()).intValue(), null, tile);

            //Add row for this iface
            final CardView cardView = new CardView(sherlockActivity);
            cardView.setCardBackgroundColor(themeBackgroundColor);

            cardView.setOnClickListener(tile);
            tileViewGroupLayout.setOnClickListener(tile);

            cardView.addView(tileViewGroupLayout);

            //Remove view prior to adding it again to parent
            dynamicTilessViewGroup.addView(cardView);
        }

        //Make it visible now
        dynamicTilessViewGroup.setVisibility(View.VISIBLE);

    }

    /**
     * Called when a previously created loader is being reset, and thus
     * making its data unavailable.  The application should at this point
     * remove any references it has to the Loader's data.
     *
     * @param loader The Loader that is being reset.
     */
    @Override
    public void onLoaderReset(Loader<Collection<DDWRTTile>> loader) {
        super.onLoaderReset(loader);
    }

    /**
     * Called when the view previously created by {@link #onCreateView} has
     * been detached from the fragment.  The next time the fragment needs
     * to be displayed, a new view will be created.  This is called
     * after {@link #onStop()} and before {@link #onDestroy()}.  It is called
     * <em>regardless</em> of whether {@link #onCreateView} returned a
     * non-null view.  Internally it is called after the view's state has
     * been saved but before it has been removed from its parent.
     */
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mIfaceTiles != null) {
            int l = 100;
            final LoaderManager supportLoaderManager = getLoaderManager();
            for (int i = l; i < l + mIfaceTiles.size(); i++) {
                supportLoaderManager.destroyLoader(i);
            }
        }
    }
}