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

Commit 88b77ad7 authored by The Android Automerger's avatar The Android Automerger
Browse files

Merge branch 'gingerbread' into gingerbread-release

parents e4dccc95 9112b8eb
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -1162,7 +1162,6 @@ public class Activity extends ContextThemeWrapper
     */
    protected void onPause() {
        mCalled = true;
        QueuedWork.waitToFinish();
    }

    /**
+3 −0
Original line number Diff line number Diff line
@@ -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);
+85 −4
Original line number Diff line number Diff line
@@ -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

@@ -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);
@@ -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;
@@ -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:
@@ -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:
@@ -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:
@@ -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:
@@ -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;
@@ -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:
@@ -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;
    }
+8 −8
Original line number Diff line number Diff line
@@ -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;

@@ -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]);
    }

    /**
@@ -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;
        }
    }
@@ -134,7 +134,7 @@ public class NdefTagConnection extends RawTagConnection {
                    throw new IOException();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died");
            attemptDeadServiceRecovery(e);
        }
    }

@@ -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;
        }
    }
@@ -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;
        }
    }
+44 −18
Original line number Diff line number Diff line
@@ -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;
@@ -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>
@@ -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>
@@ -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;
        }
    }
@@ -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;
        }
    }
@@ -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;
        }
    }
@@ -303,7 +329,7 @@ public final class NfcAdapter {
        try {
            mService.localSet(message);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
        }
    }

@@ -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;
        }
    }
@@ -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;
        }
    }
@@ -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;
        }
    }
@@ -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;
        }
    }
@@ -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