'Get list of users that have had the devices updated, or have newly
joined a room, that `user_id` may be interested in.
Args:
user_id (str)
from_token (StreamToken)'

@measure_func('device.get_user_ids_changed')
@defer.inlineCallbacks
def get_user_ids_changed(self, user_id, from_token):

    room_ids = (yield self.store.get_rooms_for_user(user_id))
    changed = (yield self.store.get_user_whose_devices_changed(from_token.device_list_key))
    rooms_changed = self.store.get_rooms_that_changed(room_ids, from_token.room_key)
    stream_ordering = RoomStreamToken.parse_stream_token(from_token.room_key).stream
    possibly_changed = set(changed)
    for room_id in rooms_changed:
        try:
            event_ids = (yield self.store.get_forward_extremeties_for_room(room_id, stream_ordering=stream_ordering))
        except errors.StoreError:
            event_ids = []
        current_state_ids = (yield self.store.get_current_state_ids(room_id))
        if (not event_ids):
            for (key, event_id) in current_state_ids.iteritems():
                (etype, state_key) = key
                if (etype != EventTypes.Member):
                    continue
                possibly_changed.add(state_key)
            continue
        prev_state_ids = (yield self.store.get_state_ids_for_events(event_ids))
        for (key, event_id) in current_state_ids.iteritems():
            (etype, state_key) = key
            if (etype != EventTypes.Member):
                continue
            for state_dict in prev_state_ids.values():
                prev_event_id = state_dict.get(key, None)
                if ((not prev_event_id) or (prev_event_id != event_id)):
                    possibly_changed.add(state_key)
                    break
    users_who_share_room = (yield self.store.get_users_who_share_room_with_user(user_id))
    defer.returnValue((users_who_share_room & possibly_changed))
