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

Commit b429a083 authored by David van Tonder's avatar David van Tonder Committed by Gerrit Code Review
Browse files

Merge "[2/2] Add bluetooth triggers to profiles" into cm-10.1

parents 54663c09 3a6696b2
Loading
Loading
Loading
Loading
+157 −29
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

/**
@@ -67,7 +68,7 @@ public final class Profile implements Parcelable, Comparable {

    private Map<Integer, StreamSettings> streams = new HashMap<Integer, StreamSettings>();

    private Map<String, Integer> mWifiTriggers = new HashMap<String, Integer>();
    private Map<String, ProfileTrigger> mTriggers = new HashMap<String, ProfileTrigger>();

    private Map<Integer, ConnectionSettings> connections = new HashMap<Integer, ConnectionSettings>();

@@ -84,6 +85,12 @@ public final class Profile implements Parcelable, Comparable {
        public static final int DISABLE = 2;
    }

    /** @hide */
    public static class TriggerType {
        public static final int WIFI = 0;
        public static final int BLUETOOTH = 1;
    }

    /** @hide */
    public static class TriggerState {
        public static final int ON_CONNECT = 0;
@@ -91,6 +98,111 @@ public final class Profile implements Parcelable, Comparable {
        public static final int DISABLED = 2;
    }

    public static class ProfileTrigger implements Parcelable {
        private int mType;
        private String mId;
        private String mName;
        private int mState;

        public ProfileTrigger(int type, String id, int state, String name) {
            mType = type;
            mId = id;
            mState = state;
            mName = name;
        }

        private ProfileTrigger(Parcel in) {
            mType = in.readInt();
            mId = in.readString();
            mState = in.readInt();
            mName = in.readString();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mType);
            dest.writeString(mId);
            dest.writeInt(mState);
            dest.writeString(mName);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        public int getType() {
            return mType;
        }

        public String getName() {
            return mName;
        }

        public String getId() {
            return mId;
        }

        public int getState() {
            return mState;
        }

        public void getXmlString(StringBuilder builder, Context context) {
            final String itemType = mType == TriggerType.WIFI ? "wifiAP" : "btDevice";

            builder.append("<");
            builder.append(itemType);
            builder.append(" ");
            builder.append(getIdType(mType));
            builder.append("=\"");
            builder.append(mId);
            builder.append("\" state=\"");
            builder.append(mState);
            builder.append("\" name=\"");
            builder.append(mName);
            builder.append("\"></");
            builder.append(itemType);
            builder.append(">\n");
        }

        public static ProfileTrigger fromXml(XmlPullParser xpp, Context context) {
            final String name = xpp.getName();
            final int type;

            if (name.equals("wifiAP")) {
                type = TriggerType.WIFI;
            } else if (name.equals("btDevice")) {
                type = TriggerType.BLUETOOTH;
            } else {
                return null;
            }

            String id = xpp.getAttributeValue(null, getIdType(type));
            int state = Integer.valueOf(xpp.getAttributeValue(null, "state"));
            String triggerName =  xpp.getAttributeValue(null, "name");
            if (triggerName == null) {
                triggerName = id;
            }

            return new ProfileTrigger(type, id, state, triggerName);
        }

        private static String getIdType(int type) {
            return type == TriggerType.WIFI ? "ssid" : "address";
        }

        public static final Parcelable.Creator<ProfileTrigger> CREATOR = new Parcelable.Creator<ProfileTrigger>() {
            public ProfileTrigger createFromParcel(Parcel in) {
                return new ProfileTrigger(in);
            }

            @Override
            public ProfileTrigger[] newArray(int size) {
                return new ProfileTrigger[size];
            }
        };
    }

    /** @hide */
    public static final Parcelable.Creator<Profile> CREATOR = new Parcelable.Creator<Profile>() {
        public Profile createFromParcel(Parcel in) {
@@ -120,22 +232,44 @@ public final class Profile implements Parcelable, Comparable {
        readFromParcel(in);
    }

    public int getWifiTrigger(String ssid) {
        if (ssid != null && mWifiTriggers.containsKey(ssid)) {
            return mWifiTriggers.get(ssid);
    public int getTrigger(int type, String id) {
        ProfileTrigger trigger = id != null ? mTriggers.get(id) : null;
        if (trigger != null) {
            return trigger.mState;
        }
        return TriggerState.DISABLED;
    }

    public void setWifiTrigger(String ssid, int value) {
        if (ssid == null || value < TriggerState.ON_CONNECT || value > TriggerState.DISABLED) {
    public ArrayList<ProfileTrigger> getTriggersFromType(int type) {
        ArrayList<ProfileTrigger> result = new ArrayList<ProfileTrigger>();
        for (Entry<String, ProfileTrigger> profileTrigger:  mTriggers.entrySet()) {
            ProfileTrigger trigger = profileTrigger.getValue();
            if (trigger.getType() == type) {
                result.add(trigger);
            }
        }
        return result;
    }

    public void setTrigger(int type, String id, int state, String name) {
        if (id == null
                || type < TriggerType.WIFI || type > TriggerType.BLUETOOTH
                || state < TriggerState.ON_CONNECT || state > TriggerState.DISABLED) {
            return;
        }
        if (value == TriggerState.DISABLED && mWifiTriggers.containsKey(ssid)) {
            mWifiTriggers.remove(ssid);

        ProfileTrigger trigger = mTriggers.get(id);

        if (state == TriggerState.DISABLED) {
            if (trigger != null) {
                mTriggers.remove(id);
            }
        } else if (trigger != null) {
            trigger.mState = state;
        } else {
            mWifiTriggers.put(ssid, value);
            mTriggers.put(id, new ProfileTrigger(type, id, state, name));
        }

        mDirty = true;
    }

@@ -212,7 +346,7 @@ public final class Profile implements Parcelable, Comparable {
        dest.writeParcelable(mRingMode, flags);
        dest.writeParcelable(mAirplaneMode, flags);
        dest.writeInt(mScreenLockMode);
        dest.writeMap(mWifiTriggers);
        dest.writeMap(mTriggers);
    }

    /** @hide */
@@ -245,7 +379,7 @@ public final class Profile implements Parcelable, Comparable {
        mRingMode = (RingModeSettings) in.readParcelable(null);
        mAirplaneMode = (AirplaneModeSettings) in.readParcelable(null);
        mScreenLockMode = in.readInt();
        in.readMap(mWifiTriggers, null);
        in.readMap(mTriggers, null);
    }

    public String getName() {
@@ -430,14 +564,10 @@ public final class Profile implements Parcelable, Comparable {
        for (ConnectionSettings cs : connections.values()) {
            cs.getXmlString(builder, context);
        }
        if (!mWifiTriggers.isEmpty()) {
        if (!mTriggers.isEmpty()) {
            builder.append("<triggers>\n");
            for (Map.Entry<String,Integer> e : mWifiTriggers.entrySet()) {
                builder.append("<wifiAP ssid=\"");
                builder.append(e.getKey());
                builder.append("\" state=\"");
                builder.append(e.getValue());
                builder.append("\"></wifiAP>\n");
            for (ProfileTrigger trigger : mTriggers.values()) {
                trigger.getXmlString(builder, context);
            }
            builder.append("</triggers>\n");
        }
@@ -469,20 +599,18 @@ public final class Profile implements Parcelable, Comparable {
        return uuids;
    }

    private static HashMap<String, Integer> readWifiTriggersFromXml(XmlPullParser xpp, Context context)
            throws XmlPullParserException,
            IOException {
    private static void readTriggersFromXml(XmlPullParser xpp, Context context, Profile profile)
            throws XmlPullParserException, IOException {
        int event = xpp.next();
        HashMap<String, Integer> triggers = new HashMap<String, Integer>();
        while (event != XmlPullParser.END_TAG || xpp.getName().equals("wifiAP")) {
        while (event != XmlPullParser.END_TAG || !xpp.getName().equals("triggers")) {
            if (event == XmlPullParser.START_TAG) {
                String ssid = xpp.getAttributeValue(null, "ssid");
                String state = xpp.getAttributeValue(null, "state");
                triggers.put(ssid, Integer.valueOf(state));
                ProfileTrigger trigger = ProfileTrigger.fromXml(xpp, context);
                if (trigger != null) {
                    profile.mTriggers.put(trigger.mId, trigger);
                }
            }
            event = xpp.next();
        }
        return triggers;
    }

    /** @hide */
@@ -560,7 +688,7 @@ public final class Profile implements Parcelable, Comparable {
                    profile.connections.put(cs.getConnectionId(), cs);
                }
                if (name.equals("triggers")) {
                    profile.mWifiTriggers = readWifiTriggersFromXml(xpp, context);
                    readTriggersFromXml(xpp, context, profile);
                }
            }
            event = xpp.next();
+28 −12
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.app.IProfileManager;
import android.app.NotificationGroup;
import android.app.Profile;
import android.app.ProfileGroup;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -89,13 +91,12 @@ public class ProfileManagerService extends IProfileManager.Stub {
    private boolean mDirty;

    private WifiManager mWifiManager;
    private String mlastConnectedSSID;
    private String mLastConnectedSSID;

    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
                persistIfDirty();
                initialize();
@@ -108,7 +109,7 @@ public class ProfileManagerService extends IProfileManager.Stub {
                switch (state) {
                    case COMPLETED:
                        triggerState = Profile.TriggerState.ON_CONNECT;
                        mlastConnectedSSID = getActiveSSID();
                        mLastConnectedSSID = getActiveSSID();
                        break;
                    case DISCONNECTED:
                        triggerState = Profile.TriggerState.ON_DISCONNECT;
@@ -116,14 +117,27 @@ public class ProfileManagerService extends IProfileManager.Stub {
                    default:
                        return;
                }
                checkTriggers(Profile.TriggerType.WIFI, mLastConnectedSSID, triggerState);
            } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)
                    || action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                int triggerState = action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)
                        ? Profile.TriggerState.ON_CONNECT : Profile.TriggerState.ON_DISCONNECT;
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                checkTriggers(Profile.TriggerType.BLUETOOTH, device.getAddress(), triggerState);
            }
        }

        private void checkTriggers(int type, String id, int newState) {
            for (Profile p : mProfiles.values()) {
                    if (triggerState ==  p.getWifiTrigger(mlastConnectedSSID)) {
                if (newState != p.getTrigger(type, id)) {
                    continue;
                }

                try {
                    setActiveProfile(p, true);
                } catch (RemoteException e) {
                            Log.e(TAG, "Could not update profile on wifi AP change", e);
                        }
                    }
                    Log.e(TAG, "Could not update profile on trigger", e);
                }
            }
        }
@@ -132,7 +146,7 @@ public class ProfileManagerService extends IProfileManager.Stub {
    public ProfileManagerService(Context context) {
        mContext = context;
        mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
        mlastConnectedSSID = getActiveSSID();
        mLastConnectedSSID = getActiveSSID();

        mWildcardGroup = new NotificationGroup(
                context.getString(com.android.internal.R.string.wildcardProfile),
@@ -145,6 +159,8 @@ public class ProfileManagerService extends IProfileManager.Stub {
        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
        filter.addAction(Intent.ACTION_SHUTDOWN);
        filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        mContext.registerReceiver(mIntentReceiver, filter);
    }