Merge "Post runnables instead of sending messages."
diff --git a/compiled-classes-phone b/compiled-classes-phone
index ec3371e..2cbfc22 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -633,6 +633,7 @@
android.bluetooth.BluetoothClass
android.bluetooth.BluetoothClass$1
android.bluetooth.BluetoothCodecConfig
+android.bluetooth.BluetoothCodecStatus
android.bluetooth.BluetoothDevice
android.bluetooth.BluetoothDevice$1
android.bluetooth.BluetoothDevice$2
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 1165fce..4960159 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -105,10 +105,9 @@
* Intent used to broadcast the change in the Audio Codec state of the
* A2DP Source profile.
*
- * <p>This intent will have 3 extras:
+ * <p>This intent will have 2 extras:
* <ul>
- * <li> {@link #EXTRA_CODEC_CONFIG} - The current codec configuration. </li>
- * <li> {@link #EXTRA_PREVIOUS_CODEC_CONFIG} - The previous codec configuration. </li>
+ * <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
* connected, otherwise it is not included.</li>
* </ul>
@@ -564,24 +563,24 @@
}
/**
- * Gets the current codec configuration.
+ * Gets the current codec status (configuration and capability).
*
- * @return the current codec configuration
+ * @return the current codec status
* @hide
*/
- public BluetoothCodecConfig getCodecConfig() {
- if (DBG) Log.d(TAG, "getCodecConfig");
+ public BluetoothCodecStatus getCodecStatus() {
+ if (DBG) Log.d(TAG, "getCodecStatus");
try {
mServiceLock.readLock().lock();
if (mService != null && isEnabled()) {
- return mService.getCodecConfig();
+ return mService.getCodecStatus();
}
if (mService == null) {
Log.w(TAG, "Proxy not attached to service");
}
return null;
} catch (RemoteException e) {
- Log.e(TAG, "Error talking to BT service in getCodecConfig()", e);
+ Log.e(TAG, "Error talking to BT service in getCodecStatus()", e);
return null;
} finally {
mServiceLock.readLock().unlock();
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index a37a0b3..a482103 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -29,24 +29,6 @@
* {@hide}
*/
public final class BluetoothCodecConfig implements Parcelable {
-
- /**
- * Extra for the codec configuration intents of the individual profiles.
- *
- * This extra represents the current codec configuration of the A2DP
- * profile.
- */
- public static final String EXTRA_CODEC_CONFIG = "android.bluetooth.codec.extra.CODEC_CONFIG";
-
- /**
- * Extra for the codec configuration intents of the individual profiles.
- *
- * This extra represents the previous codec configuration of the A2DP
- * profile.
- */
- public static final String EXTRA_PREVIOUS_CODEC_CONFIG =
- "android.bluetooth.codec.extra.PREVIOUS_CODEC_CONFIG";
-
// Add an entry for each source codec here.
// NOTE: The values should be same as those listed in the following file:
// hardware/libhardware/include/hardware/bt_av.h
@@ -128,13 +110,93 @@
mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
}
+ /**
+ * Checks whether the object contains valid codec configuration.
+ *
+ * @return true if the object contains valid codec configuration,
+ * otherwise false.
+ */
+ public boolean isValid() {
+ return (mSampleRate != SAMPLE_RATE_NONE) &&
+ (mBitsPerSample != BITS_PER_SAMPLE_NONE) &&
+ (mChannelMode != CHANNEL_MODE_NONE);
+ }
+
+ /**
+ * Adds capability string to an existing string.
+ *
+ * @param prevStr the previous string with the capabilities. Can be
+ * a null pointer.
+ * @param capStr the capability string to append to prevStr argument.
+ * @return the result string in the form "prevStr|capStr".
+ */
+ private static String appendCapabilityToString(String prevStr,
+ String capStr) {
+ if (prevStr == null) {
+ return capStr;
+ }
+ return prevStr + "|" + capStr;
+ }
+
@Override
public String toString() {
- return "{mCodecType:" + mCodecType +
+ String sampleRateStr = null;
+ if (mSampleRate == SAMPLE_RATE_NONE) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE");
+ }
+ if ((mSampleRate & SAMPLE_RATE_44100) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "44100");
+ }
+ if ((mSampleRate & SAMPLE_RATE_48000) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "48000");
+ }
+ if ((mSampleRate & SAMPLE_RATE_88200) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "88200");
+ }
+ if ((mSampleRate & SAMPLE_RATE_96000) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "96000");
+ }
+ if ((mSampleRate & SAMPLE_RATE_176400) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "176400");
+ }
+ if ((mSampleRate & SAMPLE_RATE_192000) != 0) {
+ sampleRateStr = appendCapabilityToString(sampleRateStr, "192000");
+ }
+
+ String bitsPerSampleStr = null;
+ if (mBitsPerSample == BITS_PER_SAMPLE_NONE) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE");
+ }
+ if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16");
+ }
+ if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24");
+ }
+ if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) {
+ bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32");
+ }
+
+ String channelModeStr = null;
+ if (mChannelMode == CHANNEL_MODE_NONE) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "NONE");
+ }
+ if ((mChannelMode & CHANNEL_MODE_MONO) != 0) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "MONO");
+ }
+ if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
+ }
+
+ return "{codecName:" + getCodecName() +
+ ",mCodecType:" + mCodecType +
",mCodecPriority:" + mCodecPriority +
",mSampleRate:" + String.format("0x%x", mSampleRate) +
+ "(" + sampleRateStr + ")" +
",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) +
+ "(" + bitsPerSampleStr + ")" +
",mChannelMode:" + String.format("0x%x", mChannelMode) +
+ "(" + channelModeStr + ")" +
",mCodecSpecific1:" + mCodecSpecific1 +
",mCodecSpecific2:" + mCodecSpecific2 +
",mCodecSpecific3:" + mCodecSpecific3 +
@@ -181,7 +243,32 @@
}
/**
- * Returns the codec type.
+ * Gets the codec name.
+ *
+ * @return the codec name
+ */
+ public String getCodecName() {
+ switch (mCodecType) {
+ case SOURCE_CODEC_TYPE_SBC:
+ return "SBC";
+ case SOURCE_CODEC_TYPE_AAC:
+ return "AAC";
+ case SOURCE_CODEC_TYPE_APTX:
+ return "aptX";
+ case SOURCE_CODEC_TYPE_APTX_HD:
+ return "aptX HD";
+ case SOURCE_CODEC_TYPE_LDAC:
+ return "LDAC";
+ case SOURCE_CODEC_TYPE_INVALID:
+ return "INVALID CODEC";
+ default:
+ break;
+ }
+ return "UNKNOWN CODEC(" + mCodecType + ")";
+ }
+
+ /**
+ * Gets the codec type.
* See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}.
*
* @return the codec type
@@ -191,7 +278,7 @@
}
/**
- * Returns the codec selection priority.
+ * Gets the codec selection priority.
* The codec selection priority is relative to other codecs: larger value
* means higher priority. If 0, reset to default.
*
@@ -202,7 +289,7 @@
}
/**
- * Returns the codec sample rate. The value can be a bitmask with all
+ * Gets the codec sample rate. The value can be a bitmask with all
* supported sample rates:
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or
@@ -219,7 +306,7 @@
}
/**
- * Returns the codec bits per sample. The value can be a bitmask with all
+ * Gets the codec bits per sample. The value can be a bitmask with all
* bits per sample supported:
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or
@@ -233,7 +320,7 @@
}
/**
- * Returns the codec channel mode. The value can be a bitmask with all
+ * Gets the codec channel mode. The value can be a bitmask with all
* supported channel modes:
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
@@ -246,7 +333,7 @@
}
/**
- * Returns a codec specific value1.
+ * Gets a codec specific value1.
*
* @return a codec specific value1.
*/
@@ -255,7 +342,7 @@
}
/**
- * Returns a codec specific value2.
+ * Gets a codec specific value2.
*
* @return a codec specific value2
*/
@@ -264,7 +351,7 @@
}
/**
- * Returns a codec specific value3.
+ * Gets a codec specific value3.
*
* @return a codec specific value3
*/
@@ -273,7 +360,7 @@
}
/**
- * Returns a codec specific value4.
+ * Gets a codec specific value4.
*
* @return a codec specific value4
*/
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.aidl b/core/java/android/bluetooth/BluetoothCodecStatus.aidl
new file mode 100644
index 0000000..f9c3a3d
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothCodecStatus;
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
new file mode 100644
index 0000000..c8cd8d1
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Represents the codec status (configuration and capability) for a Bluetooth
+ * A2DP source device.
+ *
+ * {@see BluetoothA2dp}
+ *
+ * {@hide}
+ */
+public final class BluetoothCodecStatus implements Parcelable {
+ /**
+ * Extra for the codec configuration intents of the individual profiles.
+ *
+ * This extra represents the current codec status of the A2DP
+ * profile.
+ */
+ public static final String EXTRA_CODEC_STATUS =
+ "android.bluetooth.codec.extra.CODEC_STATUS";
+
+ private final BluetoothCodecConfig mCodecConfig;
+ private final BluetoothCodecConfig[] mCodecsLocalCapabilities;
+ private final BluetoothCodecConfig[] mCodecsSelectableCapabilities;
+
+ public BluetoothCodecStatus(BluetoothCodecConfig codecConfig,
+ BluetoothCodecConfig[] codecsLocalCapabilities,
+ BluetoothCodecConfig[] codecsSelectableCapabilities) {
+ mCodecConfig = codecConfig;
+ mCodecsLocalCapabilities = codecsLocalCapabilities;
+ mCodecsSelectableCapabilities = codecsSelectableCapabilities;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof BluetoothCodecStatus) {
+ BluetoothCodecStatus other = (BluetoothCodecStatus)o;
+ return (Objects.equals(other.mCodecConfig, mCodecConfig) &&
+ Objects.equals(other.mCodecsLocalCapabilities,
+ mCodecsLocalCapabilities) &&
+ Objects.equals(other.mCodecsSelectableCapabilities,
+ mCodecsSelectableCapabilities));
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
+ mCodecsLocalCapabilities);
+ }
+
+ @Override
+ public String toString() {
+ return "{mCodecConfig:" + mCodecConfig +
+ ",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities) +
+ ",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities) +
+ "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<BluetoothCodecStatus> CREATOR =
+ new Parcelable.Creator<BluetoothCodecStatus>() {
+ public BluetoothCodecStatus createFromParcel(Parcel in) {
+ final BluetoothCodecConfig codecConfig = in.readTypedObject(BluetoothCodecConfig.CREATOR);
+ final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
+ final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(BluetoothCodecConfig.CREATOR);
+
+ return new BluetoothCodecStatus(codecConfig,
+ codecsLocalCapabilities,
+ codecsSelectableCapabilities);
+ }
+ public BluetoothCodecStatus[] newArray(int size) {
+ return new BluetoothCodecStatus[size];
+ }
+ };
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeTypedObject(mCodecConfig, 0);
+ out.writeTypedArray(mCodecsLocalCapabilities, 0);
+ out.writeTypedArray(mCodecsSelectableCapabilities, 0);
+ }
+
+ /**
+ * Gets the current codec configuration.
+ *
+ * @return the current codec configuration
+ */
+ public BluetoothCodecConfig getCodecConfig() {
+ return mCodecConfig;
+ }
+
+ /**
+ * Gets the codecs local capabilities.
+ *
+ * @return an array with the codecs local capabilities
+ */
+ public BluetoothCodecConfig[] getCodecsLocalCapabilities() {
+ return mCodecsLocalCapabilities;
+ }
+
+ /**
+ * Gets the codecs selectable capabilities.
+ *
+ * @return an array with the codecs selectable capabilities
+ */
+ public BluetoothCodecConfig[] getCodecsSelectableCapabilities() {
+ return mCodecsSelectableCapabilities;
+ }
+}
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 5b524eb..dbb5b7d 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
/**
@@ -37,6 +38,6 @@
oneway void adjustAvrcpAbsoluteVolume(int direction);
oneway void setAvrcpAbsoluteVolume(int volume);
boolean isA2dpPlaying(in BluetoothDevice device);
- BluetoothCodecConfig getCodecConfig();
+ BluetoothCodecStatus getCodecStatus();
oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig);
}
diff --git a/core/res/res/values-mcc704-mnc01/config.xml b/core/res/res/values-mcc704-mnc01/config.xml
new file mode 100644
index 0000000..10b6470
--- /dev/null
+++ b/core/res/res/values-mcc704-mnc01/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+ <!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD -->
+ <string-array name="config_twoDigitNumberPattern">
+ <item>"*1"</item>
+ <item>"*5"</item>
+ <item>"*9"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc708-mnc001/config.xml b/core/res/res/values-mcc708-mnc001/config.xml
new file mode 100755
index 0000000..7b7c48d
--- /dev/null
+++ b/core/res/res/values-mcc708-mnc001/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <string-array translatable="false" name="config_twoDigitNumberPattern">
+ <item>"*1"</item>
+ <item>"*5"</item>
+ </string-array>
+</resources>
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index 83001df..0a90749 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -286,7 +286,8 @@
}
// Returns seconds since device boot.
- private static long curTime() {
+ @VisibleForTesting
+ protected long currentTimeSeconds() {
return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
}
@@ -450,7 +451,7 @@
}
mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
- mLastSeen = curTime();
+ mLastSeen = currentTimeSeconds();
// Sanity check packet in case a packet arrives before we attach RA filter
// to our packet socket. b/29586253
@@ -580,7 +581,7 @@
// How many seconds does this RA's have to live, taking into account the fact
// that we might have seen it a while ago.
long currentLifetime() {
- return mMinLifetime - (curTime() - mLastSeen);
+ return mMinLifetime - (currentTimeSeconds() - mLastSeen);
}
boolean isExpired() {
@@ -946,7 +947,7 @@
Log.e(TAG, "Failed to generate APF program.", e);
return;
}
- mLastTimeInstalledProgram = curTime();
+ mLastTimeInstalledProgram = currentTimeSeconds();
mLastInstalledProgramMinLifetime = programMinLifetime;
mLastInstalledProgram = program;
mNumProgramUpdates++;
@@ -965,7 +966,7 @@
*/
private boolean shouldInstallnewProgram() {
long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
- return expiry < curTime() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING;
+ return expiry < currentTimeSeconds() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING;
}
private void hexDump(String msg, byte[] packet, int length) {
@@ -999,7 +1000,7 @@
if (ra.matches(packet, length)) {
if (VDBG) log("matched RA " + ra);
// Update lifetimes.
- ra.mLastSeen = curTime();
+ ra.mLastSeen = currentTimeSeconds();
ra.mMinLifetime = ra.minLifetime(packet, length);
ra.seenCount++;
@@ -1128,7 +1129,7 @@
pw.println("Program updates: " + mNumProgramUpdates);
pw.println(String.format(
"Last program length %d, installed %ds ago, lifetime %ds",
- mLastInstalledProgram.length, curTime() - mLastTimeInstalledProgram,
+ mLastInstalledProgram.length, currentTimeSeconds() - mLastTimeInstalledProgram,
mLastInstalledProgramMinLifetime));
pw.println("RA filters:");
@@ -1137,7 +1138,7 @@
pw.println(ra);
pw.increaseIndent();
pw.println(String.format(
- "Seen: %d, last %ds ago", ra.seenCount, curTime() - ra.mLastSeen));
+ "Seen: %d, last %ds ago", ra.seenCount, currentTimeSeconds() - ra.mLastSeen));
if (DBG) {
pw.println("Last match:");
pw.increaseIndent();
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index b3f5630..00c36f9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -150,6 +150,7 @@
private UsbDebuggingManager mDebuggingManager;
private final UsbAlsaManager mUsbAlsaManager;
private Intent mBroadcastedIntent;
+ private boolean mPendingBootBroadcast;
private class AdbSettingsObserver extends ContentObserver {
public AdbSettingsObserver() {
@@ -740,13 +741,16 @@
if (UsbManager.containsFunction(mCurrentFunctions,
UsbManager.USB_FUNCTION_ACCESSORY)) {
updateCurrentAccessory();
- } else if (!mConnected) {
- // restore defaults when USB is disconnected
- setEnabledFunctions(null, false, false);
}
if (mBootCompleted) {
+ if (!mConnected) {
+ // restore defaults when USB is disconnected
+ setEnabledFunctions(null, false, false);
+ }
updateUsbStateBroadcastIfNeeded(false);
updateUsbFunctions();
+ } else {
+ mPendingBootBroadcast = true;
}
break;
case MSG_UPDATE_HOST_STATE:
@@ -758,6 +762,8 @@
updateUsbNotification();
if (mBootCompleted) {
updateUsbStateBroadcastIfNeeded(false);
+ } else {
+ mPendingBootBroadcast = true;
}
break;
case MSG_ENABLE_ADB:
@@ -777,6 +783,10 @@
break;
case MSG_BOOT_COMPLETED:
mBootCompleted = true;
+ if (mPendingBootBroadcast) {
+ updateUsbStateBroadcastIfNeeded(false);
+ mPendingBootBroadcast = false;
+ }
setEnabledFunctions(null, false, false);
if (mCurrentAccessory != null) {
getCurrentSettings().accessoryAttached(mCurrentAccessory);
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index ff61754..91d6c68 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -29,9 +29,11 @@
import android.net.metrics.RaEvent;
import android.os.ConditionVariable;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.system.ErrnoException;
import android.system.Os;
import android.test.AndroidTestCase;
+import android.text.format.DateUtils;
import android.test.suitebuilder.annotation.SmallTest;
import static android.system.OsConstants.*;
@@ -604,6 +606,8 @@
public final static byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
private FileDescriptor mWriteSocket;
+ private final long mFixedTimeMs = SystemClock.elapsedRealtime();
+
public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter,
IpConnectivityLog log) throws Exception {
super(new ApfCapabilities(2, 1700, ARPHRD_ETHER), NetworkInterface.getByName("lo"),
@@ -617,6 +621,11 @@
}
@Override
+ protected long currentTimeSeconds() {
+ return mFixedTimeMs / DateUtils.SECOND_IN_MILLIS;
+ }
+
+ @Override
void maybeStartFilter() {
mHardwareAddress = MOCK_MAC_ADDR;
installNewProgramLocked();
@@ -969,27 +978,30 @@
// Verify that the last program pushed to the IpManager.Callback properly filters the
// given packet for the given lifetime.
- private void verifyRaLifetime(MockIpManagerCallback ipManagerCallback, ByteBuffer packet,
- int lifetime) {
- byte[] program = ipManagerCallback.getApfProgram();
+ private void verifyRaLifetime(byte[] program, ByteBuffer packet, int lifetime) {
+ final int FRACTION_OF_LIFETIME = 6;
+ final int ageLimit = lifetime / FRACTION_OF_LIFETIME;
- // Verify new program should drop RA for 1/6th its lifetime
+ // Verify new program should drop RA for 1/6th its lifetime and pass afterwards.
assertDrop(program, packet.array());
- assertDrop(program, packet.array(), lifetime/6);
- assertPass(program, packet.array(), lifetime/6 + 1);
+ assertDrop(program, packet.array(), ageLimit);
+ assertPass(program, packet.array(), ageLimit + 1);
assertPass(program, packet.array(), lifetime);
-
// Verify RA checksum is ignored
+ final short originalChecksum = packet.getShort(ICMP6_RA_CHECKSUM_OFFSET);
packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345);
assertDrop(program, packet.array());
packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345);
assertDrop(program, packet.array());
+ packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, originalChecksum);
// Verify other changes to RA make it not match filter
+ final byte originalFirstByte = packet.get(0);
packet.put(0, (byte)-1);
assertPass(program, packet.array());
packet.put(0, (byte)0);
assertDrop(program, packet.array());
+ packet.put(0, originalFirstByte);
}
// Test that when ApfFilter is shown the given packet, it generates a program to filter it
@@ -999,9 +1011,8 @@
// Verify new program generated if ApfFilter witnesses RA
ipManagerCallback.resetApfProgramWait();
apfFilter.pretendPacketReceived(packet.array());
- ipManagerCallback.getApfProgram();
-
- verifyRaLifetime(ipManagerCallback, packet, lifetime);
+ byte[] program = ipManagerCallback.getApfProgram();
+ verifyRaLifetime(program, packet, lifetime);
}
private void verifyRaEvent(RaEvent expected) {
@@ -1046,18 +1057,26 @@
TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog);
byte[] program = ipManagerCallback.getApfProgram();
+ final int ROUTER_LIFETIME = 1000;
+ final int PREFIX_VALID_LIFETIME = 200;
+ final int PREFIX_PREFERRED_LIFETIME = 100;
+ final int RDNSS_LIFETIME = 300;
+ final int ROUTE_LIFETIME = 400;
+ // Note that lifetime of 2000 will be ignored in favor of shorter route lifetime of 1000.
+ final int DNSSL_LIFETIME = 2000;
+
// Verify RA is passed the first time
ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT);
- basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)1000);
+ basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)ROUTER_LIFETIME);
basePacket.position(IPV6_DEST_ADDR_OFFSET);
basePacket.put(IPV6_ALL_NODES_ADDRESS);
assertPass(program, basePacket.array());
- testRaLifetime(apfFilter, ipManagerCallback, basePacket, 1000);
- verifyRaEvent(new RaEvent(1000, -1, -1, -1, -1, -1));
+ testRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME);
+ verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
// Ensure zero-length options cause the packet to be silently skipped.
// Do this before we test other packets. http://b/29586253
@@ -1079,11 +1098,14 @@
prefixOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
prefixOptionPacket.put((byte)(ICMP6_PREFIX_OPTION_LEN / 8));
prefixOptionPacket.putInt(
- ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET, 100);
+ ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
+ PREFIX_PREFERRED_LIFETIME);
prefixOptionPacket.putInt(
- ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET, 200);
- testRaLifetime(apfFilter, ipManagerCallback, prefixOptionPacket, 100);
- verifyRaEvent(new RaEvent(1000, 200, 100, -1, -1, -1));
+ ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
+ PREFIX_VALID_LIFETIME);
+ testRaLifetime(apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
+ verifyRaEvent(new RaEvent(
+ ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
ByteBuffer rdnssOptionPacket = ByteBuffer.wrap(
new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
@@ -1092,9 +1114,9 @@
rdnssOptionPacket.put((byte)ICMP6_RDNSS_OPTION_TYPE);
rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
rdnssOptionPacket.putInt(
- ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, 300);
- testRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, 300);
- verifyRaEvent(new RaEvent(1000, -1, -1, -1, 300, -1));
+ ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
+ testRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME);
+ verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
@@ -1103,9 +1125,9 @@
routeInfoOptionPacket.put((byte)ICMP6_ROUTE_INFO_OPTION_TYPE);
routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
routeInfoOptionPacket.putInt(
- ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, 400);
- testRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, 400);
- verifyRaEvent(new RaEvent(1000, -1, -1, 400, -1, -1));
+ ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
+ testRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
+ verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
@@ -1114,18 +1136,17 @@
dnsslOptionPacket.put((byte)ICMP6_DNSSL_OPTION_TYPE);
dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
dnsslOptionPacket.putInt(
- ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, 2000);
- // Note that lifetime of 2000 will be ignored in favor of shorter
- // route lifetime of 1000.
- testRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, 1000);
- verifyRaEvent(new RaEvent(1000, -1, -1, -1, -1, 2000));
+ ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
+ testRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME);
+ verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
// Verify that current program filters all five RAs:
- verifyRaLifetime(ipManagerCallback, basePacket, 1000);
- verifyRaLifetime(ipManagerCallback, prefixOptionPacket, 100);
- verifyRaLifetime(ipManagerCallback, rdnssOptionPacket, 300);
- verifyRaLifetime(ipManagerCallback, routeInfoOptionPacket, 400);
- verifyRaLifetime(ipManagerCallback, dnsslOptionPacket, 1000);
+ program = ipManagerCallback.getApfProgram();
+ verifyRaLifetime(program, basePacket, ROUTER_LIFETIME);
+ verifyRaLifetime(program, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
+ verifyRaLifetime(program, rdnssOptionPacket, RDNSS_LIFETIME);
+ verifyRaLifetime(program, routeInfoOptionPacket, ROUTE_LIFETIME);
+ verifyRaLifetime(program, dnsslOptionPacket, ROUTER_LIFETIME);
apfFilter.shutdown();
}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 043925ed..a9e38ce 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -706,7 +706,11 @@
attachCallback.onAttachFailed();
break;
case CALLBACK_IDENTITY_CHANGED:
- identityChangedListener.onIdentityChanged((byte[]) msg.obj);
+ if (identityChangedListener == null) {
+ Log.e(TAG, "CALLBACK_IDENTITY_CHANGED: null listener.");
+ } else {
+ identityChangedListener.onIdentityChanged((byte[]) msg.obj);
+ }
break;
case CALLBACK_RANGING_SUCCESS: {
RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index ca4d121..f1174b6 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -217,9 +217,9 @@
return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp))
&& (credential == null ? that.credential == null
: credential.equals(that.credential))
- && (policy == null) ? that.policy == null : policy.equals(that.policy)
- && (subscriptionUpdate == null) ? that.subscriptionUpdate == null
- : subscriptionUpdate.equals(that.subscriptionUpdate)
+ && (policy == null ? that.policy == null : policy.equals(that.policy))
+ && (subscriptionUpdate == null ? that.subscriptionUpdate == null
+ : subscriptionUpdate.equals(that.subscriptionUpdate))
&& isTrustRootCertListEquals(trustRootCertList, that.trustRootCertList)
&& updateIdentifier == that.updateIdentifier
&& credentialPriority == that.credentialPriority
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index b2583d3..bc29402 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -293,13 +293,13 @@
&& minRoamingDownlinkBandwidth == that.minRoamingDownlinkBandwidth
&& minRoamingUplinkBandwidth == that.minRoamingUplinkBandwidth
&& Arrays.equals(excludedSsidList, that.excludedSsidList)
- && (requiredProtoPortMap == null) ? that.requiredProtoPortMap == null
- : requiredProtoPortMap.equals(that.requiredProtoPortMap)
+ && (requiredProtoPortMap == null ? that.requiredProtoPortMap == null
+ : requiredProtoPortMap.equals(that.requiredProtoPortMap))
&& maximumBssLoadValue == that.maximumBssLoadValue
- && (preferredRoamingPartnerList == null) ? that.preferredRoamingPartnerList == null
- : preferredRoamingPartnerList.equals(that.preferredRoamingPartnerList)
- && (policyUpdate == null) ? that.policyUpdate == null
- : policyUpdate.equals(that.policyUpdate);
+ && (preferredRoamingPartnerList == null ? that.preferredRoamingPartnerList == null
+ : preferredRoamingPartnerList.equals(that.preferredRoamingPartnerList))
+ && (policyUpdate == null ? that.policyUpdate == null
+ : policyUpdate.equals(that.policyUpdate));
}
/**