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 */ 16 package com.android.settings.nfc; 17 18 import android.content.Context; 19 import android.database.ContentObserver; 20 import android.net.Uri; 21 import android.nfc.NfcAdapter; 22 import android.nfc.NfcManager; 23 import android.os.Handler; 24 import android.provider.Settings; 25 import android.support.v14.preference.SwitchPreference; 26 import android.support.v7.preference.PreferenceScreen; 27 28 import com.android.settings.core.PreferenceControllerMixin; 29 import com.android.settingslib.core.AbstractPreferenceController; 30 import com.android.settingslib.core.lifecycle.LifecycleObserver; 31 import com.android.settingslib.RestrictedPreference; 32 import com.android.settingslib.core.lifecycle.events.OnPause; 33 import com.android.settingslib.core.lifecycle.events.OnResume; 34 35 import java.util.List; 36 37 public class NfcPreferenceController extends AbstractPreferenceController 38 implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause { 39 40 public static final String KEY_TOGGLE_NFC = "toggle_nfc"; 41 public static final String KEY_ANDROID_BEAM_SETTINGS = "android_beam_settings"; 42 43 private NfcEnabler mNfcEnabler; 44 private NfcAdapter mNfcAdapter; 45 private int mAirplaneMode; 46 private AirplaneModeObserver mAirplaneModeObserver; 47 private SwitchPreference mNfcPreference; 48 private RestrictedPreference mBeamPreference; 49 NfcPreferenceController(Context context)50 public NfcPreferenceController(Context context) { 51 super(context); 52 mNfcAdapter = NfcAdapter.getDefaultAdapter(context); 53 } 54 55 @Override displayPreference(PreferenceScreen screen)56 public void displayPreference(PreferenceScreen screen) { 57 if (!isAvailable()) { 58 removePreference(screen, KEY_TOGGLE_NFC); 59 removePreference(screen, KEY_ANDROID_BEAM_SETTINGS); 60 mNfcEnabler = null; 61 return; 62 } 63 mNfcPreference = (SwitchPreference) screen.findPreference(KEY_TOGGLE_NFC); 64 mBeamPreference = (RestrictedPreference) screen.findPreference( 65 KEY_ANDROID_BEAM_SETTINGS); 66 mNfcEnabler = new NfcEnabler(mContext, mNfcPreference, mBeamPreference); 67 // Manually set dependencies for NFC when not toggleable. 68 if (!isToggleableInAirplaneMode(mContext)) { 69 mAirplaneModeObserver = new AirplaneModeObserver(); 70 updateNfcPreference(); 71 } 72 } 73 74 @Override updateNonIndexableKeys(List<String> keys)75 public void updateNonIndexableKeys(List<String> keys) { 76 final NfcManager manager = (NfcManager) mContext.getSystemService(Context.NFC_SERVICE); 77 if (manager != null) { 78 NfcAdapter adapter = manager.getDefaultAdapter(); 79 if (adapter == null) { 80 keys.add(KEY_TOGGLE_NFC); 81 keys.add(KEY_ANDROID_BEAM_SETTINGS); 82 } 83 } 84 } 85 86 @Override isAvailable()87 public boolean isAvailable() { 88 return mNfcAdapter != null; 89 } 90 91 @Override getPreferenceKey()92 public String getPreferenceKey() { 93 return null; 94 } 95 onResume()96 public void onResume() { 97 if (mAirplaneModeObserver != null) { 98 mAirplaneModeObserver.register(); 99 } 100 if (mNfcEnabler != null) { 101 mNfcEnabler.resume(); 102 } 103 } 104 105 @Override onPause()106 public void onPause() { 107 if (mAirplaneModeObserver != null) { 108 mAirplaneModeObserver.unregister(); 109 } 110 if (mNfcEnabler != null) { 111 mNfcEnabler.pause(); 112 } 113 } 114 updateNfcPreference()115 private void updateNfcPreference() { 116 final int airplaneMode = Settings.Global.getInt( 117 mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, mAirplaneMode); 118 if (airplaneMode == mAirplaneMode) { 119 return; 120 } 121 mAirplaneMode = airplaneMode; 122 boolean toggleable = mAirplaneMode != 1; 123 if (toggleable) { 124 mNfcAdapter.enable(); 125 } else { 126 mNfcAdapter.disable(); 127 } 128 mNfcPreference.setEnabled(toggleable); 129 mBeamPreference.setEnabled(toggleable); 130 } 131 isToggleableInAirplaneMode(Context context)132 public static boolean isToggleableInAirplaneMode(Context context) { 133 String toggleable = Settings.Global.getString(context.getContentResolver(), 134 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 135 return toggleable != null && toggleable.contains(Settings.Global.RADIO_NFC); 136 } 137 138 private final class AirplaneModeObserver extends ContentObserver { 139 private final Uri AIRPLANE_MODE_URI = 140 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON); 141 AirplaneModeObserver()142 private AirplaneModeObserver() { 143 super(new Handler()); 144 } 145 register()146 public void register() { 147 mContext.getContentResolver().registerContentObserver(AIRPLANE_MODE_URI, false, this); 148 } 149 unregister()150 public void unregister() { 151 mContext.getContentResolver().unregisterContentObserver(this); 152 } 153 154 @Override onChange(boolean selfChange, Uri uri)155 public void onChange(boolean selfChange, Uri uri) { 156 super.onChange(selfChange, uri); 157 updateNfcPreference(); 158 } 159 } 160 161 } 162