Android Open Source - android-tetheringfixer Steps Activity






From Project

Back to project page android-tetheringfixer.

License

The source code is released under:

MIT License

If you think the Android project android-tetheringfixer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * The MIT License (MIT)/* www . j  a v a 2  s  .  c  om*/
 *
 * Copyright (c) 2014 Eugenio Marletti
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package me.eugeniomarletti.tetheringfixer.android;

import android.animation.Animator;
import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import me.eugeniomarletti.tetheringfixer.Async;
import me.eugeniomarletti.tetheringfixer.Fixer;
import me.eugeniomarletti.tetheringfixer.R;
import me.eugeniomarletti.tetheringfixer.Steps;
import me.eugeniomarletti.tetheringfixer.Utils;

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

import static me.eugeniomarletti.tetheringfixer.Utils.addOnGlobalLayoutListener;
import static me.eugeniomarletti.tetheringfixer.Utils.getOffsetBetweenViews;

public final class StepsActivity extends Activity implements Steps.StepListListener
{
    private static final int CLICK_RETRY = R.string.click_retry;

    private static final Interpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
    private static final Interpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();

    private static final int          CARD_SLIDE_DURATION     = 750;
    private static final Interpolator CARD_SLIDE_INTERPOLATOR = DECELERATE_INTERPOLATOR;

    private static final int          TEXT_FIXED_FADE_DURATION     = 500;
    private static final Interpolator TEXT_FIXED_FADE_INTERPOLATOR = DECELERATE_INTERPOLATOR;

    private static final int          TEXT_AROUND_FADE_IN_DURATION     = 400;
    private static final Interpolator TEXT_AROUND_FADE_IN_INTERPOLATOR = DECELERATE_INTERPOLATOR;

    private static final int          TEXT_AROUND_FADE_OUT_DURATION     = TEXT_AROUND_FADE_IN_DURATION;
    private static final Interpolator TEXT_AROUND_FADE_OUT_INTERPOLATOR = ACCELERATE_INTERPOLATOR;

    private List<ListItem> listItems;

    private FrameLayout        card;
    private RelativeLayout     list;
    private BulletExpandEffect bulletExpandEffect;
    private TextView           textClick;
    private TextView           textSuccess;
    private TextView           textError;
    private CompoundButton     fixAtBoot;

    private float    cardCenteredY;
    private int      bulletColorChecked;
    private Drawable background;

    private void adjustSwitchMargin(boolean afterLayout)
    {
        if (fixAtBoot == null) return;
        final Runnable adjustSwitchMargin = new Runnable()
        {
            @Override
            public void run()
            {
                final int margin = (((View)fixAtBoot.getParent()).getHeight() - fixAtBoot.getHeight()) / 2;
                if (fixAtBoot.getRight() != margin)
                {
                    final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)fixAtBoot.getLayoutParams();
                    lp.rightMargin = margin;
                    fixAtBoot.setLayoutParams(lp);
                }
            }
        };
        if (!afterLayout) adjustSwitchMargin.run();
        else addOnGlobalLayoutListener(fixAtBoot, true, new ViewTreeObserver.OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                adjustSwitchMargin.run();
            }
        });
    }

    private void fadeTextAround(final View view, final boolean in)
    {
        if (view.getVisibility() == View.VISIBLE)
        {
            if (in) view.setAlpha(0f);
            view.animate()
                .withLayer()
                .alpha(in ? 1f : 0f)
                .setDuration(in ? TEXT_AROUND_FADE_IN_DURATION : TEXT_AROUND_FADE_OUT_DURATION)
                .setInterpolator(in ? TEXT_AROUND_FADE_IN_INTERPOLATOR : TEXT_AROUND_FADE_OUT_INTERPOLATOR);
        }
    }

    private void setCurrentListItem(int index, boolean isError, final String errorText, boolean animate)
    {
        int i = 0;
        for (ListItem listItem : listItems)
        {
            boolean activated, checked, working, error;

            if (i < index)
            {
                // before current
                checked = true;
                activated = false;
                working = false;
                error = false;
            }
            else if (i == index)
            {
                // current
                checked = false;
                activated = true;
                working = !isError;
                error = isError;
            }
            else
            {
                // after current
                checked = false;
                activated = false;
                working = false;
                error = false;
            }

            listItem.setError(error);
            listItem.setActivated(activated);
            listItem.setChecked(checked);
            listItem.setWorking(working);

            i++;
        }

        if (isError)
        {
            card.setClickable(true);

            textClick.setText(CLICK_RETRY);
            textClick.setVisibility(View.VISIBLE);
            if (errorText != null)
            {
                textError.setText(Utils.addEmoji(errorText));
                textError.setVisibility(View.VISIBLE);
            }
            else
            {
                textError.setVisibility(View.GONE);
                textError.setText(null);
            }
            if (animate)
            {
                final int oldCardPosition = Utils.getLocationInWindow(card).y;
                addOnGlobalLayoutListener(textClick, true, new ViewTreeObserver.OnGlobalLayoutListener()
                {
                    @Override
                    public void onGlobalLayout()
                    {
                        fadeTextAround(textClick, true);
                        if (errorText != null) fadeTextAround(textError, true);
                        card.setTranslationY(oldCardPosition - Utils.getLocationInWindow(card).y);
                        card.animate()
                            .translationY(0f)
                            .setDuration(CARD_SLIDE_DURATION)
                            .setInterpolator(CARD_SLIDE_INTERPOLATOR)
                            .setListener(null);
                    }
                });
            }
        }
    }

    private void setCurrentListItem(int index)
    {
        setCurrentListItem(index, false, null, true);
    }

    private void success(int index)
    {
        setCurrentListItem(index);
        final ListItem currentListItem = listItems.get(index);
        final Bullet bullet = currentListItem.getBullet();
        bullet.addBulletColorAnimationListener(new SimpleAnimatorListener()
        {
            @Override
            public void onAnimationEnd(Animator animator)
            {
                bullet.removeBulletColorAnimationListener(this);

                final Point offset = getOffsetBetweenViews(bulletExpandEffect, bullet);
                final PointF bulletCenter = bullet.getBulletCenter();
                bulletCenter.offset(offset.x, offset.y);

                bulletExpandEffect.setVisibility(View.VISIBLE); // needs to do layout to be effective
                addOnGlobalLayoutListener(bulletExpandEffect, true, new ViewTreeObserver
                        .OnGlobalLayoutListener()
                {
                    @Override
                    public void onGlobalLayout()
                    {
                        bulletExpandEffect.animateExpand(
                                bulletColorChecked, bulletCenter, bullet.getBulletSize(), new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                // expanded
                                success(true);
                            }
                        });
                    }
                });
            }
        });
        currentListItem.setWorking(false);
        currentListItem.setChecked(true);
    }

    private void success(boolean animate)
    {
        for (ListItem listItem : listItems) listItem.setVisibility(View.INVISIBLE);
        ((View)bulletExpandEffect.getParent()).setBackgroundColor(bulletColorChecked);
        bulletExpandEffect.setVisibility(View.GONE);
        textSuccess.setVisibility(View.VISIBLE);
        if (animate)
        {
            textSuccess.setAlpha(0f);
            textSuccess.animate()
                       .alpha(1f)
                       .setDuration(TEXT_FIXED_FADE_DURATION)
                       .setInterpolator(TEXT_FIXED_FADE_INTERPOLATOR)
                       .withLayer();
        }
        else textSuccess.setAlpha(1f);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        adjustSwitchMargin(true);
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fixer);

        list = (RelativeLayout)findViewById(R.id.list);
        textSuccess = (TextView)findViewById(R.id.text_success);
        textError = (TextView)findViewById(R.id.text_error);
        textClick = (TextView)findViewById(R.id.text_click);
        card = (FrameLayout)findViewById(R.id.card);
        bulletExpandEffect = (BulletExpandEffect)findViewById(R.id.bullet_expand_effect);

        background = ((View)bulletExpandEffect.getParent()).getBackground();

        textSuccess.setText(Utils.addEmoji(textSuccess.getText()));

        card.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Steps.startOrRetry();
            }
        });

        Fixer.isFixAtBootEnabledAsync(new Async.SimpleMainThreadCallback<Boolean>()
        {
            @Override
            public void mainThreadCallback(Boolean result, boolean success, Throwable error)
            {
                if (!success || result == null) throw new RuntimeException(error);
                final ActionBar ab = getActionBar();
                ab.setCustomView(R.layout.activity_fixer_actionbar);
                fixAtBoot = (CompoundButton)ab.getCustomView().findViewById(R.id.fix_at_boot_switch);
                fixAtBoot.setChecked(result);
                fixAtBoot.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
                {
                    @Override
                    public void onCheckedChanged(final CompoundButton button, boolean enabled)
                    {
                        button.setEnabled(false);
                        Fixer.setFixAtBootEnabledAsync(new Async.SimpleMainThreadCallback<Void>()
                        {
                            @Override
                            public void mainThreadCallback(Void result, boolean success, Throwable error)
                            {
                                if (!success) throw new RuntimeException(error); // can do better when i'm not lazy
                                if (Steps.isSuccess()) Fixer.shutdown();
                                button.setEnabled(true);
                            }
                        }, enabled);
                    }
                });
                ab.setDisplayShowCustomEnabled(true);
                adjustSwitchMargin(true);
            }
        });

        addOnGlobalLayoutListener(card, true, new ViewTreeObserver.OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                cardCenteredY = Utils.getLocationInWindow(card).y;
            }
        });

        addOnGlobalLayoutListener(bulletExpandEffect, true, new ViewTreeObserver.OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                final View parent = (View)bulletExpandEffect.getParent();
                final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)bulletExpandEffect.getLayoutParams();
                lp.width = parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight();
                lp.height = parent.getHeight() - parent.getPaddingTop() - parent.getPaddingBottom();
                bulletExpandEffect.setLayoutParams(lp);
            }
        });

        // inflate views for list items
        final List<String> labels = Steps.getLabels();
        listItems = new ArrayList<>(labels.size());
        for (int i = 0, labelsLength = labels.size(); i < labelsLength; i++)
        {
            final ListItem previousListItem = i > 0 ? listItems.get(i - 1) : null;
            final LayoutInflater inflater = getLayoutInflater();
            final Bullet bullet = (Bullet)inflater.inflate(R.layout.activity_fixer_bullet, list, false);
            final TextView label = (TextView)inflater.inflate(R.layout.activity_fixer_label, list, false);
            final int bulletId = Utils.generateViewId();
            final int labelId = Utils.generateViewId();
            bullet.setId(bulletId);
            label.setId(labelId);
            label.setText(labels.get(i));
            RelativeLayout.LayoutParams bulletLayoutParams = (RelativeLayout.LayoutParams)bullet.getLayoutParams();
            RelativeLayout.LayoutParams labelLayoutParams = (RelativeLayout.LayoutParams)label.getLayoutParams();
            if (previousListItem != null)
                bulletLayoutParams.addRule(RelativeLayout.BELOW, previousListItem.getBullet().getId());
            labelLayoutParams.addRule(RelativeLayout.RIGHT_OF, bulletId);
            labelLayoutParams.addRule(RelativeLayout.ALIGN_TOP, bulletId);
            labelLayoutParams.addRule(RelativeLayout.ALIGN_BOTTOM, bulletId);
            list.addView(bullet, bulletLayoutParams);
            list.addView(label, labelLayoutParams);
            listItems.add(new ListItem(bullet, label));
        }
        bulletColorChecked = listItems.get(0).getBullet().getBulletColorChecked();
    }

    @Override
    protected void onStart()
    {
        super.onStart();

        addOnGlobalLayoutListener(card, true, new ViewTreeObserver.OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                Steps.addListener(StepsActivity.this);
                final boolean isStarted = Steps.isStarted();
                final boolean isError = Steps.isError();
                final boolean isSuccess = Steps.isSuccess();
                textClick.setVisibility(!isStarted || !isSuccess ? View.VISIBLE : View.GONE);
                card.setClickable(!isStarted || isError);
                if (isSuccess) success(false);
                else
                {
                    for (ListItem listItem : listItems) listItem.setVisibility(View.VISIBLE);
                    ((View)bulletExpandEffect.getParent()).setBackground(background);
                    bulletExpandEffect.setVisibility(View.GONE);
                    textSuccess.setVisibility(View.GONE);
                    setCurrentListItem(Steps.getCurrentStep(), isError, Steps.getErrorText(), false);
                }
            }
        });
    }

    @Override
    protected void onResume()
    {
        super.onResume();

        StepsService.cancelNotification();
        StepsService.stop();

        Steps.setActionsDelayed(true);
        Steps.resume();
    }

    @Override
    protected void onPause()
    {
        super.onPause();

        Steps.pause();
        Steps.setActionsDelayed(false);
    }

    @Override
    protected void onStop()
    {
        super.onStop();

        Steps.removeListener(this);
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();

        Steps.removeListener(this);
        Steps.shutdownIfNoListeners();
    }

    @Override
    public void onStepsStart()
    {
        Utils.runOnMainThread(new Runnable()
        {
            @Override
            public void run()
            {
                card.setClickable(false);
                fadeTextAround(textClick, false);
                fadeTextAround(textError, false);
                card.animate()
                    .translationYBy(cardCenteredY - Utils.getLocationInWindow(card).y)
                    .setDuration(CARD_SLIDE_DURATION)
                    .setInterpolator(CARD_SLIDE_INTERPOLATOR)
                    .setListener(new SimpleAnimatorListener()
                    {
                        @Override
                        public void onAnimationEnd(Animator animator)
                        {
                            card.animate().setListener(null);
                            textClick.setVisibility(View.GONE);
                            textError.setVisibility(View.GONE);
                            card.setTranslationY(0f);
                        }
                    });
            }
        });
    }

    @Override
    public void onStepsRetry()
    {
        setCurrentListItem(-1);
    }

    @Override
    public void onStepError(final int itemIndex, final String errorText)
    {
        setCurrentListItem(itemIndex, true, errorText, true);
    }

    @Override
    public void onAdvanceStep(final int itemIndex)
    {
        setCurrentListItem(itemIndex);
    }

    @Override
    public void onStepsSuccess(final int itemIndex)
    {
        success(itemIndex);
    }

    private static final class ListItem
    {
        private final Bullet   bullet;
        private final TextView label;

        public ListItem(Bullet bullet, TextView label)
        {
            this.bullet = bullet;
            this.label = label;
        }

        public Bullet getBullet()
        {
            return bullet;
        }

        public TextView getLabel()
        {
            return label;
        }

        public void setError(boolean error)
        {
            bullet.setError(error);
            label.setError(error);
        }

        public void setWorking(boolean working)
        {
            bullet.setWorking(working);
            label.setWorking(working);
        }

        public void setActivated(boolean activated)
        {
            bullet.setActivated(activated);
            label.setActivated(activated);
        }

        public void setChecked(boolean checked)
        {
            bullet.setChecked(checked);
            label.setChecked(checked);
        }

        public void setVisibility(int visibility)
        {
            bullet.setVisibility(visibility);
            label.setVisibility(visibility);
        }
    }
}




Java Source Code List

me.eugeniomarletti.tetheringfixer.Async.java
me.eugeniomarletti.tetheringfixer.Fixer.java
me.eugeniomarletti.tetheringfixer.Steps.java
me.eugeniomarletti.tetheringfixer.Utils.java
me.eugeniomarletti.tetheringfixer.android.Application.java
me.eugeniomarletti.tetheringfixer.android.BootBroadcastReceiver.java
me.eugeniomarletti.tetheringfixer.android.BulletExpandEffect.java
me.eugeniomarletti.tetheringfixer.android.Bullet.java
me.eugeniomarletti.tetheringfixer.android.DrawableState.java
me.eugeniomarletti.tetheringfixer.android.PackageManager.java
me.eugeniomarletti.tetheringfixer.android.SimpleAnimatorListener.java
me.eugeniomarletti.tetheringfixer.android.StepsActivity.java
me.eugeniomarletti.tetheringfixer.android.StepsService.java
me.eugeniomarletti.tetheringfixer.android.Switch.java
me.eugeniomarletti.tetheringfixer.android.TextView.java
me.eugeniomarletti.tetheringfixer.command.CommandException.java
me.eugeniomarletti.tetheringfixer.command.CommandNotFoundException.java
me.eugeniomarletti.tetheringfixer.command.CommandNotOkException.java
me.eugeniomarletti.tetheringfixer.command.CommandResult.java
me.eugeniomarletti.tetheringfixer.command.WaitCommand.java