001/**
002 *
003 * Copyright 2017 Paul Schaub
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.omemo.internal;
018
019import java.io.Serializable;
020import java.util.HashSet;
021import java.util.Set;
022
023/**
024 * This class is used to represent device lists of contacts.
025 * There are active devices (a set of device ids, which was published with the last device list update)
026 * and inactive devices (set of devices that once were active, but are not included in recent list updates).
027 * Both kinds are cached by the client. When a device that was active in the last update is not included in
028 * a new update, it becomes an inactive device. Vice versa, inactive devices can also become active again, by
029 * being included in the latest device list update.
030 * <p>
031 * The client ensures, that his own device id is on the list of active devices, as soon as he gets online.
032 *
033 * @author Paul Schaub
034 */
035public class OmemoCachedDeviceList implements Serializable {
036    private static final long serialVersionUID = 3153579238321261203L;
037
038    private final Set<Integer> activeDevices;
039    private final Set<Integer> inactiveDevices;
040
041    public OmemoCachedDeviceList() {
042        this.activeDevices = new HashSet<>();
043        this.inactiveDevices = new HashSet<>();
044    }
045
046    public OmemoCachedDeviceList(Set<Integer> activeDevices, Set<Integer> inactiveDevices) {
047        this();
048        this.activeDevices.addAll(activeDevices);
049        this.inactiveDevices.addAll(inactiveDevices);
050    }
051
052    public OmemoCachedDeviceList(OmemoCachedDeviceList original) {
053        this(original.getActiveDevices(), original.getInactiveDevices());
054    }
055
056    /**
057     * Returns all active devices.
058     * Active devices are all devices that were in the latest DeviceList update.
059     *
060     * @return active devices
061     */
062    public Set<Integer> getActiveDevices() {
063        return activeDevices;
064    }
065
066    /**
067     * Return all inactive devices.
068     * Inactive devices are devices which were in a past DeviceList update once, but were not included in
069     * the latest update.
070     *
071     * @return inactive devices
072     */
073    public Set<Integer> getInactiveDevices() {
074        return inactiveDevices;
075    }
076
077    /**
078     * Returns an OmemoDeviceListElement containing all devices (active and inactive).
079     *
080     * @return all devices
081     */
082    public Set<Integer> getAllDevices() {
083        Set<Integer> all = new HashSet<>();
084        all.addAll(activeDevices);
085        all.addAll(inactiveDevices);
086        return all;
087    }
088
089    /**
090     * Merge a device list update into the CachedDeviceList.
091     * The source code should be self explanatory.
092     *
093     * @param deviceListUpdate received device list update
094     */
095    public void merge(Set<Integer> deviceListUpdate) {
096        inactiveDevices.addAll(activeDevices);
097        activeDevices.clear();
098        activeDevices.addAll(deviceListUpdate);
099        inactiveDevices.removeAll(activeDevices);
100    }
101
102    /**
103     * Add a device to the list of active devices and remove it from inactive.
104     *
105     * @param deviceId deviceId that will be added
106     */
107    public void addDevice(int deviceId) {
108        activeDevices.add(deviceId);
109        inactiveDevices.remove(deviceId);
110    }
111
112    public void addInactiveDevice(int deviceId) {
113        activeDevices.remove(deviceId);
114        inactiveDevices.add(deviceId);
115    }
116
117    /**
118     * Returns true if deviceId is either in the list of active or inactive devices.
119     *
120     * @param deviceId id
121     * @return true or false
122     */
123    public boolean contains(int deviceId) {
124        return activeDevices.contains(deviceId) || inactiveDevices.contains(deviceId);
125    }
126
127    public boolean isActive(int deviceId) {
128        return getActiveDevices().contains(deviceId);
129    }
130
131    @Override
132    public String toString() {
133        String out = "active: [";
134        for (int id : activeDevices) {
135            out += id + " ";
136        }
137        out += "] inacitve: [";
138        for (int id : inactiveDevices) {
139            out += id + " ";
140        }
141        out += "]";
142        return out;
143    }
144}