Merge "Add WiFi toggle prompts - framework"
diff --git a/api/current.txt b/api/current.txt
index 03e3f36..21fe3e2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36363,6 +36363,7 @@
field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
+ field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 1024; // 0x400
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final int CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE = 256; // 0x100
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
@@ -36864,8 +36865,12 @@
method public int describeContents();
method public boolean equals(java.lang.Object);
method public int getAsuLevel();
+ method public int getCqi();
method public int getDbm();
method public int getLevel();
+ method public int getRsrp();
+ method public int getRsrq();
+ method public int getRssnr();
method public int getTimingAdvance();
method public int hashCode();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 057f1af..974db45 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -39267,6 +39267,7 @@
field public static final int CAPABILITY_MULTI_USER = 32; // 0x20
field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
+ field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 1024; // 0x400
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final int CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE = 256; // 0x100
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
@@ -39799,8 +39800,12 @@
method public int describeContents();
method public boolean equals(java.lang.Object);
method public int getAsuLevel();
+ method public int getCqi();
method public int getDbm();
method public int getLevel();
+ method public int getRsrp();
+ method public int getRsrq();
+ method public int getRssnr();
method public int getTimingAdvance();
method public int hashCode();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 85b5ab8..29de7a5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -36440,6 +36440,7 @@
field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
+ field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 1024; // 0x400
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final int CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE = 256; // 0x100
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
@@ -36941,8 +36942,12 @@
method public int describeContents();
method public boolean equals(java.lang.Object);
method public int getAsuLevel();
+ method public int getCqi();
method public int getDbm();
method public int getLevel();
+ method public int getRsrp();
+ method public int getRsrq();
+ method public int getRssnr();
method public int getTimingAdvance();
method public int hashCode();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 11c2735..4271e3f 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -601,10 +601,6 @@
*/
public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
if (!getLeAccess()) return null;
- if (!isMultipleAdvertisementSupported() && !isPeripheralModeSupported()) {
- Log.e(TAG, "Bluetooth LE advertising not supported");
- return null;
- }
synchronized(mLock) {
if (sBluetoothLeAdvertiser == null) {
sBluetoothLeAdvertiser = new BluetoothLeAdvertiser(mManagerService);
@@ -1354,24 +1350,6 @@
}
/**
- * Returns whether peripheral mode is supported.
- *
- * @hide
- */
- public boolean isPeripheralModeSupported() {
- if (getState() != STATE_ON) return false;
- try {
- mServiceLock.readLock().lock();
- if (mService != null) return mService.isPeripheralModeSupported();
- } catch (RemoteException e) {
- Log.e(TAG, "failed to get peripheral mode capability: ", e);
- } finally {
- mServiceLock.readLock().unlock();
- }
- return false;
- }
-
- /**
* Return true if offloaded filters are supported
*
* @return true if chipset supports on-chip filtering
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 96a1ae8..7c5458b 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -100,7 +100,6 @@
boolean factoryReset();
boolean isMultiAdvertisementSupported();
- boolean isPeripheralModeSupported();
boolean isOffloadedFilteringSupported();
boolean isOffloadedScanBatchingSupported();
boolean isActivityAndEnergyReportingSupported();
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 26f2dea..5d27662 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -111,12 +111,6 @@
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
- if (!mBluetoothAdapter.isMultipleAdvertisementSupported() &&
- !mBluetoothAdapter.isPeripheralModeSupported()) {
- postStartFailure(callback,
- AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED);
- return;
- }
boolean isConnectable = settings.isConnectable();
if (totalBytes(advertiseData, isConnectable) > MAX_ADVERTISING_DATA_BYTES ||
totalBytes(scanResponse, false) > MAX_ADVERTISING_DATA_BYTES) {
@@ -236,9 +230,9 @@
private final AdvertiseSettings mSettings;
private final IBluetoothGatt mBluetoothGatt;
- // mAdvertiserId 0: not registered
- // -1: advertise stopped or registration timeout
- // >0: registered and advertising started
+ // mAdvertiserId -1: not registered
+ // -2: advertise stopped or registration timeout
+ // >=0: registered and advertising started
private int mAdvertiserId;
private boolean mIsAdvertising = false;
@@ -251,12 +245,12 @@
mScanResponse = scanResponse;
mSettings = settings;
mBluetoothGatt = bluetoothGatt;
- mAdvertiserId = 0;
+ mAdvertiserId = -1;
}
public void startRegisteration() {
synchronized (this) {
- if (mAdvertiserId == -1) return;
+ if (mAdvertiserId == -2) return;
try {
mBluetoothGatt.registerAdvertiser(this);
@@ -264,13 +258,13 @@
} catch (InterruptedException | RemoteException e) {
Log.e(TAG, "Failed to start registeration", e);
}
- if (mAdvertiserId > 0 && mIsAdvertising) {
+ if (mAdvertiserId >= 0 && mIsAdvertising) {
mLeAdvertisers.put(mAdvertiseCallback, this);
- } else if (mAdvertiserId <= 0) {
+ } else if (mAdvertiserId < 0) {
// Registration timeout, reset mClientIf to -1 so no subsequent operations can
// proceed.
- if (mAdvertiserId == 0) mAdvertiserId = -1;
+ if (mAdvertiserId == 0) mAdvertiserId = -2;
// Post internal error if registration failed.
postStartFailure(mAdvertiseCallback,
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
@@ -278,7 +272,7 @@
// Unregister application if it's already registered but advertise failed.
try {
mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
- mAdvertiserId = -1;
+ mAdvertiserId = -2;
} catch (RemoteException e) {
Log.e(TAG, "remote exception when unregistering", e);
}
@@ -312,7 +306,7 @@
synchronized (this) {
if (status == BluetoothGatt.GATT_SUCCESS) {
try {
- if (mAdvertiserId == -1) {
+ if (mAdvertiserId == -2) {
// Registration succeeds after timeout, unregister advertiser.
mBluetoothGatt.unregisterAdvertiser(advertiserId);
} else {
@@ -326,7 +320,7 @@
}
}
// Registration failed.
- mAdvertiserId = -1;
+ mAdvertiserId = -2;
notifyAll();
}
}
@@ -348,7 +342,7 @@
// unregister advertiser for stop.
try {
mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
- mAdvertiserId = -1;
+ mAdvertiserId = -2;
mIsAdvertising = false;
mLeAdvertisers.remove(mAdvertiseCallback);
} catch (RemoteException e) {
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index 886c0e6..f909580 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -267,9 +267,9 @@
const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
if (interfaceName) {
- String16 nameCopy(
+ String8 nameCopy = String8(String16(
reinterpret_cast<const char16_t *>(interfaceName),
- env->GetStringLength(interfaceNameObj));
+ env->GetStringLength(interfaceNameObj)));
env->ReleaseStringCritical(interfaceNameObj, interfaceName);
interfaceName = NULL;
@@ -277,7 +277,7 @@
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
- status_t err = parcel->writeInterfaceToken(nameCopy);
+ status_t err = parcel->writeInterfaceToken(nameCopy.string());
signalExceptionForError(env, err);
}
}
@@ -294,9 +294,9 @@
const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
if (interfaceName) {
- String16 interfaceNameCopy(
+ String8 interfaceNameCopy = String8(String16(
reinterpret_cast<const char16_t *>(interfaceName),
- env->GetStringLength(interfaceNameObj));
+ env->GetStringLength(interfaceNameObj)));
env->ReleaseStringCritical(interfaceNameObj, interfaceName);
interfaceName = NULL;
@@ -304,7 +304,7 @@
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
- bool valid = parcel->enforceInterface(interfaceNameCopy);
+ bool valid = parcel->enforceInterface(interfaceNameCopy.string());
if (!valid) {
jniThrowException(
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 3e111c0..ca09708 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -304,7 +304,7 @@
storageSource = "/mnt/runtime/read";
} else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
storageSource = "/mnt/runtime/write";
- } else {
+ } else if (!force_mount_namespace) {
// Sane default of no storage visible
return true;
}
diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java
index f90f1e2..fb91bbb 100644
--- a/media/java/android/media/AmrInputStream.java
+++ b/media/java/android/media/AmrInputStream.java
@@ -18,45 +18,69 @@
import java.io.InputStream;
import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import android.media.MediaCodec.BufferInfo;
+import android.util.Log;
/**
* AmrInputStream
* @hide
*/
-public final class AmrInputStream extends InputStream
-{
- static {
- System.loadLibrary("media_jni");
- }
-
+public final class AmrInputStream extends InputStream {
private final static String TAG = "AmrInputStream";
// frame is 20 msec at 8.000 khz
private final static int SAMPLES_PER_FRAME = 8000 * 20 / 1000;
-
+
+ MediaCodec mCodec;
+ BufferInfo mInfo;
+ boolean mSawOutputEOS;
+ boolean mSawInputEOS;
+
// pcm input stream
private InputStream mInputStream;
-
- // native handle
- private long mGae;
-
+
// result amr stream
private final byte[] mBuf = new byte[SAMPLES_PER_FRAME * 2];
private int mBufIn = 0;
private int mBufOut = 0;
-
+
// helper for bytewise read()
private byte[] mOneByte = new byte[1];
-
+
/**
* Create a new AmrInputStream, which converts 16 bit PCM to AMR
* @param inputStream InputStream containing 16 bit PCM.
*/
public AmrInputStream(InputStream inputStream) {
mInputStream = inputStream;
- mGae = GsmAmrEncoderNew();
- GsmAmrEncoderInitialize(mGae);
+
+ MediaFormat format = new MediaFormat();
+ format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_NB);
+ format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000);
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, 12200);
+
+ MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+ String name = mcl.findEncoderForFormat(format);
+ if (name != null) {
+ try {
+ mCodec = MediaCodec.createByCodecName(name);
+ mCodec.configure(format,
+ null /* surface */,
+ null /* crypto */,
+ MediaCodec.CONFIGURE_FLAG_ENCODE);
+ mCodec.start();
+ } catch (IOException e) {
+ if (mCodec != null) {
+ mCodec.release();
+ }
+ mCodec = null;
+ }
+ }
+ mInfo = new BufferInfo();
}
@Override
@@ -64,7 +88,7 @@
int rtn = read(mOneByte, 0, 1);
return rtn == 1 ? (0xff & mOneByte[0]) : -1;
}
-
+
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
@@ -72,67 +96,100 @@
@Override
public int read(byte[] b, int offset, int length) throws IOException {
- if (mGae == 0) throw new IllegalStateException("not open");
-
- // local buffer of amr encoded audio empty
- if (mBufOut >= mBufIn) {
- // reset the buffer
+ if (mCodec == null) {
+ throw new IllegalStateException("not open");
+ }
+
+ if (mBufOut >= mBufIn && !mSawOutputEOS) {
+ // no data left in buffer, refill it
mBufOut = 0;
mBufIn = 0;
-
- // fetch a 20 msec frame of pcm
- for (int i = 0; i < SAMPLES_PER_FRAME * 2; ) {
- int n = mInputStream.read(mBuf, i, SAMPLES_PER_FRAME * 2 - i);
- if (n == -1) return -1;
- i += n;
+
+ // first push as much data into the encoder as possible
+ while (!mSawInputEOS) {
+ int index = mCodec.dequeueInputBuffer(0);
+ if (index < 0) {
+ // no input buffer currently available
+ break;
+ } else {
+ int numRead;
+ for (numRead = 0; numRead < SAMPLES_PER_FRAME * 2; ) {
+ int n = mInputStream.read(mBuf, numRead, SAMPLES_PER_FRAME * 2 - numRead);
+ if (n == -1) {
+ mSawInputEOS = true;
+ break;
+ }
+ numRead += n;
+ }
+ ByteBuffer buf = mCodec.getInputBuffer(index);
+ buf.put(mBuf, 0, numRead);
+ mCodec.queueInputBuffer(index,
+ 0 /* offset */,
+ numRead,
+ 0 /* presentationTimeUs */,
+ mSawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0 /* flags */);
+ }
}
-
- // encode it
- mBufIn = GsmAmrEncoderEncode(mGae, mBuf, 0, mBuf, 0);
+
+ // now read encoded data from the encoder (blocking, since we just filled up the
+ // encoder's input with data it should be able to output at least one buffer)
+ while (true) {
+ int index = mCodec.dequeueOutputBuffer(mInfo, -1);
+ if (index >= 0) {
+ mBufIn = mInfo.size;
+ ByteBuffer out = mCodec.getOutputBuffer(index);
+ out.get(mBuf, 0 /* offset */, mBufIn /* length */);
+ mCodec.releaseOutputBuffer(index, false /* render */);
+ if ((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ mSawOutputEOS = true;
+ }
+ break;
+ }
+ }
}
-
- // return encoded audio to user
- if (length > mBufIn - mBufOut) length = mBufIn - mBufOut;
- System.arraycopy(mBuf, mBufOut, b, offset, length);
- mBufOut += length;
-
- return length;
+
+ if (mBufOut < mBufIn) {
+ // there is data in the buffer
+ if (length > mBufIn - mBufOut) {
+ length = mBufIn - mBufOut;
+ }
+ System.arraycopy(mBuf, mBufOut, b, offset, length);
+ mBufOut += length;
+ return length;
+ }
+
+ if (mSawInputEOS && mSawOutputEOS) {
+ // no more data available in buffer, codec or input stream
+ return -1;
+ }
+
+ // caller should try again
+ return 0;
}
@Override
public void close() throws IOException {
try {
- if (mInputStream != null) mInputStream.close();
+ if (mInputStream != null) {
+ mInputStream.close();
+ }
} finally {
mInputStream = null;
try {
- if (mGae != 0) GsmAmrEncoderCleanup(mGae);
- } finally {
- try {
- if (mGae != 0) GsmAmrEncoderDelete(mGae);
- } finally {
- mGae = 0;
+ if (mCodec != null) {
+ mCodec.release();
}
+ } finally {
+ mCodec = null;
}
}
}
@Override
protected void finalize() throws Throwable {
- if (mGae != 0) {
- close();
- throw new IllegalStateException("someone forgot to close AmrInputStream");
+ if (mCodec != null) {
+ Log.w(TAG, "AmrInputStream wasn't closed");
+ mCodec.release();
}
}
-
- //
- // AudioRecord JNI interface
- //
- private static native long GsmAmrEncoderNew();
- private static native void GsmAmrEncoderInitialize(long gae);
- private static native int GsmAmrEncoderEncode(long gae,
- byte[] pcm, int pcmOffset, byte[] amr, int amrOffset) throws IOException;
- private static native void GsmAmrEncoderCleanup(long gae);
- private static native void GsmAmrEncoderDelete(long gae);
-
}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 3355d42..8640565 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -2,7 +2,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- android_media_AmrInputStream.cpp \
android_media_ExifInterface.cpp \
android_media_ImageWriter.cpp \
android_media_ImageReader.cpp \
@@ -46,11 +45,9 @@
libusbhost \
libexif \
libpiex \
- libstagefright_amrnb_common \
libandroidfw
LOCAL_STATIC_LIBRARIES := \
- libstagefright_amrnbenc
LOCAL_C_INCLUDES += \
external/libexif/ \
@@ -60,9 +57,6 @@
frameworks/base/libs/hwui \
frameworks/av/media/libmedia \
frameworks/av/media/libstagefright \
- frameworks/av/media/libstagefright/codecs/amrnb/enc/src \
- frameworks/av/media/libstagefright/codecs/amrnb/common \
- frameworks/av/media/libstagefright/codecs/amrnb/common/include \
frameworks/av/media/mtp \
frameworks/native/include/media/openmax \
$(call include-path-for, libhardware)/hardware \
diff --git a/media/jni/android_media_AmrInputStream.cpp b/media/jni/android_media_AmrInputStream.cpp
deleted file mode 100644
index b56a364..0000000
--- a/media/jni/android_media_AmrInputStream.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-**
-** Copyright 2007, 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.
-*/
-
-#define LOG_TAG "AmrInputStream"
-#include "utils/Log.h"
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "gsmamr_enc.h"
-
-// ----------------------------------------------------------------------------
-
-using namespace android;
-
-// Corresponds to max bit rate of 12.2 kbps.
-static const int MAX_OUTPUT_BUFFER_SIZE = 32;
-static const int FRAME_DURATION_MS = 20;
-static const int SAMPLING_RATE_HZ = 8000;
-static const int SAMPLES_PER_FRAME = ((SAMPLING_RATE_HZ * FRAME_DURATION_MS) / 1000);
-static const int BYTES_PER_SAMPLE = 2; // Assume 16-bit PCM samples
-static const int BYTES_PER_FRAME = (SAMPLES_PER_FRAME * BYTES_PER_SAMPLE);
-
-struct GsmAmrEncoderState {
- GsmAmrEncoderState()
- : mEncState(NULL),
- mSidState(NULL),
- mLastModeUsed(0) {
- }
-
- ~GsmAmrEncoderState() {}
-
- void* mEncState;
- void* mSidState;
- int32_t mLastModeUsed;
-};
-
-static jlong android_media_AmrInputStream_GsmAmrEncoderNew
- (JNIEnv *env, jclass /* clazz */) {
- GsmAmrEncoderState* gae = new GsmAmrEncoderState();
- if (gae == NULL) {
- jniThrowRuntimeException(env, "Out of memory");
- }
- return (jlong)gae;
-}
-
-static void android_media_AmrInputStream_GsmAmrEncoderInitialize
- (JNIEnv *env, jclass /* clazz */, jlong gae) {
- GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
- int32_t nResult = AMREncodeInit(&state->mEncState, &state->mSidState, false);
- if (nResult != OK) {
- jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
- "GsmAmrEncoder initialization failed %d", nResult);
- }
-}
-
-static jint android_media_AmrInputStream_GsmAmrEncoderEncode
- (JNIEnv *env, jclass /* clazz */,
- jlong gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) {
-
- jbyte inBuf[BYTES_PER_FRAME];
- jbyte outBuf[MAX_OUTPUT_BUFFER_SIZE];
-
- env->GetByteArrayRegion(pcm, pcmOffset, sizeof(inBuf), inBuf);
- GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
- int32_t length = AMREncode(state->mEncState, state->mSidState,
- (Mode) MR122,
- (int16_t *) inBuf,
- (unsigned char *) outBuf,
- (Frame_Type_3GPP*) &state->mLastModeUsed,
- AMR_TX_WMF);
- if (length < 0) {
- jniThrowExceptionFmt(env, "java/io/IOException",
- "Failed to encode a frame with error code: %d", length);
- return (jint)-1;
- }
-
- // The 1st byte of PV AMR frames are WMF (Wireless Multimedia Forum)
- // bitpacked, i.e.;
- // [P(4) + FT(4)]. Q=1 for good frame, P=padding bit, 0
- // Here we are converting the header to be as specified in Section 5.3 of
- // RFC 3267 (AMR storage format) i.e.
- // [P(1) + FT(4) + Q(1) + P(2)].
- if (length > 0) {
- outBuf[0] = (outBuf[0] << 3) | 0x4;
- }
-
- env->SetByteArrayRegion(amr, amrOffset, length, outBuf);
-
- return (jint)length;
-}
-
-static void android_media_AmrInputStream_GsmAmrEncoderCleanup
- (JNIEnv* /* env */, jclass /* clazz */, jlong gae) {
- GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
- AMREncodeExit(&state->mEncState, &state->mSidState);
- state->mEncState = NULL;
- state->mSidState = NULL;
-}
-
-static void android_media_AmrInputStream_GsmAmrEncoderDelete
- (JNIEnv* /* env */, jclass /* clazz */, jlong gae) {
- delete (GsmAmrEncoderState*)gae;
-}
-
-// ----------------------------------------------------------------------------
-
-static const JNINativeMethod gMethods[] = {
- {"GsmAmrEncoderNew", "()J", (void*)android_media_AmrInputStream_GsmAmrEncoderNew},
- {"GsmAmrEncoderInitialize", "(J)V", (void*)android_media_AmrInputStream_GsmAmrEncoderInitialize},
- {"GsmAmrEncoderEncode", "(J[BI[BI)I", (void*)android_media_AmrInputStream_GsmAmrEncoderEncode},
- {"GsmAmrEncoderCleanup", "(J)V", (void*)android_media_AmrInputStream_GsmAmrEncoderCleanup},
- {"GsmAmrEncoderDelete", "(J)V", (void*)android_media_AmrInputStream_GsmAmrEncoderDelete},
-};
-
-
-int register_android_media_AmrInputStream(JNIEnv *env)
-{
- const char* const kClassPathName = "android/media/AmrInputStream";
-
- return AndroidRuntime::registerNativeMethods(env,
- kClassPathName, gMethods, NELEM(gMethods));
-}
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 2fb1a3b..8f14b79 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -1106,7 +1106,6 @@
extern int register_android_media_MediaSync(JNIEnv *env);
extern int register_android_media_ResampleInputStream(JNIEnv *env);
extern int register_android_media_MediaProfiles(JNIEnv *env);
-extern int register_android_media_AmrInputStream(JNIEnv *env);
extern int register_android_mtp_MtpDatabase(JNIEnv *env);
extern int register_android_mtp_MtpDevice(JNIEnv *env);
extern int register_android_mtp_MtpServer(JNIEnv *env);
@@ -1152,11 +1151,6 @@
goto bail;
}
- if (register_android_media_AmrInputStream(env) < 0) {
- ALOGE("ERROR: AmrInputStream native registration failed\n");
- goto bail;
- }
-
if (register_android_media_ResampleInputStream(env) < 0) {
ALOGE("ERROR: ResampleInputStream native registration failed\n");
goto bail;
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 2a5b194..5b36598 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -58,6 +58,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.Map;
@@ -117,7 +118,6 @@
private static final int SERVICE_IBLUETOOTHGATT = 2;
private final Context mContext;
- private static int mBleAppCount = 0;
// Locks are not provided for mName and mAddress.
// They are accessed in handler or broadcast receiver, same thread context.
@@ -211,10 +211,7 @@
if (isAirplaneModeOn()) {
// Clear registered LE apps to force shut-off
- synchronized (this) {
- mBleAppCount = 0;
- mBleApps.clear();
- }
+ clearBleApps();
if (st == BluetoothAdapter.STATE_BLE_ON) {
//if state is BLE_ON make sure you trigger disableBLE part
try {
@@ -438,28 +435,28 @@
class ClientDeathRecipient implements IBinder.DeathRecipient {
public void binderDied() {
if (DBG) Slog.d(TAG, "Binder is dead - unregister Ble App");
- if (mBleAppCount > 0) --mBleAppCount;
-
- if (mBleAppCount == 0) {
- if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash");
- try {
- mBluetoothLock.readLock().lock();
- if (mBluetooth != null &&
- mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
- mEnable = false;
- mBluetooth.onBrEdrDown();
- }
- } catch (RemoteException e) {
- Slog.e(TAG,"Unable to call onBrEdrDown", e);
- } finally {
- mBluetoothLock.readLock().unlock();
+ if (isBleAppPresent()) {
+ // Nothing to do, another app is here.
+ return;
+ }
+ if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash");
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth != null &&
+ mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
+ mEnable = false;
+ mBluetooth.onBrEdrDown();
}
+ } catch (RemoteException e) {
+ Slog.e(TAG,"Unable to call onBrEdrDown", e);
+ } finally {
+ mBluetoothLock.readLock().unlock();
}
}
}
/** Internal death rec list */
- Map<IBinder, ClientDeathRecipient> mBleApps = new HashMap<IBinder, ClientDeathRecipient>();
+ Map<IBinder, ClientDeathRecipient> mBleApps = new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
@Override
public boolean isBleScanAlwaysAvailable() {
@@ -479,17 +476,20 @@
ContentObserver contentObserver = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
- if (!isBleScanAlwaysAvailable()) {
- disableBleScanMode();
- clearBleApps();
- try {
- mBluetoothLock.readLock().lock();
- if (mBluetooth != null) mBluetooth.onBrEdrDown();
- } catch (RemoteException e) {
- Slog.e(TAG, "error when disabling bluetooth", e);
- } finally {
- mBluetoothLock.readLock().unlock();
- }
+ if (isBleScanAlwaysAvailable()) {
+ // Nothing to do
+ return;
+ }
+ // BLE scan is not available.
+ disableBleScanMode();
+ clearBleApps();
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth != null) mBluetooth.onBrEdrDown();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error when disabling bluetooth", e);
+ } finally {
+ mBluetoothLock.readLock().unlock();
}
}
};
@@ -525,9 +525,6 @@
throw new IllegalArgumentException("Wake lock is already dead.");
}
mBleApps.put(token, deathRec);
- synchronized (this) {
- ++mBleAppCount;
- }
if (DBG) Slog.d(TAG, "Registered for death Notification");
}
@@ -537,31 +534,26 @@
// Unregister death recipient as the app goes away.
token.unlinkToDeath(r, 0);
mBleApps.remove(token);
- synchronized (this) {
- if (mBleAppCount > 0) --mBleAppCount;
- }
if (DBG) Slog.d(TAG, "Unregistered for death Notification");
}
}
- if (DBG) Slog.d(TAG, "Updated BleAppCount" + mBleAppCount);
- if (mBleAppCount == 0 && mEnable) {
+ int appCount = mBleApps.size();
+ if (DBG) Slog.d(TAG, appCount + " registered Ble Apps");
+ if (appCount == 0 && mEnable) {
disableBleScanMode();
}
- return mBleAppCount;
+ return appCount;
}
// Clear all apps using BLE scan only mode.
private void clearBleApps() {
- synchronized (this) {
- mBleApps.clear();
- mBleAppCount = 0;
- }
+ mBleApps.clear();
}
/** @hide*/
public boolean isBleAppPresent() {
- if (DBG) Slog.d(TAG, "isBleAppPresent() count: " + mBleAppCount);
- return (mBleAppCount > 0);
+ if (DBG) Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
+ return mBleApps.size() > 0;
}
/**
@@ -1417,12 +1409,12 @@
if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) &&
(newState == BluetoothAdapter.STATE_OFF) &&
(mBluetooth != null) && mEnable) {
- recoverBluetoothServiceFromError();
+ recoverBluetoothServiceFromError(false);
}
if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
(newState == BluetoothAdapter.STATE_BLE_ON) &&
(mBluetooth != null) && mEnable) {
- recoverBluetoothServiceFromError();
+ recoverBluetoothServiceFromError(true);
}
// If we tried to enable BT while BT was in the process of shutting down,
// wait for the BT process to fully tear down and then force a restart
@@ -1837,7 +1829,7 @@
quietMode ? 1 : 0, 0));
}
- private void recoverBluetoothServiceFromError() {
+ private void recoverBluetoothServiceFromError(boolean clearBle) {
Slog.e(TAG,"recoverBluetoothServiceFromError");
try {
mBluetoothLock.readLock().lock();
@@ -1875,6 +1867,10 @@
mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
mState = BluetoothAdapter.STATE_OFF;
+ if (clearBle) {
+ clearBleApps();
+ }
+
mEnable = false;
if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index dbc2b0c..615ae49 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -114,7 +114,10 @@
public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4;
/**
- * Flag indicating that this {@code PhoneAccount} is capable of placing video calls.
+ * Flag indicating that this {@code PhoneAccount} is currently able to place video calls.
+ * <p>
+ * See also {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING} which indicates whether the
+ * {@code PhoneAccount} supports placing video calls.
* <p>
* See {@link #getCapabilities}
*/
@@ -179,6 +182,23 @@
public static final int CAPABILITY_EMERGENCY_VIDEO_CALLING = 0x200;
/**
+ * Flag indicating that this {@link PhoneAccount} supports video calling.
+ * This is not an indication that the {@link PhoneAccount} is currently able to make a video
+ * call, but rather that it has the ability to make video calls (but not necessarily at this
+ * time).
+ * <p>
+ * Whether a {@link PhoneAccount} can make a video call is ultimately controlled by
+ * {@link #CAPABILITY_VIDEO_CALLING}, which indicates whether the {@link PhoneAccount} is
+ * currently capable of making a video call. Consider a case where, for example, a
+ * {@link PhoneAccount} supports making video calls (e.g.
+ * {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING}), but a current lack of network connectivity
+ * prevents video calls from being made (e.g. {@link #CAPABILITY_VIDEO_CALLING}).
+ * <p>
+ * See {@link #getCapabilities}
+ */
+ public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 0x400;
+
+ /**
* URI scheme for telephone number URIs.
*/
public static final String SCHEME_TEL = "tel";
@@ -716,6 +736,9 @@
*/
private String capabilitiesToString(int capabilities) {
StringBuilder sb = new StringBuilder();
+ if (hasCapabilities(CAPABILITY_SUPPORTS_VIDEO_CALLING)) {
+ sb.append("SuppVideo ");
+ }
if (hasCapabilities(CAPABILITY_VIDEO_CALLING)) {
sb.append("Video ");
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 3c0a8d6..434caad 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -168,20 +168,34 @@
}
/**
- * @hide
+ * Get reference signal received quality
*/
public int getRsrq() {
return mRsrq;
}
/**
- * @hide
+ * Get reference signal signal-to-noise ratio
*/
public int getRssnr() {
return mRssnr;
}
/**
+ * Get reference signal received power
+ */
+ public int getRsrp() {
+ return mRsrp;
+ }
+
+ /**
+ * Get channel quality indicator
+ */
+ public int getCqi() {
+ return mCqi;
+ }
+
+ /**
* Get signal strength as dBm
*/
@Override
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
index ee2e895..8b1cfae 100644
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
@@ -28,5 +28,6 @@
Messenger getMessenger();
Messenger getP2pStateMachineMessenger();
void setMiracastMode(int mode);
+ void checkConfigureWifiDisplayPermission();
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 398308d..c93ac7b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -1324,6 +1324,11 @@
Channel c, WifiP2pWfdInfo wfdInfo,
ActionListener listener) {
checkChannel(c);
+ try {
+ mService.checkConfigureWifiDisplayPermission();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo);
}