Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc6db072 authored by Hans Boehm's avatar Hans Boehm Committed by Android (Google) Code Review
Browse files

Merge "Cleanup of timeout handling and message" into mnc-dr-dev

parents d5f67fe2 9192d5c7
Loading
Loading
Loading
Loading
+47 −7
Original line number Diff line number Diff line
@@ -21,22 +21,50 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.widget.TextView;

public class AlertDialogFragment extends DialogFragment {
/**
 * Display a message with a dismiss putton, and optionally a second button.
 */
public class AlertDialogFragment extends DialogFragment implements DialogInterface.OnClickListener {

    public interface OnClickListener {
        /**
         * This method will be invoked when a button in the dialog is clicked.
         *
         * @param fragment the AlertDialogFragment that received the click
         * @param which the button that was clicked (e.g.
         *            {@link DialogInterface#BUTTON_POSITIVE}) or the position
         *            of the item clicked
         */
        public void onClick(AlertDialogFragment fragment, int which);
    }

    private static final String NAME = AlertDialogFragment.class.getName();
    private static final String KEY_MESSAGE = NAME + "_message";
    private static final String KEY_BUTTON_NEGATIVE = NAME + "_button_negative";
    private static final String KEY_BUTTON_POSITIVE = NAME + "_button_positive";

    public static void showMessageDialog(Activity activity, CharSequence message) {
    /**
     * Create and show a DialogFragment with the given message.
     * @param activity originating Activity
     * @param message displayed message
     * @param positiveButtonLabel label for second button, if any.  If non-null, activity must
     * implement AlertDialogFragment.OnClickListener to respond.
     */
    public static void showMessageDialog(Activity activity, CharSequence message,
            @Nullable CharSequence positiveButtonLabel) {
        final AlertDialogFragment dialogFragment = new AlertDialogFragment();
        final Bundle args = new Bundle();
        args.putCharSequence(KEY_MESSAGE, message);
        args.putCharSequence(KEY_BUTTON_NEGATIVE, activity.getString(R.string.dismiss));

        final AlertDialogFragment dialogFragment = new AlertDialogFragment();
        if (positiveButtonLabel != null) {
            args.putCharSequence(KEY_BUTTON_POSITIVE, positiveButtonLabel);
        }
        dialogFragment.setArguments(args);
        dialogFragment.show(activity.getFragmentManager(), null /* tag */);
    }
@@ -53,9 +81,21 @@ public class AlertDialogFragment extends DialogFragment {
        final TextView textView = (TextView) inflater.inflate(R.layout.dialog_message,
                null /* root */);
        textView.setText(args.getCharSequence(KEY_MESSAGE));
        return new AlertDialog.Builder(context)
        final AlertDialog.Builder builder = new AlertDialog.Builder(context)
                .setView(textView)
                .setNegativeButton(args.getCharSequence(KEY_BUTTON_NEGATIVE), null /* listener */)
                .create();
                .setNegativeButton(args.getCharSequence(KEY_BUTTON_NEGATIVE), null /* listener */);
        final CharSequence positiveButtonLabel = args.getCharSequence(KEY_BUTTON_POSITIVE);
        if (positiveButtonLabel != null) {
            builder.setPositiveButton(positiveButtonLabel, this);
        }
        return builder.create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        final Activity activity = getActivity();
        if (activity instanceof AlertDialogFragment.OnClickListener /* always true */) {
            ((AlertDialogFragment.OnClickListener) activity).onClick(this, which);
        }
    }
}
+14 −3
Original line number Diff line number Diff line
@@ -32,7 +32,9 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
@@ -71,7 +73,8 @@ import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class Calculator extends Activity
        implements OnTextSizeChangeListener, OnLongClickListener, CalculatorText.OnPasteListener {
        implements OnTextSizeChangeListener, OnLongClickListener, CalculatorText.OnPasteListener,
        AlertDialogFragment.OnClickListener {

    /**
     * Constant for an invalid resource id.
@@ -849,6 +852,14 @@ public class Calculator extends Activity
        mFormulaText.requestFocus();
    }

    @Override
    public void onClick(AlertDialogFragment fragment, int which) {
        if (which == DialogInterface.BUTTON_POSITIVE) {
            // Timeout extension request.
            mEvaluator.setLongTimeOut();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
@@ -889,7 +900,7 @@ public class Calculator extends Activity
    }

    private void displayMessage(String s) {
        AlertDialogFragment.showMessageDialog(this, s);
        AlertDialogFragment.showMessageDialog(this, s, null);
    }

    private void displayFraction() {
+70 −33
Original line number Diff line number Diff line
@@ -234,43 +234,65 @@ class Evaluator {
            .show();
    }

    // Maximum timeout for background computations.  Exceeding a few tens of seconds
    // increases the risk of running out of memory and impacting the rest of the system.
    private final long MAX_TIMEOUT = 15000;
    // Timeout handling.
    // Expressions are evaluated with a sort timeout or a long timeout.
    // Each implies different maxima on both computation time and bit length.
    // We recheck bit length separetly to avoid wasting time on decimal conversions that are
    // destined to fail.

    // Timeout for requested evaluations, in milliseconds.  This is currently not saved and
    // restored with the state; we reset the timeout when the calculator is restarted.  We'll call
    // that a feature; others might argue it's a bug.
    private long mTimeout = 2000;
    /**
     * Is a long timeout in effect for the main expression?
     */
    private boolean mLongTimeout = false;

    /**
     * Is a long timeout in effect for the saved expression?
     */
    private boolean mLongSavedTimeout = false;

    /**
     * Return the timeout in milliseconds.
     * @param longTimeout a long timeout is in effect
     */
    private long getTimeout(boolean longTimeout) {
        return longTimeout ? 15000 : 2000;
        // Exceeding a few tens of seconds increases the risk of running out of memory
        // and impacting the rest of the system.
    }

    // Timeout for unrequested, speculative evaluations, in milliseconds.
    /**
     * Return the maximum number of bits in the result.  Longer results are assumed to time out.
     * @param longTimeout a long timeout is in effect
     */
    private int getMaxResultBits(boolean longTimeout) {
        return longTimeout ? 350000 : 120000;
    }

    /**
     * Timeout for unrequested, speculative evaluations, in milliseconds.
     */
    private final long QUICK_TIMEOUT = 1000;

    private int mMaxResultBits = 120000;             // Don't try to display a larger result.
    private final int MAX_MAX_RESULT_BITS = 350000;  // Long timeout version.
    private final int QUICK_MAX_RESULT_BITS = 50000; // Instant result version.
    /**
     * Maximum result bit length for unrequested, speculative evaluations.
     */
    private final int QUICK_MAX_RESULT_BITS = 50000;

    private void displayTimeoutMessage() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(mCalculator)
                .setMessage(R.string.timeout)
                .setNegativeButton(R.string.dismiss, null /* listener */);
        if (mTimeout != MAX_TIMEOUT) {
            builder.setPositiveButton(R.string.ok_remove_timeout,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface d, int which) {
                            mTimeout = MAX_TIMEOUT;
                            mMaxResultBits = MAX_MAX_RESULT_BITS;
        AlertDialogFragment.showMessageDialog(mCalculator, mCalculator.getString(R.string.timeout),
                (mLongTimeout ? null : mCalculator.getString(R.string.ok_remove_timeout)));
    }
                    });
        }
        builder.show();

    public void setLongTimeOut() {
        mLongTimeout = true;
    }

    // Compute initial cache contents and result when we're good and ready.
    // We leave the expression display up, with scrolling
    // disabled, until this computation completes.
    // Can result in an error display if something goes wrong.
    // By default we set a timeout to catch runaway computations.
    /**
     * Compute initial cache contents and result when we're good and ready.
     * We leave the expression display up, with scrolling disabled, until this computation
     * completes.  Can result in an error display if something goes wrong.  By default we set a
     * timeout to catch runaway computations.
     */
    class AsyncEvaluator extends AsyncTask<Void, Void, InitialResult> {
        private boolean mDm;  // degrees
        private boolean mRequired; // Result was requested by user.
@@ -299,7 +321,7 @@ class Evaluator {
        }
        @Override
        protected void onPreExecute() {
            long timeout = mRequired ? mTimeout : QUICK_TIMEOUT;
            long timeout = mRequired ? getTimeout(mLongTimeout) : QUICK_TIMEOUT;
            mTimeoutRunnable = new Runnable() {
                @Override
                public void run() {
@@ -312,7 +334,7 @@ class Evaluator {
         * Is a computed result too big for decimal conversion?
         */
        private boolean isTooBig(CalculatorExpr.EvalResult res) {
            int maxBits = mRequired ? mMaxResultBits : QUICK_MAX_RESULT_BITS;
            int maxBits = mRequired ? getMaxResultBits(mLongTimeout) : QUICK_MAX_RESULT_BITS;
            if (res.ratVal != null) {
                return res.ratVal.wholeNumberBits() > maxBits;
            } else {
@@ -821,11 +843,17 @@ class Evaluator {
        mMsdIndex = INVALID_MSD;
    }

    public void clear() {

    private void clearPreservingTimeout() {
        mExpr.clear();
        clearCache();
    }

    public void clear() {
        clearPreservingTimeout();
        mLongTimeout = false;
    }

    /**
     * Start asynchronous result evaluation of formula.
     * Will result in display on completion.
@@ -916,6 +944,8 @@ class Evaluator {
        try {
            CalculatorExpr.initExprInput();
            mDegreeMode = in.readBoolean();
            mLongTimeout = in.readBoolean();
            mLongSavedTimeout = in.readBoolean();
            mExpr = new CalculatorExpr(in);
            mSavedName = in.readUTF();
            mSaved = new CalculatorExpr(in);
@@ -931,6 +961,8 @@ class Evaluator {
        try {
            CalculatorExpr.initExprOutput();
            out.writeBoolean(mDegreeMode);
            out.writeBoolean(mLongTimeout);
            out.writeBoolean(mLongSavedTimeout);
            mExpr.write(out);
            out.writeUTF(mSavedName);
            mSaved.write(out);
@@ -959,6 +991,9 @@ class Evaluator {
    public void delete() {
        mChangedValue = true;
        mExpr.delete();
        if (mExpr.isEmpty()) {
            mLongTimeout = false;
        }
    }

    void setDegreeMode(boolean degreeMode) {
@@ -993,7 +1028,7 @@ class Evaluator {
     */
    public void collapse() {
        final CalculatorExpr abbrvExpr = getResultExpr();
        clear();
        clearPreservingTimeout();
        mExpr.append(abbrvExpr);
        mChangedValue = true;
    }
@@ -1009,6 +1044,7 @@ class Evaluator {
        final CalculatorExpr abbrvExpr = getResultExpr();
        mSaved.clear();
        mSaved.append(abbrvExpr);
        mLongSavedTimeout = mLongTimeout;
        return true;
    }

@@ -1042,6 +1078,7 @@ class Evaluator {

    public void appendSaved() {
        mChangedValue = true;
        mLongTimeout |= mLongSavedTimeout;
        mExpr.append(mSaved);
    }