1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.bluetooth.le;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
22/**
23 * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each
24 * Bluetooth LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an
25 * instance of this class.
26 */
27public final class AdvertiseSettings implements Parcelable {
28    /**
29     * Perform Bluetooth LE advertising in low power mode. This is the default and preferred
30     * advertising mode as it consumes the least power.
31     */
32    public static final int ADVERTISE_MODE_LOW_POWER = 0;
33
34    /**
35     * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising
36     * frequency and power consumption.
37     */
38    public static final int ADVERTISE_MODE_BALANCED = 1;
39
40    /**
41     * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power
42     * consumption and should not be used for continuous background advertising.
43     */
44    public static final int ADVERTISE_MODE_LOW_LATENCY = 2;
45
46    /**
47     * Advertise using the lowest transmission (TX) power level. Low transmission power can be used
48     * to restrict the visibility range of advertising packets.
49     */
50    public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0;
51
52    /**
53     * Advertise using low TX power level.
54     */
55    public static final int ADVERTISE_TX_POWER_LOW = 1;
56
57    /**
58     * Advertise using medium TX power level.
59     */
60    public static final int ADVERTISE_TX_POWER_MEDIUM = 2;
61
62    /**
63     * Advertise using high TX power level. This corresponds to largest visibility range of the
64     * advertising packet.
65     */
66    public static final int ADVERTISE_TX_POWER_HIGH = 3;
67
68    /**
69     * The maximum limited advertisement duration as specified by the Bluetooth SIG
70     */
71    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
72
73    private final int mAdvertiseMode;
74    private final int mAdvertiseTxPowerLevel;
75    private final int mAdvertiseTimeoutMillis;
76    private final boolean mAdvertiseConnectable;
77
78    private AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel,
79            boolean advertiseConnectable, int advertiseTimeout) {
80        mAdvertiseMode = advertiseMode;
81        mAdvertiseTxPowerLevel = advertiseTxPowerLevel;
82        mAdvertiseConnectable = advertiseConnectable;
83        mAdvertiseTimeoutMillis = advertiseTimeout;
84    }
85
86    private AdvertiseSettings(Parcel in) {
87        mAdvertiseMode = in.readInt();
88        mAdvertiseTxPowerLevel = in.readInt();
89        mAdvertiseConnectable = in.readInt() != 0 ? true : false;
90        mAdvertiseTimeoutMillis = in.readInt();
91    }
92
93    /**
94     * Returns the advertise mode.
95     */
96    public int getMode() {
97        return mAdvertiseMode;
98    }
99
100    /**
101     * Returns the TX power level for advertising.
102     */
103    public int getTxPowerLevel() {
104        return mAdvertiseTxPowerLevel;
105    }
106
107    /**
108     * Returns whether the advertisement will indicate connectable.
109     */
110    public boolean isConnectable() {
111        return mAdvertiseConnectable;
112    }
113
114    /**
115     * Returns the advertising time limit in milliseconds.
116     */
117    public int getTimeout() {
118        return mAdvertiseTimeoutMillis;
119    }
120
121    @Override
122    public String toString() {
123        return "Settings [mAdvertiseMode=" + mAdvertiseMode
124             + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
125             + ", mAdvertiseConnectable=" + mAdvertiseConnectable
126             + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
127    }
128
129    @Override
130    public int describeContents() {
131        return 0;
132    }
133
134    @Override
135    public void writeToParcel(Parcel dest, int flags) {
136        dest.writeInt(mAdvertiseMode);
137        dest.writeInt(mAdvertiseTxPowerLevel);
138        dest.writeInt(mAdvertiseConnectable ? 1 : 0);
139        dest.writeInt(mAdvertiseTimeoutMillis);
140    }
141
142    public static final Parcelable.Creator<AdvertiseSettings> CREATOR =
143            new Creator<AdvertiseSettings>() {
144            @Override
145                public AdvertiseSettings[] newArray(int size) {
146                    return new AdvertiseSettings[size];
147                }
148
149            @Override
150                public AdvertiseSettings createFromParcel(Parcel in) {
151                    return new AdvertiseSettings(in);
152                }
153            };
154
155    /**
156     * Builder class for {@link AdvertiseSettings}.
157     */
158    public static final class Builder {
159        private int mMode = ADVERTISE_MODE_LOW_POWER;
160        private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM;
161        private int mTimeoutMillis = 0;
162        private boolean mConnectable = true;
163
164        /**
165         * Set advertise mode to control the advertising power and latency.
166         *
167         * @param advertiseMode Bluetooth LE Advertising mode, can only be one of
168         *            {@link AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
169         *            {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED}, or
170         *            {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
171         * @throws IllegalArgumentException If the advertiseMode is invalid.
172         */
173        public Builder setAdvertiseMode(int advertiseMode) {
174            if (advertiseMode < ADVERTISE_MODE_LOW_POWER
175                    || advertiseMode > ADVERTISE_MODE_LOW_LATENCY) {
176                throw new IllegalArgumentException("unknown mode " + advertiseMode);
177            }
178            mMode = advertiseMode;
179            return this;
180        }
181
182        /**
183         * Set advertise TX power level to control the transmission power level for the advertising.
184         *
185         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
186         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW},
187         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
188         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM} or
189         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
190         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
191         */
192        public Builder setTxPowerLevel(int txPowerLevel) {
193            if (txPowerLevel < ADVERTISE_TX_POWER_ULTRA_LOW
194                    || txPowerLevel > ADVERTISE_TX_POWER_HIGH) {
195                throw new IllegalArgumentException("unknown tx power level " + txPowerLevel);
196            }
197            mTxPowerLevel = txPowerLevel;
198            return this;
199        }
200
201        /**
202         * Set whether the advertisement type should be connectable or non-connectable.
203         *
204         * @param connectable Controls whether the advertisment type will be connectable (true)
205         *                    or non-connectable (false).
206         */
207        public Builder setConnectable(boolean connectable) {
208            mConnectable = connectable;
209            return this;
210        }
211
212        /**
213         * Limit advertising to a given amount of time.
214         * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds.
215         *                       A value of 0 will disable the time limit.
216         * @throws IllegalArgumentException If the provided timeout is over 180000 ms.
217         */
218        public Builder setTimeout(int timeoutMillis) {
219            if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
220                throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
221                                    + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
222            }
223            mTimeoutMillis = timeoutMillis;
224            return this;
225        }
226
227        /**
228         * Build the {@link AdvertiseSettings} object.
229         */
230        public AdvertiseSettings build() {
231            return new AdvertiseSettings(mMode, mTxPowerLevel, mConnectable, mTimeoutMillis);
232        }
233    }
234}
235