1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settings.nfc;
17
18import android.content.Context;
19import android.database.ContentObserver;
20import android.net.Uri;
21import android.nfc.NfcAdapter;
22import android.nfc.NfcManager;
23import android.os.Handler;
24import android.provider.Settings;
25import android.support.v14.preference.SwitchPreference;
26import android.support.v7.preference.Preference;
27import android.support.v7.preference.PreferenceScreen;
28
29import com.android.settings.core.PreferenceController;
30import com.android.settings.core.lifecycle.LifecycleObserver;
31import com.android.settings.core.lifecycle.events.OnPause;
32import com.android.settings.core.lifecycle.events.OnResume;
33import com.android.settings.network.AirplaneModePreferenceController;
34import com.android.settings.overlay.FeatureFactory;
35import com.android.settingslib.RestrictedPreference;
36
37import java.util.List;
38
39public class NfcPreferenceController extends PreferenceController
40        implements LifecycleObserver, OnResume, OnPause {
41
42    public static final String KEY_TOGGLE_NFC = "toggle_nfc";
43    public static final String KEY_ANDROID_BEAM_SETTINGS = "android_beam_settings";
44
45    private NfcEnabler mNfcEnabler;
46    private NfcAdapter mNfcAdapter;
47    private int mAirplaneMode;
48    private AirplaneModeObserver mAirplaneModeObserver;
49    private SwitchPreference mNfcPreference;
50    private RestrictedPreference mBeamPreference;
51
52    public NfcPreferenceController(Context context) {
53        super(context);
54        mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
55    }
56
57    @Override
58    public void displayPreference(PreferenceScreen screen) {
59        if (!isAvailable()) {
60            removePreference(screen, KEY_TOGGLE_NFC);
61            removePreference(screen, KEY_ANDROID_BEAM_SETTINGS);
62            mNfcEnabler = null;
63            return;
64        }
65        mNfcPreference = (SwitchPreference) screen.findPreference(KEY_TOGGLE_NFC);
66        mBeamPreference = (RestrictedPreference) screen.findPreference(
67                KEY_ANDROID_BEAM_SETTINGS);
68        mNfcEnabler = new NfcEnabler(mContext, mNfcPreference, mBeamPreference);
69        String toggleable = Settings.Global.getString(mContext.getContentResolver(),
70                Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
71        // Manually set dependencies for NFC when not toggleable.
72        if (toggleable == null || !toggleable.contains(Settings.Global.RADIO_NFC)) {
73            mAirplaneModeObserver = new AirplaneModeObserver();
74            updateNfcPreference();
75        }
76    }
77
78    @Override
79    public void updateNonIndexableKeys(List<String> keys) {
80        final NfcManager manager = (NfcManager) mContext.getSystemService(Context.NFC_SERVICE);
81        if (manager != null) {
82            NfcAdapter adapter = manager.getDefaultAdapter();
83            if (adapter == null) {
84                keys.add(KEY_TOGGLE_NFC);
85                keys.add(KEY_ANDROID_BEAM_SETTINGS);
86            }
87        }
88    }
89
90    @Override
91    public boolean isAvailable() {
92        return mNfcAdapter != null;
93    }
94
95    @Override
96    public String getPreferenceKey() {
97        return null;
98    }
99
100    public void onResume() {
101        if (mAirplaneModeObserver != null) {
102            mAirplaneModeObserver.register();
103        }
104        if (mNfcEnabler != null) {
105            mNfcEnabler.resume();
106        }
107    }
108
109    @Override
110    public void onPause() {
111        if (mAirplaneModeObserver != null) {
112            mAirplaneModeObserver.unregister();
113        }
114        if (mNfcEnabler != null) {
115            mNfcEnabler.pause();
116        }
117    }
118
119    private void updateNfcPreference() {
120        final int airplaneMode = Settings.Global.getInt(
121                mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, mAirplaneMode);
122        if (airplaneMode == mAirplaneMode) {
123            return;
124        }
125        mAirplaneMode = airplaneMode;
126        boolean toggleable = mAirplaneMode != 1;
127        if (toggleable) {
128            mNfcAdapter.enable();
129        } else {
130            mNfcAdapter.disable();
131        }
132        mNfcPreference.setEnabled(toggleable);
133        mBeamPreference.setEnabled(toggleable);
134    }
135
136    private final class AirplaneModeObserver extends ContentObserver {
137        private final Uri AIRPLANE_MODE_URI =
138                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON);
139
140        private AirplaneModeObserver() {
141            super(new Handler());
142        }
143
144        public void register() {
145            mContext.getContentResolver().registerContentObserver(AIRPLANE_MODE_URI, false, this);
146        }
147
148        public void unregister() {
149            mContext.getContentResolver().unregisterContentObserver(this);
150        }
151
152        @Override
153        public void onChange(boolean selfChange, Uri uri) {
154            super.onChange(selfChange, uri);
155            updateNfcPreference();
156        }
157    }
158
159}
160