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

Commit d36d650a authored by Brad Fitzpatrick's avatar Brad Fitzpatrick Committed by Nick Pelly
Browse files

NFC: async enabling/disabling, ala Bluewooth & Wifi.

Don't ANR when toggling.

Bug: 3097279
Change-Id: Ief09a5a4d023f32b02b2f3b72ac701e8089254c8
parent dd49624e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -784,6 +784,7 @@
    <string name="nfc_quick_toggle_title">NFC</string>
    <!-- Used in the 1st-level settings screen as the turn-on summary -->
    <string name="nfc_quick_toggle_summary">Use Near Field Communication to read and exchange tags</string>
    <string name="nfc_toggle_error" msgid="8998642457947607263">An error occurred.</string>

    <!-- Wi-Fi Settings --> <skip />
    <!-- Used in the 1st-level settings screen to turn on Wi-Fi -->
+61 −25
Original line number Diff line number Diff line
@@ -17,10 +17,15 @@
package com.android.settings.nfc;

import com.android.settings.R;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.preference.Preference;
import android.os.Handler;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.provider.Settings;
import android.util.Log;

@@ -35,6 +40,20 @@ public class NfcEnabler implements Preference.OnPreferenceChangeListener {
    private final Context mContext;
    private final CheckBoxPreference mCheckbox;
    private final NfcAdapter mNfcAdapter;
    private final IntentFilter mIntentFilter;
    private final Handler mHandler = new Handler();

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGE.equals(action)) {
                handleNfcStateChanged(intent.getBooleanExtra(
                    NfcAdapter.EXTRA_NEW_BOOLEAN_STATE,
                    false));
            }
        }
    };

    private boolean mNfcState;

@@ -47,49 +66,66 @@ public class NfcEnabler implements Preference.OnPreferenceChangeListener {
            // NFC is not supported
            mCheckbox.setEnabled(false);
        }

        mIntentFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);

    }

    public void resume() {
        if (mNfcAdapter == null) {
            return;
        }
        mContext.registerReceiver(mReceiver, mIntentFilter);
        mCheckbox.setOnPreferenceChangeListener(this);
        mNfcState = Settings.System.getInt(mContext.getContentResolver(),
                Settings.System.NFC_ON, 0) != 0;
		updateUi();
        mCheckbox.setChecked(mNfcState);
    }

    public void pause() {
        if (mNfcAdapter == null) {
            return;
        }
        mContext.unregisterReceiver(mReceiver);
        mCheckbox.setOnPreferenceChangeListener(null);
    }

    public boolean onPreferenceChange(Preference preference, Object value) {
        // Turn on/off Nfc
        mNfcState = (Boolean) value;
        setEnabled();
        // Turn NFC on/off

        return false;
    }
        final boolean desiredState = (Boolean) value;
        mCheckbox.setEnabled(false);

    private void setEnabled() {
        if (mNfcState) {
            if (!mNfcAdapter.enableTagDiscovery()) {
                Log.w(TAG, "NFC enabling failed");
				mNfcState = false;
        // Start async update of the NFC adapter state, as the API is
        // unfortunately blocking...
        new Thread("toggleNFC") {
            public void run() {
                Log.d(TAG, "Setting NFC enabled state to: " + desiredState);
                boolean success = false;
                if (desiredState) {
                    success = mNfcAdapter.enableTagDiscovery();
                } else {
                    success = mNfcAdapter.disableTagDiscovery();
                }
                if (success) {
                    Log.d(TAG, "Successfully changed NFC enabled state to " + desiredState);
                    // UI will be updated by BroadcastReceiver, above.
                } else {
            if (!mNfcAdapter.disableTagDiscovery()) {
                Log.w(TAG, "NFC disabling failed");
				mNfcState = true;
                    Log.w(TAG, "Error setting NFC enabled state to " + desiredState);
                    mHandler.post(new Runnable() {
                            public void run() {
                                mCheckbox.setEnabled(true);
                                mCheckbox.setSummary(R.string.nfc_toggle_error);
                            }
                        });
                }
            }
		updateUi();
        }.start();
        return false;
    }

    private void updateUi() {
        mCheckbox.setChecked(mNfcState);
    private void handleNfcStateChanged(boolean newState) {
        mCheckbox.setChecked(newState);
        mCheckbox.setEnabled(true);
    }
}