Loading core/java/android/app/Activity.java +0 −1 Original line number Diff line number Diff line Loading @@ -1162,7 +1162,6 @@ public class Activity extends ContextThemeWrapper */ protected void onPause() { mCalled = true; QueuedWork.waitToFinish(); } /** Loading core/java/android/app/ActivityThread.java +3 −0 Original line number Diff line number Diff line Loading @@ -2265,6 +2265,9 @@ public final class ActivityThread { r.activity.mConfigChangeFlags |= configChanges; Bundle state = performPauseActivity(token, finished, true); // Make sure any pending writes are now committed. QueuedWork.waitToFinish(); // Tell the activity manager we have paused. try { ActivityManagerNative.getDefault().activityPaused(token, state); Loading core/java/android/bluetooth/BluetoothDeviceProfileState.java +85 −4 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine public static final int UNPAIR = 100; public static final int AUTO_CONNECT_PROFILES = 101; public static final int TRANSITION_TO_STABLE = 102; public static final int CONNECT_OTHER_PROFILES = 103; private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs Loading Loading @@ -129,10 +130,6 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine sendMessage(TRANSITION_TO_STABLE); } } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { if (!getCurrentState().equals(mBondedDevice)) { Log.e(TAG, "State is: " + getCurrentState()); return; } Message msg = new Message(); msg.what = AUTO_CONNECT_PROFILES; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); Loading Loading @@ -274,16 +271,39 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_AUTO_CONNECT && !mHeadsetService.isConnected(mDevice)) { Log.i(TAG, "Headset:Auto Connect Profiles"); mHeadsetService.connectHeadset(mDevice); } if (mA2dpService != null && mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_AUTO_CONNECT && mA2dpService.getConnectedSinks().length == 0) { Log.i(TAG, "A2dp:Auto Connect Profiles"); mA2dpService.connectSink(mDevice); } } break; case CONNECT_OTHER_PROFILES: if (isPhoneDocked(mDevice)) { break; } if (message.arg1 == CONNECT_A2DP_OUTGOING) { if (mA2dpService != null && mA2dpService.getConnectedSinks().length == 0) { Log.i(TAG, "A2dp:Connect Other Profiles"); mA2dpService.connectSink(mDevice); } } else if (message.arg1 == CONNECT_HFP_OUTGOING) { if (!mHeadsetServiceConnected) { deferMessage(message); } else { if (!mHeadsetService.isConnected(mDevice)) { Log.i(TAG, "Headset:Connect Other Profiles"); mHeadsetService.connectHeadset(mDevice); } } } break; case TRANSITION_TO_STABLE: // ignore. break; Loading Loading @@ -377,6 +397,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -449,6 +470,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -541,6 +563,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -611,6 +634,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -656,6 +680,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine } else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) { return mHeadsetService.acceptIncomingConnect(mDevice); } else if (mHeadsetState == BluetoothHeadset.STATE_DISCONNECTED) { handleConnectionOfOtherProfiles(command); return mHeadsetService.createIncomingConnect(mDevice); } break; Loading @@ -665,6 +690,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine } break; case CONNECT_A2DP_INCOMING: handleConnectionOfOtherProfiles(command); // ignore, Bluez takes care return true; case DISCONNECT_HFP_OUTGOING: Loading Loading @@ -713,6 +739,61 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine return false; } private void handleConnectionOfOtherProfiles(int command) { // The white paper recommendations mentions that when there is a // link loss, it is the responsibility of the remote device to connect. // Many connect only 1 profile - and they connect the second profile on // some user action (like play being pressed) and so we need this code. // Auto Connect code only connects to the last connected device - which // is useful in cases like when the phone reboots. But consider the // following case: // User is connected to the car's phone and A2DP profile. // User comes to the desk and places the phone in the dock // (or any speaker or music system or even another headset) and thus // gets connected to the A2DP profile. User goes back to the car. // Ideally the car's system is supposed to send incoming connections // from both Handsfree and A2DP profile. But they don't. The Auto // connect code, will not work here because we only auto connect to the // last connected device for that profile which in this case is the dock. // Now suppose a user is using 2 headsets simultaneously, one for the // phone profile one for the A2DP profile. If this is the use case, we // expect the user to use the preference to turn off the A2DP profile in // the Settings screen for the first headset. Else, after link loss, // there can be an incoming connection from the first headset which // might result in the connection of the A2DP profile (if the second // headset is slower) and thus the A2DP profile on the second headset // will never get connected. // // TODO(): Handle other profiles here. switch (command) { case CONNECT_HFP_INCOMING: // Connect A2DP if there is no incoming connection // If the priority is OFF - don't auto connect. // If the priority is AUTO_CONNECT, auto connect code takes care. if (mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_ON) { Message msg = new Message(); msg.what = CONNECT_OTHER_PROFILES; msg.arg1 = CONNECT_A2DP_OUTGOING; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); } break; case CONNECT_A2DP_INCOMING: // This is again against spec. HFP incoming connections should be made // before A2DP, so we should not hit this case. But many devices // don't follow this. if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_ON) { Message msg = new Message(); msg.what = CONNECT_OTHER_PROFILES; msg.arg1 = CONNECT_HFP_OUTGOING; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); } break; default: break; } } /*package*/ BluetoothDevice getDevice() { return mDevice; } Loading core/java/android/nfc/NdefTagConnection.java +8 −8 Original line number Diff line number Diff line Loading @@ -42,8 +42,8 @@ public class NdefTagConnection extends RawTagConnection { * Internal constructor, to be used by NfcAdapter * @hide */ /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag, String target) throws RemoteException { super(service, tag); /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException { super(adapter, tag); String[] targets = tag.getNdefTargets(); int i; Loading @@ -63,8 +63,8 @@ public class NdefTagConnection extends RawTagConnection { * Internal constructor, to be used by NfcAdapter * @hide */ /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag) throws RemoteException { this(service, tag, tag.getNdefTargets()[0]); /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException { this(adapter, tag, tag.getNdefTargets()[0]); } /** Loading Loading @@ -97,7 +97,7 @@ public class NdefTagConnection extends RawTagConnection { msgArray[0] = msg; return msgArray; } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); return null; } } Loading Loading @@ -134,7 +134,7 @@ public class NdefTagConnection extends RawTagConnection { throw new IOException(); } } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); } } Loading @@ -161,7 +161,7 @@ public class NdefTagConnection extends RawTagConnection { throw new IOException(); } } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); return false; } } Loading @@ -188,7 +188,7 @@ public class NdefTagConnection extends RawTagConnection { return result; } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); return NDEF_MODE_UNKNOWN; } } Loading core/java/android/nfc/NfcAdapter.java +44 −18 Original line number Diff line number Diff line Loading @@ -168,7 +168,10 @@ public final class NfcAdapter { private static boolean sIsInitialized = false; private static NfcAdapter sAdapter; private final INfcAdapter mService; // Final after construction, except for attemptDeadServiceRecovery() // when NFC crashes. // Not locked - we accept a best effort attempt when NFC crashes. /*package*/ INfcAdapter mService; private NfcAdapter(INfcAdapter service) { mService = service; Loading @@ -194,6 +197,16 @@ public final class NfcAdapter { } } /** get handle to NFC service interface */ private static synchronized INfcAdapter getServiceInterface() { /* get a handle to NFC service */ IBinder b = ServiceManager.getService("nfc"); if (b == null) { return null; } return INfcAdapter.Stub.asInterface(b); } /** * Get a handle to the default NFC Adapter on this Android device. * <p> Loading @@ -214,18 +227,31 @@ public final class NfcAdapter { return null; } /* get a handle to NFC service */ IBinder b = ServiceManager.getService("nfc"); if (b == null) { INfcAdapter service = getServiceInterface(); if (service == null) { Log.e(TAG, "could not retrieve NFC service"); return null; } sAdapter = new NfcAdapter(INfcAdapter.Stub.asInterface(b)); sAdapter = new NfcAdapter(service); return sAdapter; } } /** NFC service dead - attempt best effort recovery */ /*package*/ void attemptDeadServiceRecovery(Exception e) { Log.e(TAG, "NFC service dead - attempting to recover", e); INfcAdapter service = getServiceInterface(); if (service == null) { Log.e(TAG, "could not retrieve NFC service during service recovery"); return; } /* assigning to mService is not thread-safe, but this is best-effort code * and on a well-behaved system should never happen */ mService = service; return; } /** * Return true if this NFC Adapter has any features enabled. * <p> Loading @@ -241,7 +267,7 @@ public final class NfcAdapter { try { return mService.isEnabled(); } catch (RemoteException e) { Log.e(TAG, "RemoteException in isEnabled()", e); attemptDeadServiceRecovery(e); return false; } } Loading @@ -258,7 +284,7 @@ public final class NfcAdapter { try { return mService.enable(); } catch (RemoteException e) { Log.e(TAG, "RemoteException in enable()", e); attemptDeadServiceRecovery(e); return false; } } Loading @@ -277,7 +303,7 @@ public final class NfcAdapter { try { return mService.disable(); } catch (RemoteException e) { Log.e(TAG, "RemoteException in disable()", e); attemptDeadServiceRecovery(e); return false; } } Loading @@ -303,7 +329,7 @@ public final class NfcAdapter { try { mService.localSet(message); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); } } Loading @@ -317,7 +343,7 @@ public final class NfcAdapter { try { return mService.localGet(); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -331,9 +357,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new RawTagConnection(mService, tag); return new RawTagConnection(this, tag); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -347,9 +373,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new RawTagConnection(mService, tag, target); return new RawTagConnection(this, tag, target); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -363,9 +389,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new NdefTagConnection(mService, tag); return new NdefTagConnection(this, tag); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -379,9 +405,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new NdefTagConnection(mService, tag, target); return new NdefTagConnection(this, tag, target); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading Loading
core/java/android/app/Activity.java +0 −1 Original line number Diff line number Diff line Loading @@ -1162,7 +1162,6 @@ public class Activity extends ContextThemeWrapper */ protected void onPause() { mCalled = true; QueuedWork.waitToFinish(); } /** Loading
core/java/android/app/ActivityThread.java +3 −0 Original line number Diff line number Diff line Loading @@ -2265,6 +2265,9 @@ public final class ActivityThread { r.activity.mConfigChangeFlags |= configChanges; Bundle state = performPauseActivity(token, finished, true); // Make sure any pending writes are now committed. QueuedWork.waitToFinish(); // Tell the activity manager we have paused. try { ActivityManagerNative.getDefault().activityPaused(token, state); Loading
core/java/android/bluetooth/BluetoothDeviceProfileState.java +85 −4 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine public static final int UNPAIR = 100; public static final int AUTO_CONNECT_PROFILES = 101; public static final int TRANSITION_TO_STABLE = 102; public static final int CONNECT_OTHER_PROFILES = 103; private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs Loading Loading @@ -129,10 +130,6 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine sendMessage(TRANSITION_TO_STABLE); } } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { if (!getCurrentState().equals(mBondedDevice)) { Log.e(TAG, "State is: " + getCurrentState()); return; } Message msg = new Message(); msg.what = AUTO_CONNECT_PROFILES; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); Loading Loading @@ -274,16 +271,39 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_AUTO_CONNECT && !mHeadsetService.isConnected(mDevice)) { Log.i(TAG, "Headset:Auto Connect Profiles"); mHeadsetService.connectHeadset(mDevice); } if (mA2dpService != null && mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_AUTO_CONNECT && mA2dpService.getConnectedSinks().length == 0) { Log.i(TAG, "A2dp:Auto Connect Profiles"); mA2dpService.connectSink(mDevice); } } break; case CONNECT_OTHER_PROFILES: if (isPhoneDocked(mDevice)) { break; } if (message.arg1 == CONNECT_A2DP_OUTGOING) { if (mA2dpService != null && mA2dpService.getConnectedSinks().length == 0) { Log.i(TAG, "A2dp:Connect Other Profiles"); mA2dpService.connectSink(mDevice); } } else if (message.arg1 == CONNECT_HFP_OUTGOING) { if (!mHeadsetServiceConnected) { deferMessage(message); } else { if (!mHeadsetService.isConnected(mDevice)) { Log.i(TAG, "Headset:Connect Other Profiles"); mHeadsetService.connectHeadset(mDevice); } } } break; case TRANSITION_TO_STABLE: // ignore. break; Loading Loading @@ -377,6 +397,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -449,6 +470,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -541,6 +563,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -611,6 +634,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine case DISCONNECT_PBAP_OUTGOING: case UNPAIR: case AUTO_CONNECT_PROFILES: case CONNECT_OTHER_PROFILES: deferMessage(message); break; case TRANSITION_TO_STABLE: Loading Loading @@ -656,6 +680,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine } else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) { return mHeadsetService.acceptIncomingConnect(mDevice); } else if (mHeadsetState == BluetoothHeadset.STATE_DISCONNECTED) { handleConnectionOfOtherProfiles(command); return mHeadsetService.createIncomingConnect(mDevice); } break; Loading @@ -665,6 +690,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine } break; case CONNECT_A2DP_INCOMING: handleConnectionOfOtherProfiles(command); // ignore, Bluez takes care return true; case DISCONNECT_HFP_OUTGOING: Loading Loading @@ -713,6 +739,61 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine return false; } private void handleConnectionOfOtherProfiles(int command) { // The white paper recommendations mentions that when there is a // link loss, it is the responsibility of the remote device to connect. // Many connect only 1 profile - and they connect the second profile on // some user action (like play being pressed) and so we need this code. // Auto Connect code only connects to the last connected device - which // is useful in cases like when the phone reboots. But consider the // following case: // User is connected to the car's phone and A2DP profile. // User comes to the desk and places the phone in the dock // (or any speaker or music system or even another headset) and thus // gets connected to the A2DP profile. User goes back to the car. // Ideally the car's system is supposed to send incoming connections // from both Handsfree and A2DP profile. But they don't. The Auto // connect code, will not work here because we only auto connect to the // last connected device for that profile which in this case is the dock. // Now suppose a user is using 2 headsets simultaneously, one for the // phone profile one for the A2DP profile. If this is the use case, we // expect the user to use the preference to turn off the A2DP profile in // the Settings screen for the first headset. Else, after link loss, // there can be an incoming connection from the first headset which // might result in the connection of the A2DP profile (if the second // headset is slower) and thus the A2DP profile on the second headset // will never get connected. // // TODO(): Handle other profiles here. switch (command) { case CONNECT_HFP_INCOMING: // Connect A2DP if there is no incoming connection // If the priority is OFF - don't auto connect. // If the priority is AUTO_CONNECT, auto connect code takes care. if (mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_ON) { Message msg = new Message(); msg.what = CONNECT_OTHER_PROFILES; msg.arg1 = CONNECT_A2DP_OUTGOING; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); } break; case CONNECT_A2DP_INCOMING: // This is again against spec. HFP incoming connections should be made // before A2DP, so we should not hit this case. But many devices // don't follow this. if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_ON) { Message msg = new Message(); msg.what = CONNECT_OTHER_PROFILES; msg.arg1 = CONNECT_HFP_OUTGOING; sendMessageDelayed(msg, AUTO_CONNECT_DELAY); } break; default: break; } } /*package*/ BluetoothDevice getDevice() { return mDevice; } Loading
core/java/android/nfc/NdefTagConnection.java +8 −8 Original line number Diff line number Diff line Loading @@ -42,8 +42,8 @@ public class NdefTagConnection extends RawTagConnection { * Internal constructor, to be used by NfcAdapter * @hide */ /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag, String target) throws RemoteException { super(service, tag); /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException { super(adapter, tag); String[] targets = tag.getNdefTargets(); int i; Loading @@ -63,8 +63,8 @@ public class NdefTagConnection extends RawTagConnection { * Internal constructor, to be used by NfcAdapter * @hide */ /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag) throws RemoteException { this(service, tag, tag.getNdefTargets()[0]); /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException { this(adapter, tag, tag.getNdefTargets()[0]); } /** Loading Loading @@ -97,7 +97,7 @@ public class NdefTagConnection extends RawTagConnection { msgArray[0] = msg; return msgArray; } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); return null; } } Loading Loading @@ -134,7 +134,7 @@ public class NdefTagConnection extends RawTagConnection { throw new IOException(); } } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); } } Loading @@ -161,7 +161,7 @@ public class NdefTagConnection extends RawTagConnection { throw new IOException(); } } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); return false; } } Loading @@ -188,7 +188,7 @@ public class NdefTagConnection extends RawTagConnection { return result; } catch (RemoteException e) { Log.e(TAG, "NFC service died"); attemptDeadServiceRecovery(e); return NDEF_MODE_UNKNOWN; } } Loading
core/java/android/nfc/NfcAdapter.java +44 −18 Original line number Diff line number Diff line Loading @@ -168,7 +168,10 @@ public final class NfcAdapter { private static boolean sIsInitialized = false; private static NfcAdapter sAdapter; private final INfcAdapter mService; // Final after construction, except for attemptDeadServiceRecovery() // when NFC crashes. // Not locked - we accept a best effort attempt when NFC crashes. /*package*/ INfcAdapter mService; private NfcAdapter(INfcAdapter service) { mService = service; Loading @@ -194,6 +197,16 @@ public final class NfcAdapter { } } /** get handle to NFC service interface */ private static synchronized INfcAdapter getServiceInterface() { /* get a handle to NFC service */ IBinder b = ServiceManager.getService("nfc"); if (b == null) { return null; } return INfcAdapter.Stub.asInterface(b); } /** * Get a handle to the default NFC Adapter on this Android device. * <p> Loading @@ -214,18 +227,31 @@ public final class NfcAdapter { return null; } /* get a handle to NFC service */ IBinder b = ServiceManager.getService("nfc"); if (b == null) { INfcAdapter service = getServiceInterface(); if (service == null) { Log.e(TAG, "could not retrieve NFC service"); return null; } sAdapter = new NfcAdapter(INfcAdapter.Stub.asInterface(b)); sAdapter = new NfcAdapter(service); return sAdapter; } } /** NFC service dead - attempt best effort recovery */ /*package*/ void attemptDeadServiceRecovery(Exception e) { Log.e(TAG, "NFC service dead - attempting to recover", e); INfcAdapter service = getServiceInterface(); if (service == null) { Log.e(TAG, "could not retrieve NFC service during service recovery"); return; } /* assigning to mService is not thread-safe, but this is best-effort code * and on a well-behaved system should never happen */ mService = service; return; } /** * Return true if this NFC Adapter has any features enabled. * <p> Loading @@ -241,7 +267,7 @@ public final class NfcAdapter { try { return mService.isEnabled(); } catch (RemoteException e) { Log.e(TAG, "RemoteException in isEnabled()", e); attemptDeadServiceRecovery(e); return false; } } Loading @@ -258,7 +284,7 @@ public final class NfcAdapter { try { return mService.enable(); } catch (RemoteException e) { Log.e(TAG, "RemoteException in enable()", e); attemptDeadServiceRecovery(e); return false; } } Loading @@ -277,7 +303,7 @@ public final class NfcAdapter { try { return mService.disable(); } catch (RemoteException e) { Log.e(TAG, "RemoteException in disable()", e); attemptDeadServiceRecovery(e); return false; } } Loading @@ -303,7 +329,7 @@ public final class NfcAdapter { try { mService.localSet(message); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); } } Loading @@ -317,7 +343,7 @@ public final class NfcAdapter { try { return mService.localGet(); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -331,9 +357,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new RawTagConnection(mService, tag); return new RawTagConnection(this, tag); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -347,9 +373,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new RawTagConnection(mService, tag, target); return new RawTagConnection(this, tag, target); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -363,9 +389,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new NdefTagConnection(mService, tag); return new NdefTagConnection(this, tag); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading @@ -379,9 +405,9 @@ public final class NfcAdapter { throw new IllegalArgumentException("mock tag cannot be used for connections"); } try { return new NdefTagConnection(mService, tag, target); return new NdefTagConnection(this, tag, target); } catch (RemoteException e) { Log.e(TAG, "NFC service died", e); attemptDeadServiceRecovery(e); return null; } } Loading