summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/api/system-lint-baseline.txt7
-rw-r--r--core/api/test-lint-baseline.txt2
-rw-r--r--core/java/android/accounts/AccountManager.java24
-rw-r--r--core/java/android/app/ActivityManagerInternal.java3
-rw-r--r--core/java/android/app/ActivityThread.java43
-rw-r--r--core/java/android/app/Instrumentation.java6
-rw-r--r--core/java/android/app/PendingIntent.java3
-rw-r--r--core/java/android/app/WallpaperManager.java2
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java252
-rw-r--r--[-rwxr-xr-x]core/java/android/bluetooth/BluetoothClass.java5
-rw-r--r--core/java/android/bluetooth/BluetoothCodecConfig.java37
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java316
-rw-r--r--core/java/android/bluetooth/BluetoothDeviceGroup.java892
-rw-r--r--core/java/android/bluetooth/BluetoothDun.java296
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java40
-rw-r--r--core/java/android/bluetooth/BluetoothGroupCallback.java132
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java175
-rw-r--r--core/java/android/bluetooth/BluetoothProfile.java54
-rw-r--r--core/java/android/bluetooth/BluetoothQualityReport.java1447
-rw-r--r--core/java/android/bluetooth/BluetoothSocket.java62
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java35
-rw-r--r--core/java/android/bluetooth/BluetoothVcp.java420
-rw-r--r--core/java/android/bluetooth/DeviceGroup.java177
-rw-r--r--core/java/android/bluetooth/le/AdvertiseData.java45
-rw-r--r--core/java/android/bluetooth/le/AdvertisingSetParameters.java15
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeScanner.java22
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeUtils.java41
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java9
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingManager.java69
-rw-r--r--core/java/android/bluetooth/le/ScanFilter.java174
-rw-r--r--core/java/android/bluetooth/le/ScanRecord.java52
-rw-r--r--core/java/android/bluetooth/le/ScanResult.java51
-rw-r--r--core/java/android/bluetooth/le/ScanSettings.java9
-rw-r--r--core/java/android/content/ContentResolver.java3
-rw-r--r--core/java/android/content/Intent.java13
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java93
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java41
-rw-r--r--core/java/android/hardware/Camera.java1540
-rw-r--r--core/java/android/hardware/SystemSensorManager.java2
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java4
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java87
-rw-r--r--core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java3
-rw-r--r--core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java35
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java43
-rw-r--r--core/java/android/hardware/camera2/utils/SurfaceUtils.java32
-rw-r--r--core/java/android/net/NetworkStats.java1
-rw-r--r--core/java/android/net/NetworkStatsHistory.java28
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl6
-rw-r--r--core/java/android/nfc/cardemulation/AidGroup.java11
-rw-r--r--core/java/android/nfc/cardemulation/ApduServiceInfo.java23
-rw-r--r--core/java/android/nfc/tech/MifareClassic.java6
-rw-r--r--core/java/android/nfc/tech/NfcA.java13
-rw-r--r--core/java/android/os/Process.java25
-rw-r--r--core/java/android/os/storage/DiskInfo.java2
-rw-r--r--core/java/android/provider/Browser.java6
-rw-r--r--core/java/android/provider/CalendarContract.java8
-rw-r--r--core/java/android/provider/ContactsContract.java7
-rw-r--r--core/java/android/provider/Settings.java43
-rw-r--r--core/java/android/provider/Telephony.java51
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java2
-rw-r--r--core/java/android/speech/SpeechRecognizer.java1
-rw-r--r--core/java/android/util/BoostFramework.java790
-rw-r--r--core/java/android/util/FeatureFlagUtils.java7
-rw-r--r--core/java/android/util/NtpTrustedTime.java69
-rw-r--r--core/java/android/util/SeempLog.java754
-rw-r--r--core/java/android/util/SparseArrayMap.java2
-rw-r--r--core/java/android/util/TrustedTime.java6
-rw-r--r--core/java/android/util/apk/ApkSignatureVerifier.java150
-rw-r--r--core/java/android/view/Choreographer.java85
-rw-r--r--core/java/android/view/DisplayCutout.java7
-rw-r--r--core/java/android/view/InputEventReceiver.java14
-rw-r--r--core/java/android/view/SurfaceView.java20
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/ViewRootImpl.java10
-rw-r--r--core/java/android/view/WindowManagerImpl.java2
-rw-r--r--core/java/android/webkit/WebChromeClient.java4
-rwxr-xr-x[-rw-r--r--]core/java/android/widget/AbsListView.java82
-rw-r--r--core/java/android/widget/OverScroller.java29
-rw-r--r--core/java/android/widget/Scroller.java3
-rw-r--r--core/java/com/android/ims/internal/uce/common/CapInfo.java6
-rw-r--r--core/java/com/android/internal/app/ActivityTrigger.java101
-rw-r--r--core/java/com/android/internal/os/BinderDeathDispatcher.java6
-rw-r--r--core/java/com/android/internal/os/TEST_MAPPING10
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java6
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl2
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java11
-rw-r--r--core/java/com/android/server/SystemConfig.java14
-rw-r--r--core/jni/Android.bp2
-rw-r--r--core/jni/AndroidRuntime.cpp6
-rw-r--r--core/jni/android_graphics_BLASTBufferQueue.cpp14
-rw-r--r--core/jni/android_hardware_Camera.cpp154
-rw-r--r--core/jni/android_hardware_input_InputWindowHandle.cpp1
-rw-r--r--core/jni/android_media_AudioFormat.h35
-rw-r--r--core/jni/android_util_Process.cpp98
-rw-r--r--core/jni/android_util_SeempLog.cpp218
-rw-r--r--core/jni/android_view_InputEventReceiver.cpp31
-rw-r--r--core/jni/com_android_internal_app_ActivityTrigger.cpp256
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp26
-rw-r--r--core/proto/android/providers/settings/global.proto2
-rw-r--r--core/res/AndroidManifest.xml39
-rw-r--r--core/res/res/drawable/ic_wifi_4_signal_0.xml41
-rw-r--r--core/res/res/drawable/ic_wifi_4_signal_1.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_4_signal_2.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_4_signal_3.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_4_signal_4.xml41
-rw-r--r--core/res/res/drawable/ic_wifi_5_signal_0.xml41
-rw-r--r--core/res/res/drawable/ic_wifi_5_signal_1.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_5_signal_2.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_5_signal_3.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_5_signal_4.xml41
-rw-r--r--core/res/res/drawable/ic_wifi_6_signal_0.xml41
-rw-r--r--core/res/res/drawable/ic_wifi_6_signal_1.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_6_signal_2.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_6_signal_3.xml44
-rw-r--r--core/res/res/drawable/ic_wifi_6_signal_4.xml41
-rw-r--r--core/res/res/values/bools.xml1
-rw-r--r--core/res/res/values/config.xml27
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml29
-rw-r--r--core/tests/ConnectivityManagerTest/AndroidManifest.xml1
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java62
122 files changed, 10634 insertions, 253 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 3aa17f0865b4..16c5253427a8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -14031,6 +14031,7 @@ package android.telephony.ims.stub {
public class ImsUtImplBase {
ctor public ImsUtImplBase();
method public void close();
+ method public int queryCFForServiceClass(int, String, int);
method public int queryCallBarring(int);
method public int queryCallBarringForServiceClass(int, int);
method public int queryCallForward(int, String);
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index b435acfccde8..5f3225a01811 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -1,4 +1,8 @@
// Baseline format: 1.0
+AcronymName: android.telephony.ims.stub.ImsUtImplBase#queryCFForServiceClass(int, String, int):
+ Acronyms should not be capitalized in method names: was `queryCFForServiceClass`, should this be `queryCfForServiceClass`?
+
+
ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
@@ -81,6 +85,9 @@ MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringWe
MissingNullability: android.telephony.data.DataService#onUnbind(android.content.Intent) parameter #0:
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCFForServiceClass(int, String, int) parameter #1:
+ Missing nullability on parameter `number` in method `queryCFForServiceClass`
+
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 5409165542f4..0aeba4854866 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -2013,6 +2013,8 @@ MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int,
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCallForward(int, String) parameter #1:
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCFForServiceClass(int, String, int) parameter #1:
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener) parameter #0:
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#transact(android.os.Bundle) parameter #0:
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 79fb86365b74..3183c172bac5 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -608,6 +608,7 @@ public class AccountManager {
* @return The account's password, null if none or if the account doesn't exist
*/
public String getPassword(final Account account) {
+ android.util.SeempLog.record(22);
if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.getPassword(account);
@@ -638,6 +639,7 @@ public class AccountManager {
* @return The user data, null if the account, key doesn't exist, or the user is locked
*/
public String getUserData(final Account account, final String key) {
+ android.util.SeempLog.record(23);
return mUserDataCache.query(new AccountKeyData(account,key));
}
@@ -877,6 +879,7 @@ public class AccountManager {
return new Future2Task<String>(handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.getAuthTokenLabel(mResponse, accountType, authTokenType);
}
@@ -921,6 +924,7 @@ public class AccountManager {
return new Future2Task<Boolean>(handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName());
}
@Override
@@ -981,6 +985,7 @@ public class AccountManager {
return new Future2Task<Account[]>(handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.getAccountsByFeatures(mResponse, type, features,
mContext.getOpPackageName());
}
@@ -1025,6 +1030,7 @@ public class AccountManager {
* already exists, the account is null, the user is locked, or another error occurs.
*/
public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
+ android.util.SeempLog.record(24);
if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.addAccountExplicitly(
@@ -1243,6 +1249,7 @@ public class AccountManager {
return new Future2Task<Account>(handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.renameAccount(mResponse, account, newName);
}
@Override
@@ -1304,6 +1311,7 @@ public class AccountManager {
@Deprecated
public AccountManagerFuture<Boolean> removeAccount(final Account account,
AccountManagerCallback<Boolean> callback, Handler handler) {
+ android.util.SeempLog.record(25);
return removeAccountAsUser(account, callback, handler, mContext.getUser());
}
@@ -1351,6 +1359,7 @@ public class AccountManager {
@UserHandleAware
public AccountManagerFuture<Bundle> removeAccount(final Account account,
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
+ android.util.SeempLog.record(28);
return removeAccountAsUser(account, activity, callback, handler, mContext.getUser());
}
@@ -1370,6 +1379,7 @@ public class AccountManager {
return new Future2Task<Boolean>(handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier());
}
@Override
@@ -1396,6 +1406,7 @@ public class AccountManager {
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(34);
mService.removeAccountAsUser(mResponse, account, activity != null,
userHandle.getIdentifier());
}
@@ -1509,6 +1520,7 @@ public class AccountManager {
* @param password The password to set, null to clear the password
*/
public void setPassword(final Account account, final String password) {
+ android.util.SeempLog.record(26);
if (account == null) throw new IllegalArgumentException("account is null");
try {
mService.setPassword(account, password);
@@ -1537,6 +1549,7 @@ public class AccountManager {
* @param account The account whose password to clear
*/
public void clearPassword(final Account account) {
+ android.util.SeempLog.record(27);
if (account == null) throw new IllegalArgumentException("account is null");
try {
mService.clearPassword(account);
@@ -1564,6 +1577,7 @@ public class AccountManager {
* @param value String value to set, {@code null} to clear this user data key
*/
public void setUserData(final Account account, final String key, final String value) {
+ android.util.SeempLog.record(28);
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
try {
@@ -1714,6 +1728,7 @@ public class AccountManager {
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.getAuthToken(mResponse, account, authTokenType,
false /* notifyOnAuthFailure */, true /* expectActivityLaunch */,
optionsIn);
@@ -1885,6 +1900,7 @@ public class AccountManager {
return new AmsTask(null, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.getAuthToken(mResponse, account, authTokenType,
notifyAuthFailure, false /* expectActivityLaunch */, optionsIn);
}
@@ -1947,6 +1963,7 @@ public class AccountManager {
final Bundle addAccountOptions,
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
if (Process.myUserHandle().equals(mContext.getUser())) {
+ android.util.SeempLog.record(29);
if (accountType == null) throw new IllegalArgumentException("accountType is null");
final Bundle optionsIn = new Bundle();
if (addAccountOptions != null) {
@@ -1957,6 +1974,7 @@ public class AccountManager {
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.addAccount(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, optionsIn);
}
@@ -1986,6 +2004,7 @@ public class AccountManager {
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.addAccountAsUser(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier());
}
@@ -2035,6 +2054,7 @@ public class AccountManager {
return new Future2Task<Boolean>(handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(34);
mService.copyAccountToUser(
mResponse, account, fromUser.getIdentifier(), toUser.getIdentifier());
}
@@ -2134,6 +2154,7 @@ public class AccountManager {
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.confirmCredentialsAsUser(mResponse, account, options, activity != null,
userId);
}
@@ -2247,10 +2268,12 @@ public class AccountManager {
public AccountManagerFuture<Bundle> editProperties(final String accountType,
final Activity activity, final AccountManagerCallback<Bundle> callback,
final Handler handler) {
+ android.util.SeempLog.record(30);
if (accountType == null) throw new IllegalArgumentException("accountType is null");
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
mService.editProperties(mResponse, accountType, activity != null);
}
}.start();
@@ -2677,6 +2700,7 @@ public class AccountManager {
@Override
public void doWork() throws RemoteException {
+ android.util.SeempLog.record(31);
getAccountByTypeAndFeatures(mAccountType, mFeatures,
new AccountManagerCallback<Bundle>() {
@Override
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 7be4c3e1465b..4aa219f5c472 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -639,6 +639,9 @@ public abstract class ActivityManagerInternal {
*/
public abstract @TempAllowListType int getPushMessagingOverQuotaBehavior();
+ // Starts a process as empty.
+ public abstract int startActivityAsUserEmpty(Bundle options);
+
/**
* Returns the capability of the given uid
*/
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8af74edb88ff..d255870ecc5c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -157,6 +157,7 @@ import android.system.StructStat;
import android.telephony.TelephonyFrameworkInitializer;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
+import android.util.BoostFramework;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -6464,6 +6465,8 @@ public final class ActivityThread extends ClientTransactionHandler
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
+ long st_bindApp = SystemClock.uptimeMillis();
+ BoostFramework ux_perf = null;
// Register the UI Thread as a sensitive thread to the runtime.
VMRuntime.registerSensitiveThread();
// In the case the stack depth property exists, pass it down to the runtime.
@@ -6576,10 +6579,17 @@ public final class ActivityThread extends ClientTransactionHandler
/**
* Switch this process to density compatibility mode if needed.
*/
- if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
+ if ((data.appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
== 0) {
mDensityCompatMode = true;
Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
+ } else {
+ int overrideDensity = data.appInfo.getOverrideDensity();
+ if(overrideDensity != 0) {
+ Log.d(TAG, "override app density from " + DisplayMetrics.DENSITY_DEVICE + " to " + overrideDensity);
+ mDensityCompatMode = true;
+ Bitmap.setDefaultDensity(overrideDensity);
+ }
}
mConfigurationController.updateDefaultDensity(data.config.densityDpi);
@@ -6678,6 +6688,15 @@ public final class ActivityThread extends ClientTransactionHandler
}
if (!Process.isIsolated()) {
+ final int old_mask = StrictMode.allowThreadDiskWritesMask();
+ try {
+ ux_perf = new BoostFramework(appContext);
+ } finally {
+ StrictMode.setThreadPolicyMask(old_mask);
+ }
+ }
+
+ if (!Process.isIsolated()) {
final int oldMask = StrictMode.allowThreadDiskWritesMask();
try {
setupGraphicsSupport(appContext);
@@ -6796,6 +6815,28 @@ public final class ActivityThread extends ClientTransactionHandler
throw e.rethrowFromSystemServer();
}
}
+ long end_bindApp = SystemClock.uptimeMillis();
+ int bindApp_dur = (int) (end_bindApp - st_bindApp);
+ String pkg_name = null;
+ if (appContext != null) {
+ pkg_name = appContext.getPackageName();
+ }
+ if (ux_perf != null && !Process.isIsolated() && pkg_name != null) {
+ String pkgDir = null;
+ try
+ {
+ String codePath = appContext.getPackageCodePath();
+ pkgDir = codePath.substring(0, codePath.lastIndexOf('/'));
+ }
+ catch(Exception e)
+ {
+ Slog.e(TAG, "HeavyGameThread () : Exception_1 = " + e);
+ }
+ ux_perf.perfUXEngine_events(BoostFramework.UXE_EVENT_BINDAPP, 0,
+ pkg_name,
+ bindApp_dur,
+ pkgDir);
+ }
}
private void handleSetContentCaptureOptionsCallback(String packageName) {
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index fd6fa57b9e8d..a445267b36a9 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -509,6 +509,7 @@ public class Instrumentation {
*/
@NonNull
public Activity startActivitySync(@NonNull Intent intent, @Nullable Bundle options) {
+ android.util.SeempLog.record_str(376, intent.toString());
validateNotAppThread();
final Activity activity;
@@ -1722,6 +1723,7 @@ public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
+ android.util.SeempLog.record_str(377, intent.toString());
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
@@ -1797,6 +1799,7 @@ public class Instrumentation {
public int execStartActivitiesAsUser(Context who, IBinder contextThread,
IBinder token, Activity target, Intent[] intents, Bundle options,
int userId) {
+ android.util.SeempLog.record_str(378, intents.toString());
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
@@ -1871,6 +1874,7 @@ public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
+ android.util.SeempLog.record_str(377, intent.toString());
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
@@ -1941,6 +1945,7 @@ public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String resultWho,
Intent intent, int requestCode, Bundle options, UserHandle user) {
+ android.util.SeempLog.record_str(377, intent.toString());
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
@@ -2040,6 +2045,7 @@ public class Instrumentation {
public void execStartActivityFromAppTask(
Context who, IBinder contextThread, IAppTask appTask,
Intent intent, Bundle options) {
+ android.util.SeempLog.record_str(380, intent.toString());
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 0136a35e3975..2150fc9dc0e7 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -51,8 +51,10 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.SystemProperties;
import android.util.AndroidException;
import android.util.ArraySet;
+import android.util.Log;
import android.util.proto.ProtoOutputStream;
import com.android.internal.os.IResultReceiver;
@@ -140,6 +142,7 @@ public final class PendingIntent implements Parcelable {
@EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.R)
static final long PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED = 160794467L;
+
/** @hide */
@IntDef(flag = true,
value = {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index fca4c698c49c..b337396ebe5d 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -680,7 +680,7 @@ public class WallpaperManager {
cmProxy.doColorManagement(decoder, info);
}
}));
- } catch (OutOfMemoryError | IOException e) {
+ } catch (OutOfMemoryError | IOException | ArrayIndexOutOfBoundsException e) {
Log.w(TAG, "Can't decode file", e);
}
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 5094498dbee5..76e743f155dc 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -84,7 +84,9 @@ import java.util.WeakHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
/**
* Represents the local device Bluetooth adapter. The {@link BluetoothAdapter}
* lets you perform fundamental Bluetooth tasks, such as initiate
@@ -829,6 +831,7 @@ public final class BluetoothAdapter {
*/
@RequiresNoPermission
public BluetoothDevice getRemoteDevice(String address) {
+ android.util.SeempLog.record(62);
final BluetoothDevice res = new BluetoothDevice(address);
res.setAttributionSource(mAttributionSource);
return res;
@@ -847,6 +850,7 @@ public final class BluetoothAdapter {
*/
@RequiresNoPermission
public BluetoothDevice getRemoteDevice(byte[] address) {
+ android.util.SeempLog.record(62);
if (address == null || address.length != 6) {
throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
}
@@ -1054,7 +1058,10 @@ public final class BluetoothAdapter {
@SuppressLint("AndroidFrameworkRequiresPermission")
protected Integer recompute(Void query) {
try {
- return mService.getState();
+ if (mService != null) {
+ return mService.getState();
+ }
+ return BluetoothAdapter.STATE_OFF;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1110,6 +1117,7 @@ public final class BluetoothAdapter {
@RequiresNoPermission
@AdapterState
public int getState() {
+ android.util.SeempLog.record(63);
int state = getStateInternal();
// Consider all internal states as OFF
@@ -1195,6 +1203,7 @@ public final class BluetoothAdapter {
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean enable() {
+ android.util.SeempLog.record(56);
if (isEnabled()) {
if (DBG) {
Log.d(TAG, "enable(): BT already enabled!");
@@ -1234,6 +1243,7 @@ public final class BluetoothAdapter {
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disable() {
+ android.util.SeempLog.record(57);
try {
return mManagerService.disable(mAttributionSource, true);
} catch (RemoteException e) {
@@ -1253,6 +1263,7 @@ public final class BluetoothAdapter {
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disable(boolean persist) {
+ android.util.SeempLog.record(57);
try {
return mManagerService.disable(mAttributionSource, persist);
@@ -1328,13 +1339,14 @@ public final class BluetoothAdapter {
public boolean factoryReset() {
try {
mServiceLock.readLock().lock();
- if (mService != null && mService.factoryReset(mAttributionSource)
- && mManagerService != null
- && mManagerService.onFactoryReset(mAttributionSource)) {
- return true;
+ if (mManagerService != null) {
+ SystemProperties.set("persist.bluetooth.factoryreset", "true");
+ /* factoryReset handles both bluetooth reset and config remove
+ * functionality, hence remove onFactoryReset call to avoid redundant code
+ */
+ return mManagerService.factoryReset();
}
Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later");
- SystemProperties.set("persist.bluetooth.factoryreset", "true");
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
@@ -1818,6 +1830,7 @@ public final class BluetoothAdapter {
@RequiresBluetoothLocationPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public boolean startDiscovery() {
+ android.util.SeempLog.record(58);
if (getState() != STATE_ON) {
return false;
}
@@ -2003,7 +2016,21 @@ public final class BluetoothAdapter {
return false;
}
-
+ /** @hide */
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean isBroadcastActive() {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) {
+ return mService.isBroadcastActive(mAttributionSource);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return false;
+ }
/**
* Connects all enabled and supported bluetooth profiles between the local and remote device.
* Connection is asynchronous and you should listen to each profile's broadcast intent
@@ -2308,6 +2335,13 @@ public final class BluetoothAdapter {
}
/**
+ * @hide
+ */
+ public void btCmdGetFunctionCallmap(boolean isdump) {
+ Log.d(TAG, "btCmdGetFunctionCallmap: " + isdump);
+ }
+
+ /**
* Return true if Hearing Aid Profile is supported.
*
* @return true if phone supports Hearing Aid Profile
@@ -2481,6 +2515,7 @@ public final class BluetoothAdapter {
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public Set<BluetoothDevice> getBondedDevices() {
+ android.util.SeempLog.record(61);
if (getState() != STATE_ON) {
return toDeviceSet(Arrays.asList());
}
@@ -2661,6 +2696,7 @@ public final class BluetoothAdapter {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SuppressLint("AndroidFrameworkRequiresPermission")
public int getProfileConnectionState(int profile) {
+ android.util.SeempLog.record(64);
if (getState() != STATE_ON) {
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -2790,6 +2826,7 @@ public final class BluetoothAdapter {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid)
throws IOException {
+ android.util.SeempLog.record(59);
return createNewRfcommSocketAndRecord(name, uuid, false, false);
}
@@ -2987,6 +3024,92 @@ public final class BluetoothAdapter {
return null;
}
+ private void closeBCProfile(BluetoothProfile proxy) {
+ Class<?> bshClass = null;
+ Method bshClose = null;
+ try {
+ bshClass = Class.forName("android.bluetooth.BluetoothSyncHelper");
+ } catch (ClassNotFoundException ex) {
+ Log.e(TAG, "no BSH: exists");
+ bshClass = null;
+ }
+ if (bshClass != null) {
+ Log.d(TAG, "Able to get BSH class handle");
+ try {
+ bshClose = bshClass.getDeclaredMethod("close", null);
+ } catch (NoSuchMethodException e) {
+ Log.e(TAG, "no BSH:isSupported method exists");
+ }
+ if (bshClose != null) {
+ try {
+ bshClose.invoke(proxy, null);
+ } catch(IllegalAccessException e) {
+ Log.e(TAG, "bshClose IllegalAccessException");
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "bshClose InvocationTargetException");
+ }
+ }
+ }
+ Log.d(TAG, "CloseBCProfile returns");
+ }
+
+ private boolean getBCProfile(Context context, BluetoothProfile.ServiceListener sl) {
+ boolean ret = true;
+ boolean isProfileSupported = false;
+ Class<?> bshClass = null;
+ Method bshSupported = null;
+ Constructor bshCons = null;
+ Object bshObj = null;
+ try {
+ bshClass = Class.forName("android.bluetooth.BluetoothSyncHelper");
+ } catch (ClassNotFoundException ex) {
+ Log.e(TAG, "no BSH: exists");
+ bshClass = null;
+ }
+ if (bshClass != null) {
+ Log.d(TAG, "Able to get BSH class handle");
+ try {
+ bshSupported = bshClass.getDeclaredMethod("isSupported", null);
+ } catch (NoSuchMethodException e) {
+ Log.e(TAG, "no BSH:isSupported method exists: gdm");
+ }
+ try {
+ bshCons =
+ bshClass.getDeclaredConstructor(
+ new Class[]{Context.class,
+ BluetoothProfile.ServiceListener.class});
+ } catch (NoSuchMethodException ex) {
+ Log.e(TAG, "bshCons: NoSuchMethodException: gdm" + ex);
+ }
+ }
+ if (bshClass != null && bshSupported != null && bshCons != null) {
+ try {
+ isProfileSupported = (boolean)bshSupported.invoke(null, null);
+ } catch(IllegalAccessException e) {
+ Log.e(TAG, "BSH:isSupported IllegalAccessException");
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "BSH:isSupported InvocationTargetException");
+ }
+ if (isProfileSupported) {
+ try {
+ bshObj = bshCons.newInstance(
+ context, sl);
+ } catch (InstantiationException ex) {
+ Log.e(TAG, "bshCons InstantiationException:" + ex);
+ } catch (IllegalAccessException ex) {
+ Log.e(TAG, "bshCons InstantiationException:" + ex);
+ } catch (InvocationTargetException ex) {
+ Log.e(TAG, "bshCons InvocationTargetException:" + ex);
+ }
+ }
+ }
+ if (bshObj == null) {
+ ret = false;
+ }
+ Log.d(TAG, "getBCService returns" + ret);
+ return ret;
+ }
+
/**
* Get the profile proxy object associated with the profile.
*
@@ -3034,6 +3157,9 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.PBAP) {
BluetoothPbap pbap = new BluetoothPbap(context, listener, this);
return true;
+ } else if (profile == BluetoothProfile.DUN) {
+ BluetoothDun dun = new BluetoothDun(context, listener);
+ return true;
} else if (profile == BluetoothProfile.HEALTH) {
Log.e(TAG, "getProfileProxy(): BluetoothHealth is deprecated");
return false;
@@ -3056,12 +3182,22 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.HID_DEVICE) {
BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener, this);
return true;
+ } else if (profile == BluetoothProfile.BROADCAST) {
+ return getBroadcastProfile(context, listener);
+ } else if (profile == BluetoothProfile.BC_PROFILE) {
+ return getBCProfile(context, listener);
} else if (profile == BluetoothProfile.HEARING_AID) {
if (isHearingAidProfileSupported()) {
BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener, this);
return true;
}
return false;
+ } else if (profile == BluetoothProfile.GROUP_CLIENT) {
+ BluetoothDeviceGroup groupClient = new BluetoothDeviceGroup(context, listener);
+ return true;
+ } else if (profile == BluetoothProfile.VCP) {
+ BluetoothVcp vcp = new BluetoothVcp(context, listener);
+ return true;
} else if (profile == BluetoothProfile.LE_AUDIO) {
BluetoothLeAudio leAudio = new BluetoothLeAudio(context, listener, this);
return true;
@@ -3118,6 +3254,10 @@ public final class BluetoothAdapter {
BluetoothPbap pbap = (BluetoothPbap) proxy;
pbap.close();
break;
+ case BluetoothProfile.DUN:
+ BluetoothDun dun = (BluetoothDun)proxy;
+ dun.close();
+ break;
case BluetoothProfile.GATT:
BluetoothGatt gatt = (BluetoothGatt) proxy;
gatt.close();
@@ -3150,6 +3290,12 @@ public final class BluetoothAdapter {
BluetoothHidDevice hidDevice = (BluetoothHidDevice) proxy;
hidDevice.close();
break;
+ case BluetoothProfile.BROADCAST:
+ closeBroadcastProfile(proxy);
+ break;
+ case BluetoothProfile.BC_PROFILE:
+ closeBCProfile(proxy);
+ break;
case BluetoothProfile.HEARING_AID:
BluetoothHearingAid hearingAid = (BluetoothHearingAid) proxy;
hearingAid.close();
@@ -3157,6 +3303,71 @@ public final class BluetoothAdapter {
case BluetoothProfile.LE_AUDIO:
BluetoothLeAudio leAudio = (BluetoothLeAudio) proxy;
leAudio.close();
+ break;
+ case BluetoothProfile.GROUP_CLIENT:
+ BluetoothDeviceGroup groupClient = (BluetoothDeviceGroup) proxy;
+ groupClient.close();
+ break;
+ case BluetoothProfile.VCP:
+ BluetoothVcp vcp = (BluetoothVcp) proxy;
+ vcp.close();
+ break;
+ }
+ }
+ private boolean getBroadcastProfile(Context context,
+ BluetoothProfile.ServiceListener listener) {
+ boolean ret = true;
+ Class<?> broadcastClass = null;
+ Constructor bcastConstructor = null;
+ Object broadcastObj = null;
+ try {
+ broadcastClass = Class.forName("android.bluetooth.BluetoothBroadcast");
+ } catch (ClassNotFoundException ex) {
+ Log.e(TAG, "no BluetoothBroadcast: exists");
+ }
+ if (broadcastClass != null) {
+ try {
+ bcastConstructor =
+ broadcastClass.getDeclaredConstructor(new Class[]{Context.class,
+ BluetoothProfile.ServiceListener.class});
+ } catch (NoSuchMethodException ex) {
+ Log.e(TAG, "bcastConstructor: NoSuchMethodException: gdm" + ex);
+ }
+ }
+ if (bcastConstructor != null) {
+ try {
+ broadcastObj = bcastConstructor.newInstance(context, listener);
+ } catch (InstantiationException | IllegalAccessException |
+ InvocationTargetException ex) {
+ ex.printStackTrace();
+ }
+ }
+ if (broadcastObj == null) {
+ return false;
+ }
+ return true;
+ }
+ private void closeBroadcastProfile(BluetoothProfile proxy) {
+ Class<?> broadcastClass = null;
+ Method broadcastClose = null;
+ try {
+ broadcastClass = Class.forName("android.bluetooth.BluetootBroadcast");
+ } catch (ClassNotFoundException ex) {
+ Log.e(TAG, "no BluetoothBroadcast: exists");
+ }
+ if (broadcastClass != null) {
+ try {
+ broadcastClose = broadcastClass.getDeclaredMethod("close", null);
+ } catch (NoSuchMethodException e) {
+ Log.e(TAG, "no Broadcast:close method exists");
+ }
+ if (broadcastClose != null) {
+ try {
+ broadcastClose.invoke(proxy, null);
+ } catch(IllegalAccessException | InvocationTargetException ex) {
+ ex.printStackTrace();
+ }
+ }
}
}
@@ -3244,8 +3455,10 @@ public final class BluetoothAdapter {
synchronized (mBluetoothConnectionCallbackExecutorMap) {
if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
try {
- mService.registerBluetoothConnectionCallback(mConnectionCallback,
- mAttributionSource);
+ if (mService != null) {
+ mService.registerBluetoothConnectionCallback
+ (mConnectionCallback, mAttributionSource);
+ }
} catch (RemoteException e) {
Log.e(TAG, "onBluetoothServiceUp: Failed to register bluetooth"
+ "connection callback", e);
@@ -3253,7 +3466,6 @@ public final class BluetoothAdapter {
}
}
}
-
public void onBluetoothServiceDown() {
synchronized (mServiceLock.writeLock()) {
mService = null;
@@ -3267,8 +3479,8 @@ public final class BluetoothAdapter {
mBluetoothLeScanner.cleanup();
}
}
+ Log.d(TAG, "onBluetoothServiceDown: Finished sending callbacks to registered clients");
}
-
public void onBrEdrDown() {
}
};
@@ -3497,6 +3709,22 @@ public final class BluetoothAdapter {
}
}
+ /**
+ * @hide
+ */
+ public void unregisterAdapter() {
+ try {
+ //mServiceLock.writeLock().lock();
+ if (mManagerService != null){
+ mManagerService.unregisterAdapter(mManagerCallback);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ //mServiceLock.writeLock().unlock();
+ }
+ }
+
private Set<BluetoothDevice> toDeviceSet(List<BluetoothDevice> devices) {
Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(devices);
return Collections.unmodifiableSet(deviceSet);
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 7fe18a0704ba..1d19c9431e69 100755..100644
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -119,6 +119,11 @@ public final class BluetoothClass implements Parcelable {
private static final int BITMASK = 0xFFE000;
public static final int LIMITED_DISCOVERABILITY = 0x002000;
+ /**
+ * @hide
+ */
+ public static final int GROUP = 0x004000;
+
public static final int POSITIONING = 0x010000;
public static final int NETWORKING = 0x020000;
public static final int RENDER = 0x040000;
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index 1d0bf97c34eb..1184d20107ba 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -46,7 +46,9 @@ public final class BluetoothCodecConfig implements Parcelable {
SOURCE_CODEC_TYPE_APTX,
SOURCE_CODEC_TYPE_APTX_HD,
SOURCE_CODEC_TYPE_LDAC,
- SOURCE_CODEC_TYPE_MAX,
+ SOURCE_CODEC_TYPE_APTX_ADAPTIVE,
+ SOURCE_CODEC_TYPE_APTX_TWSP,
+ SOURCE_QVA_CODEC_TYPE_MAX,
SOURCE_CODEC_TYPE_INVALID
})
@Retention(RetentionPolicy.SOURCE)
@@ -71,6 +73,22 @@ public final class BluetoothCodecConfig implements Parcelable {
public static final int SOURCE_CODEC_TYPE_MAX = 5;
@UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_APTX_ADAPTIVE = SOURCE_CODEC_TYPE_MAX;
+
+ @UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_APTX_TWSP = SOURCE_CODEC_TYPE_MAX + 1;
+
+ @UnsupportedAppUsage
+ public static final int SOURCE_QVA_CODEC_TYPE_MAX = SOURCE_CODEC_TYPE_MAX + 2;
+
+ /* CELT is not an A2DP Codec and only used to fetch encoder
+ ** format for BA usecase, moving out of a2dp codec value list
+ */
+ @UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_CELT = 8;
+
+ public static final int SOURCE_CODEC_TYPE_LC3 = 9;
+
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
/** @hide */
@@ -126,6 +144,14 @@ public final class BluetoothCodecConfig implements Parcelable {
@UnsupportedAppUsage
public static final int SAMPLE_RATE_192000 = 0x1 << 5;
+ public static final int SAMPLE_RATE_16000 = 0x1 << 6;
+
+ public static final int SAMPLE_RATE_24000 = 0x1 << 7;
+
+ public static final int SAMPLE_RATE_32000 = 0x1 << 8;
+
+ public static final int SAMPLE_RATE_8000 = 0x1 << 9;
+
/** @hide */
@IntDef(prefix = "BITS_PER_SAMPLE_", value = {
@@ -167,6 +193,7 @@ public final class BluetoothCodecConfig implements Parcelable {
@UnsupportedAppUsage
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
+ public static final int CHANNEL_MODE_JOINT_STEREO = 0x1 << 2;
private final @SourceCodecType int mCodecType;
private @CodecPriority int mCodecPriority;
@@ -403,6 +430,10 @@ public final class BluetoothCodecConfig implements Parcelable {
return "aptX HD";
case SOURCE_CODEC_TYPE_LDAC:
return "LDAC";
+ case SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
+ return "aptX Adaptive";
+ case SOURCE_CODEC_TYPE_APTX_TWSP:
+ return "aptX TWS+";
case SOURCE_CODEC_TYPE_INVALID:
return "INVALID CODEC";
default:
@@ -652,6 +683,10 @@ public final class BluetoothCodecConfig implements Parcelable {
if (mCodecSpecific1 != other.mCodecSpecific1) {
return false;
}
+ case SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
+ if (other.mCodecSpecific4 > 0) {
+ return false;
+ }
// fall through
default:
return true;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 5a5fac4a7664..7b8c061deefc 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1,4 +1,39 @@
/*
+ * Copyright (C) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -218,6 +253,18 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static final String ACTION_BOND_STATE_CHANGED =
"android.bluetooth.device.action.BOND_STATE_CHANGED";
+ /**
+ * Broadcast Action: Broadcast details of IOT device when an IOT
+ * related issue is observed.
+ * <p>Always contains the extra fields {@link #EXTRA_NAME}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * @hide
+ **/
+
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_REMOTE_ISSUE_OCCURRED =
+ "org.codeaurora.intent.bluetooth.action.REMOTE_ISSUE_OCCURRED";
+
/**
* Broadcast Action: Indicates the battery level of a remote device has
* been retrieved for the first time, or changed since the last retrieval
@@ -259,6 +306,17 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static final int BATTERY_LEVEL_BLUETOOTH_OFF = -100;
/**
+ * Broadcast Action: Indicates the remote devices are TWS plus earbuds pair.
+ * <p>Always contains the extra fields {@link #EXTRA_TWS_PLUS_DEVICE1},
+ * {@link #EXTRA_TWS_PLUS_DEVICE2}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_TWS_PLUS_DEVICE_PAIR =
+ "android.bluetooth.device.action.TWS_PLUS_DEVICE_PAIR";
+
+ /**
* Used as a Parcelable {@link BluetoothDevice} extra field in every intent
* broadcast by this class. It contains the {@link BluetoothDevice} that
* the intent applies to.
@@ -272,6 +330,77 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
/**
+ * Used as a Parcelable {@link BluetoothQualityReport} extra field in
+ * {@link #ACTION_REMOTE_ISSUE_OCCURRED} intent. It contains the {@link BluetoothQualityReport}.
+ * @hide
+ */
+ public static final String EXTRA_BQR = "android.bluetooth.qti.extra.EXTRA_BQR";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED}
+ * intents. It contains the type of IOT issue that occurred.
+ * @hide
+ */
+ public static final String EXTRA_ISSUE_TYPE = "android.bluetooth.qti.extra.ERROR_TYPE";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the details of details of the issue.
+ * @hide
+ */
+ public static final String EXTRA_ERROR_CODE = "android.bluetooth.qti.extra.ERROR_CODE";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the SoC event mask when issue occurred.
+ * @hide
+ */
+ public static final String EXTRA_ERROR_EVENT_MASK = "android.bluetooth.qti.extra.ERROR_EVENT_MASK";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the LMP Version of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_LMP_VERSION = "android.bluetooth.qti.extra.EXTRA_LMP_VERSION";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the LMP Sub Version of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_LMP_SUBVER = "android.bluetooth.qti.extra.EXTRA_LMP_SUBVER";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the Manufacturer ID of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_MANUFACTURER = "android.bluetooth.qti.extra.EXTRA_MANUFACTURER";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the Power level.
+ * @hide
+ */
+ public static final String EXTRA_POWER_LEVEL = "android.bluetooth.qti.extra.EXTRA_POWER_LEVEL";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the Link Quality of the connection.
+ * @hide
+ */
+ public static final String EXTRA_LINK_QUALITY = "android.bluetooth.qti.extra.EXTRA_LINK_QUALITY";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the coutnt of glitches occured since last broadcast.
+ * @hide
+ */
+ public static final String EXTRA_GLITCH_COUNT = "android.bluetooth.qti.extra.EXTRA_GLITCH_COUNT";
+
+
+ /**
* Used as an optional short extra field in {@link #ACTION_FOUND} intents.
* Contains the RSSI value of the remote device as reported by the
* Bluetooth hardware.
@@ -303,6 +432,23 @@ public final class BluetoothDevice implements Parcelable, Attributable {
*/
public static final String EXTRA_PREVIOUS_BOND_STATE =
"android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_TWS+_DEVICE_PAIR}
+ * intents. It contains the first TWS+ earbud address of pair.
+ * @hide
+ */
+ public static final String EXTRA_TWS_PLUS_DEVICE1 =
+ "android.bluetooth.device.extra.EXTRA_TWS_PLUS_DEVICE1";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_TWS+_DEVICE_PAIR}
+ * intents. It contains the second TWS+ earbud address of pair.
+ * @hide
+ */
+ public static final String EXTRA_TWS_PLUS_DEVICE2 =
+ "android.bluetooth.device.extra.EXTRA_TWS_PLUS_DEVICE2";
+
/**
* Indicates the remote device is not bonded (paired).
* <p>There is no shared link key with the remote device, so communication
@@ -1111,10 +1257,12 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/*package*/
@UnsupportedAppUsage
static IBluetooth getService() {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ IBluetooth tService = adapter.getBluetoothService(sStateChangeCallback);
+
synchronized (BluetoothDevice.class) {
if (sService == null) {
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- sService = adapter.getBluetoothService(sStateChangeCallback);
+ sService = tService;
}
}
return sService;
@@ -1125,9 +1273,10 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public void onBluetoothServiceUp(IBluetooth bluetoothService)
throws RemoteException {
synchronized (BluetoothDevice.class) {
- if (sService == null) {
- sService = bluetoothService;
+ if (sService != null) {
+ Log.w(TAG, "sService is not NULL");
}
+ sService = bluetoothService;
}
}
@@ -1496,6 +1645,16 @@ public final class BluetoothDevice implements Parcelable, Attributable {
Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
return false;
}
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ if (adapter != null &&
+ (((transport == TRANSPORT_LE || transport == TRANSPORT_AUTO)
+ && !adapter.isLeEnabled())
+ || ((transport == TRANSPORT_BREDR || transport == TRANSPORT_AUTO)
+ && !isBluetoothEnabled()))) {
+ Log.w(TAG, "creatBond() initiated in improper adapter state : " + adapter.getState()
+ + " transport = " + transport);
+ return false;
+ }
try {
return service.createBond(
this, transport, remoteP192Data, remoteP256Data, mAttributionSource);
@@ -1530,6 +1689,25 @@ public final class BluetoothDevice implements Parcelable, Attributable {
return false;
}
+ /** @hide */
+ @UnsupportedAppUsage
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public void setBondingInitiatedLocally(boolean localInitiated) {
+ final IBluetooth service = sService;
+ if (service == null) {
+ Log.w(TAG, "BT not enabled, setBondingInitiatedLocally failed");
+ return;
+ }
+ try {
+ service.setBondingInitiatedLocally(this, localInitiated, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return;
+ }
+
/**
* Cancel an in-progress bonding request started with {@link #createBond}.
*
@@ -1572,6 +1750,13 @@ public final class BluetoothDevice implements Parcelable, Attributable {
Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
return false;
}
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ if (adapter != null && !adapter.isLeEnabled()) {
+ Log.w(TAG, "removeBond() initiated in improper adapter state : "
+ + adapter.getState());
+ return false;
+ }
+
try {
Log.i(TAG, "removeBond() for device " + getAddress()
+ " called by pid: " + Process.myPid()
@@ -1839,6 +2024,47 @@ public final class BluetoothDevice implements Parcelable, Attributable {
}
/**
+ * Returns whether if the device is TWS+ device.
+ *
+ * @return True if the devcie is TWS+ device.
+ * @hide
+ */
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean isTwsPlusDevice() {
+ if (sService == null) {
+ Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
+ return false;
+ }
+ try {
+ return sService.isTwsPlusDevice(this, mAttributionSource);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
+ /**
+ * Get the TWS+ peer address of the remote device.
+ *
+ * @return the TWS+ peer address of the remote device if available, otherwise
+ * null.
+ * @hide
+ */
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public String getTwsPlusPeerAddress() {
+ if (sService == null) {
+ Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
+ return null;
+ }
+ try {
+ return sService.getTwsPlusPeerAddress(this, mAttributionSource);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return null;
+ }
+
+ /**
* Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
*
* @return true pin has been set false for error
@@ -2539,6 +2765,48 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport,
boolean opportunistic, int phy, Handler handler) {
+ return connectGatt(context, autoConnect, callback, transport, opportunistic,
+ phy, handler, false);
+ }
+
+ /**
+ * Connect to GATT Server hosted by this device. Caller acts as GATT client.
+ * The callback is used to deliver results to Caller, such as connection status as well
+ * as any further GATT client operations.
+ * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
+ * GATT client operations.
+ *
+ * @param callback GATT callback handler that will receive asynchronous callbacks.
+ * @param autoConnect Whether to directly connect to the remote device (false) or to
+ * automatically connect as soon as the remote device becomes available (true).
+ * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
+ * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
+ * BluetoothDevice#TRANSPORT_LE}
+ * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
+ * does not hold a GATT connection. It automatically disconnects when no other GATT connections
+ * are active for the remote device.
+ * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
+ * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
+ * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
+ * is set to true.
+ * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
+ * an un-specified background thread.
+ * @param eattSupport specifies whether client app needs EATT channel for client operations.
+ * If both local and remote devices support EATT and local app asks for EATT, GATT client
+ * operations will be performed using EATT channel.
+ * If either local or remote device doesn't support EATT but local App asks for EATT, GATT
+ * client operations will be performed using unenhanced ATT channel.
+ *
+ * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
+ * operations.
+ *
+ * @throws NullPointerException if callback is null
+ *
+ * @hide
+ */
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback, int transport, boolean opportunistic,
+ int phy, Handler handler, boolean eattSupport) {
if (callback == null) {
throw new NullPointerException("callback is null");
}
@@ -2555,7 +2823,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
}
BluetoothGatt gatt = new BluetoothGatt(
iGatt, this, transport, opportunistic, phy, mAttributionSource);
- gatt.connect(autoConnect, callback, handler);
+ gatt.connect(autoConnect, callback, handler, eattSupport);
return gatt;
} catch (RemoteException e) {
Log.e(TAG, "", e);
@@ -2701,4 +2969,42 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static @MetadataKey int getMaxMetadataKey() {
return METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD;
}
+
+ /**
+ * Returns Device type.
+ *
+ * @return device type.
+ * @hide
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public int getDeviceType() {
+ if (sService == null) {
+ Log.e(TAG, "getDeviceType query remote device info failed");
+ return -1;
+ }
+ try {
+ return sService.getDeviceType(this, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "getDeviceType fail ", e);
+ }
+ return -1;
+ }
+
+ /**
+ * Used as a String extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
+ * It contains the Group ID of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_GROUP_ID = "android.bluetooth.qti.extra.GROUP_ID";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
+ * It contains the IGNORE DEVICE flag of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_IS_PRIVATE_ADDRESS =
+ "android.bluetooth.qti.extra.IS_PRIVATE_ADDRESS";
}
diff --git a/core/java/android/bluetooth/BluetoothDeviceGroup.java b/core/java/android/bluetooth/BluetoothDeviceGroup.java
new file mode 100644
index 000000000000..e271fac12b45
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothDeviceGroup.java
@@ -0,0 +1,892 @@
+/******************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package android.bluetooth;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
+import android.bluetooth.annotations.RequiresBluetoothScanPermission;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.bluetooth.IBluetoothGroupCallback;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+
+/**
+ * This class provides the public APIs to perform operations of
+ * the Group Identification Profile.
+ *
+ * <p> This class provides functionalities to enable communication with remote
+ * devices which are grouped together to achieve common use cases in
+ * synchronized manner.
+ * <p> BluetoothDeviceGroup is a proxy object for controlling the Bluetooth Group
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the BluetoothDeviceGroup
+ * proxy object. Use {@link BluetoothAdapter#closeProfileProxy} to close connection
+ * of the BluetoothDeviceGroup proxy object with the profile service.
+ * <p> BluetoothDeviceGroup proxy object can be used to identify and fetch Device Group.
+ * Also, API’s are exposed to get exclusive access of group devices for critical
+ * operations. Implement BluetoothGroupCallback to get results invoked API's.
+ *
+ * @hide
+ */
+
+
+public final class BluetoothDeviceGroup implements BluetoothProfile {
+ private static final String TAG = "BluetoothDeviceGroup";
+ private static final boolean DBG = true;
+ private static final boolean VDBG = false;
+
+ /** Group Client App is registerd for callbacks successfully */
+ public static final int APP_REGISTRATION_SUCCESSFUL = 0;
+ /** Group Client App registration failed for callbacks */
+ public static final int APP_REGISTRATION_FAILED = 1;
+
+ /** Group Discovery Status when discovery is started */
+ public static final int GROUP_DISCOVERY_STARTED = 0x00;
+
+ /** Group Discovery Status when discovery is stopped */
+ public static final int GROUP_DISCOVERY_STOPPED = 0x01;
+
+ /** When Application starts Group discovery */
+ public static final int DISCOVERY_STARTED_BY_APPL = 0x00;
+
+ /** When Application stops Group discovery */
+ public static final int DISCOVERY_STOPPED_BY_APPL = 0x01;
+
+ /** When Group discovery is started as a result of
+ * change in Group property. */
+ public static final int DISCOVERY_STARTED_GROUP_PROP_CHANGED = 0x02;
+
+ /** When all devices of Group are discovered */
+ public static final int DISCOVERY_COMPLETED = 0x03;
+
+ /** Group discovery by timeeut. Group device not found in 10 sec. */
+ public static final int DISCOVERY_STOPPED_BY_TIMEOUT = 0x04;
+
+ /** Invalid params are provided for Group discovery */
+ public static final int DISCOVERY_NOT_STARTED_INVALID_PARAMS = 0x05;
+
+ /** Value to release Exclusive Access */
+ public static final int ACCESS_RELEASED = 0x01;
+
+ /** Value to acquire Exclusive Access */
+ public static final int ACCESS_GRANTED = 0x02;
+
+ /** When exclusive access is changed to #ACCESS_RELEASED for all reqested Group devices */
+ public static final int EXCLUSIVE_ACCESS_RELEASED = 0x00;
+
+ /** When exclusive access of the Group device is changed to #ACCESS_RELEASED by timeout */
+ public static final int EXCLUSIVE_ACCESS_RELEASED_BY_TIMEOUT = 0x01;
+
+ /** When exclusive access of all requested Group devices is changed to #ACCESS_GRANTED */
+ public static final int ALL_DEVICES_GRANTED_ACCESS = 0x02;
+
+ /** When exclusive access of some of the requested Group devices is changed to #ACCESS_GRANTED
+ * because of timeout in #setExclusiveAccess operation */
+ public static final int SOME_GRANTED_ACCESS_REASON_TIMEOUT = 0x03;
+
+ /** When access value of some of the requested Group devices is changed to #ACCESS_GRANTED
+ * because some of the Group devices were disconnected */
+ public static final int SOME_GRANTED_ACCESS_REASON_DISCONNECTION = 0x04;
+
+ /** When Exclusive Access couldnt be fetched as one of the Group devices denied
+ * to set value to #ACCESS_DENIED*/
+ public static final int ACCESS_DENIED = 0x05;
+
+ /** Suggests that invalid parameters are passed in #setExclusiveAccess request*/
+ public static final int INVALID_ACCESS_REQ_PARAMS = 0x06;
+
+ /** Invalid Group ID */
+ public static final int INVALID_GROUP_ID = 0x10;
+
+ /** MIN GROUP_ID Value*/
+ public static final int GROUP_ID_MIN = 0x00;
+ /** MAX GROUP_ID Value*/
+ public static final int GROUP_ID_MAX = 0x0F;
+
+ /** Invalid APP ID */
+ public static final int INVALID_APP_ID = 0x10;
+
+ /** MIN APP_ID Value*/
+ public static final int APP_ID_MIN = 0x00;
+ /** MAX APP_ID Value*/
+ public static final int APP_ID_MAX = 0x0F;
+
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.group.profile.action.CONNECTION_STATE_CHANGED";
+
+ private int mAppId;
+ private boolean mAppRegistered = false;
+ private Handler mHandler;
+ private BluetoothGroupCallback mCallback;
+
+ private BluetoothAdapter mAdapter;
+ private final AttributionSource mAttributionSource;
+ private final BluetoothProfileConnector<IBluetoothDeviceGroup> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.GROUP_CLIENT,
+ "BluetoothDeviceGroup", IBluetoothDeviceGroup.class.getName()) {
+ @Override
+ public IBluetoothDeviceGroup getServiceInterface(IBinder service) {
+ return IBluetoothDeviceGroup.Stub.asInterface(Binder.allowBlocking(service));
+ }
+ };
+
+ /**
+ * Creates a BluetoothDeviceGroup proxy object for interacting with the local
+ * Bluetooth Service which handles Group operations.
+ * @hide
+ */
+ /*package*/ BluetoothDeviceGroup(Context context, ServiceListener listener) {
+ mProfileConnector.connect(context, listener);
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mAttributionSource = mAdapter.getAttributionSource();
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (RemoteException re) {
+ Log.e(TAG, "", re);
+ }
+ }
+ }
+
+ private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+ new IBluetoothStateChangeCallback.Stub() {
+ public void onBluetoothStateChange(boolean up) {
+ if (!up) {
+ mAppRegistered = false;
+ }
+ }
+ };
+
+ /**
+ * Close this BluetoothGroupDevice client object.
+ *
+ * Application should call this method as soon as it is done with
+ * Group operations.
+ */
+ /*package*/ void close() {
+ if (VDBG) log("close()");
+
+ mAppRegistered = false;
+ final IBluetoothDeviceGroup service = getService();
+ if (service != null) {
+ try {
+ service.unregisterGroupClientApp(mAppId, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+
+ mProfileConnector.disconnect();
+ }
+
+ /**
+ * @hide
+ */
+ private IBluetoothDeviceGroup getService() {
+ return mProfileConnector.getService();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void finalize() {
+ close();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (VDBG) log("getConnectedDevices()");
+
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (VDBG) log("getDevicesMatchingStates()");
+
+ return null;
+ }
+
+ private boolean isEnabled() {
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
+ }
+
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null &&
+ BluetoothAdapter.checkBluetoothAddress(device.getAddress());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getConnectionState(BluetoothDevice device) {
+ if (VDBG) log("getState(" + device + ")");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+
+ private final IBluetoothGroupCallback.Stub mBluetoothGroupCallback =
+ new IBluetoothGroupCallback.Stub() {
+
+ @Override
+ public void onGroupClientAppRegistered(int status, int appId) {
+ if (DBG) {
+ Log.d(TAG, "onGroupClientAppRegistered() - status=" + status
+ + " appId = " + appId);
+ }
+
+ if (status != APP_REGISTRATION_SUCCESSFUL) {
+ mAppRegistered = false;
+ }
+
+ mAppId = appId;
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onGroupClientAppRegistered(status, appId);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onGroupClientAppUnregistered(int status) {
+ if (DBG) {
+ Log.d(TAG, "onGroupClientAppUnregistered() - status=" + status
+ + " mAppId=" + mAppId);
+ }
+ }
+
+ @Override
+ public void onConnectionStateChanged (int state, BluetoothDevice device) {
+ if (DBG) {
+ Log.d(TAG, "onConnectionStateChanged() - state = " + state
+ + " device = " + device);
+ }
+
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onConnectionStateChanged(state, device);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onNewGroupFound(int groupId, BluetoothDevice device,
+ ParcelUuid uuid) {
+ if (DBG) {
+ Log.d(TAG, "onNewGroupFound() - appId = " + mAppId +
+ ", groupId = " + groupId + ", device: " + device +
+ ", Including service UUID: " + uuid.toString());
+ }
+
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onNewGroupFound(groupId, device, uuid.getUuid());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onGroupDiscoveryStatusChanged(int groupId, int status, int reason) {
+ if (DBG) {
+ Log.d(TAG, "onGroupDiscoveryStatusChanged() - appId = " + mAppId +
+ ", groupId = " + groupId + ", status: " + status +
+ ", reason: " + reason);
+ }
+
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onGroupDiscoveryStatusChanged(groupId, status, reason);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onGroupDeviceFound(int groupId, BluetoothDevice device) {
+ if (DBG) {
+ Log.d(TAG, "onGroupDeviceFound() - appId = " + mAppId + ", device = " + device);
+ }
+
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onGroupDeviceFound(groupId, device);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onExclusiveAccessChanged(int groupId, int value, int status,
+ List<BluetoothDevice> devices) {
+ if (DBG) {
+ Log.d(TAG, "onExclusiveAccessChanged() - appId = " + mAppId
+ + ", groupId = " + groupId + ", value = " + value
+ + " accessStatus = " + status + ", devices: " + devices);
+ }
+
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onExclusiveAccessChanged(groupId, value, status, devices);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onExclusiveAccessStatusFetched(int groupId, int accessValue) {
+ }
+
+ @Override
+ public void onExclusiveAccessAvailable (int groupId, BluetoothDevice device) {
+ if (DBG) {
+ Log.d(TAG, "onExclusiveAccessAvailable() - appId = " + mAppId
+ + ", groupId = " + groupId + ", device: " + device);
+ }
+
+ runOrQueueCallback(new Runnable() {
+ @Override
+ public void run() {
+ final BluetoothGroupCallback callback = mCallback;
+ if (callback != null) {
+ callback.onExclusiveAccessAvailable(groupId, device);
+ }
+ }
+ });
+ }
+ };
+
+ /**
+ * Registers callbacks to be received by application on completion of
+ * required operations.
+ *
+ * @param callbacks Reference of BluetoothGroupCallback implemented in
+ * application.
+ * @param handler handler that will receive asynchronous callbacks.
+ * @return true, if operation was initiated successfully.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean registerGroupClientApp(BluetoothGroupCallback callbacks, Handler handler) {
+ if (DBG) log("registerGroupClientApp() mAppRegistered = " + mAppRegistered);
+
+ /* Check if app is trying multiple registrations */
+ if (mAppRegistered) {
+ Log.e(TAG, "App already registered.");
+ return false;
+ }
+
+ mHandler = handler;
+ mCallback = callbacks;
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy not attached to Profile Service. Can't register App.");
+ return false;
+ }
+
+ mAppRegistered = true;
+ try {
+ UUID uuid = UUID.randomUUID();
+ service.registerGroupClientApp(new ParcelUuid(uuid), mBluetoothGroupCallback,
+ mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ /**
+ * Starts discovery of the remaining Group devices which are part of the group.
+ *
+ * <p> This API should be called when onNewGroupFound() is received in the
+ * application and when given group is the required device group. This
+ * API can also be used to rediscover the undiscovered Group devices.
+ *
+ * <p> To the application that started group discovery,
+ * {@link BluetoothGroupCallback#onGroupDeviceFound} callback will be given when
+ * a new Group device is found and {@link BluetoothGroupCallback#onGroupDiscoveryStatusChanged}
+ * callback will be given when discovery is started.
+ *
+ * @param groupId Identifier of the Group for which group
+ * discovery has to be started.
+ * @return true, if operation was initiated successfully.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean startGroupDiscovery(int groupId) {
+ if (DBG) log("startGroupDiscovery() : groupId = " + groupId);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't start group discovery");
+ return false;
+ }
+
+ try {
+ UUID uuid = UUID.randomUUID();
+ service.startGroupDiscovery(mAppId ,groupId, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ /**
+ * Stops ongoing group discovery for Group identified by groupId.
+ *
+ * <p> {@link BluetoothGroupCallback#onGroupDiscoveryStatusChanged} is given
+ * when group discovery is stopped.
+ *
+ * @param groupId Identifier of the Group for which group
+ * discovery has to be stopped.
+ * @return true, if operation was initiated successfully.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean stopGroupDiscovery(int groupId) {
+ if (DBG) log("stopGroupDiscovery() : groupId = " + groupId);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't Stop group discovery");
+ return false;
+ }
+
+ try {
+ service.stopGroupDiscovery(mAppId ,groupId, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ /**
+ * Fetches already discovered Groups.
+ *
+ * @return List of DeviceGroup that are already discovered.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public List<DeviceGroup> getDiscoveredGroups() {
+ return getDiscoveredGroups(false);
+ }
+
+ /**
+ * Fetches already discovered device groups.
+ *
+ * @param mPublicAddr All discovered device groups with public address of devices.
+ * @return List of Device Groups that are already discovered.
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public List<DeviceGroup> getDiscoveredGroups(boolean mPublicAddr) {
+ if (DBG) log("getDiscoveredGroups()");
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return null;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't fetch Groups.");
+ return null;
+ }
+
+ try {
+ List<DeviceGroup> groups = service.getDiscoveredGroups(mPublicAddr, mAttributionSource);
+ return groups;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+
+ return null;
+ }
+
+ /**
+ * Fetch details of a already discovered Group identified by groupId.
+ *
+ * @param groupId Identifier of the Group for which Group details are required.
+ * @return Required DeviceGroup.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public DeviceGroup getGroup(int groupId) {
+ return getGroup(groupId, false);
+ }
+
+ /**
+ * Fetch details of a already discovered Group identified by groupId.
+ *
+ * @param groupId Identifier of the device group for which group
+ * details are required.
+ * @param mPublicAddr DeviceGroup with Public Address of the group devices.
+ * @return Required DeviceGroup.
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public DeviceGroup getGroup(int groupId, boolean mPublicAddr) {
+ if (DBG) log("getGroup() : groupId = " + groupId);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return null;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't fetch Group.");
+ return null;
+ }
+
+ try {
+ DeviceGroup group = service.getDeviceGroup(groupId, mPublicAddr, mAttributionSource);
+ return group;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+
+ return null;
+ }
+
+ /**
+ * Get Group Identifier of the remote device to which it belongs.
+ *
+ * @param device BluetoothDevice instance of the remote device.
+ * @param uuid ParcelUuid of the primary service in which this
+ * Group Service is included.
+ * @return Group identifier of the required device.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getRemoteDeviceGroupId (BluetoothDevice device, ParcelUuid uuid) {
+ return getRemoteDeviceGroupId(device, uuid, false);
+ }
+
+ /**
+ * Get Group Identifier of the remote device to which it belongs.
+ *
+ * @param device BluetoothDevice instance of the remote device.
+ * @param uuid ParcelUuid of the primary service in which this
+ * Group Service is included.
+ * @param mPublicAddr Suggests that group identifier is required for passed
+ * public address of the remote device.
+ * @return Group identifier of the required group for the device
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getRemoteDeviceGroupId (BluetoothDevice device, ParcelUuid uuid,
+ boolean mPublicAddr) {
+ if (DBG) log("getRemoteDeviceGroupId() : device = " + device);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return INVALID_GROUP_ID;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service." +
+ "Can't get group id for device.");
+ return INVALID_GROUP_ID;
+ }
+
+ try {
+ return service.getRemoteDeviceGroupId(device, uuid, mPublicAddr, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return INVALID_GROUP_ID;
+ }
+
+ /**
+ * Suggests whether discovery for a given Group is ongoing.
+ *
+ * @param groupId Identifier of the Group for which discovery
+ * status is to be known.
+ * @return true, if group discovery is ongoing for mentioned group.
+ * Otherwise, false.
+ */
+ @RequiresBluetoothScanPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public boolean isGroupDiscoveryInProgress (int groupId) {
+ if (DBG) log("isGroupDiscoveryInProgress() : groupId = " + groupId);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service.Can't get discovery status.");
+ return false;
+ }
+
+ try {
+ return service.isGroupDiscoveryInProgress(groupId, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return false;
+ }
+
+ /**
+ * Acquires/Releases exclusive access of a given Group or subgroup.
+ * The result of this operation is returned in
+ * {@link BluetoothGroupCallback#onExclusiveAccessChanged} callback.
+ *
+ * @param groupId Identifier of the Group.
+ * @param devices List of BluetoothDevice for which access has to be changed.
+ * If this parameter is passed as null, all Group devices in the
+ * mentioned group will be considered for request.
+ * @param value Access which required to be changed.
+ * 0x01 – Access released ({@link #ACCESS_RELEASED}).
+ * 0x02 - Access granted ({@link #ACCESS_GRANTED}).
+ * @return true, if operation was initiated successfully.
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public boolean setExclusiveAccess(int groupId, List<BluetoothDevice> devices, int value) {
+ if (DBG) log("setExclusiveAccess() : groupId = " + groupId +
+ ", access value: " + value);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't proceed.");
+ return false;
+ }
+
+ try {
+ service.setExclusiveAccess(mAppId, groupId, devices, value, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ /**
+ * Returns Status of the exclusive access for mentioned Group.
+ *
+ * @param groupId Identifier of the Group.
+ * @param devices List of BluetoothDevice for which access value has to be known.
+ * If this parameter is passed as null, all Group devices in the
+ * mentioned group will be queried for access status.
+ * @return true, if operation was initiated successfully.
+ * @hide
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public boolean getExclusiveAccessStatus (int groupId, List<BluetoothDevice> devices) {
+ if (DBG) log("getExclusiveAccessStatus() : groupId = " + groupId);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service." +
+ " Can't get exclusive access status.");
+ return false;
+ }
+
+ try {
+ service.getExclusiveAccessStatus(mAppId, groupId, devices, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ /**
+ * Creates GATT Connection with remote device for Group Operations.
+ *
+ * <p> This API acts as trigger to start service discovery to identify
+ * new device group on remote device once connection has been established
+ * successfully. Application calling connect will get
+ * {@link BluetoothGroupCallback#onNewGroupFoundcallback} after
+ * {@link #onConnectionStateChanged} (once connection has been established
+ * and group discovery is completed.)
+ *
+ * @param device BluetoothDevice instance od remote device with which
+ * Connection is required to be established.
+ * @return true, if operation was initiated successfully.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean connect (BluetoothDevice device) {
+ if (DBG) log("connect : device = " + device);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't connect.");
+ return false;
+ }
+
+ try {
+ service.connect(mAppId, device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ /**
+ * Initiates GATT disconnection for Group Operations.
+ *
+ * @param device BluetoothDevice instance of remote device.
+ * This API must be called if application is not
+ * interested in any Group operations.
+ * @return true, if operation was initiated successfully.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean disconnect (BluetoothDevice device) {
+ if (DBG) log("disconnect : device = " + device);
+
+ if (!mAppRegistered) {
+ Log.e(TAG, "App not registered for Group operations." +
+ " Register App using registerGroupClientApp");
+ return false;
+ }
+
+ final IBluetoothDeviceGroup service = getService();
+ if (service == null) {
+ Log.e(TAG, "Proxy is not attached to Profile Service. Can't disconnect");
+ return false;
+ }
+
+ try {
+ service.disconnect(mAppId, device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ }
+ return true;
+ }
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
+
+ /**
+ * Queue the runnable on a {@link Handler} provided by the user, or execute the runnable
+ * immediately if no Handler was provided.
+ */
+ private void runOrQueueCallback(final Runnable cb) {
+ if (mHandler == null) {
+ try {
+ cb.run();
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception in callback", ex);
+ }
+ } else {
+ mHandler.post(cb);
+ }
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothDun.java b/core/java/android/bluetooth/BluetoothDun.java
new file mode 100644
index 000000000000..cbf44e54dd77
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothDun.java
@@ -0,0 +1,296 @@
+/*
+*Copyright (c) 2018, The Linux Foundation. All rights reserved.
+*
+*Redistribution and use in source and binary forms, with or without
+*modification, are permitted provided that the following conditions are
+*met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+*THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+*WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+*MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+*ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+*BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+*CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+*SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+*WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+*OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+*IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+package android.bluetooth;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the APIs to control the Bluetooth Dun
+ * Profile.
+ *
+ *<p>BluetoothDun is a proxy object for controlling the Bluetooth DUN
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothDun proxy object.
+ *
+ *<p>Each method is protected with its appropriate permission.
+ *@hide
+ */
+public final class BluetoothDun implements BluetoothProfile {
+ private static final String TAG = "BluetoothDun";
+ private static final boolean DBG = false;
+ private static final boolean VDBG = false;
+
+ /**
+ * Intent used to broadcast the change in connection state of the Dun
+ * profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTED}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "codeaurora.bluetooth.dun.profile.action.CONNECTION_STATE_CHANGED";
+
+ private Context mContext;
+ private ServiceListener mServiceListener;
+ private BluetoothAdapter mAdapter;
+ private IBluetoothDun mDunService;
+
+ /**
+ * Create a BluetoothDun proxy object for interacting with the local
+ * Bluetooth Service which handles the Dun profile
+ *
+ */
+ /*package*/ BluetoothDun(Context context, ServiceListener l) {
+ mContext = context;
+ mServiceListener = l;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ try {
+ mAdapter.getBluetoothManager().registerStateChangeCallback(mStateChangeCallback);
+ } catch (RemoteException re) {
+ Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
+ }
+ Log.d(TAG, "BluetoothDun() call bindService");
+ doBind();
+ }
+
+ boolean doBind() {
+ Intent intent = new Intent(IBluetoothDun.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+ android.os.Process.myUserHandle())) {
+ Log.e(TAG, "Could not bind to Bluetooth Dun Service with " + intent);
+ return false;
+ }
+ return true;
+ }
+
+
+ /*package*/ void close() {
+ if (VDBG) log("close()");
+ mServiceListener = null;
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.unregisterStateChangeCallback(mStateChangeCallback);
+ } catch (RemoteException re) {
+ Log.w(TAG,"Unable to unregister BluetoothStateChangeCallback",re);
+ }
+ }
+
+ synchronized (mConnection) {
+ if ( mDunService != null) {
+ try {
+ mDunService = null;
+ mContext.unbindService(mConnection);
+ } catch (Exception re) {
+ Log.e(TAG,"",re);
+ }
+ }
+ }
+ }
+
+ protected void finalize() {
+ close();
+ }
+
+ private IBluetoothStateChangeCallback mStateChangeCallback =
+ new IBluetoothStateChangeCallback.Stub() {
+
+ @Override
+ public void onBluetoothStateChange(boolean on) {
+ //Handle enable request to bind again.
+ Log.d(TAG, "onBluetoothStateChange on: " + on);
+ if (on) {
+ try {
+ if (mDunService == null) {
+ Log.d(TAG, "onBluetoothStateChange call bindService");
+ doBind();
+ }
+ } catch (IllegalStateException e) {
+ Log.e(TAG,"onBluetoothStateChange: could not bind to DUN service: ", e);
+ } catch (SecurityException e) {
+ Log.e(TAG,"onBluetoothStateChange: could not bind to DUN service: ", e);
+ }
+ } else {
+ if (VDBG) Log.d(TAG,"Unbinding service...");
+ synchronized (mConnection) {
+ if ( mDunService != null) {
+ try {
+ mDunService = null;
+ mContext.unbindService(mConnection);
+ } catch (Exception re) {
+ Log.e(TAG,"",re);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Initiate disconnection from DUN server.
+ *
+ * <p> Once the disconnection is initiated by any device either local host
+ * or remote device, the state will transition from {@link #STATE_CONNECTED}
+ * to {@link #STATE_DISCONNECTED}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ * permission.
+ *
+ * @param device Remote Bluetooth Device
+ * @return false on immediate error,
+ * true otherwise
+ * @hide
+ */
+ public boolean disconnect(BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ if (mDunService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mDunService.disconnect(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+ if (mDunService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (VDBG) log("getConnectedDevices()");
+ if (mDunService != null && isEnabled()) {
+ try {
+ return mDunService.getConnectedDevices();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
+ }
+ if (mDunService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (VDBG) log("getDevicesMatchingStates()");
+ if (mDunService != null && isEnabled()) {
+ try {
+ return mDunService.getDevicesMatchingConnectionStates(states);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
+ }
+ if (mDunService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getConnectionState(BluetoothDevice device) {
+ if (VDBG) log("getState(" + device + ")");
+ if (mDunService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mDunService.getConnectionState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ }
+ if (mDunService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+
+ private ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ if (DBG) Log.d(TAG, "BluetoothDUN Proxy object connected");
+ mDunService = IBluetoothDun.Stub.asInterface(service);
+
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.DUN,
+ BluetoothDun.this);
+ }
+ }
+ public void onServiceDisconnected(ComponentName className) {
+ if (DBG) Log.d(TAG, "BluetoothDUN Proxy object disconnected");
+ mDunService = null;
+ if (mServiceListener != null) {
+ mServiceListener.onServiceDisconnected(BluetoothProfile.DUN);
+ }
+ }
+ };
+
+ private boolean isEnabled() {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+ return false;
+ }
+
+ private boolean isValidDevice(BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
+ }
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index aea82102ca36..5d4f2ae87b48 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -927,9 +927,45 @@ public final class BluetoothGatt implements BluetoothProfile {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
/*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
Handler handler) {
+ return connect(autoConnect, callback, handler, false);
+ }
+
+ /**
+ * Initiate a connection to a Bluetooth GATT capable device.
+ *
+ * <p>The connection may not be established right away, but will be
+ * completed when the remote device is available. A
+ * {@link BluetoothGattCallback#onConnectionStateChange} callback will be
+ * invoked when the connection state changes as a result of this function.
+ *
+ * <p>The autoConnect parameter determines whether to actively connect to
+ * the remote device, or rather passively scan and finalize the connection
+ * when the remote device is in range/available. Generally, the first ever
+ * connection to a device should be direct (autoConnect set to false) and
+ * subsequent connections to known devices should be invoked with the
+ * autoConnect parameter set to true.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+ *
+ * @param device Remote device to connect to
+ * @param autoConnect Whether to directly connect to the remote device (false) or to
+ * automatically connect as soon as the remote device becomes available (true).
+ * @param eattSupport specifies whether client app needs EATT channel for client operations.
+ * If both local and remote devices support EATT and local app asks for EATT, GATT client
+ * operations will be performed using EATT channel.
+ * If either local or remote device doesn't support EATT but local App asks for EATT, GATT
+ * client operations will be performed using unenhanced ATT channel.
+ * @return true, if the connection attempt was initiated successfully
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
+ Handler handler, boolean eattSupport) {
if (DBG) {
Log.d(TAG,
- "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
+ "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect
+ + ", eattSupport: " + eattSupport);
}
synchronized (mStateLock) {
if (mConnState != CONN_STATE_IDLE) {
@@ -940,7 +976,7 @@ public final class BluetoothGatt implements BluetoothProfile {
mAutoConnect = autoConnect;
- if (!registerApp(callback, handler)) {
+ if (!registerApp(callback, handler, eattSupport)) {
synchronized (mStateLock) {
mConnState = CONN_STATE_IDLE;
}
diff --git a/core/java/android/bluetooth/BluetoothGroupCallback.java b/core/java/android/bluetooth/BluetoothGroupCallback.java
new file mode 100644
index 000000000000..a818cc77fd3a
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGroupCallback.java
@@ -0,0 +1,132 @@
+/******************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package android.bluetooth;
+
+import java.util.UUID;
+import java.util.List;
+/**
+ * This abstract class is used to implement {@link BluetoothDeviceGroup} callbacks.
+ * @hide
+ */
+public abstract class BluetoothGroupCallback {
+ /**
+ * This Callback gives connection state changed with specific group device.
+ *
+ * @param state Connection state of the {@link BluetoothProfile} group device.
+ * @param device Remote device for which connection state has changed.
+ */
+ public void onConnectionStateChanged (int state, BluetoothDevice device) {
+ }
+
+ /**
+ * This callback is given when application is registered for Group operation
+ * callbacks. This callback is given after {@link BluetoothDeviceGroup#registerGroupClientApp}
+ * is called.
+ *
+ * @param status Status of the group client app registration.
+ * @param appId Identifier of the application for group operations.
+ */
+ public void onGroupClientAppRegistered(int status, int appId) {
+ }
+
+ /**
+ * This callback is triggered when a new device group has been identified
+ * from one of the connected device. After this callback is received, application
+ * can choose to trigger discovery of device group using API
+ * {@link BluetoothDeviceGroup#startGroupDiscovery}
+ *
+ * @param groupId Identifier of the Device Group.
+ * @param device Remote device with which Device Group is found.
+ * @param uuid UUID of the primary Service for this Device Group Service.
+ */
+ public void onNewGroupFound (int groupId, BluetoothDevice device, UUID uuid) {
+ }
+
+ /**
+ * This Callback is triggered when device group discovery is either started/stopped.
+ *
+ * @param groupId Identifier of the device group.
+ * @param status Device Group Discovery status.
+ * {@link BluetoothDeviceGroup#GROUP_DISCOVERY_STARTED}
+ * or {@link BluetoothDeviceGroup#GROUP_DISCOVERY_STOPPED}.
+ * @param reason Reason for change in the discovery status.
+ */
+ public void onGroupDiscoveryStatusChanged (int groupId, int status, int reason) {
+ }
+
+ /**
+ * This callback is triggered when new group device has been found after group
+ * discovery has been started. This callback is given on discovery of every
+ * new group device.
+ *
+ * @param groupId Identifier of the device group.
+ * @param device {@link BluetoothDevice} instance of discovered group device.
+ */
+ public void onGroupDeviceFound (int groupId, BluetoothDevice device) {
+ }
+
+ /**
+ * This callback is triggered after exclusive access status of the group
+ * or subgroup has been changed after the request from application.
+ *
+ * @param groupId Identifier of the device group.
+ * @param value Changed value of the exclusive access.
+ * @param status Status associated with the exclusive access.
+ * @param devices List of devices for which exclusive access has been changed.
+ */
+ public void onExclusiveAccessChanged (int groupId, int value, int status,
+ List<BluetoothDevice> devices) {
+ }
+
+ /**
+ * This callback gives access status of requested group/subgroup once
+ * it is fetched.
+ *
+ * @param groupId Identifier of the device group.
+ * @param accessStatus Value of the Exclusive Access.
+ */
+ public void onExclusiveAccessStatusFetched (int groupId, int accessStatus) {
+ }
+
+ /**
+ * This callback is given to application when exclusive access is available
+ * for the device of a given group for which was denied earlier.
+ * <p> Exclusive Access is considered available when group device sends notification
+ * for access changed to BluetoothDeviceGroup#ACCESS_RELEASED. This callback is
+ * given to the application which has requested the access earlier and the request
+ * had failed as one of the group device had DENIED the access.
+ *
+ * @param groupId Identifier of the device group.
+ * @param device {@link BluetoothDevice} which has exclusive access available.
+ */
+ public void onExclusiveAccessAvailable (int groupId, BluetoothDevice device) {
+ }
+
+} \ No newline at end of file
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index b594ae34436e..aadd036250fe 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -43,8 +43,11 @@ import android.os.RemoteException;
import android.util.CloseGuard;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Public API for controlling the Bluetooth Headset Service. This includes both
@@ -270,6 +273,13 @@ public final class BluetoothHeadset implements BluetoothProfile {
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";
/**
+ * Headset state when SCO audio is disconnecting.
+ *
+ * @hide
+ */
+ public static final int STATE_AUDIO_DISCONNECTING = 13;
+
+ /**
* Headset state when SCO audio is not connected.
* This state can be one of
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
@@ -294,6 +304,41 @@ public final class BluetoothHeadset implements BluetoothProfile {
public static final int STATE_AUDIO_CONNECTED = 12;
/**
+ * Intent used to broadcast the Battery status of TWS+ devices
+ *
+ * <p>This intent will have 2 extras:
+ * <ul>
+ * <li> {@link #EXTRA_HF_TWSP_BATTERY_STATE} - Current Battey state of TWS+
+ * device. 0 for Discharging, 1 for Charging
+ * <\li>
+ * <li> {@link #EXTRA_HF_TWSP_BATTERY_LEVEL} - Current Battey charging level
+ * in percentage of TWS+ device.
+ * <\li>
+ *
+ * @hide
+ */
+ public static final String ACTION_HF_TWSP_BATTERY_STATE_CHANGED =
+ "android.bluetooth.headset.action.HF_TWSP_BATTERY_STATE_CHANGED";
+
+ /**
+ * A int extra field in {@link #EXTRA_HF_TWSP_BATTERY_STATE}
+ * intents that contains the battery state of TWS+ device
+ *
+ * @hide
+ */
+ public static final String EXTRA_HF_TWSP_BATTERY_STATE =
+ "android.bluetooth.headset.extra.HF_TWSP_BATTERY_STATE";
+
+ /**
+ * A int extra field in {@link #EXTRA_HF_TWSP_BATTERY_LEVEL}
+ * intents that contains the value of battery level in percentage for TWS+ device
+ * @hide
+ */
+ public static final String EXTRA_HF_TWSP_BATTERY_LEVEL =
+ "android.bluetooth.headset.extra.HF_TWSP_BATTERY_LEVEL";
+
+
+ /**
* Intent used to broadcast the headset's indicator status
*
* <p>This intent will have 3 extras:
@@ -344,7 +389,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
private Context mContext;
private ServiceListener mServiceListener;
- private volatile IBluetoothHeadset mService;
+ private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
+ @GuardedBy("mServiceLock") private IBluetoothHeadset mService;
private final BluetoothAdapter mAdapter;
private final AttributionSource mAttributionSource;
@@ -395,7 +441,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
private boolean doBind() {
synchronized (mConnection) {
if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
+ if (DBG) Log.d(TAG, "Binding service...");
try {
return mAdapter.getBluetoothManager().bindBluetoothProfileService(
BluetoothProfile.HEADSET, mConnection);
@@ -409,15 +455,17 @@ public final class BluetoothHeadset implements BluetoothProfile {
private void doUnbind() {
synchronized (mConnection) {
+ if (DBG) Log.d(TAG, "Unbinding service...");
if (mService != null) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
try {
mAdapter.getBluetoothManager().unbindBluetoothProfileService(
BluetoothProfile.HEADSET, mConnection);
} catch (RemoteException e) {
Log.e(TAG, "Unable to unbind HeadsetService", e);
} finally {
+ mServiceLock.writeLock().lock();
mService = null;
+ mServiceLock.writeLock().unlock();
}
}
}
@@ -542,19 +590,24 @@ public final class BluetoothHeadset implements BluetoothProfile {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- final IBluetoothHeadset service = mService;
- if (service != null && isEnabled()) {
- try {
- return Attributable.setAttributionSource(
- service.getConnectedDevicesWithAttribution(mAttributionSource),
- mAttributionSource);
- } catch (RemoteException e) {
- Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return new ArrayList<BluetoothDevice>();
+ try {
+ mServiceLock.readLock().lock();
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
+ try {
+ return Attributable.setAttributionSource(
+ service.getConnectedDevicesWithAttribution(mAttributionSource),
+ mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
}
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ } finally {
+ mServiceLock.readLock().unlock();
}
- if (service == null) Log.w(TAG, "Proxy not attached to service");
- return new ArrayList<BluetoothDevice>();
}
/**
@@ -872,14 +925,19 @@ public final class BluetoothHeadset implements BluetoothProfile {
public boolean isAudioConnected(BluetoothDevice device) {
if (VDBG) log("isAudioConnected()");
final IBluetoothHeadset service = mService;
- if (service != null && isEnabled() && isValidDevice(device)) {
- try {
- return service.isAudioConnected(device, mAttributionSource);
- } catch (RemoteException e) {
- Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ try {
+ mServiceLock.readLock().lock();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.isAudioConnected(device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
}
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ } finally {
+ mServiceLock.readLock().unlock();
}
- if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -1381,17 +1439,26 @@ public final class BluetoothHeadset implements BluetoothProfile {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothHeadset.Stub.asInterface(Binder.allowBlocking(service));
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_HEADSET_SERVICE_CONNECTED));
+ try {
+ mServiceLock.writeLock().lock();
+ mService = IBluetoothHeadset.Stub.asInterface(Binder.allowBlocking(service));
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_HEADSET_SERVICE_CONNECTED));
+ } finally {
+ mServiceLock.writeLock().unlock();
+ }
}
@Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
- doUnbind();
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_HEADSET_SERVICE_DISCONNECTED));
+ try {
+ mServiceLock.writeLock().lock();
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_HEADSET_SERVICE_DISCONNECTED));
+ } finally {
+ mServiceLock.writeLock().unlock();
+ }
}
};
@@ -1433,4 +1500,60 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
}
};
+
+ /**
+ * Notify Headset of phone state change.
+ * This is a backdoor for phone app to call BluetoothHeadset since
+ * there is currently not a good way to get precise call state change outside
+ * of phone app.
+ *
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ })
+ public void phoneStateChangedDsDa(int numActive, int numHeld, int callState, String number,
+ int type, String name) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
+ try {
+ service.phoneStateChangedDsDa(numActive, numHeld, callState, number, type, name,
+ mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+
+ /**
+ * Send Headset of CLCC response
+ *
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ })
+ public void clccResponseDsDa(int index, int direction, int status, int mode, boolean mpty,
+ String number, int type) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
+ try {
+ service.clccResponseDsDa(index, direction, status, mode, mpty, number, type,
+ mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+
}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 161c843f0398..5f9d953bd730 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -213,12 +213,60 @@ public interface BluetoothProfile {
int LE_AUDIO = 22;
/**
+ * DUN
+ * @hide
+ */
+ public static final int DUN = 23;
+
+ /**
+ * Group Operation Profile (Client Role)
+ * @hide
+ */
+ public int GROUP_CLIENT = 24;
+
+ /**
+ * Broadcast
+ * @hide
+ */
+ public int BROADCAST = 25;
+
+ /**
+ * VCP
+ * @hide
+ */
+ public static final int VCP = 26;
+
+ /**
+ * BC_PROFILE
+ * @hide
+ */
+ public static final int BC_PROFILE = 27;
+
+ /**
+ * PC_PROFILE
+ * @hide
+ */
+ public static final int PC_PROFILE = 28;
+
+ /**
+ * CC_SERVER
+ * @hide
+ */
+ public static final int CC_SERVER = 29;
+
+ /**
+ * MCP_SERVER
+ * @hide
+ */
+ public static final int MCP_SERVER = 30;
+
+ /**
* Max profile ID. This value should be updated whenever a new profile is added to match
* the largest value assigned to a profile.
*
* @hide
*/
- int MAX_PROFILE_ID = 22;
+ int MAX_PROFILE_ID = 30;
/**
* Default priority for devices that we try to auto-connect to and
@@ -416,6 +464,10 @@ public interface BluetoothProfile {
return "OPP";
case HEARING_AID:
return "HEARING_AID";
+ case BROADCAST:
+ return "BROADCAST";
+ case VCP:
+ return "VCP";
default:
return "UNKNOWN_PROFILE";
}
diff --git a/core/java/android/bluetooth/BluetoothQualityReport.java b/core/java/android/bluetooth/BluetoothQualityReport.java
new file mode 100644
index 000000000000..e9ed008b6954
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothQualityReport.java
@@ -0,0 +1,1447 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package android.bluetooth;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/**
+ * This class provides the public APIs to access the data of BQR event reported
+ * from firmware side. Currently it supports five event types: Quality monitor event,
+ * Approaching LSTO event, A2DP choppy event, SCO choppy event and Connect fail event.
+ * To know which kind of event is wrapped in this {@link BluetoothQualityReport} object,
+ * you need to call {@link #getQualityReportId}.
+ * <ul>
+ * <li> For Quality monitor event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object.
+ * <li> For Approaching LSTO event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsLsto} to get a
+ * {@link BluetoothQualityReport.BqrVsLsto} object.
+ * <li> For A2DP choppy event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsA2dpChoppy} to
+ * get a {@link BluetoothQualityReport.BqrVsA2dpChoppy} object.
+ * <li> For SCO choppy event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsScoChoppy} to
+ * get a {@link BluetoothQualityReport.BqrVsScoChoppy} object.
+ * <li> For Connect fail event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsConnectFail} to
+ * get a {@link BluetoothQualityReport.BqrVsConnectFail} object.
+ * </ul>
+ *
+ * @hide
+ */
+public final class BluetoothQualityReport implements Parcelable {
+ private static final String TAG = "BluetoothQualityReport";
+
+ public static final int QUALITY_REPORT_ID_MONITOR = 0x01;
+ public static final int QUALITY_REPORT_ID_APPROACH_LSTO = 0x02;
+ public static final int QUALITY_REPORT_ID_A2DP_CHOPPY = 0x03;
+ public static final int QUALITY_REPORT_ID_SCO_CHOPPY = 0x04;
+ /* Vendor Specific Report IDs from 0x20 */
+ public static final int QUALITY_REPORT_ID_CONN_FAIL = 0x20;
+
+ private String mAddr;
+ private int mLmpVer;
+ private int mLmpSubVer;
+ private int mManufacturerId;
+ private String mName;
+ private int mBluetoothClass;
+
+ private BqrCommon mBqrCommon;
+
+ private BqrVsCommon mBqrVsCommon;
+ private BqrVsLsto mBqrVsLsto;
+ private BqrVsA2dpChoppy mBqrVsA2dpChoppy;
+ private BqrVsScoChoppy mBqrVsScoChoppy;
+ private BqrVsConnectFail mBqrVsConnectFail;
+
+ enum PacketType {
+ INVALID, TYPE_ID, TYPE_NULL, TYPE_POLL, TYPE_FHS, TYPE_HV1, TYPE_HV2, TYPE_HV3,
+ TYPE_DV, TYPE_EV3, TYPE_EV4, TYPE_EV5, TYPE_2EV3, TYPE_2EV5, TYPE_3EV3, TYPE_3EV5,
+ TYPE_DM1, TYPE_DH1, TYPE_DM3, TYPE_DH3, TYPE_DM5, TYPE_DH5, TYPE_AUX1, TYPE_2DH1,
+ TYPE_2DH3, TYPE_2DH5, TYPE_3DH1, TYPE_3DH3, TYPE_3DH5;
+
+ private static PacketType[] sAllValues = values();
+
+ static PacketType fromOrdinal(int n) {
+ if (n < sAllValues.length) {
+ return sAllValues[n];
+ }
+ return INVALID;
+ }
+ }
+
+ enum ConnState {
+ CONN_IDLE(0x00), CONN_ACTIVE(0x81), CONN_HOLD(0x02), CONN_SNIFF_IDLE(0x03),
+ CONN_SNIFF_ACTIVE(0x84), CONN_SNIFF_MASTER_TRANSITION(0x85), CONN_PARK(0x06),
+ CONN_PARK_PEND(0x47), CONN_UNPARK_PEND(0x08), CONN_UNPARK_ACTIVE(0x89),
+ CONN_DISCONNECT_PENDING(0x4A), CONN_PAGING(0x0B), CONN_PAGE_SCAN(0x0C),
+ CONN_LOCAL_LOOPBACK(0x0D), CONN_LE_ACTIVE(0x0E), CONN_ANT_ACTIVE(0x0F),
+ CONN_TRIGGER_SCAN(0x10), CONN_RECONNECTING(0x11), CONN_SEMI_CONN(0x12);
+
+ private int mValue;
+ private static ConnState[] sAllStates = values();
+
+ private ConnState(int val) {
+ mValue = val;
+ }
+
+ public static String getName(int val) {
+ for (ConnState state: sAllStates) {
+ if (state.mValue == val) {
+ return state.toString();
+ }
+ }
+ return "INVALID";
+ }
+ }
+
+ enum LinkQuality {
+ ULTRA_HIGH, HIGH, STANDARD, MEDIUM, LOW, INVALID;
+
+ private static LinkQuality[] sAllValues = values();
+
+ static LinkQuality fromOrdinal(int n) {
+ if (n < sAllValues.length - 1) {
+ return sAllValues[n];
+ }
+ return INVALID;
+ }
+ }
+
+ enum AirMode {
+ uLaw, aLaw, CVSD, transparent_msbc, INVALID;
+
+ private static AirMode[] sAllValues = values();
+
+ static AirMode fromOrdinal(int n) {
+ if (n < sAllValues.length - 1) {
+ return sAllValues[n];
+ }
+ return INVALID;
+ }
+ }
+
+ public BluetoothQualityReport(String remoteAddr, int lmpVer, int lmpSubVer,
+ int manufacturerId, String remoteName, int remoteCoD, byte[] rawData) {
+ if (!BluetoothAdapter.checkBluetoothAddress(remoteAddr)) {
+ Log.d(TAG, "remote addr is invalid");
+ mAddr = "00:00:00:00:00:00";
+ } else {
+ mAddr = remoteAddr;
+ }
+
+ mLmpVer = lmpVer;
+ mLmpSubVer = lmpSubVer;
+ mManufacturerId = manufacturerId;
+ if (remoteName == null) {
+ Log.d(TAG, "remote name is null");
+ mName = "";
+ } else {
+ mName = remoteName;
+ }
+ mBluetoothClass = remoteCoD;
+
+ mBqrCommon = new BqrCommon(rawData, 0);
+
+ mBqrVsCommon = new BqrVsCommon(rawData, BqrCommon.BQR_COMMON_LEN);
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_MONITOR)
+ return;
+
+ int vsPartOffset = BqrCommon.BQR_COMMON_LEN + mBqrVsCommon.getLength();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ mBqrVsLsto = new BqrVsLsto(rawData, vsPartOffset);
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ mBqrVsA2dpChoppy = new BqrVsA2dpChoppy(rawData, vsPartOffset);
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ mBqrVsScoChoppy = new BqrVsScoChoppy(rawData, vsPartOffset);
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ mBqrVsConnectFail = new BqrVsConnectFail(rawData, vsPartOffset);
+ } else {
+ throw new IllegalArgumentException(TAG + ": unkown quality report id:" + id);
+ }
+ }
+
+ private BluetoothQualityReport(Parcel in) {
+ mBqrCommon = new BqrCommon(in);
+ mAddr = in.readString();
+ mLmpVer = in.readInt();
+ mLmpSubVer = in.readInt();
+ mManufacturerId = in.readInt();
+ mName = in.readString();
+ mBluetoothClass = in.readInt();
+
+ mBqrVsCommon = new BqrVsCommon(in);
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ mBqrVsLsto = new BqrVsLsto(in);
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ mBqrVsA2dpChoppy = new BqrVsA2dpChoppy(in);
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ mBqrVsScoChoppy = new BqrVsScoChoppy(in);
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ mBqrVsConnectFail = new BqrVsConnectFail(in);
+ }
+ }
+
+ /**
+ * Get the quality report id.
+ * @return the id, is one of {@link #QUALITY_REPORT_ID_MONITOR},
+ * {@link #QUALITY_REPORT_ID_APPROACH_LSTO}, {@link #QUALITY_REPORT_ID_A2DP_CHOPPY},
+ * {@link #QUALITY_REPORT_ID_SCO_CHOPPY}, {@link #QUALITY_REPORT_ID_CONN_FAIL}.
+ */
+ public int getQualityReportId() {
+ return mBqrCommon.getQualityReportId();
+ }
+
+ /**
+ * Get the string of the quality report id.
+ * @return the string of the id.
+ */
+ public String getQualityReportIdStr() {
+ int id = mBqrCommon.getQualityReportId();
+ switch (id) {
+ case QUALITY_REPORT_ID_MONITOR:
+ return "Quality monitor";
+ case QUALITY_REPORT_ID_APPROACH_LSTO:
+ return "Approaching LSTO";
+ case QUALITY_REPORT_ID_A2DP_CHOPPY:
+ return "A2DP choppy";
+ case QUALITY_REPORT_ID_SCO_CHOPPY:
+ return "SCO choppy";
+ case QUALITY_REPORT_ID_CONN_FAIL:
+ return "Connect fail";
+ default:
+ return "INVALID";
+ }
+ }
+
+ /**
+ * Get bluetooth address of remote device in this report.
+ * @return bluetooth address of remote device.
+ */
+ public String getAddress() {
+ return mAddr;
+ }
+
+ /**
+ * Get LMP version of remote device in this report.
+ * @return LMP version of remote device.
+ */
+ public int getLmpVersion() {
+ return mLmpVer;
+ }
+
+ /**
+ * Get LMP subVersion of remote device in this report.
+ * @return LMP subVersion of remote device.
+ */
+ public int getLmpSubVersion() {
+ return mLmpSubVer;
+ }
+
+ /**
+ * Get manufacturer id of remote device in this report.
+ * @return manufacturer id of remote device.
+ */
+ public int getManufacturerId() {
+ return mManufacturerId;
+ }
+
+ /**
+ * Get the name of remote device in this report.
+ * @return the name of remote device.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Get the class of remote device in this report.
+ * @return the class of remote device.
+ */
+ public int getBluetoothClass() {
+ return mBluetoothClass;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrCommon} object.
+ * @return the {@link BluetoothQualityReport.BqrCommon} object.
+ */
+ public BqrCommon getBqrCommon() {
+ return mBqrCommon;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsCommon} object.
+ * @return the {@link BluetoothQualityReport.BqrVsCommon} object.
+ */
+ public BqrVsCommon getBqrVsCommon() {
+ return mBqrVsCommon;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsLsto} object.
+ * @return the {@link BluetoothQualityReport.BqrVsLsto} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_APPROACH_LSTO}.
+ */
+ public BqrVsLsto getBqrVsLsto() {
+ return mBqrVsLsto;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsA2dpChoppy} object.
+ * @return the {@link BluetoothQualityReport.BqrVsA2dpChoppy} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_A2DP_CHOPPY}.
+ */
+ public BqrVsA2dpChoppy getBqrVsA2dpChoppy() {
+ return mBqrVsA2dpChoppy;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsScoChoppy} object.
+ * @return the {@link BluetoothQualityReport.BqrVsScoChoppy} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_SCO_CHOPPY}.
+ */
+ public BqrVsScoChoppy getBqrVsScoChoppy() {
+ return mBqrVsScoChoppy;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsConnectFail} object.
+ * @return the {@link BluetoothQualityReport.BqrVsConnectFail} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_CONN_FAIL}.
+ */
+ public BqrVsConnectFail getBqrVsConnectFail() {
+ return mBqrVsConnectFail;
+ }
+
+ public static final @android.annotation.NonNull Parcelable.Creator<BluetoothQualityReport> CREATOR =
+ new Parcelable.Creator<BluetoothQualityReport>() {
+ public BluetoothQualityReport createFromParcel(Parcel in) {
+ return new BluetoothQualityReport(in);
+ }
+
+ public BluetoothQualityReport[] newArray(int size) {
+ return new BluetoothQualityReport[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ mBqrCommon.writeToParcel(out, flags);
+ out.writeString(mAddr);
+ out.writeInt(mLmpVer);
+ out.writeInt(mLmpSubVer);
+ out.writeInt(mManufacturerId);
+ out.writeString(mName);
+ out.writeInt(mBluetoothClass);
+ mBqrVsCommon.writeToParcel(out, flags);
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ mBqrVsLsto.writeToParcel(out, flags);
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ mBqrVsA2dpChoppy.writeToParcel(out, flags);
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ mBqrVsScoChoppy.writeToParcel(out, flags);
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ mBqrVsConnectFail.writeToParcel(out, flags);
+ }
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = "BQR: {\n"
+ + " mAddr: " + mAddr
+ + ", mLmpVer: " + String.format("0x%02X", mLmpVer)
+ + ", mLmpSubVer: " + String.format("0x%04X", mLmpSubVer)
+ + ", mManufacturerId: " + String.format("0x%04X", mManufacturerId)
+ + ", mName: " + mName
+ + ", mBluetoothClass: " + String.format("0x%X", mBluetoothClass)
+ + ",\n"
+ + mBqrCommon + "\n"
+ + mBqrVsCommon + "\n";
+
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ str += mBqrVsLsto + "\n}";
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ str += mBqrVsA2dpChoppy + "\n}";
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ str += mBqrVsScoChoppy + "\n}";
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ str += mBqrVsConnectFail + "\n}";
+ } else if (id == QUALITY_REPORT_ID_MONITOR) {
+ str += "}";
+ }
+
+ return str;
+ }
+
+ /**
+ * This class provides the public APIs to access the common part of BQR event.
+ */
+ public class BqrCommon implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrCommon";
+ static final int BQR_COMMON_LEN = 48;
+
+ private int mQualityReportId;
+ private int mPacketType;
+ private int mConnectionHandle;
+ private int mConnectionRole;
+ private int mTxPowerLevel;
+ private int mRssi;
+ private int mSnr;
+ private int mUnusedAfhChannelCount;
+ private int mAfhSelectUnidealChannelCount;
+ private int mLsto;
+ private long mPiconetClock;
+ private long mRetransmissionCount;
+ private long mNoRxCount;
+ private long mNakCount;
+ private long mLastTxAckTimestamp;
+ private long mFlowOffCount;
+ private long mLastFlowOnTimestamp;
+ private long mOverflowCount;
+ private long mUnderflowCount;
+
+ private BqrCommon(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length < offset + BQR_COMMON_LEN) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mQualityReportId = bqrBuf.get() & 0xFF;
+ mPacketType = bqrBuf.get() & 0xFF;
+ mConnectionHandle = bqrBuf.getShort() & 0xFFFF;
+ mConnectionRole = bqrBuf.get() & 0xFF;
+ mTxPowerLevel = bqrBuf.get() & 0xFF;
+ mRssi = bqrBuf.get();
+ mSnr = bqrBuf.get();
+ mUnusedAfhChannelCount = bqrBuf.get() & 0xFF;
+ mAfhSelectUnidealChannelCount = bqrBuf.get() & 0xFF;
+ mLsto = bqrBuf.getShort() & 0xFFFF;
+ mPiconetClock = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mRetransmissionCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mNoRxCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mNakCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mLastTxAckTimestamp = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mFlowOffCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mLastFlowOnTimestamp = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mOverflowCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mUnderflowCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ }
+
+ private BqrCommon(Parcel in) {
+ mQualityReportId = in.readInt();
+ mPacketType = in.readInt();
+ mConnectionHandle = in.readInt();
+ mConnectionRole = in.readInt();
+ mTxPowerLevel = in.readInt();
+ mRssi = in.readInt();
+ mSnr = in.readInt();
+ mUnusedAfhChannelCount = in.readInt();
+ mAfhSelectUnidealChannelCount = in.readInt();
+ mLsto = in.readInt();
+ mPiconetClock = in.readLong();
+ mRetransmissionCount = in.readLong();
+ mNoRxCount = in.readLong();
+ mNakCount = in.readLong();
+ mLastTxAckTimestamp = in.readLong();
+ mFlowOffCount = in.readLong();
+ mLastFlowOnTimestamp = in.readLong();
+ mOverflowCount = in.readLong();
+ mUnderflowCount = in.readLong();
+ }
+
+ int getQualityReportId() {
+ return mQualityReportId;
+ }
+
+ /**
+ * Get the packet type of the connection.
+ * @return the packet type.
+ */
+ public int getPacketType() {
+ return mPacketType;
+ }
+
+ /**
+ * Get the string of packet type
+ * @return the string of packet type.
+ */
+ public String getPacketTypeStr() {
+ PacketType type = PacketType.fromOrdinal(mPacketType);
+ return type.toString();
+ }
+
+ /**
+ * Get the connecton handle of the connection
+ * @return the connecton handle.
+ */
+ public int getConnectionHandle() {
+ return mConnectionHandle;
+ }
+
+ /**
+ * Get the connecton Role of the connection, "Master" or "Slave".
+ * @return the connecton Role.
+ */
+ public String getConnectionRole() {
+ if (mConnectionRole == 0) {
+ return "Master";
+ } else if (mConnectionRole == 1) {
+ return "Slave";
+ } else {
+ return "INVALID:" + mConnectionRole;
+ }
+ }
+
+ /**
+ * Get the current transmit power level for the connection.
+ * @return the TX power level.
+ */
+ public int getTxPowerLevel() {
+ return mTxPowerLevel;
+ }
+
+ /**
+ * Get the Received Signal Strength Indication (RSSI) value for the connection.
+ * @return the RSSI.
+ */
+ public int getRssi() {
+ return mRssi;
+ }
+
+ /**
+ * get the Signal-to-Noise Ratio (SNR) value for the connection.
+ * @return the SNR.
+ */
+ public int getSnr() {
+ return mSnr;
+ }
+
+ /**
+ * Get the number of unused channels in AFH_channel_map.
+ * @return the number of unused channels.
+ */
+ public int getUnusedAfhChannelCount() {
+ return mUnusedAfhChannelCount;
+ }
+
+ /**
+ * Get the number of the channels which are interfered and quality is
+ * bad but are still selected for AFH.
+ * @return the number of the selected unideal channels.
+ */
+ public int getAfhSelectUnidealChannelCount() {
+ return mAfhSelectUnidealChannelCount;
+ }
+
+ /**
+ * Get the current link supervision timeout setting.
+ * time_ms: N * 0.625 ms (1 slot).
+ * @return link supervision timeout value.
+ */
+ public int getLsto() {
+ return mLsto;
+ }
+
+ /**
+ * Get the piconet clock for the specified Connection_Handle.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the piconet clock.
+ */
+ public long getPiconetClock() {
+ return mPiconetClock;
+ }
+
+ /**
+ * Get the count of retransmission.
+ * @return the count of retransmission.
+ */
+ public long getRetransmissionCount() {
+ return mRetransmissionCount;
+ }
+
+ /**
+ * Get the count of no RX.
+ * @return the count of no RX.
+ */
+ public long getNoRxCount() {
+ return mNoRxCount;
+ }
+
+ /**
+ * Get the count of NAK(Negative Acknowledge).
+ * @return the count of NAK.
+ */
+ public long getNakCount() {
+ return mNakCount;
+ }
+
+ /**
+ * Get the timestamp of last TX ACK.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of last TX ACK.
+ */
+ public long getLastTxAckTimestamp() {
+ return mLastTxAckTimestamp;
+ }
+
+ /**
+ * Get the count of flow-off.
+ * @return the count of flow-off.
+ */
+ public long getFlowOffCount() {
+ return mFlowOffCount;
+ }
+
+ /**
+ * Get the timestamp of last flow-on.
+ * @return the timestamp of last flow-on.
+ */
+ public long getLastFlowOnTimestamp() {
+ return mLastFlowOnTimestamp;
+ }
+
+ /**
+ * Get the buffer overflow count (how many bytes of TX data are dropped) since the
+ * last event.
+ * @return the buffer overflow count.
+ */
+ public long getOverflowCount() {
+ return mOverflowCount;
+ }
+
+ /**
+ * Get the buffer underflow count (in byte).
+ * @return the buffer underflow count.
+ */
+ public long getUnderflowCount() {
+ return mUnderflowCount;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mQualityReportId);
+ dest.writeInt(mPacketType);
+ dest.writeInt(mConnectionHandle);
+ dest.writeInt(mConnectionRole);
+ dest.writeInt(mTxPowerLevel);
+ dest.writeInt(mRssi);
+ dest.writeInt(mSnr);
+ dest.writeInt(mUnusedAfhChannelCount);
+ dest.writeInt(mAfhSelectUnidealChannelCount);
+ dest.writeInt(mLsto);
+ dest.writeLong(mPiconetClock);
+ dest.writeLong(mRetransmissionCount);
+ dest.writeLong(mNoRxCount);
+ dest.writeLong(mNakCount);
+ dest.writeLong(mLastTxAckTimestamp);
+ dest.writeLong(mFlowOffCount);
+ dest.writeLong(mLastFlowOnTimestamp);
+ dest.writeLong(mOverflowCount);
+ dest.writeLong(mUnderflowCount);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrCommon: {\n"
+ + " mQualityReportId: " + BluetoothQualityReport.this.getQualityReportIdStr()
+ + "(" + String.format("0x%02X", mQualityReportId) + ")"
+ + ", mPacketType: " + getPacketTypeStr()
+ + "(" + String.format("0x%02X", mPacketType) + ")"
+ + ", mConnectionHandle: " + String.format("0x%04X", mConnectionHandle)
+ + ", mConnectionRole: " + getConnectionRole() + "(" + mConnectionRole + ")"
+ + ", mTxPowerLevel: " + mTxPowerLevel
+ + ", mRssi: " + mRssi
+ + ", mSnr: " + mSnr
+ + ", mUnusedAfhChannelCount: " + mUnusedAfhChannelCount
+ + ",\n"
+ + " mAfhSelectUnidealChannelCount: " + mAfhSelectUnidealChannelCount
+ + ", mLsto: " + mLsto
+ + ", mPiconetClock: " + String.format("0x%08X", mPiconetClock)
+ + ", mRetransmissionCount: " + mRetransmissionCount
+ + ", mNoRxCount: " + mNoRxCount
+ + ", mNakCount: " + mNakCount
+ + ", mLastTxAckTimestamp: " + String.format("0x%08X", mLastTxAckTimestamp)
+ + ", mFlowOffCount: " + mFlowOffCount
+ + ",\n"
+ + " mLastFlowOnTimestamp: " + String.format("0x%08X", mLastFlowOnTimestamp)
+ + ", mOverflowCount: " + mOverflowCount
+ + ", mUnderflowCount: " + mUnderflowCount
+ + "\n }";
+
+ return str;
+ }
+
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific common part of
+ * BQR event.
+ */
+ public class BqrVsCommon implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsCommon";
+ private static final int BQR_VS_COMMON_LEN = 6 + 1;
+
+ private String mAddr;
+ private int mCalFailedItemCount;
+
+ private BqrVsCommon(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length < offset + BQR_VS_COMMON_LEN) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mAddr = String.format("%02X:%02X:%02X:%02X:%02X:%02X", bqrBuf.get(offset+5),
+ bqrBuf.get(offset+4), bqrBuf.get(offset+3), bqrBuf.get(offset+2),
+ bqrBuf.get(offset+1), bqrBuf.get(offset+0));
+ bqrBuf.position(offset+6);
+ mCalFailedItemCount = bqrBuf.get() & 0xFF;
+ }
+
+ private BqrVsCommon(Parcel in) {
+ mAddr = in.readString();
+ mCalFailedItemCount = in.readInt();
+ }
+
+ /**
+ * Get the count of calibration failed items.
+ * @return the count of calibration failure.
+ */
+ public int getCalFailedItemCount() {
+ return mCalFailedItemCount;
+ }
+
+ int getLength() {
+ return BQR_VS_COMMON_LEN;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mAddr);
+ dest.writeInt(mCalFailedItemCount);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsCommon: {\n"
+ + " mAddr: " + mAddr
+ + ", mCalFailedItemCount: " + mCalFailedItemCount
+ + "\n }";
+
+ return str;
+ }
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * Approaching LSTO event.
+ */
+ public class BqrVsLsto implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsLsto";
+
+ private int mConnState;
+ private long mBasebandStats;
+ private long mSlotsUsed;
+ private int mCxmDenials;
+ private int mTxSkipped;
+ private int mRfLoss;
+ private long mNativeClock;
+ private long mLastTxAckTimestamp;
+
+ private BqrVsLsto(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mConnState = bqrBuf.get() & 0xFF;
+ mBasebandStats = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mSlotsUsed = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mTxSkipped = bqrBuf.getShort() & 0xFFFF;
+ mRfLoss = bqrBuf.getShort() & 0xFFFF;
+ mNativeClock = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mLastTxAckTimestamp = bqrBuf.getInt() & 0xFFFFFFFFL;
+ }
+
+ private BqrVsLsto(Parcel in) {
+ mConnState = in.readInt();
+ mBasebandStats = in.readLong();
+ mSlotsUsed = in.readLong();
+ mCxmDenials = in.readInt();
+ mTxSkipped = in.readInt();
+ mRfLoss = in.readInt();
+ mNativeClock = in.readLong();
+ mLastTxAckTimestamp = in.readLong();
+ }
+
+ /**
+ * Get the conn state of sco.
+ * @return the conn state.
+ */
+ public int getConnState() {
+ return mConnState;
+ }
+
+ /**
+ * Get the string of conn state of sco.
+ * @return the string of conn state.
+ */
+ public String getConnStateStr() {
+ return ConnState.getName(mConnState);
+ }
+
+ /**
+ * Get the baseband statistics.
+ * @return the baseband statistics.
+ */
+ public long getBasebandStats() {
+ return mBasebandStats;
+ }
+
+ /**
+ * Get the count of slots allocated for current connection.
+ * @return the count of slots allocated for current connection.
+ */
+ public long getSlotsUsed() {
+ return mSlotsUsed;
+ }
+
+ /**
+ * Get the count of Coex denials.
+ * @return the count of CXM denials.
+ */
+ public int getCxmDenials() {
+ return mCxmDenials;
+ }
+
+ /**
+ * Get the count of TX skipped when no poll from remote device.
+ * @return the count of TX skipped.
+ */
+ public int getTxSkipped() {
+ return mTxSkipped;
+ }
+
+ /**
+ * Get the count of RF loss.
+ * @return the count of RF loss.
+ */
+ public int getRfLoss() {
+ return mRfLoss;
+ }
+
+ /**
+ * Get the timestamp when issue happened.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp when issue happened.
+ */
+ public long getNativeClock() {
+ return mNativeClock;
+ }
+
+ /**
+ * Get the timestamp of last TX ACK.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of last TX ACK.
+ */
+ public long getLastTxAckTimestamp() {
+ return mLastTxAckTimestamp;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mConnState);
+ dest.writeLong(mBasebandStats);
+ dest.writeLong(mSlotsUsed);
+ dest.writeInt(mCxmDenials);
+ dest.writeInt(mTxSkipped);
+ dest.writeInt(mRfLoss);
+ dest.writeLong(mNativeClock);
+ dest.writeLong(mLastTxAckTimestamp);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsLsto: {\n"
+ + " mConnState: " + getConnStateStr()
+ + "(" + String.format("0x%02X", mConnState) + ")"
+ + ", mBasebandStats: " + String.format("0x%08X", mBasebandStats)
+ + ", mSlotsUsed: " + mSlotsUsed
+ + ", mCxmDenials: " + mCxmDenials
+ + ", mTxSkipped: " + mTxSkipped
+ + ", mRfLoss: " + mRfLoss
+ + ", mNativeClock: " + String.format("0x%08X", mNativeClock)
+ + ", mLastTxAckTimestamp: " + String.format("0x%08X", mLastTxAckTimestamp)
+ + "\n }";
+
+ return str;
+ }
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * A2dp choppy event.
+ */
+ public class BqrVsA2dpChoppy implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsA2dpChoppy";
+
+ private long mArrivalTime;
+ private long mScheduleTime;
+ private int mGlitchCount;
+ private int mTxCxmDenials;
+ private int mRxCxmDenials;
+ private int mAclTxQueueLength;
+ private int mLinkQuality;
+
+ private BqrVsA2dpChoppy(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mArrivalTime = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mScheduleTime = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mGlitchCount = bqrBuf.getShort() & 0xFFFF;
+ mTxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mRxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mAclTxQueueLength = bqrBuf.get() & 0xFF;
+ mLinkQuality = bqrBuf.get() & 0xFF;
+ }
+
+ private BqrVsA2dpChoppy(Parcel in) {
+ mArrivalTime = in.readLong();
+ mScheduleTime = in.readLong();
+ mGlitchCount = in.readInt();
+ mTxCxmDenials = in.readInt();
+ mRxCxmDenials = in.readInt();
+ mAclTxQueueLength = in.readInt();
+ mLinkQuality = in.readInt();
+ }
+
+ /**
+ * Get the timestamp of a2dp packet arrived.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of a2dp packet arrived.
+ */
+ public long getArrivalTime() {
+ return mArrivalTime;
+ }
+
+ /**
+ * Get the timestamp of a2dp packet scheduled.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of a2dp packet scheduled.
+ */
+ public long getScheduleTime() {
+ return mScheduleTime;
+ }
+
+ /**
+ * Get the a2dp glitch count since the last event.
+ * @return the a2dp glitch count.
+ */
+ public int getGlitchCount() {
+ return mGlitchCount;
+ }
+
+ /**
+ * Get the count of Coex TX denials.
+ * @return the count of Coex TX denials.
+ */
+ public int getTxCxmDenials() {
+ return mTxCxmDenials;
+ }
+
+ /**
+ * Get the count of Coex RX denials.
+ * @return the count of Coex RX denials.
+ */
+ public int getRxCxmDenials() {
+ return mRxCxmDenials;
+ }
+
+ /**
+ * Get the ACL queue length which are pending TX in FW.
+ * @return the ACL queue length.
+ */
+ public int getAclTxQueueLength() {
+ return mAclTxQueueLength;
+ }
+
+ /**
+ * Get the link quality for the current connection.
+ * @return the link quality.
+ */
+ public int getLinkQuality() {
+ return mLinkQuality;
+ }
+
+ /**
+ * Get the string of link quality for the current connection.
+ * @return the string of link quality.
+ */
+ public String getLinkQualityStr() {
+ LinkQuality q = LinkQuality.fromOrdinal(mLinkQuality);
+ return q.toString();
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mArrivalTime);
+ dest.writeLong(mScheduleTime);
+ dest.writeInt(mGlitchCount);
+ dest.writeInt(mTxCxmDenials);
+ dest.writeInt(mRxCxmDenials);
+ dest.writeInt(mAclTxQueueLength);
+ dest.writeInt(mLinkQuality);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsA2dpChoppy: {\n"
+ + " mArrivalTime: " + String.format("0x%08X", mArrivalTime)
+ + ", mScheduleTime: " + String.format("0x%08X", mScheduleTime)
+ + ", mGlitchCount: " + mGlitchCount
+ + ", mTxCxmDenials: " + mTxCxmDenials
+ + ", mRxCxmDenials: " + mRxCxmDenials
+ + ", mAclTxQueueLength: " + mAclTxQueueLength
+ + ", mLinkQuality: " + getLinkQualityStr()
+ + "(" + String.format("0x%02X", mLinkQuality) + ")"
+ + "\n }";
+
+ return str;
+ }
+
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * SCO choppy event.
+ */
+ public class BqrVsScoChoppy implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsScoChoppy";
+
+ private int mGlitchCount;
+ private int mIntervalEsco;
+ private int mWindowEsco;
+ private int mAirFormat;
+ private int mInstanceCount;
+ private int mTxCxmDenials;
+ private int mRxCxmDenials;
+ private int mTxAbortCount;
+ private int mLateDispatch;
+ private int mMicIntrMiss;
+ private int mLpaIntrMiss;
+ private int mSprIntrMiss;
+ private int mPlcFillCount;
+ private int mPlcDiscardCount;
+ private int mMissedInstanceCount;
+ private int mTxRetransmitSlotCount;
+ private int mRxRetransmitSlotCount;
+ private int mGoodRxFrameCount;
+
+ private BqrVsScoChoppy(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mGlitchCount = bqrBuf.getShort() & 0xFFFF;
+ mIntervalEsco = bqrBuf.get() & 0xFF;
+ mWindowEsco = bqrBuf.get() & 0xFF;
+ mAirFormat = bqrBuf.get() & 0xFF;
+ mInstanceCount = bqrBuf.getShort() & 0xFFFF;
+ mTxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mRxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mTxAbortCount = bqrBuf.getShort() & 0xFFFF;
+ mLateDispatch = bqrBuf.getShort() & 0xFFFF;
+ mMicIntrMiss = bqrBuf.getShort() & 0xFFFF;
+ mLpaIntrMiss = bqrBuf.getShort() & 0xFFFF;
+ mSprIntrMiss = bqrBuf.getShort() & 0xFFFF;
+ mPlcFillCount = bqrBuf.getShort() & 0xFFFF;
+ mPlcDiscardCount = bqrBuf.getShort() & 0xFFFF;
+ try {
+ mMissedInstanceCount = bqrBuf.getShort() & 0xFFFF;
+ mTxRetransmitSlotCount = bqrBuf.getShort() & 0xFFFF;
+ mRxRetransmitSlotCount = bqrBuf.getShort() & 0xFFFF;
+ mGoodRxFrameCount = bqrBuf.getShort() & 0xFFFF;
+ } catch (BufferUnderflowException e) {
+ Log.v(TAG, "some fields are not contained");
+ }
+ }
+
+ private BqrVsScoChoppy(Parcel in) {
+ mGlitchCount = in.readInt();
+ mIntervalEsco = in.readInt();
+ mWindowEsco = in.readInt();
+ mAirFormat = in.readInt();
+ mInstanceCount = in.readInt();
+ mTxCxmDenials = in.readInt();
+ mRxCxmDenials = in.readInt();
+ mTxAbortCount = in.readInt();
+ mLateDispatch = in.readInt();
+ mMicIntrMiss = in.readInt();
+ mLpaIntrMiss = in.readInt();
+ mSprIntrMiss = in.readInt();
+ mPlcFillCount = in.readInt();
+ mPlcDiscardCount = in.readInt();
+ mMissedInstanceCount = in.readInt();
+ mTxRetransmitSlotCount = in.readInt();
+ mRxRetransmitSlotCount = in.readInt();
+ mGoodRxFrameCount = in.readInt();
+ }
+
+ /**
+ * Get the sco glitch count since the last event.
+ * @return the sco glitch count.
+ */
+ public int getGlitchCount() {
+ return mGlitchCount;
+ }
+
+ /**
+ * Get ESCO interval in slots. It is the value of Transmission_Interval parameter in
+ * Synchronous Connection Complete event.
+ * @return ESCO interval in slots.
+ */
+ public int getIntervalEsco() {
+ return mIntervalEsco;
+ }
+
+ /**
+ * Get ESCO window in slots. It is the value of Retransmission Window parameter in
+ * Synchronous Connection Complete event.
+ * @return ESCO window in slots.
+ */
+ public int getWindowEsco() {
+ return mWindowEsco;
+ }
+
+ /**
+ * Get the air mode. It is the value of Air Mode parameter in
+ * Synchronous Connection Complete event.
+ * @return the air mode.
+ */
+ public int getAirFormat() {
+ return mAirFormat;
+ }
+
+ /**
+ * Get the string of air mode.
+ * @return the string of air mode.
+ */
+ public String getAirFormatStr() {
+ AirMode m = AirMode.fromOrdinal(mAirFormat);
+ return m.toString();
+ }
+
+ /**
+ * Get the xSCO instance count.
+ * @return the xSCO instance count.
+ */
+ public int getInstanceCount() {
+ return mInstanceCount;
+ }
+
+ /**
+ * Get the count of Coex TX denials.
+ * @return the count of Coex TX denials.
+ */
+ public int getTxCxmDenials() {
+ return mTxCxmDenials;
+ }
+
+ /**
+ * Get the count of Coex RX denials.
+ * @return the count of Coex RX denials.
+ */
+ public int getRxCxmDenials() {
+ return mRxCxmDenials;
+ }
+
+ /**
+ * Get the count of sco packets aborted.
+ * @return the count of sco packets aborted.
+ */
+ public int getTxAbortCount() {
+ return mTxAbortCount;
+ }
+
+ /**
+ * Get the count of sco packets dispatched late.
+ * @return the count of sco packets dispatched late.
+ */
+ public int getLateDispatch() {
+ return mLateDispatch;
+ }
+
+ /**
+ * Get the count of missed Mic interrrupts.
+ * @return the count of missed Mic interrrupts.
+ */
+ public int getMicIntrMiss() {
+ return mMicIntrMiss;
+ }
+
+ /**
+ * Get the count of missed LPA interrrupts.
+ * @return the count of missed LPA interrrupts.
+ */
+ public int getLpaIntrMiss() {
+ return mLpaIntrMiss;
+ }
+
+ /**
+ * Get the count of missed Speaker interrrupts.
+ * @return the count of missed Speaker interrrupts.
+ */
+ public int getSprIntrMiss() {
+ return mSprIntrMiss;
+ }
+
+ /**
+ * Get the count of packet loss concealment filled.
+ * @return the count of packet loss concealment filled.
+ */
+ public int getPlcFillCount() {
+ return mPlcFillCount;
+ }
+
+ /**
+ * Get the count of packet loss concealment discarded.
+ * @return the count of packet loss concealment discarded.
+ */
+ public int getPlcDiscardCount() {
+ return mPlcDiscardCount;
+ }
+
+ /**
+ * Get the count of sco instances missed.
+ * @return the count of sco instances missed.
+ */
+ public int getMissedInstanceCount() {
+ return mMissedInstanceCount;
+ }
+
+ /**
+ * Get the count of slots for Tx retransmission.
+ * @return the count of slots for Tx retransmission.
+ */
+ public int getTxRetransmitSlotCount() {
+ return mTxRetransmitSlotCount;
+ }
+
+ /**
+ * Get the count of slots for Rx retransmission.
+ * @return the count of slots for Rx retransmission.
+ */
+ public int getRxRetransmitSlotCount() {
+ return mRxRetransmitSlotCount;
+ }
+
+ /**
+ * Get the count of Rx good packets
+ * @return the count of Rx good packets.
+ */
+ public int getGoodRxFrameCount() {
+ return mGoodRxFrameCount;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mGlitchCount);
+ dest.writeInt(mIntervalEsco);
+ dest.writeInt(mWindowEsco);
+ dest.writeInt(mAirFormat);
+ dest.writeInt(mInstanceCount);
+ dest.writeInt(mTxCxmDenials);
+ dest.writeInt(mRxCxmDenials);
+ dest.writeInt(mTxAbortCount);
+ dest.writeInt(mLateDispatch);
+ dest.writeInt(mMicIntrMiss);
+ dest.writeInt(mLpaIntrMiss);
+ dest.writeInt(mSprIntrMiss);
+ dest.writeInt(mPlcFillCount);
+ dest.writeInt(mPlcDiscardCount);
+ dest.writeInt(mMissedInstanceCount);
+ dest.writeInt(mTxRetransmitSlotCount);
+ dest.writeInt(mRxRetransmitSlotCount);
+ dest.writeInt(mGoodRxFrameCount);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsScoChoppy: {\n"
+ + " mGlitchCount: " + mGlitchCount
+ + ", mIntervalEsco: " + mIntervalEsco
+ + ", mWindowEsco: " + mWindowEsco
+ + ", mAirFormat: " + getAirFormatStr()
+ + "(" + String.format("0x%02X", mAirFormat) + ")"
+ + ", mInstanceCount: " + mInstanceCount
+ + ", mTxCxmDenials: " + mTxCxmDenials
+ + ", mRxCxmDenials: " + mRxCxmDenials
+ + ", mTxAbortCount: " + mTxAbortCount
+ + ",\n"
+ + " mLateDispatch: " + mLateDispatch
+ + ", mMicIntrMiss: " + mMicIntrMiss
+ + ", mLpaIntrMiss: " + mLpaIntrMiss
+ + ", mSprIntrMiss: " + mSprIntrMiss
+ + ", mPlcFillCount: " + mPlcFillCount
+ + ", mPlcDiscardCount: " + mPlcDiscardCount
+ + ", mMissedInstanceCount: " + mMissedInstanceCount
+ + ", mTxRetransmitSlotCount: " + mTxRetransmitSlotCount
+ + ",\n"
+ + " mRxRetransmitSlotCount: " + mRxRetransmitSlotCount
+ + ", mGoodRxFrameCount: " + mGoodRxFrameCount
+ + "\n }";
+
+ return str;
+ }
+
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * Connect fail event.
+ */
+ public class BqrVsConnectFail implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsConnectFail";
+
+ private int mFailReason;
+
+ private BqrVsConnectFail(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mFailReason = bqrBuf.get() & 0xFF;
+ }
+
+ private BqrVsConnectFail(Parcel in) {
+ mFailReason = in.readInt();
+ }
+
+ /**
+ * Get the fail reason.
+ * @return the fail reason.
+ */
+ public int getFailReason() {
+ return mFailReason;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mFailReason);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsConnectFail: {\n"
+ + " mFailReason: " + String.format("0x%02X", mFailReason)
+ + "\n }";
+
+ return str;
+ }
+ }
+
+}
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 1655b62bbfec..0d2bd216f19f 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -27,7 +27,6 @@ import android.os.ParcelFileDescriptor;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;
-
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -272,6 +271,7 @@ public final class BluetoothSocket implements Closeable {
as.mSocketOS = as.mSocket.getOutputStream();
as.mAddress = remoteAddr;
as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddr);
+ as.mPort = mPort;
return as;
}
@@ -806,5 +806,65 @@ public final class BluetoothSocket implements Closeable {
return ret;
}
+ /**
+ * setSocketOpt for the Buetooth Socket.
+ *
+ * @param optionName socket option name
+ * @param optionVal socket option value
+ * @param optionLen socket option length
+ * @return -1 on immediate error,
+ * 0 otherwise
+ * @hide
+ */
+ @UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int setSocketOpt(int optionName, byte [] optionVal, int optionLen) throws IOException {
+ int ret = 0;
+ if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
+ IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+ if (bluetoothProxy == null) {
+ Log.e(TAG, "setSocketOpt fail, reason: bluetooth is off");
+ return -1;
+ }
+ try {
+ if(VDBG) Log.d(TAG, "setSocketOpt(), mType: " + mType + " mPort: " + mPort);
+ ret = bluetoothProxy.setSocketOpt(mType, mPort, optionName, optionVal, optionLen);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return -1;
+ }
+ return ret;
+ }
+
+ /**
+ * getSocketOpt for the Buetooth Socket.
+ *
+ * @param optionName socket option name
+ * @param optionVal socket option value
+ * @return -1 on immediate error,
+ * length of returned socket option otherwise
+ * @hide
+ */
+ @UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getSocketOpt(int optionName, byte [] optionVal) throws IOException {
+ int ret = 0;
+ if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
+ IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+ if (bluetoothProxy == null) {
+ Log.e(TAG, "getSocketOpt fail, reason: bluetooth is off");
+ return -1;
+ }
+ try {
+ if(VDBG) Log.d(TAG, "getSocketOpt(), mType: " + mType + " mPort: " + mPort);
+ ret = bluetoothProxy.getSocketOpt(mType, mPort, optionName, optionVal);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ return -1;
+ }
+ return ret;
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index bc3754a2fc56..02f9044445a2 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -177,6 +177,41 @@ public final class BluetoothUuid {
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_HEARINGAID_UUID =
+ ParcelUuid.fromString("00006AD2-0000-1000-8000-00805F9B34FB");
+
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_MEDIA_T_UUID =
+ ParcelUuid.fromString("00006AD0-0000-1000-8000-00805F9B34FB");
+
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_MEDIA_P_UUID =
+ ParcelUuid.fromString("00006AD1-0000-1000-8000-00805F9B34FB");
+
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_MEDIA_G_UUID =
+ ParcelUuid.fromString("00006AD3-0000-1000-8000-00805F9B34FB");
+
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_MEDIA_W_UUID =
+ ParcelUuid.fromString("2587db3c-ce70-4fc9-935f-777ab4188fd7");
+
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_VOICE_P_UUID =
+ ParcelUuid.fromString("00006AD4-0000-1000-8000-00805F9B34FB");
+
+ /** @hide */
+ @NonNull
+ public static ParcelUuid ADVANCE_VOICE_T_UUID =
+ ParcelUuid.fromString("00006AD5-0000-1000-8000-00805F9B34FB");
+
/**
* Length of bytes for 16 bit UUID
*
diff --git a/core/java/android/bluetooth/BluetoothVcp.java b/core/java/android/bluetooth/BluetoothVcp.java
new file mode 100644
index 000000000000..1f8498c62fb4
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothVcp.java
@@ -0,0 +1,420 @@
+/*
+ *Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *Not a contribution
+ */
+
+/*
+ * Copyright 2018 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.annotation.RequiresPermission;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
+import android.content.AttributionSource;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the public APIs to control the Bluetooth VCP profile.
+ *
+ * <p>BluetoothVcp is a proxy object for controlling the Bluetooth VolumeControl
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothVcp proxy object.
+ *
+ * {@hide}
+ */
+public final class BluetoothVcp implements BluetoothProfile {
+ private static final String TAG = "BluetoothVcp";
+ private static final boolean DBG = true;
+ private static final boolean VDBG = true;
+
+ /**
+ * Intent used to broadcast the change in connection state of the VCP
+ * profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.vcp.profile.action.CONNECTION_STATE_CHANGED";
+
+ /**
+ * Intent used to broadcast the volume change of the Volume Renderer device
+ *
+ * <p>This intent will have 1 extras:
+ * <ul>
+ * <li> {@link #EXTRA_VOLUME} - Current volume settings of Renderer device
+ * device. Range: 0 - 255.
+ *
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public static final String ACTION_VOLUME_CHANGED =
+ "android.bluetooth.vcp.profile.action.VOLUME_CHANGED";
+
+ /**
+ * A int extra field in {@link #ACTION_VOLUME_CHANGED}
+ * intents that contains the volume of the Volume Renderer device.
+ */
+ public static final String EXTRA_VOLUME =
+ "android.bluetooth.vcp.profile.extra.VOLUME";
+
+ /**
+ * Intent used to broadcast the mute change of the Volume Renderer device
+ *
+ * <p>This intent will have 1 extras:
+ * <ul>
+ * <li> {@link #EXTRA_MUTE} - Current mute status of Renderer device
+ * device. False: unmute, True: mute.
+ *
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public static final String ACTION_MUTE_CHANGED =
+ "android.bluetooth.vcp.profile.action.MUTE_CHANGED";
+
+ /**
+ * A boolean extra field in {@link #ACTION_MUTE_CHANGED}
+ * intents that contains the mute status of the Volume Renderer device.
+ */
+ public static final String EXTRA_MUTE =
+ "android.bluetooth.vcp.profile.extra.MUTE";
+
+ /**
+ * Intent used to broadcast the connection mode change of the VCP
+ *
+ * <p>This intent will have 1 extras:
+ * <ul>
+ * <li> {@link #EXTRA_MODE} - Current connection mode of VCP
+ * can be any of {@link #MODE_NONE}, {@link #MODE_UNICAST},
+ * {@link #MODE_BROADCAST}, {@link #MODE_UNICAST_BROADCAST},
+ *
+ * @hide
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public static final String ACTION_CONNECTION_MODE_CHANGED =
+ "android.bluetooth.vcp.profile.action.CONNECTION_MODE_CHANGED";
+
+ /**
+ * A int extra field in {@link #ACTION_CONNECTION_MODE_CHANGED}
+ * intents that contains the connection mode of the VCP.
+ */
+ public static final String EXTRA_MODE =
+ "android.bluetooth.vcp.profile.extra.MODE";
+
+ /** None VCP connection */
+ public static final int MODE_NONE = 0x00;
+ /** VCP connection setup with unicast mode */
+ public static final int MODE_UNICAST = 0x01;
+ /** VCP connection setup with broadcast mode */
+ public static final int MODE_BROADCAST = 0x02;
+ /** VCP connection setup with unicast and broadcast mode */
+ public static final int MODE_UNICAST_BROADCAST = 0x03;
+
+ public static final int A2DP = 0x0001;
+ public static final int HFP = 0x0002;
+ public static final int LE_MEDIA = 0x0010;
+ public static final int LE_VOICE = 0x2000;
+
+ public static final int CALL_STREAM = 0;
+ public static final int MEDIA_STREAM = 1;
+
+ private BluetoothAdapter mAdapter;
+ private final AttributionSource mAttributionSource;
+ private final BluetoothProfileConnector<IBluetoothVcp> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.VCP,
+ "BluetoothVcp", IBluetoothVcp.class.getName()) {
+ @Override
+ public IBluetoothVcp getServiceInterface(IBinder service) {
+ return IBluetoothVcp.Stub.asInterface(
+ Binder.allowBlocking(service));
+ }
+ };
+
+ /**
+ * Create a BluetoothVcp proxy object for interacting with the local
+ * Bluetooth VCP service.
+ */
+ /*package*/ BluetoothVcp(Context context, ServiceListener listener) {
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mProfileConnector.connect(context, listener);
+ mAttributionSource = mAdapter.getAttributionSource();
+ }
+
+ /*package*/ void close() {
+ mProfileConnector.disconnect();
+ }
+
+ private IBluetoothVcp getService() {
+ return mProfileConnector.getService();
+ }
+
+ @Override
+ public void finalize() {
+ close();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (VDBG) log("getConnectedDevices()");
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (VDBG) log("getDevicesMatchingStates()");
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getConnectionState(BluetoothDevice device) {
+ if (VDBG) log("getConnectionState(" + device + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.getConnectionState(device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+
+ /**
+ * Get current VCP Connection mode
+ *
+ * @param device: remote device instance
+ * @return current connection mode of VCP:
+ * {@link #BluetoothVcp.MODE_NONE} if none VCP connection
+ * {@link #BluetoothVcp.MODE_UNICAST} if VCP is connected for unicast
+ * {@link #BluetoothVcp.MODE_BROADCAST} if VCP is connected for broadcast
+ * {@link #BluetoothVcp.MODE_UNICAST_BROADCAST} if VCP
+ * is connected for unicast and broadcast
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getConnectionMode(BluetoothDevice device) {
+ if (VDBG) log("getConnectionMode(" + device + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.getConnectionMode(device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return MODE_NONE;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return MODE_NONE;
+ }
+
+ /**
+ * Set absolute volume to remote device via VCP connection
+ *
+ * @param device: remote device instance
+ * @prarm volume: requested volume settings for remote device
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public void setAbsoluteVolume(BluetoothDevice device, int volume) {
+ if (VDBG) log("setAbsoluteVolume(" + device + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ service.setAbsoluteVolume(device, volume, mAttributionSource);
+ return;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ }
+
+ /**
+ * Get current absolute volume of the remote device
+ *
+ * @param device: remote device instance
+ * @return current absolute volume of the remote device
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getAbsoluteVolume(BluetoothDevice device) {
+ if (VDBG) log("getAbsoluteVolume(" + device + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.getAbsoluteVolume(device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return -1;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return -1;
+ }
+
+ /**
+ * Mute or unmute remote device via VCP connection
+ *
+ * @param device: remote device instance
+ * @prarm enableMute: true if mute, false if unmute
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public void setMute(BluetoothDevice device, boolean enableMute) {
+ if (VDBG) log("setMute(" + device + ")" +" enableMute: " + enableMute);
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ service.setMute(device, enableMute, mAttributionSource);
+ return;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ }
+
+ /**
+ * Get mute status of remote device
+ *
+ * @param device: remote device instance
+ * @return current mute status of the remote device
+ * true if mute status, false if unmute status
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean isMute(BluetoothDevice device) {
+ if (VDBG) log("isMute(" + device + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.isMute(device, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
+ * set active stream for a DuMo device
+ *
+ * @param device: remote device instance
+ * @param audioType: call/media audio
+ * @param profile: profile that is needed to be active
+ * @return success/failure
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean setActiveProfile(BluetoothDevice device, int audioType, int profile) {
+ if (VDBG) log("setActiveProfile(" + device + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.setActiveProfile(device, audioType, profile, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
+ * set active stream for a DuMo device
+ *
+ * @param audioType: call/media audio
+ * @return ID of current active profile
+ */
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public int getActiveProfile(int audioType) {
+ if (VDBG) log("getActiveProfile(" + audioType + ")");
+ final IBluetoothVcp service =
+ getService();
+ if (service != null && isEnabled()) {
+ try {
+ return service.getActiveProfile(audioType, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return -1;
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return -1;
+ }
+
+ private boolean isEnabled() {
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
+ }
+
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
+ }
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
+}
+
diff --git a/core/java/android/bluetooth/DeviceGroup.java b/core/java/android/bluetooth/DeviceGroup.java
new file mode 100644
index 000000000000..0dac87f3d8f6
--- /dev/null
+++ b/core/java/android/bluetooth/DeviceGroup.java
@@ -0,0 +1,177 @@
+/******************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Provides Device Group details.
+ *
+ * {@see BluetoothDeviceGroup}
+ * @hide
+ *
+ */
+
+public final class DeviceGroup implements Parcelable {
+ /** Identifier of the Device Group */
+ private int mGroupId;
+ /** Size of the Device Group. */
+ private int mSize;
+ /** List of all group devices {@link BluetoothDevice} */
+ private CopyOnWriteArrayList <BluetoothDevice> mGroupDevices
+ = new CopyOnWriteArrayList<BluetoothDevice>();
+ /** Primary Service UUID which has included required Device Group service*/
+ private final ParcelUuid mIncludingSrvcUUID;
+ /** Suggests whether exclusive access can be taken for this device group */
+ private final boolean mExclusiveAccessSupport;
+
+ /**
+ * Constructor.
+ * @hide
+ */
+ public DeviceGroup(int groupId, int size, List<BluetoothDevice> groupDevices,
+ ParcelUuid includingSrvcUUID, boolean exclusiveAccessSupport) {
+ mGroupId = groupId;
+ mSize = size;
+ mGroupDevices.addAll(groupDevices);
+ mIncludingSrvcUUID = includingSrvcUUID;
+ mExclusiveAccessSupport = exclusiveAccessSupport;
+ }
+
+ public DeviceGroup(Parcel in) {
+ mGroupId = in.readInt();
+ mSize = in.readInt();
+ in.readList(mGroupDevices, BluetoothDevice.class.getClassLoader());
+ mIncludingSrvcUUID = in.readParcelable(ParcelUuid.class.getClassLoader());
+ mExclusiveAccessSupport = in.readBoolean();
+ }
+
+ /**
+ * Used to retrieve identifier of the Device Group.
+ *
+ * @return Identifier of the Device Group.
+ */
+ public int getDeviceGroupId() {
+ return mGroupId;
+ }
+
+ /**
+ * Used to know total number group devices which are part of this Device Group.
+ *
+ * @return size of the Device Group
+ */
+ public int getDeviceGroupSize() {
+ return mSize;
+ }
+
+ /**
+ * Indicates total number of group devices discovered in Group Discovery procedure.
+ *
+ * @return total group devices discovered in the Device Group.
+ */
+ public int getTotalDiscoveredGroupDevices() {
+ return mGroupDevices.size();
+ }
+
+
+ /**
+ * Used to fetch group devices of the Device Group.
+ *
+ *@return List of group devices {@link BluetoothDevice} in the Device Group.
+ */
+ public List<BluetoothDevice> getDeviceGroupMembers() {
+ return mGroupDevices;
+ }
+
+ /**
+ * Suggests primary GATT service which has included this DeviceGroup Service
+ * for this device group. If remote device is part of multiple Device Groups then
+ * this uuid cant be null. If remote device is part of only one device froup
+ * then this returned parameter can be null.
+ *
+ *@return UUID of the GATT primary Service which has included this device group.
+ */
+ public ParcelUuid getIncludingServiceUUID() {
+ return mIncludingSrvcUUID;
+ }
+
+ /**
+ * Suggests whether exclusive access is supported by this Device Group.
+ *
+ * @return true, if exclusive access operation is supported by this Device Group.
+ * Otherwise, false.
+ */
+ public boolean isExclusiveAccessSupported() {
+ return mExclusiveAccessSupport;
+ }
+
+ /**
+ * Indicates whether all devices of this Device Group are discovered.
+ *
+ * @return true, if all group devices are discovered. Otherwise, false.
+ */
+ public boolean isGroupDiscoveredCompleted() {
+ return (mSize == getTotalDiscoveredGroupDevices());
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mGroupId);
+ dest.writeInt(mSize);
+ dest.writeList(mGroupDevices);
+ dest.writeParcelable(mIncludingSrvcUUID, 0);
+ dest.writeBoolean(mExclusiveAccessSupport);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<DeviceGroup> CREATOR =
+ new Parcelable.Creator<DeviceGroup>() {
+ public DeviceGroup createFromParcel(Parcel in) {
+ return new DeviceGroup(in);
+ }
+
+ public DeviceGroup[] newArray(int size) {
+ return new DeviceGroup[size];
+ }
+ };
+}
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
index cec658049ca5..f0075263894f 100644
--- a/core/java/android/bluetooth/le/AdvertiseData.java
+++ b/core/java/android/bluetooth/le/AdvertiseData.java
@@ -51,19 +51,22 @@ public final class AdvertiseData implements Parcelable {
private final Map<ParcelUuid, byte[]> mServiceData;
private final boolean mIncludeTxPowerLevel;
private final boolean mIncludeDeviceName;
+ private final byte[] mTransportDiscoveryData;
private AdvertiseData(List<ParcelUuid> serviceUuids,
List<ParcelUuid> serviceSolicitationUuids,
SparseArray<byte[]> manufacturerData,
Map<ParcelUuid, byte[]> serviceData,
boolean includeTxPowerLevel,
- boolean includeDeviceName) {
+ boolean includeDeviceName,
+ byte[] transportDiscoveryData) {
mServiceUuids = serviceUuids;
mServiceSolicitationUuids = serviceSolicitationUuids;
mManufacturerSpecificData = manufacturerData;
mServiceData = serviceData;
mIncludeTxPowerLevel = includeTxPowerLevel;
mIncludeDeviceName = includeDeviceName;
+ mTransportDiscoveryData = transportDiscoveryData;
}
/**
@@ -112,12 +115,20 @@ public final class AdvertiseData implements Parcelable {
}
/**
+ * Returns an array of Transport Discovery data.
+ * @hide
+ */
+ public byte[] getTransportDiscoveryData() {
+ return mTransportDiscoveryData;
+ }
+
+ /**
* @hide
*/
@Override
public int hashCode() {
return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mManufacturerSpecificData,
- mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
+ mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel, mTransportDiscoveryData);
}
/**
@@ -138,7 +149,8 @@ public final class AdvertiseData implements Parcelable {
other.mManufacturerSpecificData)
&& BluetoothLeUtils.equals(mServiceData, other.mServiceData)
&& mIncludeDeviceName == other.mIncludeDeviceName
- && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
+ && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel
+ && BluetoothLeUtils.equals(mTransportDiscoveryData, other.mTransportDiscoveryData);
}
@Override
@@ -148,7 +160,8 @@ public final class AdvertiseData implements Parcelable {
+ BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
+ BluetoothLeUtils.toString(mServiceData)
+ ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
- + mIncludeDeviceName + "]";
+ + mIncludeDeviceName + ", mTransportDiscoveryData="
+ + BluetoothLeUtils.toString(mTransportDiscoveryData)+ "]";
}
@Override
@@ -175,6 +188,10 @@ public final class AdvertiseData implements Parcelable {
}
dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
+ dest.writeInt(mTransportDiscoveryData != null ? mTransportDiscoveryData.length : 0);
+ if (mTransportDiscoveryData != null) {
+ dest.writeByteArray(mTransportDiscoveryData);
+ }
}
public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseData> CREATOR =
@@ -211,6 +228,11 @@ public final class AdvertiseData implements Parcelable {
}
builder.setIncludeTxPowerLevel(in.readByte() == 1);
builder.setIncludeDeviceName(in.readByte() == 1);
+ int transportDiscoveryDataSize = in.readInt();
+ if (transportDiscoveryDataSize > 0) {
+ byte[] transportDiscoveryData = in.createByteArray();
+ builder.addTransportDiscoveryData(transportDiscoveryData);
+ }
return builder.build();
}
};
@@ -227,6 +249,7 @@ public final class AdvertiseData implements Parcelable {
private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
private boolean mIncludeTxPowerLevel;
private boolean mIncludeDeviceName;
+ private byte[] mTransportDiscoveryData;
/**
* Add a service UUID to advertise data.
@@ -315,12 +338,24 @@ public final class AdvertiseData implements Parcelable {
}
/**
+ * Add Transport Discovery data
+ * @hide
+ */
+ public Builder addTransportDiscoveryData(byte[] transportDiscoveryData) {
+ if ((transportDiscoveryData == null) || (transportDiscoveryData.length == 0)) {
+ throw new IllegalArgumentException("transportDiscoveryData is null");
+ }
+ mTransportDiscoveryData = transportDiscoveryData;
+ return this;
+ }
+
+ /**
* Build the {@link AdvertiseData}.
*/
public AdvertiseData build() {
return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids,
mManufacturerSpecificData, mServiceData, mIncludeTxPowerLevel,
- mIncludeDeviceName);
+ mIncludeDeviceName, mTransportDiscoveryData);
}
}
}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index e39b198ae384..360e8f8815e0 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.os.Parcelable;
+import android.app.ActivityThread;
/**
* The {@link AdvertisingSetParameters} provide a way to adjust advertising
@@ -389,10 +390,20 @@ public final class AdvertisingSetParameters implements Parcelable {
* {@link AdvertisingSetParameters#TX_POWER_MEDIUM},
* or {@link AdvertisingSetParameters#TX_POWER_HIGH}.
* @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
+ * Allow tx power level to be set more than {@link AdvertisingSetParameters#TX_POWER_HIGH},
+ * if the setTxPowerLevel is invoked from com.android.bluetooth process
*/
public Builder setTxPowerLevel(int txPowerLevel) {
- if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
- throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
+ String packageName = ActivityThread.currentPackageName();
+ if (packageName.equals("com.android.bluetooth")) {
+ int maxPowerLevel = 20;
+ if (txPowerLevel < TX_POWER_MIN || txPowerLevel > maxPowerLevel) {
+ throw new IllegalArgumentException("invalid txPowerLevel " + txPowerLevel);
+ }
+ } else {
+ if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
+ throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
+ }
}
mTxPowerLevel = txPowerLevel;
return this;
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 34aac8bfdb25..2afe24f1439a 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -38,6 +38,7 @@ import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -260,6 +261,13 @@ public final class BluetoothLeScanner {
if (gatt == null) {
return postCallbackErrorOrReturn(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
}
+
+ if ((settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_SENSOR_ROUTING)
+ && (filters == null || filters.isEmpty())) {
+ ScanFilter filter = (new ScanFilter.Builder()).build();
+ filters = Arrays.asList(filter);
+ }
+
if (!isSettingsConfigAllowedForScan(settings)) {
return postCallbackErrorOrReturn(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
@@ -272,6 +280,10 @@ public final class BluetoothLeScanner {
return postCallbackErrorOrReturn(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
}
+ if (!isRoutingAllowedForScan(settings)) {
+ return postCallbackErrorOrReturn(callback,
+ ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
+ }
if (callback != null) {
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
settings, workSource, callback, resultStorages);
@@ -648,4 +660,14 @@ public final class BluetoothLeScanner {
}
return true;
}
+
+ private boolean isRoutingAllowedForScan(ScanSettings settings) {
+ final int callbackType = settings.getCallbackType();
+
+ if (callbackType == ScanSettings.CALLBACK_TYPE_SENSOR_ROUTING
+ && settings.getScanMode() == ScanSettings.SCAN_MODE_OPPORTUNISTIC) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
index 6381f557c1b2..f8d1c517540d 100644
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ b/core/java/android/bluetooth/le/BluetoothLeUtils.java
@@ -77,6 +77,28 @@ public class BluetoothLeUtils {
}
/**
+ * Returns a string composed from a byte array.
+ */
+ static <T> String toString(byte[] data) {
+ if (data == null) {
+ return "null";
+ }
+ if (data.length == 0) {
+ return "{}";
+ }
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('{');
+ for(int i=0; i < data.length; i++) {
+ buffer.append(data[i]);
+ if ((i+1) < data.length) {
+ buffer.append(", ");
+ }
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
* Check whether two {@link SparseArray} equal.
*/
static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
@@ -126,6 +148,25 @@ public class BluetoothLeUtils {
}
/**
+ * Check whether two byte arrays are equal.
+ */
+ static <T> boolean equals(byte[] data, byte[] otherData) {
+ if (data == otherData) {
+ return true;
+ }
+ if (data == null || otherData == null) {
+ return false;
+ }
+ if (data.length != otherData.length) {
+ return false;
+ }
+ if (!Objects.deepEquals(data, otherData)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Ensure Bluetooth is turned on.
*
* @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
index 14ac911fcb7f..b3fd484f699f 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
@@ -78,4 +78,13 @@ public abstract class PeriodicAdvertisingCallback {
*/
public void onSyncLost(int syncHandle) {
}
+
+ /**
+ * Callback when periodic sync transfered.
+ *
+ * @param device
+ * @param status
+ */
+ public void onSyncTransfered(BluetoothDevice device, int status) {
+ }
}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
index dea686d18ea2..ff9a41b92f34 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
@@ -259,6 +259,75 @@ public final class PeriodicAdvertisingManager {
}
});
}
+
+ public void onSyncTransfered(BluetoothDevice device, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onSyncTransfered(device, status);
+ // App can still unregister the sync until notified it's lost.
+ // Remove callback after app was notifed.
+ //mCallbackWrappers.remove(callback);
+ }
+ });
+ }
};
}
+
+ public void transferSync(BluetoothDevice bda, int service_data, int sync_handle) {
+ IBluetoothGatt gatt;
+ try {
+ gatt = mBluetoothManager.getBluetoothGatt();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+ PeriodicAdvertisingCallback callback = null;
+ for (PeriodicAdvertisingCallback cb : mCallbackWrappers.keySet()) {
+ callback = cb;
+ }
+ if (callback != null) {
+ callback.onSyncTransfered(bda,
+ PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
+ }
+ return;
+ }
+ try {
+ gatt.transferSync(bda, service_data , sync_handle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ return;
+ }
+ }
+
+ public void transferSetInfo(BluetoothDevice bda, int service_data,
+ int adv_handle, PeriodicAdvertisingCallback callback) {
+ transferSetInfo(bda, service_data, adv_handle, callback, null);
+ }
+
+ public void transferSetInfo (BluetoothDevice bda, int service_data,
+ int adv_handle, PeriodicAdvertisingCallback callback, Handler handler) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback can't be null");
+ }
+ IBluetoothGatt gatt;
+ try {
+ gatt = mBluetoothManager.getBluetoothGatt();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+ return;
+ }
+ if (handler == null) {
+ handler = new Handler(Looper.getMainLooper());
+ }
+ IPeriodicAdvertisingCallback wrapper = wrap(callback, handler);
+ if (wrapper == null) {
+ throw new IllegalArgumentException("callback was not properly registered");
+ }
+ try {
+ gatt.transferSetInfo(bda, service_data , adv_handle, wrapper);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ return;
+ }
+
+ }
}
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 8ff018121ab0..20ed49850b1d 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -51,6 +51,12 @@ import java.util.UUID;
*/
public final class ScanFilter implements Parcelable {
+ /**
+ * Provide TDS data scan results for WiFi Alliance Org id
+ * @hide
+ */
+ public static final int WIFI_ALLIANCE_ORG_ID = 2;
+
@Nullable
private final String mDeviceName;
@@ -85,6 +91,15 @@ public final class ScanFilter implements Parcelable {
@Nullable
private final byte[] mManufacturerDataMask;
+ private final int mOrgId;
+ private final int mTDSFlags;
+ private final int mTDSFlagsMask;
+ private final byte[] mWifiNANHash;
+
+ private final boolean mGroupBasedFiltering;
+
+ private static final int GROUP_DATA_LEN = 6;
+
/** @hide */
public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
@@ -93,7 +108,9 @@ public final class ScanFilter implements Parcelable {
ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
byte[] serviceData, byte[] serviceDataMask,
int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
- @AddressType int addressType, @Nullable byte[] irk) {
+ @AddressType int addressType, @Nullable byte[] irk,
+ int orgId, int TDSFlags, int TDSFlagsMask, byte[] wifiNANHash,
+ boolean groupBasedFiltering) {
mDeviceName = name;
mServiceUuid = uuid;
mServiceUuidMask = uuidMask;
@@ -108,6 +125,11 @@ public final class ScanFilter implements Parcelable {
mManufacturerDataMask = manufacturerDataMask;
mAddressType = addressType;
mIrk = irk;
+ mOrgId = orgId;
+ mTDSFlags = TDSFlags;
+ mTDSFlagsMask = TDSFlagsMask;
+ mWifiNANHash = wifiNANHash;
+ mGroupBasedFiltering = groupBasedFiltering;
}
@Override
@@ -177,6 +199,18 @@ public final class ScanFilter implements Parcelable {
dest.writeByteArray(mIrk);
}
}
+ dest.writeInt(mOrgId);
+ dest.writeInt(mOrgId < 0 ? 0 : 1);
+ if(mOrgId >= 0) {
+ dest.writeInt(mTDSFlags);
+ dest.writeInt(mTDSFlagsMask);
+ dest.writeInt(mWifiNANHash == null ? 0 : 1);
+ if (mWifiNANHash != null) {
+ dest.writeInt(mWifiNANHash.length);
+ dest.writeByteArray(mWifiNANHash);
+ }
+ }
+ dest.writeBoolean(mGroupBasedFiltering);
}
/**
@@ -267,6 +301,25 @@ public final class ScanFilter implements Parcelable {
builder.setDeviceAddress(address, addressType);
}
}
+
+ int orgId = in.readInt();
+ if(in.readInt() == 1) {
+ int tdsFlags = in.readInt();
+ int tdsFlagsMask = in.readInt();
+ if (in.readInt() == 1) {
+ int wifiNANHashLength = in.readInt();
+ byte[] wifiNanHash = new byte[wifiNANHashLength];
+ in.readByteArray(wifiNanHash);
+ builder.setTransportDiscoveryData(orgId, tdsFlags, tdsFlagsMask,
+ wifiNanHash);
+ }
+ else {
+ builder.setTransportDiscoveryData(orgId, tdsFlags, tdsFlagsMask, null);
+ }
+ }
+
+ boolean groupBasedFiltering = in.readBoolean();
+ builder.setGroupBasedFiltering(groupBasedFiltering);
return builder.build();
}
};
@@ -363,6 +416,45 @@ public final class ScanFilter implements Parcelable {
}
/**
+ * @hide
+ * Returns the organization id. -1 if the organization id is not set.
+ */
+ public int getOrgId() {
+ return mOrgId;
+ }
+
+ /**
+ * @hide
+ * Returns the TDS flags. -1 if TDS flags is not set.
+ */
+ public int getTDSFlags() {
+ return mTDSFlags;
+ }
+
+ /**
+ * @hide
+ * Returns the TDS flags mask. -1 if TDS flags mask is not set.
+ */
+ public int getTDSFlagsMask() {
+ return mTDSFlagsMask;
+ }
+
+ /**
+ * @hide
+ */
+ public byte[] getWifiNANHash() {
+ return mWifiNANHash;
+ }
+
+ /**
+ * @hide
+ * Returns true, if Group AD Type based filtering is enabled. Otherwise, false.
+ */
+ public boolean getGroupFilteringValue() {
+ return mGroupBasedFiltering;
+ }
+
+ /**
* Check if the scan filter matches a {@code scanResult}. A scan result is considered as a match
* if it matches all the field filters.
*/
@@ -419,6 +511,26 @@ public final class ScanFilter implements Parcelable {
return false;
}
}
+
+ //Transport Discovery data match
+ if(mOrgId >= 0) {
+ byte[] tdsData = scanRecord.getTDSData();
+ if ((tdsData != null) && (tdsData.length > 0)) {
+ if ((mOrgId != tdsData[0]) ||
+ ((mTDSFlags & mTDSFlagsMask) != (tdsData[1] & mTDSFlagsMask))) {
+ return false;
+ }
+ }
+ }
+
+ // Group AD Type filter match
+ if (mGroupBasedFiltering) {
+ byte [] groupIdData = scanRecord.getGroupIdentifierData();
+ if (groupIdData != null && groupIdData.length != GROUP_DATA_LEN) {
+ return false;
+ }
+ }
+
// All filters match.
return true;
}
@@ -513,7 +625,11 @@ public final class ScanFilter implements Parcelable {
+ Arrays.toString(mServiceData) + ", mServiceDataMask="
+ Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
+ ", mManufacturerData=" + Arrays.toString(mManufacturerData)
- + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask) + "]";
+ + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask)
+ + ", mOrganizationId=" + mOrgId + ", mTDSFlags=" + mTDSFlags
+ + ", mTDSFlagsMask=" + mTDSFlagsMask
+ + ", mWifiNANHash=" + Arrays.toString(mWifiNANHash) +"]"
+ + ", mGroupBasedFiltering=" + mGroupBasedFiltering;
}
@Override
@@ -525,7 +641,9 @@ public final class ScanFilter implements Parcelable {
Arrays.hashCode(mServiceData),
Arrays.hashCode(mServiceDataMask),
mServiceUuid, mServiceUuidMask,
- mServiceSolicitationUuid, mServiceSolicitationUuidMask);
+ mServiceSolicitationUuid, mServiceSolicitationUuidMask,
+ mOrgId, mTDSFlags, mTDSFlagsMask, Arrays.hashCode(mWifiNANHash),
+ mGroupBasedFiltering);
}
@Override
@@ -549,7 +667,12 @@ public final class ScanFilter implements Parcelable {
&& Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
&& Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
&& Objects.equals(mServiceSolicitationUuidMask,
- other.mServiceSolicitationUuidMask);
+ other.mServiceSolicitationUuidMask)
+ && mOrgId == other.mOrgId
+ && mTDSFlags == other.mTDSFlags
+ && mTDSFlagsMask == other.mTDSFlagsMask
+ && Objects.deepEquals(mWifiNANHash, other.mWifiNANHash)
+ && mGroupBasedFiltering == other.mGroupBasedFiltering;
}
/**
@@ -591,6 +714,13 @@ public final class ScanFilter implements Parcelable {
private byte[] mManufacturerData;
private byte[] mManufacturerDataMask;
+ private int mOrgId = -1;
+ private int mTDSFlags = -1;
+ private int mTDSFlagsMask = -1;
+ private byte[] mWifiNANHash;
+
+ private boolean mGroupBasedFiltering;
+
/**
* Set filter on device name.
*/
@@ -895,6 +1025,38 @@ public final class ScanFilter implements Parcelable {
return this;
}
+
+ /**
+ * @hide
+ * Set filter on transport discovery data.
+ * @throws IllegalArgumentException If the {@code orgId} is invalid or {@code
+ * wifiNANhash} is not null while {@code orgId} is non-Wifi.
+ */
+ public Builder setTransportDiscoveryData(int orgId, int TDSFlags, int TDSFlagsMask,
+ byte[] wifiNANHash) {
+ if (orgId < 0) {
+ throw new IllegalArgumentException("invalid organization id");
+ }
+ if ((orgId != WIFI_ALLIANCE_ORG_ID) && (wifiNANHash != null)) {
+ throw new IllegalArgumentException("Wifi NAN Hash is not null for non-Wifi Org Id");
+ }
+ mOrgId = orgId;
+ mTDSFlags = TDSFlags;
+ mTDSFlagsMask = TDSFlagsMask;
+ mWifiNANHash = wifiNANHash;
+ return this;
+ }
+
+ /**
+ * @hide
+ * Enable filter on Group AD Type.
+ */
+ public @NonNull Builder setGroupBasedFiltering(
+ boolean enable) {
+ mGroupBasedFiltering = enable;
+ return this;
+ }
+
/**
* Build {@link ScanFilter}.
*
@@ -906,7 +1068,9 @@ public final class ScanFilter implements Parcelable {
mServiceSolicitationUuidMask,
mServiceDataUuid, mServiceData, mServiceDataMask,
mManufacturerId, mManufacturerData, mManufacturerDataMask,
- mAddressType, mIrk);
+ mAddressType, mIrk,
+ mOrgId, mTDSFlags, mTDSFlagsMask, mWifiNANHash,
+ mGroupBasedFiltering);
}
}
}
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index 9b8c2eaf4d19..28dbfbef993f 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -59,6 +59,11 @@ public final class ScanRecord {
private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT = 0x1F;
private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT = 0x15;
private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
+ private static final int DATA_TYPE_TRANSPORT_DISCOVERY_DATA = 0x26;
+ /**
+ * @hide
+ */
+ public static int DATA_TYPE_GROUP_AD_TYPE = 0x00;
// Flags of the advertising data.
private final int mAdvertiseFlags;
@@ -81,6 +86,12 @@ public final class ScanRecord {
// Raw bytes of scan record.
private final byte[] mBytes;
+ // Transport Discovery data.
+ private final byte[] mTDSData;
+
+ // Group Identifier Data
+ private final byte[] mGroupIdentifierData;
+
/**
* Returns the advertising flags indicating the discoverable mode and capability of the device.
* Returns -1 if the flag field is not set.
@@ -165,6 +176,22 @@ public final class ScanRecord {
}
/**
+ * @hide
+ * Returns Transport Discovery data
+ */
+ public byte[] getTDSData() {
+ return mTDSData;
+ }
+
+ /**
+ * @hide
+ * Returns Group Identifier data
+ */
+ public byte[] getGroupIdentifierData() {
+ return mGroupIdentifierData;
+ }
+
+ /**
* Returns raw bytes of scan record.
*/
public byte[] getBytes() {
@@ -197,7 +224,7 @@ public final class ScanRecord {
SparseArray<byte[]> manufacturerData,
Map<ParcelUuid, byte[]> serviceData,
int advertiseFlags, int txPowerLevel,
- String localName, byte[] bytes) {
+ String localName, byte[] tdsData, byte[] groupIdentifierData, byte[] bytes) {
mServiceSolicitationUuids = serviceSolicitationUuids;
mServiceUuids = serviceUuids;
mManufacturerSpecificData = manufacturerData;
@@ -205,6 +232,8 @@ public final class ScanRecord {
mDeviceName = localName;
mAdvertiseFlags = advertiseFlags;
mTxPowerLevel = txPowerLevel;
+ mTDSData = tdsData;
+ mGroupIdentifierData = groupIdentifierData;
mBytes = bytes;
}
@@ -235,6 +264,9 @@ public final class ScanRecord {
SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
+ byte[] tdsData = null;
+ byte[] groupIdentifierData = null;
+
try {
while (currentPos < scanRecord.length) {
// length is unsigned int.
@@ -312,8 +344,15 @@ public final class ScanRecord {
dataLength - 2);
manufacturerData.put(manufacturerId, manufacturerDataBytes);
break;
+ case DATA_TYPE_TRANSPORT_DISCOVERY_DATA:
+ tdsData = extractBytes(scanRecord, currentPos, dataLength);
+ break;
+
default:
- // Just ignore, we don't handle such data type.
+ if (fieldType == DATA_TYPE_GROUP_AD_TYPE) {
+ Log.d(TAG, "Parsing Group Identifier data");
+ groupIdentifierData = extractBytes(scanRecord, currentPos, dataLength);
+ }
break;
}
currentPos += dataLength;
@@ -323,12 +362,14 @@ public final class ScanRecord {
serviceUuids = null;
}
return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
- serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
+ serviceData, advertiseFlag, txPowerLevel, localName, tdsData,
+ groupIdentifierData, scanRecord);
} catch (Exception e) {
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
// As the record is invalid, ignore all the parsed results for this packet
// and return an empty record with raw scanRecord bytes in results
- return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
+ return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, null,
+ null, scanRecord);
}
}
@@ -339,7 +380,8 @@ public final class ScanRecord {
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
mManufacturerSpecificData)
+ ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
- + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
+ + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName +
+ ", mTDSData=" + BluetoothLeUtils.toString(mTDSData) +"]";
}
// Parse service UUIDs.
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index 522845628487..40ff3bec817e 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -93,6 +93,7 @@ public final class ScanResult implements Parcelable, Attributable {
private int mAdvertisingSid;
private int mTxPower;
private int mPeriodicAdvertisingInterval;
+ private int mAddressType;
/**
* Constructs a new ScanResult.
@@ -117,6 +118,7 @@ public final class ScanResult implements Parcelable, Attributable {
mAdvertisingSid = SID_NOT_PRESENT;
mTxPower = 127;
mPeriodicAdvertisingInterval = 0;
+ mAddressType = -1;
}
/**
@@ -146,6 +148,42 @@ public final class ScanResult implements Parcelable, Attributable {
mPeriodicAdvertisingInterval = periodicAdvertisingInterval;
mScanRecord = scanRecord;
mTimestampNanos = timestampNanos;
+ mAddressType = -1;
+ }
+
+ /**
+ * Constructs a new ScanResult.
+ *
+ * @param device Remote Bluetooth device found.
+ * @param addressType addressType for the Scan result
+ * @param eventType Event type.
+ * @param primaryPhy Primary advertising phy.
+ * @param secondaryPhy Secondary advertising phy.
+ * @param advertisingSid Advertising set ID.
+ * @param txPower Transmit power.
+ * @param rssi Received signal strength.
+ * @param periodicAdvertisingInterval Periodic advertising interval.
+ * @param scanRecord Scan record including both advertising data and scan response data.
+ * @param timestampNanos Timestamp at which the scan result was observed.
+ * @param addressType addressType for the Scan result
+ *
+ *@hide
+ */
+ public ScanResult(BluetoothDevice device, int addressType, int eventType, int primaryPhy,
+ int secondaryPhy,
+ int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
+ ScanRecord scanRecord, long timestampNanos) {
+ mDevice = device;
+ mEventType = eventType;
+ mPrimaryPhy = primaryPhy;
+ mSecondaryPhy = secondaryPhy;
+ mAdvertisingSid = advertisingSid;
+ mTxPower = txPower;
+ mRssi = rssi;
+ mPeriodicAdvertisingInterval = periodicAdvertisingInterval;
+ mScanRecord = scanRecord;
+ mTimestampNanos = timestampNanos;
+ mAddressType = addressType;
}
private ScanResult(Parcel in) {
@@ -174,6 +212,7 @@ public final class ScanResult implements Parcelable, Attributable {
dest.writeInt(mAdvertisingSid);
dest.writeInt(mTxPower);
dest.writeInt(mPeriodicAdvertisingInterval);
+ dest.writeInt(mAddressType);
}
private void readFromParcel(Parcel in) {
@@ -191,6 +230,7 @@ public final class ScanResult implements Parcelable, Attributable {
mAdvertisingSid = in.readInt();
mTxPower = in.readInt();
mPeriodicAdvertisingInterval = in.readInt();
+ mAddressType = in.readInt();
}
@Override
@@ -308,6 +348,14 @@ public final class ScanResult implements Parcelable, Attributable {
return mPeriodicAdvertisingInterval;
}
+ /**
+ *
+ *@hide
+ */
+ public int getAddressType() {
+ return mAddressType;
+ }
+
@Override
public int hashCode() {
return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
@@ -333,7 +381,8 @@ public final class ScanResult implements Parcelable, Attributable {
&& mSecondaryPhy == other.mSecondaryPhy
&& mAdvertisingSid == other.mAdvertisingSid
&& mTxPower == other.mTxPower
- && mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
+ && mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval
+ && mAddressType == other.mAddressType;
}
@Override
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 1aa7cb5111ce..f946cadc7311 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -79,6 +79,12 @@ public final class ScanSettings implements Parcelable {
*/
public static final int CALLBACK_TYPE_MATCH_LOST = 4;
+ /**
+ * Provide results to sensor router instead of the apps processor
+ * @hide
+ */
+ public static final int CALLBACK_TYPE_SENSOR_ROUTING = 8;
+
/**
* Determines how many advertisements to match per filter, as this is scarce hw resource
@@ -319,7 +325,8 @@ public final class ScanSettings implements Parcelable {
private boolean isValidCallbackType(int callbackType) {
if (callbackType == CALLBACK_TYPE_ALL_MATCHES
|| callbackType == CALLBACK_TYPE_FIRST_MATCH
- || callbackType == CALLBACK_TYPE_MATCH_LOST) {
+ || callbackType == CALLBACK_TYPE_MATCH_LOST
+ || callbackType == CALLBACK_TYPE_SENSOR_ROUTING) {
return true;
}
return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 265ff331ffa0..4956e3780000 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1104,6 +1104,7 @@ public abstract class ContentResolver implements ContentInterface {
public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder) {
+ android.util.SeempLog.record_uri(13, uri);
return query(uri, projection, selection, selectionArgs, sortOrder, null);
}
@@ -1190,6 +1191,7 @@ public abstract class ContentResolver implements ContentInterface {
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable CancellationSignal cancellationSignal) {
+ android.util.SeempLog.record_uri(13, uri);
Objects.requireNonNull(uri, "uri");
try {
@@ -2176,6 +2178,7 @@ public abstract class ContentResolver implements ContentInterface {
@Override
public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url,
@Nullable ContentValues values, @Nullable Bundle extras) {
+ android.util.SeempLog.record_uri(37, url);
Objects.requireNonNull(url, "url");
try {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 35794d79b49d..75d2634ca2f9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2900,6 +2900,18 @@ public class Intent implements Parcelable, Cloneable {
public static final String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION";
/**
+ * Broadcast Action: Sent to the optional package verifier when a package
+ * needs to be verified. The data contains the package URI.
+ * <p class="note">
+ * This is a protected intent.
+ * </p>
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PACKAGE_NEEDS_OPTIONAL_VERIFICATION = "com.qualcomm.qti.intent.action.PACKAGE_NEEDS_OPTIONAL_VERIFICATION";
+
+ /**
* Broadcast Action: Sent to the system package verifier when a package is
* verified. The data contains the package URI.
* <p class="note">
@@ -11408,6 +11420,7 @@ public class Intent implements Parcelable, Cloneable {
case ACTION_MEDIA_SCANNER_SCAN_FILE:
case ACTION_PACKAGE_NEEDS_VERIFICATION:
case ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION:
+ case ACTION_PACKAGE_NEEDS_OPTIONAL_VERIFICATION:
case ACTION_PACKAGE_VERIFIED:
case ACTION_PACKAGE_ENABLE_ROLLBACK:
// Ignore legacy actions
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 2c4ff5889263..9934823abd47 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -29,6 +29,8 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Environment;
+import android.os.SystemProperties;
+import android.util.DisplayMetrics;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
@@ -61,58 +63,58 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
private static ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class);
/**
- * Default task affinity of all activities in this application. See
- * {@link ActivityInfo#taskAffinity} for more information. This comes
- * from the "taskAffinity" attribute.
+ * Default task affinity of all activities in this application. See
+ * {@link ActivityInfo#taskAffinity} for more information. This comes
+ * from the "taskAffinity" attribute.
*/
public String taskAffinity;
-
+
/**
* Optional name of a permission required to be able to access this
* application's components. From the "permission" attribute.
*/
public String permission;
-
+
/**
* The name of the process this application should run in. From the
* "process" attribute or, if not set, the same as
* <var>packageName</var>.
*/
public String processName;
-
+
/**
* Class implementing the Application object. From the "class"
* attribute.
*/
public String className;
-
+
/**
* A style resource identifier (in the package's resources) of the
* description of an application. From the "description" attribute
* or, if not set, 0.
*/
- public int descriptionRes;
-
+ public int descriptionRes;
+
/**
* A style resource identifier (in the package's resources) of the
* default visual theme of the application. From the "theme" attribute
* or, if not set, 0.
*/
public int theme;
-
+
/**
* Class implementing the Application's manage space
* functionality. From the "manageSpaceActivity"
* attribute. This is an optional attribute and will be null if
* applications don't specify it in their manifest
*/
- public String manageSpaceActivityName;
-
+ public String manageSpaceActivityName;
+
/**
* Class implementing the Application's backup functionality. From
* the "backupAgent" attribute. This is an optional attribute and
* will be null if the application does not specify it in its manifest.
- *
+ *
* <p>If android:allowBackup is set to false, this attribute is ignored.
*/
public String backupAgentName;
@@ -173,7 +175,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@code signatureOrSystem}.
*/
public static final int FLAG_SYSTEM = 1<<0;
-
+
/**
* Value for {@link #flags}: set to true if this application would like to
* allow debugging of its
@@ -182,7 +184,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:debuggable} of the &lt;application&gt; tag.
*/
public static final int FLAG_DEBUGGABLE = 1<<1;
-
+
/**
* Value for {@link #flags}: set to true if this application has code
* associated with it. Comes
@@ -190,7 +192,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:hasCode} of the &lt;application&gt; tag.
*/
public static final int FLAG_HAS_CODE = 1<<2;
-
+
/**
* Value for {@link #flags}: set to true if this application is persistent.
* Comes from {@link android.R.styleable#AndroidManifestApplication_persistent
@@ -211,20 +213,20 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:allowTaskReparenting} of the &lt;application&gt; tag.
*/
public static final int FLAG_ALLOW_TASK_REPARENTING = 1<<5;
-
+
/**
* Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
* Comes from {@link android.R.styleable#AndroidManifestApplication_allowClearUserData
* android:allowClearUserData} of the &lt;application&gt; tag.
*/
public static final int FLAG_ALLOW_CLEAR_USER_DATA = 1<<6;
-
+
/**
* Value for {@link #flags}: this is set if this application has been
* installed as an update to a built-in system application.
*/
public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
-
+
/**
* Value for {@link #flags}: this is set if the application has specified
* {@link android.R.styleable#AndroidManifestApplication_testOnly
@@ -239,15 +241,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:smallScreens}.
*/
public static final int FLAG_SUPPORTS_SMALL_SCREENS = 1<<9;
-
+
/**
* Value for {@link #flags}: true when the application's window can be
* displayed on normal screens. Corresponds to
* {@link android.R.styleable#AndroidManifestSupportsScreens_normalScreens
* android:normalScreens}.
*/
- public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1<<10;
-
+ public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1<<10;
+
/**
* Value for {@link #flags}: true when the application's window can be
* increased in size for larger screens. Corresponds to
@@ -255,7 +257,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:largeScreens}.
*/
public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
-
+
/**
* Value for {@link #flags}: true when the application knows how to adjust
* its UI for different screen sizes. Corresponds to
@@ -263,7 +265,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:resizeable}.
*/
public static final int FLAG_RESIZEABLE_FOR_SCREENS = 1<<12;
-
+
/**
* Value for {@link #flags}: true when the application knows how to
* accommodate different screen densities. Corresponds to
@@ -275,7 +277,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
@Deprecated
public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 1<<13;
-
+
/**
* Value for {@link #flags}: set to true if this application would like to
* request the VM to operate under the safe mode. Comes from
@@ -287,7 +289,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
/**
* Value for {@link #flags}: set to <code>false</code> if the application does not wish
* to permit any OS-driven backups of its data; <code>true</code> otherwise.
- *
+ *
* <p>Comes from the
* {@link android.R.styleable#AndroidManifestApplication_allowBackup android:allowBackup}
* attribute of the &lt;application&gt; tag.
@@ -350,7 +352,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* android:xlargeScreens}.
*/
public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19;
-
+
/**
* Value for {@link #flags}: true when the application has requested a
* large heap for its processes. Corresponds to
@@ -845,6 +847,19 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final String METADATA_PRELOADED_FONTS = "preloaded_fonts";
/**
+ * Boolean indicating whether the resolution of the SurfaceView associated
+ * with this appplication can be overriden.
+ * {@hide}
+ */
+ public int overrideRes = 0;
+
+ /**
+ * In case, app needs different density than device density, set this value.
+ * {@hide}
+ */
+ public int overrideDensity = 0;
+
+ /**
* The required smallest screen width the application can run on. If 0,
* nothing has been specified. Comes from
* {@link android.R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp
@@ -1113,7 +1128,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* the same uid).
*/
public int uid;
-
+
/**
* The minimum SDK version this application can run on. It will not run
* on earlier versions.
@@ -1785,7 +1800,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
if (sb == null) {
sb = ab.packageName;
}
-
+
return sCollator.compare(sa.toString(), sb.toString());
}
@@ -1797,7 +1812,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public ApplicationInfo() {
}
-
+
public ApplicationInfo(ApplicationInfo orig) {
super(orig);
taskAffinity = orig.taskAffinity;
@@ -1808,6 +1823,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
flags = orig.flags;
privateFlags = orig.privateFlags;
privateFlagsExt = orig.privateFlagsExt;
+ overrideRes = orig.overrideRes;
+ overrideDensity = orig.overrideDensity;
requiresSmallestWidthDp = orig.requiresSmallestWidthDp;
compatibleWidthLimitDp = orig.compatibleWidthLimitDp;
largestWidthLimitDp = orig.largestWidthLimitDp;
@@ -1893,6 +1910,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeInt(flags);
dest.writeInt(privateFlags);
dest.writeInt(privateFlagsExt);
+ dest.writeInt(overrideRes);
+ dest.writeInt(overrideDensity);
dest.writeInt(requiresSmallestWidthDp);
dest.writeInt(compatibleWidthLimitDp);
dest.writeInt(largestWidthLimitDp);
@@ -1983,6 +2002,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
flags = source.readInt();
privateFlags = source.readInt();
privateFlagsExt = source.readInt();
+ overrideRes = source.readInt();
+ overrideDensity = source.readInt();
requiresSmallestWidthDp = source.readInt();
compatibleWidthLimitDp = source.readInt();
largestWidthLimitDp = source.readInt();
@@ -2069,7 +2090,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
/**
* Disable compatibility mode
- *
+ *
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -2290,7 +2311,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
}
return pm.getDefaultActivityIcon();
}
-
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private boolean isPackageUnavailable(PackageManager pm) {
try {
@@ -2511,6 +2532,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
return output.toArray(new String[output.size()]);
}
+ /** @hide */
+ public int getOverrideDensity() {
+ return overrideDensity;
+ }
+
/** {@hide} */ public void setCodePath(String codePath) { scanSourceDir = codePath; }
/** {@hide} */ public void setBaseCodePath(String baseCodePath) { sourceDir = baseCodePath; }
/** {@hide} */ public void setSplitCodePaths(String[] splitCodePaths) { splitSourceDirs = splitCodePaths; }
@@ -2526,6 +2552,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public void setRequestRawExternalStorageAccess(@Nullable Boolean value) {
requestRawExternalStorageAccess = value;
}
+ /** {@hide} */ public void setOverrideRes(int overrideResolution) { overrideRes = overrideResolution; }
/** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -2548,7 +2575,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public int getMemtagMode() {
return memtagMode;
}
-
/**
* Returns whether the application has requested automatic zero-initialization of native heap
* memory allocations to be enabled or disabled.
@@ -2557,4 +2583,5 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public int getNativeHeapZeroInitialized() {
return nativeHeapZeroInitialized;
}
+ /** {@hide} */ public int canOverrideRes() { return overrideRes; }
}
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 439c6396f1d0..8f0d50d94d18 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -34,6 +34,7 @@ import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
+import android.util.Log;
/**
* CompatibilityInfo class keeps the information about the screen compatibility mode that the
@@ -47,6 +48,8 @@ public class CompatibilityInfo implements Parcelable {
public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo() {
};
+ static final String TAG = "CompatibilityInfo";
+
/**
* This is the number of pixels we would like to have along the
* short axis of an app that needs to run on a normal size screen.
@@ -163,11 +166,18 @@ public class CompatibilityInfo implements Parcelable {
// Let the user decide.
compatFlags |= NEEDS_SCREEN_COMPAT;
}
-
- // Modern apps always support densities.
- applicationDensity = DisplayMetrics.DENSITY_DEVICE;
- applicationScale = 1.0f;
- applicationInvertedScale = 1.0f;
+ int density = appInfo.getOverrideDensity();
+ if(density != 0) {
+ applicationDensity = density;
+ applicationScale = DisplayMetrics.DENSITY_DEVICE / (float) applicationDensity;
+ applicationInvertedScale = 1.0f / applicationScale;
+ compatFlags |= SCALING_REQUIRED;
+ } else {
+ // Modern apps always support densities.
+ applicationDensity = DisplayMetrics.DENSITY_DEVICE;
+ applicationScale = 1.0f;
+ applicationInvertedScale = 1.0f;
+ }
} else {
/**
@@ -254,26 +264,31 @@ public class CompatibilityInfo implements Parcelable {
compatFlags |= NEVER_NEEDS_COMPAT;
}
- if (overrideScale != 1.0f) {
+ int density = appInfo.getOverrideDensity();
+ if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) == 0) {
+ applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
+ applicationScale = DisplayMetrics.DENSITY_DEVICE
+ / (float) DisplayMetrics.DENSITY_DEFAULT;
+ applicationInvertedScale = 1.0f / applicationScale;
+ compatFlags |= SCALING_REQUIRED;
+ } else if((density != 0) || (overrideScale != 1.0f)) {
applicationScale = overrideScale;
applicationInvertedScale = 1.0f / overrideScale;
applicationDensity = (int) ((DisplayMetrics.DENSITY_DEVICE_STABLE
* applicationInvertedScale) + .5f);
compatFlags |= HAS_OVERRIDE_SCALING;
- } else if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
+ } else {
applicationDensity = DisplayMetrics.DENSITY_DEVICE;
applicationScale = 1.0f;
applicationInvertedScale = 1.0f;
- } else {
- applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
- applicationScale = DisplayMetrics.DENSITY_DEVICE
- / (float) DisplayMetrics.DENSITY_DEFAULT;
- applicationInvertedScale = 1.0f / applicationScale;
- compatFlags |= SCALING_REQUIRED;
}
}
mCompatibilityFlags = compatFlags;
+
+ Log.d(TAG, "mCompatibilityFlags - " + Integer.toHexString(mCompatibilityFlags));
+ Log.d(TAG, "applicationDensity - " + applicationDensity);
+ Log.d(TAG, "applicationScale - " + applicationScale);
}
private CompatibilityInfo(int compFlags,
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 3bdd39f5d7d7..0e6f46a79fe6 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -45,6 +45,7 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSIllegalArgumentException;
@@ -54,6 +55,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
+import android.os.SystemProperties;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback;
@@ -171,6 +173,10 @@ public class Camera {
private static final int CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x200;
private static final int CAMERA_MSG_PREVIEW_METADATA = 0x400;
private static final int CAMERA_MSG_FOCUS_MOVE = 0x800;
+ /* ### QC ADD-ONS: START */
+ private static final int CAMERA_MSG_STATS_DATA = 0x1000;
+ private static final int CAMERA_MSG_META_DATA = 0x2000;
+ /* ### QC ADD-ONS: END */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private long mNativeContext; // accessed by native methods
@@ -202,6 +208,17 @@ public class Camera {
private boolean mShutterSoundEnabledFromApp = true;
private static final int NO_ERROR = 0;
+ private static final int EACCESS = -13;
+ private static final int ENODEV = -19;
+ private static final int EBUSY = -16;
+ private static final int EINVAL = -22;
+ private static final int ENOSYS = -38;
+ private static final int EUSERS = -87;
+ private static final int EOPNOTSUPP = -95;
+ /* ### QC ADD-ONS: START */
+ private CameraDataCallback mCameraDataCallback;
+ private CameraMetaDataCallback mCameraMetaDataCallback;
+ /* ### QC ADD-ONS: END */
/**
* Broadcast Action: A new picture is taken by the camera, and the entry of
@@ -279,7 +296,35 @@ public class Camera {
* @return total number of accessible camera devices, or 0 if there are no
* cameras or an error was encountered enumerating them.
*/
- public native static int getNumberOfCameras();
+ public static int getNumberOfCameras() {
+ boolean exposeAuxCamera = false;
+ String packageName = ActivityThread.currentOpPackageName();
+ /* Force to expose only two cameras
+ * if the package name does not falls in this bucket
+ */
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist");
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ exposeAuxCamera = true;
+ break;
+ }
+ }
+ }
+ int numberOfCameras = _getNumberOfCameras();
+ if (exposeAuxCamera == false && (numberOfCameras > 2)) {
+ numberOfCameras = 2;
+ }
+ return numberOfCameras;
+ }
+
+ /**
+ * Returns the number of physical cameras available on this device.
+ */
+ /** @hide */
+ public native static int _getNumberOfCameras();
/**
* Returns the information about a particular camera.
@@ -290,6 +335,9 @@ public class Camera {
* low-level failure).
*/
public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) {
+ if(cameraId >= getNumberOfCameras()){
+ throw new RuntimeException("Unknown camera ID");
+ }
_getCameraInfo(cameraId, cameraInfo);
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
IAudioService audioService = IAudioService.Stub.asInterface(b);
@@ -323,6 +371,17 @@ public class Camera {
*/
public static final int CAMERA_FACING_FRONT = 1;
+ /* ### QC ADD-ONS: START TBD*/
+ /** @hide
+ * camera is in ZSL mode.
+ */
+ public static final int CAMERA_SUPPORT_MODE_ZSL = 2;
+
+ /** @hide
+ * camera is in non-ZSL mode.
+ */
+ public static final int CAMERA_SUPPORT_MODE_NONZSL = 3;
+ /* ### QC ADD-ONS: END */
/**
* The direction that the camera faces. It should be
* CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
@@ -474,6 +533,10 @@ public class Camera {
mPostviewCallback = null;
mUsingPreviewAllocation = false;
mZoomListener = null;
+ /* ### QC ADD-ONS: START */
+ mCameraDataCallback = null;
+ mCameraMetaDataCallback = null;
+ /* ### QC ADD-ONS: END */
Looper looper;
if ((looper = Looper.myLooper()) != null) {
@@ -490,6 +553,9 @@ public class Camera {
/** used by Camera#open, Camera#open(int) */
Camera(int cameraId) {
+ if(cameraId >= getNumberOfCameras()){
+ throw new RuntimeException("Unknown camera ID");
+ }
int err = cameraInit(cameraId);
if (checkInitErrors(err)) {
if (err == -EACCES) {
@@ -814,6 +880,7 @@ public class Camera {
* @see android.media.MediaActionSound
*/
public final void setPreviewCallback(PreviewCallback cb) {
+ android.util.SeempLog.record(66);
mPreviewCallback = cb;
mOneShot = false;
mWithBuffer = false;
@@ -842,6 +909,7 @@ public class Camera {
* @see android.media.MediaActionSound
*/
public final void setOneShotPreviewCallback(PreviewCallback cb) {
+ android.util.SeempLog.record(68);
mPreviewCallback = cb;
mOneShot = true;
mWithBuffer = false;
@@ -882,6 +950,7 @@ public class Camera {
* @see android.media.MediaActionSound
*/
public final void setPreviewCallbackWithBuffer(PreviewCallback cb) {
+ android.util.SeempLog.record(67);
mPreviewCallback = cb;
mOneShot = false;
mWithBuffer = true;
@@ -1213,7 +1282,23 @@ public class Camera {
mAutoFocusMoveCallback.onAutoFocusMoving(msg.arg1 == 0 ? false : true, mCamera);
}
return;
+ /* ### QC ADD-ONS: START */
+ case CAMERA_MSG_STATS_DATA:
+ int statsdata[] = new int[257];
+ for(int i =0; i<257; i++ ) {
+ statsdata[i] = byteToInt( (byte[])msg.obj, i*4);
+ }
+ if (mCameraDataCallback != null) {
+ mCameraDataCallback.onCameraData(statsdata, mCamera);
+ }
+ return;
+ case CAMERA_MSG_META_DATA:
+ if (mCameraMetaDataCallback != null) {
+ mCameraMetaDataCallback.onCameraMetaData((byte[])msg.obj, mCamera);
+ }
+ return;
+ /* ### QC ADD-ONS: END */
default:
Log.e(TAG, "Unknown message type " + msg.what);
return;
@@ -1447,6 +1532,7 @@ public class Camera {
*/
public final void takePicture(ShutterCallback shutter, PictureCallback raw,
PictureCallback jpeg) {
+ android.util.SeempLog.record(65);
takePicture(shutter, raw, null, jpeg);
}
private native final void native_takePicture(int msgType);
@@ -1485,6 +1571,7 @@ public class Camera {
*/
public final void takePicture(ShutterCallback shutter, PictureCallback raw,
PictureCallback postview, PictureCallback jpeg) {
+ android.util.SeempLog.record(65);
mShutterCallback = shutter;
mRawImageCallback = raw;
mPostviewCallback = postview;
@@ -1954,6 +2041,23 @@ public class Camera {
* as a set. Either they are all valid, or none of them are.
*/
public Point mouth = null;
+
+ /**
+ * {@hide}
+ */
+ public int smileDegree = 0;
+ /**
+ * {@hide}
+ */
+ public int smileScore = 0;
+ /**
+ * {@hide}
+ */
+ public int blinkDetected = 0;
+ /**
+ * {@hide}
+ */
+ public int faceRecognised = 0;
}
/**
@@ -2078,6 +2182,27 @@ public class Camera {
return p;
}
+ /** @hide
+ * Returns the current cct value of white balance.
+ *
+ * If it's in AWB mode, cct is determined by stats/awb module.
+ *
+ * If it's in Manual WB mode, it actually returns cct value
+ * set by user via {@link #setParameters(Camera.Parameters)}.
+ */
+ public int getWBCurrentCCT() {
+ Parameters p = new Parameters();
+ String s = native_getParameters();
+ p.unflatten(s);
+
+ int cct = 0;
+ if (p.getWBCurrentCCT() != null) {
+ cct = Integer.parseInt(p.getWBCurrentCCT());
+ }
+
+ return cct;
+ }
+
/**
* Returns an empty {@link Parameters} for testing purpose.
*
@@ -2091,6 +2216,157 @@ public class Camera {
return camera.new Parameters();
}
+ /* ### QC ADD-ONS: START */
+ private static int byteToInt(byte[] b, int offset) {
+ int value = 0;
+ for (int i = 0; i < 4; i++) {
+ int shift = (4 - 1 - i) * 8;
+ value += (b[(3-i) + offset] & 0x000000FF) << shift;
+ }
+ return value;
+ }
+ /** @hide
+ * Handles the callback for when Camera Data is available.
+ * data is read from the camera.
+ */
+ public interface CameraDataCallback {
+ /**
+ * Callback for when camera data is available.
+ *
+ * @param data a int array of the camera data
+ * @param camera the Camera service object
+ */
+ void onCameraData(int[] data, Camera camera);
+ };
+
+ /** @hide
+ * Set camera histogram mode and registers a callback function to run.
+ * Only valid after startPreview() has been called.
+ *
+ * @param cb the callback to run
+ */
+ public final void setHistogramMode(CameraDataCallback cb)
+ {
+ mCameraDataCallback = cb;
+ native_setHistogramMode(cb!=null);
+ }
+ private native final void native_setHistogramMode(boolean mode);
+
+ /** @hide
+ * Set camera histogram command to send data.
+ *
+ */
+ public final void sendHistogramData()
+ {
+ native_sendHistogramData();
+ }
+ private native final void native_sendHistogramData();
+
+ /** @hide
+ * Handles the callback for when Camera Meta Data is available.
+ * Meta data is read from the camera.
+ */
+ public interface CameraMetaDataCallback {
+ /**
+ * Callback for when camera meta data is available.
+ *
+ * @param data a byte array of the camera meta data
+ * @param camera the Camera service object
+ */
+ void onCameraMetaData(byte[] data, Camera camera);
+ };
+
+ /** @hide
+ * Set camera meta data and registers a callback function to run.
+ * Only valid after startPreview() has been called.
+ *
+ * @param cb the callback to run
+ */
+ public final void setMetadataCb(CameraMetaDataCallback cb)
+ {
+ mCameraMetaDataCallback = cb;
+ native_setMetadataCb(cb!=null);
+ }
+ private native final void native_setMetadataCb(boolean mode);
+
+ /** @hide
+ * Set camera face detection command to send meta data.
+ */
+ public final void sendMetaData()
+ {
+ native_sendMetaData();
+ }
+ private native final void native_sendMetaData();
+
+ /** @hide
+ * Configure longshot mode. Available only in ZSL.
+ *
+ * @param enable enable/disable this mode
+ */
+ public final void setLongshot(boolean enable)
+ {
+ native_setLongshot(enable);
+ }
+ private native final void native_setLongshot(boolean enable);
+
+ /** @hide
+ * Handles the Touch Co-ordinate.
+ */
+ public class Coordinate {
+ /**
+ * Sets the x,y co-ordinates for a touch event
+ *
+ * @param x the x co-ordinate (pixels)
+ * @param y the y co-ordinate (pixels)
+ */
+ public Coordinate(int x, int y) {
+ xCoordinate = x;
+ yCoordinate = y;
+ }
+ /**
+ * Compares {@code obj} to this co-ordinate.
+ *
+ * @param obj the object to compare this co-ordinate with.
+ * @return {@code true} if the xCoordinate and yCoordinate of {@code obj} is the
+ * same as those of this coordinate. {@code false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Coordinate)) {
+ return false;
+ }
+ Coordinate c = (Coordinate) obj;
+ return xCoordinate == c.xCoordinate && yCoordinate == c.yCoordinate;
+ }
+
+ /** x co-ordinate for the touch event*/
+ public int xCoordinate;
+
+ /** y co-ordinate for the touch event */
+ public int yCoordinate;
+ };
+
+ /** @hide
+ * Returns the current focus position.
+ *
+ * If it's in AF mode, it's the lens position after af is done.
+ *
+ * If it's in Manual Focus mode, it actually returns the value
+ * set by user via {@link #setParameters(Camera.Parameters)}.
+ */
+ public int getCurrentFocusPosition() {
+ Parameters p = new Parameters();
+ String s = native_getParameters();
+ p.unflatten(s);
+
+ int focus_pos = -1;
+ if (p.getCurrentFocusPosition() != null) {
+ focus_pos = Integer.parseInt(p.getCurrentFocusPosition());
+ }
+ return focus_pos;
+ }
+
+ /* ### QC ADD-ONS: END */
/**
* Returns a copied {@link Parameters}; for shim use only.
*
@@ -2352,6 +2628,10 @@ public class Camera {
public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight";
public static final String WHITE_BALANCE_TWILIGHT = "twilight";
public static final String WHITE_BALANCE_SHADE = "shade";
+ /** @hide
+ * wb manual cct mode.
+ */
+ public static final String WHITE_BALANCE_MANUAL_CCT = "manual-cct";
// Values for color effect settings.
public static final String EFFECT_NONE = "none";
@@ -2399,6 +2679,11 @@ public class Camera {
*/
public static final String FLASH_MODE_TORCH = "torch";
+ /** @hide
+ * Scene mode is off.
+ */
+ public static final String SCENE_MODE_ASD = "asd";
+
/**
* Scene mode is off.
*/
@@ -2475,6 +2760,14 @@ public class Camera {
* Capture the naturally warm color of scenes lit by candles.
*/
public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
+ /** @hide
+ * SCENE_MODE_BACKLIGHT
+ **/
+ public static final String SCENE_MODE_BACKLIGHT = "backlight";
+ /** @hide
+ * SCENE_MODE_FLOWERS
+ **/
+ public static final String SCENE_MODE_FLOWERS = "flowers";
/**
* Applications are looking for a barcode. Camera driver will be
@@ -2517,6 +2810,13 @@ public class Camera {
*/
public static final String FOCUS_MODE_FIXED = "fixed";
+ /** @hide
+ * Normal focus mode. Applications should call
+ * {@link #autoFocus(AutoFocusCallback)} to start the focus in this
+ * mode.
+ */
+ public static final String FOCUS_MODE_NORMAL = "normal";
+
/**
* Extended depth of field (EDOF). Focusing is done digitally and
* continuously. Applications should not call {@link
@@ -2569,6 +2869,11 @@ public class Camera {
*/
public static final String FOCUS_MODE_CONTINUOUS_PICTURE = "continuous-picture";
+ /** @hide
+ * manual focus mode
+ */
+ public static final String FOCUS_MODE_MANUAL_POSITION = "manual";
+
// Indices for focus distance array.
/**
* The array index of near focus distance for use with
@@ -2605,11 +2910,15 @@ public class Camera {
// Formats for setPreviewFormat and setPictureFormat.
private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
+ private static final String PIXEL_FORMAT_YUV420SP_ADRENO = "yuv420sp-adreno";
private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
private static final String PIXEL_FORMAT_YUV420P = "yuv420p";
private static final String PIXEL_FORMAT_RGB565 = "rgb565";
private static final String PIXEL_FORMAT_JPEG = "jpeg";
private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
+ private static final String PIXEL_FORMAT_RAW = "raw";
+ private static final String PIXEL_FORMAT_YV12 = "yv12";
+ private static final String PIXEL_FORMAT_NV12 = "nv12";
/**
* Order matters: Keys that are {@link #set(String, String) set} later
@@ -3429,8 +3738,11 @@ public class Camera {
* parameters.
*/
public void removeGpsData() {
+ remove(KEY_QC_GPS_LATITUDE_REF);
remove(KEY_GPS_LATITUDE);
+ remove(KEY_QC_GPS_LONGITUDE_REF);
remove(KEY_GPS_LONGITUDE);
+ remove(KEY_QC_GPS_ALTITUDE_REF);
remove(KEY_GPS_ALTITUDE);
remove(KEY_GPS_TIMESTAMP);
remove(KEY_GPS_PROCESSING_METHOD);
@@ -4454,5 +4766,1231 @@ public class Camera {
if (s1 != null && s1.equals(s2)) return true;
return false;
}
+ /* ### QC ADD-ONS: START */
+
+ /* ### QC ADDED PARAMETER KEYS*/
+ private static final String KEY_QC_HFR_SIZE = "hfr-size";
+ private static final String KEY_QC_PREVIEW_FRAME_RATE_MODE = "preview-frame-rate-mode";
+ private static final String KEY_QC_PREVIEW_FRAME_RATE_AUTO_MODE = "frame-rate-auto";
+ private static final String KEY_QC_PREVIEW_FRAME_RATE_FIXED_MODE = "frame-rate-fixed";
+ private static final String KEY_QC_GPS_LATITUDE_REF = "gps-latitude-ref";
+ private static final String KEY_QC_GPS_LONGITUDE_REF = "gps-longitude-ref";
+ private static final String KEY_QC_GPS_ALTITUDE_REF = "gps-altitude-ref";
+ private static final String KEY_QC_GPS_STATUS = "gps-status";
+ private static final String KEY_QC_EXIF_DATETIME = "exif-datetime";
+ private static final String KEY_QC_TOUCH_AF_AEC = "touch-af-aec";
+ private static final String KEY_QC_TOUCH_INDEX_AEC = "touch-index-aec";
+ private static final String KEY_QC_TOUCH_INDEX_AF = "touch-index-af";
+ private static final String KEY_QC_MANUAL_FOCUS_POSITION = "manual-focus-position";
+ private static final String KEY_QC_MANUAL_FOCUS_POS_TYPE = "manual-focus-pos-type";
+ private static final String KEY_QC_SCENE_DETECT = "scene-detect";
+ private static final String KEY_QC_ISO_MODE = "iso";
+ private static final String KEY_QC_EXPOSURE_TIME = "exposure-time";
+ private static final String KEY_QC_MIN_EXPOSURE_TIME = "min-exposure-time";
+ private static final String KEY_QC_MAX_EXPOSURE_TIME = "max-exposure-time";
+ private static final String KEY_QC_LENSSHADE = "lensshade";
+ private static final String KEY_QC_HISTOGRAM = "histogram";
+ private static final String KEY_QC_SKIN_TONE_ENHANCEMENT = "skinToneEnhancement";
+ private static final String KEY_QC_AUTO_EXPOSURE = "auto-exposure";
+ private static final String KEY_QC_SHARPNESS = "sharpness";
+ private static final String KEY_QC_MAX_SHARPNESS = "max-sharpness";
+ private static final String KEY_QC_CONTRAST = "contrast";
+ private static final String KEY_QC_MAX_CONTRAST = "max-contrast";
+ private static final String KEY_QC_SATURATION = "saturation";
+ private static final String KEY_QC_MAX_SATURATION = "max-saturation";
+ private static final String KEY_QC_DENOISE = "denoise";
+ private static final String KEY_QC_CONTINUOUS_AF = "continuous-af";
+ private static final String KEY_QC_SELECTABLE_ZONE_AF = "selectable-zone-af";
+ private static final String KEY_QC_FACE_DETECTION = "face-detection";
+ private static final String KEY_QC_MEMORY_COLOR_ENHANCEMENT = "mce";
+ private static final String KEY_QC_REDEYE_REDUCTION = "redeye-reduction";
+ private static final String KEY_QC_ZSL = "zsl";
+ private static final String KEY_QC_CAMERA_MODE = "camera-mode";
+ private static final String KEY_QC_VIDEO_HIGH_FRAME_RATE = "video-hfr";
+ private static final String KEY_QC_VIDEO_HDR = "video-hdr";
+ private static final String KEY_QC_POWER_MODE = "power-mode";
+ private static final String KEY_QC_POWER_MODE_SUPPORTED = "power-mode-supported";
+ private static final String KEY_QC_WB_MANUAL_CCT = "wb-manual-cct";
+ private static final String KEY_QC_MIN_WB_CCT = "min-wb-cct";
+ private static final String KEY_QC_MAX_WB_CCT = "max-wb-cct";
+ private static final String KEY_QC_AUTO_HDR_ENABLE = "auto-hdr-enable";
+ private static final String KEY_QC_VIDEO_ROTATION = "video-rotation";
+
+ /** @hide
+ * KEY_QC_AE_BRACKET_HDR
+ **/
+ public static final String KEY_QC_AE_BRACKET_HDR = "ae-bracket-hdr";
+
+ /* ### QC ADDED PARAMETER VALUES*/
+
+ // Values for touch af/aec settings.
+ /** @hide
+ * TOUCH_AF_AEC_OFF
+ **/
+ public static final String TOUCH_AF_AEC_OFF = "touch-off";
+ /** @hide
+ * TOUCH_AF_AEC_ON
+ **/
+ public static final String TOUCH_AF_AEC_ON = "touch-on";
+
+ // Values for auto exposure settings.
+ /** @hide
+ * Auto exposure frame-avg
+ **/
+ public static final String AUTO_EXPOSURE_FRAME_AVG = "frame-average";
+ /** @hide
+ * Auto exposure center weighted
+ **/
+ public static final String AUTO_EXPOSURE_CENTER_WEIGHTED = "center-weighted";
+ /** @hide
+ * Auto exposure spot metering
+ **/
+ public static final String AUTO_EXPOSURE_SPOT_METERING = "spot-metering";
+
+ //Values for ISO settings
+ /** @hide
+ * ISO_AUTO
+ **/
+ public static final String ISO_AUTO = "auto";
+ /** @hide
+ * ISO_HJR
+ **/
+ public static final String ISO_HJR = "ISO_HJR";
+ /** @hide
+ * ISO_100
+ **/
+ public static final String ISO_100 = "ISO100";
+ /** @hide
+ * ISO_200
+ **/
+ public static final String ISO_200 = "ISO200";
+ /** @hide
+ * ISO_400
+ **/
+ public static final String ISO_400 = "ISO400";
+ /** @hide
+ * ISO_800
+ **/
+ public static final String ISO_800 = "ISO800";
+ /** @hide
+ * ISO_1600
+ **/
+ public static final String ISO_1600 = "ISO1600";
+
+ /** @hide
+ * ISO_3200
+ **/
+ public static final String ISO_3200 = "ISO3200";
+
+ //Values for Lens Shading
+ /** @hide
+ * LENSSHADE_ENABLE
+ **/
+ public static final String LENSSHADE_ENABLE = "enable";
+ /** @hide
+ * LENSSHADE_DISABLE
+ **/
+ public static final String LENSSHADE_DISABLE= "disable";
+
+ //Values for Histogram
+ /** @hide
+ * Histogram enable
+ **/
+ public static final String HISTOGRAM_ENABLE = "enable";
+ /** @hide
+ * Histogram disable
+ **/
+ public static final String HISTOGRAM_DISABLE= "disable";
+
+ //Values for Skin Tone Enhancement
+ /** @hide
+ * SKIN_TONE_ENHANCEMENT_ENABLE
+ **/
+ public static final String SKIN_TONE_ENHANCEMENT_ENABLE = "enable";
+ /** @hide
+ * SKIN_TONE_ENHANCEMENT_DISABLE
+ **/
+ public static final String SKIN_TONE_ENHANCEMENT_DISABLE= "disable";
+
+ // Values for MCE settings.
+ /** @hide
+ * MCE_ENaBLE
+ **/
+ public static final String MCE_ENABLE = "enable";
+ /** @hide
+ * MCE_DISABLE
+ **/
+ public static final String MCE_DISABLE = "disable";
+
+ // Values for ZSL settings.
+ /** @hide
+ * ZSL_ON
+ **/
+ public static final String ZSL_ON = "on";
+ /** @hide
+ * ZSL_OFF
+ **/
+ public static final String ZSL_OFF = "off";
+
+ // Values for HDR Bracketing settings.
+
+ /** @hide
+ * AEC bracketing off
+ **/
+ public static final String AE_BRACKET_HDR_OFF = "Off";
+ /** @hide
+ * AEC bracketing hdr
+ **/
+ public static final String AE_BRACKET_HDR = "HDR";
+ /** @hide
+ * AEC bracketing aec-bracket
+ **/
+ public static final String AE_BRACKET = "AE-Bracket";
+
+ // Values for Power mode.
+ /** @hide
+ * LOW_POWER
+ **/
+ public static final String LOW_POWER = "Low_Power";
+ /** @hide
+ * NORMAL_POWER
+ **/
+ public static final String NORMAL_POWER = "Normal_Power";
+
+ // Values for HFR settings.
+ /** @hide
+ * VIDEO_HFR_OFF
+ **/
+ public static final String VIDEO_HFR_OFF = "off";
+ /** @hide
+ * VIDEO_HFR_2X
+ **/
+ public static final String VIDEO_HFR_2X = "60";
+ /** @hide
+ * VIDEO_HFR_3X
+ **/
+ public static final String VIDEO_HFR_3X = "90";
+ /** @hide
+ * VIDEO_HFR_4X
+ **/
+ public static final String VIDEO_HFR_4X = "120";
+
+ // Values for auto scene detection settings.
+ /** @hide
+ * SCENE_DETECT_OFF
+ **/
+ public static final String SCENE_DETECT_OFF = "off";
+ /** @hide
+ * SCENE_DETECT_ON
+ **/
+ public static final String SCENE_DETECT_ON = "on";
+
+ //Values for Continuous AF
+
+ /** @hide
+ * CAF off
+ **/
+ public static final String CONTINUOUS_AF_OFF = "caf-off";
+ /** @hide
+ * CAF on
+ **/
+ public static final String CONTINUOUS_AF_ON = "caf-on";
+ /** @hide
+ * Denoise off
+ **/
+ public static final String DENOISE_OFF = "denoise-off";
+ /** @hide
+ * Denoise on
+ **/
+ public static final String DENOISE_ON = "denoise-on";
+
+ // Values for Redeye Reduction settings.
+ /** @hide
+ * REDEYE_REDUCTION_ENABLE
+ **/
+ public static final String REDEYE_REDUCTION_ENABLE = "enable";
+ /** @hide
+ * REDEYE_REDUCTION_DISABLE
+ **/
+ public static final String REDEYE_REDUCTION_DISABLE = "disable";
+
+ // Values for selectable zone af settings.
+ /** @hide
+ * SELECTABLE_ZONE_AF_AUTO
+ **/
+ public static final String SELECTABLE_ZONE_AF_AUTO = "auto";
+ /** @hide
+ * SELECTABLE_ZONE_AF_SPOTMETERING
+ **/
+ public static final String SELECTABLE_ZONE_AF_SPOTMETERING = "spot-metering";
+ /** @hide
+ * SELECTABLE_ZONE_AF_CENTER_WEIGHTED
+ **/
+ public static final String SELECTABLE_ZONE_AF_CENTER_WEIGHTED = "center-weighted";
+ /** @hide
+ * SELECTABLE_ZONE_AF_FRAME_AVERAGE
+ **/
+ public static final String SELECTABLE_ZONE_AF_FRAME_AVERAGE = "frame-average";
+
+ // Values for Face Detection settings.
+ /** @hide
+ * Face Detection off
+ **/
+ public static final String FACE_DETECTION_OFF = "off";
+ /** @hide
+ * Face Detction on
+ **/
+ public static final String FACE_DETECTION_ON = "on";
+
+ // Values for video rotation settings.
+
+ /** @hide
+ * VIDEO_ROTATION_0
+ **/
+ public static final String VIDEO_ROTATION_0 = "0";
+ /** @hide
+ * VIDEO_ROTATION_90
+ **/
+ public static final String VIDEO_ROTATION_90 = "90";
+ /** @hide
+ * VIDEO_ROTATION_180
+ **/
+ public static final String VIDEO_ROTATION_180 = "180";
+ /** @hide
+ * VIDEO_ROTATION_270
+ **/
+ public static final String VIDEO_ROTATION_270 = "270";
+
+ /* ### QC ADDED PARAMETER APIS*/
+ /** @hide
+ * Gets the supported preview sizes in high frame rate recording mode.
+ *
+ * @return a list of Size object. This method will always return a list
+ * with at least one element.
+ */
+ public List<Size> getSupportedHfrSizes() {
+ String str = get(KEY_QC_HFR_SIZE + SUPPORTED_VALUES_SUFFIX);
+ return splitSize(str);
+ }
+
+ /** @hide
+ * Gets the supported Touch AF/AEC setting.
+ *
+ * @return a List of TOUCH_AF_AEC_XXX string constants. null if TOUCH AF/AEC
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedTouchAfAec() {
+ String str = get(KEY_QC_TOUCH_AF_AEC + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /**
+ * Gets the supported Touch AF/AEC setting.
+ *
+ * @return a List of TOUCH_AF_AEC_XXX string constants. null if TOUCH AF/AEC
+ * setting is not supported.
+ *
+ */
+
+ /** @hide
+ * Gets the supported frame rate modes.
+ *
+ * @return a List of FRAME_RATE_XXX_MODE string constant. null if this
+ * setting is not supported.
+ */
+ public List<String> getSupportedPreviewFrameRateModes() {
+ String str = get(KEY_QC_PREVIEW_FRAME_RATE_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported auto scene detection modes.
+ *
+ * @return a List of SCENE_DETECT_XXX string constant. null if scene detection
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedSceneDetectModes() {
+ String str = get(KEY_QC_SCENE_DETECT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported ISO values.
+ *
+ * @return a List of FLASH_MODE_XXX string constants. null if flash mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedIsoValues() {
+ String str = get(KEY_QC_ISO_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Lensshade modes.
+ *
+ * @return a List of LENS_MODE_XXX string constants. null if lens mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedLensShadeModes() {
+ String str = get(KEY_QC_LENSSHADE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Histogram modes.
+ *
+ * @return a List of HISTOGRAM_XXX string constants. null if histogram mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedHistogramModes() {
+ String str = get(KEY_QC_HISTOGRAM + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Skin Tone Enhancement modes.
+ *
+ * @return a List of SKIN_TONE_ENHANCEMENT_XXX string constants. null if skin tone enhancement
+ * setting is not supported.
+ */
+ public List<String> getSupportedSkinToneEnhancementModes() {
+ String str = get(KEY_QC_SKIN_TONE_ENHANCEMENT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported auto exposure setting.
+ *
+ * @return a List of AUTO_EXPOSURE_XXX string constants. null if auto exposure
+ * setting is not supported.
+ */
+ public List<String> getSupportedAutoexposure() {
+ String str = get(KEY_QC_AUTO_EXPOSURE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported MCE modes.
+ *
+ * @return a List of MCE_ENABLE/DISABLE string constants. null if MCE mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedMemColorEnhanceModes() {
+ String str = get(KEY_QC_MEMORY_COLOR_ENHANCEMENT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported ZSL modes.
+ *
+ * @return a List of ZSL_OFF/OFF string constants. null if ZSL mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedZSLModes() {
+ String str = get(KEY_QC_ZSL + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Video HDR modes.
+ *
+ * @return a List of Video HDR_OFF/OFF string constants. null if
+ * Video HDR mode setting is not supported.
+ */
+ public List<String> getSupportedVideoHDRModes() {
+ String str = get(KEY_QC_VIDEO_HDR + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported HFR modes.
+ *
+ * @return a List of VIDEO_HFR_XXX string constants. null if hfr mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedVideoHighFrameRateModes() {
+ String str = get(KEY_QC_VIDEO_HIGH_FRAME_RATE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Continuous AF modes.
+ *
+ * @return a List of CONTINUOUS_AF_XXX string constant. null if continuous AF
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedContinuousAfModes() {
+ String str = get(KEY_QC_CONTINUOUS_AF + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported DENOISE modes.
+ *
+ * @return a List of DENOISE_XXX string constant. null if DENOISE
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedDenoiseModes() {
+ String str = get(KEY_QC_DENOISE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported selectable zone af setting.
+ *
+ * @return a List of SELECTABLE_ZONE_AF_XXX string constants. null if selectable zone af
+ * setting is not supported.
+ */
+ public List<String> getSupportedSelectableZoneAf() {
+ String str = get(KEY_QC_SELECTABLE_ZONE_AF + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported face detection modes.
+ *
+ * @return a List of FACE_DETECTION_XXX string constant. null if face detection
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedFaceDetectionModes() {
+ String str = get(KEY_QC_FACE_DETECTION + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported redeye reduction modes.
+ *
+ * @return a List of REDEYE_REDUCTION_XXX string constant. null if redeye reduction
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedRedeyeReductionModes() {
+ String str = get(KEY_QC_REDEYE_REDUCTION + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Sets GPS altitude reference. This will be stored in JPEG EXIF header.
+ * @param altRef reference GPS altitude in meters.
+ */
+ public void setGpsAltitudeRef(double altRef) {
+ set(KEY_QC_GPS_ALTITUDE_REF, Double.toString(altRef));
+ }
+
+ /** @hide
+ * Sets GPS Status. This will be stored in JPEG EXIF header.
+ *
+ * @param status GPS status (UTC in seconds since January 1,
+ * 1970).
+ */
+ public void setGpsStatus(double status) {
+ set(KEY_QC_GPS_STATUS, Double.toString(status));
+ }
+
+ /** @hide
+ * Sets the touch co-ordinate for Touch AEC.
+ *
+ * @param x the x co-ordinate of the touch event
+ * @param y the y co-ordinate of the touch event
+ *
+ */
+ public void setTouchIndexAec(int x, int y) {
+ String v = Integer.toString(x) + "x" + Integer.toString(y);
+ set(KEY_QC_TOUCH_INDEX_AEC, v);
+ }
+
+ /** @hide
+ * Returns the touch co-ordinates of the touch event.
+ *
+ * @return a Index object with the x and y co-ordinated
+ * for the touch event
+ *
+ */
+ public Coordinate getTouchIndexAec() {
+ String pair = get(KEY_QC_TOUCH_INDEX_AEC);
+ return strToCoordinate(pair);
+ }
+
+ /** @hide
+ * Sets the touch co-ordinate for Touch AF.
+ *
+ * @param x the x co-ordinate of the touch event
+ * @param y the y co-ordinate of the touch event
+ *
+ */
+ public void setTouchIndexAf(int x, int y) {
+ String v = Integer.toString(x) + "x" + Integer.toString(y);
+ set(KEY_QC_TOUCH_INDEX_AF, v);
+ }
+
+ /** @hide
+ * Returns the touch co-ordinates of the touch event.
+ *
+ * @return a Index object with the x and y co-ordinated
+ * for the touch event
+ *
+ */
+ public Coordinate getTouchIndexAf() {
+ String pair = get(KEY_QC_TOUCH_INDEX_AF);
+ return strToCoordinate(pair);
+ }
+ /** @hide
+ * Set Sharpness Level
+ *
+ * @param sharpness level
+ */
+ public void setSharpness(int sharpness){
+ if((sharpness < 0) || (sharpness > getMaxSharpness()) )
+ throw new IllegalArgumentException(
+ "Invalid Sharpness " + sharpness);
+
+ set(KEY_QC_SHARPNESS, String.valueOf(sharpness));
+ }
+
+ /** @hide
+ * Set Contrast Level
+ *
+ * @param contrast level
+ */
+ public void setContrast(int contrast){
+ if((contrast < 0 ) || (contrast > getMaxContrast()))
+ throw new IllegalArgumentException(
+ "Invalid Contrast " + contrast);
+
+ set(KEY_QC_CONTRAST, String.valueOf(contrast));
+ }
+
+ /** @hide
+ * Set Saturation Level
+ *
+ * @param saturation level
+ */
+ public void setSaturation(int saturation){
+ if((saturation < 0 ) || (saturation > getMaxSaturation()))
+ throw new IllegalArgumentException(
+ "Invalid Saturation " + saturation);
+
+ set(KEY_QC_SATURATION, String.valueOf(saturation));
+ }
+
+ /** @hide
+ * @return true if full size video snapshot is supported.
+ */
+ public boolean isPowerModeSupported() {
+ String str = get(KEY_QC_POWER_MODE_SUPPORTED);
+ return TRUE.equals(str);
+ }
+
+ /** @hide
+ * Get Sharpness level
+ *
+ * @return sharpness level
+ */
+ public int getSharpness(){
+ return getInt(KEY_QC_SHARPNESS);
+ }
+
+ /** @hide
+ * Get Max Sharpness Level
+ *
+ * @return max sharpness level
+ */
+ public int getMaxSharpness(){
+ return getInt(KEY_QC_MAX_SHARPNESS);
+ }
+
+ /** @hide
+ * Get Contrast level
+ *
+ * @return contrast level
+ */
+ public int getContrast(){
+ return getInt(KEY_QC_CONTRAST);
+ }
+
+ /** @hide
+ * Get Max Contrast Level
+ *
+ * @return max contrast level
+ */
+ public int getMaxContrast(){
+ return getInt(KEY_QC_MAX_CONTRAST);
+ }
+
+ /** @hide
+ * Get Saturation level
+ *
+ * @return saturation level
+ */
+ public int getSaturation(){
+ return getInt(KEY_QC_SATURATION);
+ }
+
+ /** @hide
+ * Get Max Saturation Level
+ *
+ * @return max contrast level
+ */
+ public int getMaxSaturation(){
+ return getInt(KEY_QC_MAX_SATURATION);
+ }
+
+ /** @hide
+ * Sets GPS latitude reference coordinate. This will be stored in JPEG EXIF
+ * header.
+ * @param latRef GPS latitude reference coordinate.
+ */
+ public void setGpsLatitudeRef(String latRef) {
+ set(KEY_QC_GPS_LATITUDE_REF, latRef);
+ }
+
+ /** @hide
+ * Sets GPS longitude reference coordinate. This will be stored in JPEG EXIF
+ * header.
+ * @param lonRef GPS longitude reference coordinate.
+ */
+ public void setGpsLongitudeRef(String lonRef) {
+ set(KEY_QC_GPS_LONGITUDE_REF, lonRef);
+ }
+
+ /** @hide
+ * Sets system timestamp. This will be stored in JPEG EXIF header.
+ *
+ * @param dateTime current timestamp (UTC in seconds since January 1,
+ * 1970).
+ */
+ public void setExifDateTime(String dateTime) {
+ set(KEY_QC_EXIF_DATETIME, dateTime);
+ }
+
+ /** @hide
+ * Gets the current Touch AF/AEC setting.
+ *
+ * @return one of TOUCH_AF_AEC_XXX string constant. null if Touch AF/AEC
+ * setting is not supported.
+ *
+ */
+ public String getTouchAfAec() {
+ return get(KEY_QC_TOUCH_AF_AEC);
+ }
+
+ /** @hide
+ * Sets the current TOUCH AF/AEC setting.
+ *
+ * @param value TOUCH_AF_AEC_XXX string constants.
+ *
+ */
+ public void setTouchAfAec(String value) {
+ set(KEY_QC_TOUCH_AF_AEC, value);
+ }
+
+ /** @hide
+ * Gets the current redeye reduction setting.
+ *
+ * @return one of REDEYE_REDUCTION_XXX string constant. null if redeye reduction
+ * setting is not supported.
+ *
+ */
+ public String getRedeyeReductionMode() {
+ return get(KEY_QC_REDEYE_REDUCTION);
+ }
+
+ /** @hide
+ * Sets the redeye reduction. Other parameters may be changed after changing
+ * redeye reduction. After setting redeye reduction,
+ * applications should call getParameters to know if some parameters are
+ * changed.
+ *
+ * @param value REDEYE_REDUCTION_XXX string constants.
+ *
+ */
+ public void setRedeyeReductionMode(String value) {
+ set(KEY_QC_REDEYE_REDUCTION, value);
+ }
+
+ /** @hide
+ * Gets the frame rate mode setting.
+ *
+ * @return one of FRAME_RATE_XXX_MODE string constant. null if this
+ * setting is not supported.
+ */
+ public String getPreviewFrameRateMode() {
+ return get(KEY_QC_PREVIEW_FRAME_RATE_MODE);
+ }
+
+ /** @hide
+ * Sets the frame rate mode.
+ *
+ * @param value FRAME_RATE_XXX_MODE string constants.
+ */
+ public void setPreviewFrameRateMode(String value) {
+ set(KEY_QC_PREVIEW_FRAME_RATE_MODE, value);
+ }
+
+ /** @hide
+ * Gets the current auto scene detection setting.
+ *
+ * @return one of SCENE_DETECT_XXX string constant. null if auto scene detection
+ * setting is not supported.
+ *
+ */
+ public String getSceneDetectMode() {
+ return get(KEY_QC_SCENE_DETECT);
+ }
+
+ /** @hide
+ * Sets the auto scene detect. Other parameters may be changed after changing
+ * scene detect. After setting auto scene detection,
+ * applications should call getParameters to know if some parameters are
+ * changed.
+ *
+ * @param value SCENE_DETECT_XXX string constants.
+ *
+ */
+ public void setSceneDetectMode(String value) {
+ set(KEY_QC_SCENE_DETECT, value);
+ }
+
+ /** @hide
+ * Gets the current hdr bracketing mode setting.
+ *
+ * @return current hdr bracketing mode.
+ * @see #KEY_AE_BRACKET_OFF
+ * @see #KEY_AE_BRACKET_HDR
+ * @see #KEY_AE_BRACKET_BRACKATING
+ */
+ public String getAEBracket() {
+ return get(KEY_QC_AE_BRACKET_HDR);
+ }
+
+ /** @hide
+ * Sets the Power mode.
+ *
+ * @param value Power mode.
+ * @see #getPowerMode()
+ */
+ public void setPowerMode(String value) {
+ set(KEY_QC_POWER_MODE, value);
+ }
+
+ /** @hide
+ * Gets the current power mode setting.
+ *
+ * @return current power mode. null if power mode setting is not
+ * supported.
+ * @see #POWER_MODE_LOW
+ * @see #POWER_MODE_NORMAL
+ */
+ public String getPowerMode() {
+ return get(KEY_QC_POWER_MODE);
+ }
+
+ /** @hide
+ * Set HDR-Bracketing Level
+ *
+ * @param value HDR-Bracketing
+ */
+ public void setAEBracket(String value){
+ set(KEY_QC_AE_BRACKET_HDR, value);
+ }
+
+ /** @hide
+ * Gets the current ISO setting.
+ *
+ * @return one of ISO_XXX string constant. null if ISO
+ * setting is not supported.
+ */
+ public String getISOValue() {
+ return get(KEY_QC_ISO_MODE);
+ }
+
+ /** @hide
+ * Sets the ISO.
+ *
+ * @param iso ISO_XXX string constant.
+ */
+ public void setISOValue(String iso) {
+ set(KEY_QC_ISO_MODE, iso);
+ }
+
+ /** @hide
+ * Sets the exposure time.
+ *
+ * @param value exposure time.
+ */
+ public void setExposureTime(int value) {
+ set(KEY_QC_EXPOSURE_TIME, Integer.toString(value));
+ }
+
+ /** @hide
+ * Gets the current exposure time.
+ *
+ * @return exposure time.
+ */
+ public String getExposureTime() {
+ return get(KEY_QC_EXPOSURE_TIME);
+ }
+
+ /** @hide
+ * Gets the min supported exposure time.
+ *
+ * @return min supported exposure time.
+ */
+ public String getMinExposureTime() {
+ return get(KEY_QC_MIN_EXPOSURE_TIME);
+ }
+
+ /** @hide
+ * Gets the max supported exposure time.
+ *
+ * @return max supported exposure time.
+ */
+ public String getMaxExposureTime() {
+ return get(KEY_QC_MAX_EXPOSURE_TIME);
+ }
+
+ /** @hide
+ * Gets the current LensShade Mode.
+ *
+ * @return LensShade Mode
+ */
+ public String getLensShade() {
+ return get(KEY_QC_LENSSHADE);
+ }
+
+ /** @hide
+ * Sets the current LensShade Mode.
+ *
+ * @return LensShade Mode
+ */
+ public void setLensShade(String lensshade) {
+ set(KEY_QC_LENSSHADE, lensshade);
+ }
+
+ /** @hide
+ * Gets the current auto exposure setting.
+ *
+ * @return one of AUTO_EXPOSURE_XXX string constant. null if auto exposure
+ * setting is not supported.
+ */
+ public String getAutoExposure() {
+ return get(KEY_QC_AUTO_EXPOSURE);
+ }
+
+ /** @hide
+ * Sets the current auto exposure setting.
+ *
+ * @param value AUTO_EXPOSURE_XXX string constants.
+ */
+ public void setAutoExposure(String value) {
+ set(KEY_QC_AUTO_EXPOSURE, value);
+ }
+
+ /** @hide
+ * Gets the current MCE Mode.
+ *
+ * @return MCE value
+ */
+ public String getMemColorEnhance() {
+ return get(KEY_QC_MEMORY_COLOR_ENHANCEMENT);
+ }
+
+ /** @hide
+ * Sets the current MCE Mode.
+ *
+ * @return MCE Mode
+ */
+ public void setMemColorEnhance(String mce) {
+ set(KEY_QC_MEMORY_COLOR_ENHANCEMENT, mce);
+ }
+
+ /** @hide
+ * Set white balance manual cct value.
+ *
+ * @param cct user CCT setting.
+ */
+ public void setWBManualCCT(int cct) {
+ set(KEY_QC_WB_MANUAL_CCT, Integer.toString(cct));
+ }
+
+ /** @hide
+ * Gets the WB min supported CCT.
+ *
+ * @return min cct value.
+ */
+ public String getWBMinCCT() {
+ return get(KEY_QC_MIN_WB_CCT);
+ }
+
+ /** @hide
+ * Gets the WB max supported CCT.
+ *
+ * @return max cct value.
+ */
+ public String getMaxWBCCT() {
+ return get(KEY_QC_MAX_WB_CCT);
+ }
+
+ /** @hide
+ * Gets the current WB CCT.
+ *
+ * @return CCT value
+ */
+ public String getWBCurrentCCT() {
+ return get(KEY_QC_WB_MANUAL_CCT);
+ }
+
+ /** @hide
+ * Gets the current ZSL Mode.
+ *
+ * @return ZSL mode value
+ */
+ public String getZSLMode() {
+ return get(KEY_QC_ZSL);
+ }
+
+ /** @hide
+ * Sets the current ZSL Mode. ZSL mode is set as a 0th bit in KEY_CAMERA_MODE.
+ *
+ * @return null
+ */
+ public void setZSLMode(String zsl) {
+ set(KEY_QC_ZSL, zsl);
+ }
+
+ /** @hide
+ * Sets the current Auto HDR Mode.
+ * @ auto_hdr auto hdr string for enable/disable
+ * @return null
+ */
+ public void setAutoHDRMode(String auto_hdr){
+ set(KEY_QC_AUTO_HDR_ENABLE,auto_hdr);
+ }
+
+ /** @hide
+ * Gets the current Camera Mode Flag. Camera mode includes a
+ * flag(byte) which indicates different camera modes.
+ * For now support for ZSL added at bit0
+ *
+ * @return Camera Mode.
+ */
+ public String getCameraMode() {
+ return get(KEY_QC_CAMERA_MODE);
+ }
+
+ /** @hide
+ * Sets the current Camera Mode.
+ *
+ * @return null
+ */
+ public void setCameraMode(int cameraMode) {
+ set(KEY_QC_CAMERA_MODE, cameraMode);
+ }
+
+ private static final int MANUAL_FOCUS_POS_TYPE_INDEX = 0;
+ private static final int MANUAL_FOCUS_POS_TYPE_DAC = 1;
+ /** @hide
+ * Set focus position.
+ *
+ * @param pos user setting of focus position.
+ */
+ public void setFocusPosition(int type, int pos) {
+ set(KEY_QC_MANUAL_FOCUS_POS_TYPE, Integer.toString(type));
+ set(KEY_QC_MANUAL_FOCUS_POSITION, Integer.toString(pos));
+ }
+
+ /** @hide
+ * Gets the current focus position.
+ *
+ * @return current focus position
+ */
+ public String getCurrentFocusPosition() {
+ return get(KEY_QC_MANUAL_FOCUS_POSITION);
+ }
+
+
+ /** @hide
+ * Gets the current HFR Mode.
+ *
+ * @return VIDEO_HFR_XXX string constants
+ */
+ public String getVideoHighFrameRate() {
+ return get(KEY_QC_VIDEO_HIGH_FRAME_RATE);
+ }
+
+ /** @hide
+ * Sets the current HFR Mode.
+ *
+ * @param hfr VIDEO_HFR_XXX string constants
+ */
+ public void setVideoHighFrameRate(String hfr) {
+ set(KEY_QC_VIDEO_HIGH_FRAME_RATE, hfr);
+ }
+
+ /** @hide
+ * Gets the current Video HDR Mode.
+ *
+ * @return Video HDR mode value
+ */
+ public String getVideoHDRMode() {
+ return get(KEY_QC_VIDEO_HDR);
+ }
+
+ /** @hide
+ * Sets the current Video HDR Mode.
+ *
+ * @return null
+ */
+ public void setVideoHDRMode(String videohdr) {
+ set(KEY_QC_VIDEO_HDR, videohdr);
+ }
+
+ /** @hide
+ * Gets the current DENOISE setting.
+ *
+ * @return one of DENOISE_XXX string constant. null if Denoise
+ * setting is not supported.
+ *
+ */
+ public String getDenoise() {
+ return get(KEY_QC_DENOISE);
+ }
+
+ /** @hide
+ * Gets the current Continuous AF setting.
+ *
+ * @return one of CONTINUOUS_AF_XXX string constant. null if continuous AF
+ * setting is not supported.
+ *
+ */
+ public String getContinuousAf() {
+ return get(KEY_QC_CONTINUOUS_AF);
+ }
+
+ /** @hide
+ * Sets the current Denoise mode.
+ * @param value DENOISE_XXX string constants.
+ *
+ */
+
+ public void setDenoise(String value) {
+ set(KEY_QC_DENOISE, value);
+ }
+
+ /** @hide
+ * Sets the current Continuous AF mode.
+ * @param value CONTINUOUS_AF_XXX string constants.
+ *
+ */
+ public void setContinuousAf(String value) {
+ set(KEY_QC_CONTINUOUS_AF, value);
+ }
+
+ /** @hide
+ * Gets the current selectable zone af setting.
+ *
+ * @return one of SELECTABLE_ZONE_AF_XXX string constant. null if selectable zone af
+ * setting is not supported.
+ */
+ public String getSelectableZoneAf() {
+ return get(KEY_QC_SELECTABLE_ZONE_AF);
+ }
+
+ /** @hide
+ * Sets the current selectable zone af setting.
+ *
+ * @param value SELECTABLE_ZONE_AF_XXX string constants.
+ */
+ public void setSelectableZoneAf(String value) {
+ set(KEY_QC_SELECTABLE_ZONE_AF, value);
+ }
+
+ /** @hide
+ * Gets the current face detection setting.
+ *
+ * @return one of FACE_DETECTION_XXX string constant. null if face detection
+ * setting is not supported.
+ *
+ */
+ public String getFaceDetectionMode() {
+ return get(KEY_QC_FACE_DETECTION);
+ }
+
+ /** @hide
+ * Sets the auto scene detect. Other settings like Touch AF/AEC might be
+ * changed after setting face detection.
+ *
+ * @param value FACE_DETECTION_XXX string constants.
+ *
+ */
+ public void setFaceDetectionMode(String value) {
+ set(KEY_QC_FACE_DETECTION, value);
+ }
+
+ /** @hide
+ * Gets the current video rotation setting.
+ *
+ * @return one of VIDEO_QC_ROTATION_XXX string constant. null if video rotation
+ * setting is not supported.
+ */
+ public String getVideoRotation() {
+ return get(KEY_QC_VIDEO_ROTATION);
+ }
+
+ /** @hide
+ * Sets the current video rotation setting.
+ *
+ * @param value VIDEO_QC_ROTATION_XXX string constants.
+ */
+ public void setVideoRotation(String value) {
+ set(KEY_QC_VIDEO_ROTATION, value);
+ }
+ /** @hide
+ * Gets the supported video rotation modes.
+ *
+ * @return a List of VIDEO_QC_ROTATION_XXX string constant. null if this
+ * setting is not supported.
+ */
+ public List<String> getSupportedVideoRotationValues() {
+ String str = get(KEY_QC_VIDEO_ROTATION + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ // Splits a comma delimited string to an ArrayList of Coordinate.
+ // Return null if the passing string is null or the Coordinate is 0.
+ private ArrayList<Coordinate> splitCoordinate(String str) {
+ if (str == null) return null;
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
+ ArrayList<Coordinate> coordinateList = new ArrayList<Coordinate>();
+ for (String s : splitter) {
+ Coordinate coordinate = strToCoordinate(s);
+ if (coordinate != null) coordinateList.add(coordinate);
+ }
+ if (coordinateList.size() == 0) return null;
+ return coordinateList;
+ }
+
+ // Parses a string (ex: "500x500") to Coordinate object.
+ // Return null if the passing string is null.
+ private Coordinate strToCoordinate(String str) {
+ if (str == null) return null;
+
+ int pos = str.indexOf('x');
+ if (pos != -1) {
+ String x = str.substring(0, pos);
+ String y = str.substring(pos + 1);
+ return new Coordinate(Integer.parseInt(x),
+ Integer.parseInt(y));
+ }
+ Log.e(TAG, "Invalid Coordinate parameter string=" + str);
+ return null;
+ }
+ /* ### QC ADD-ONS: END */
};
}
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index fe8dc46aff4d..0ae131a45537 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -174,6 +174,7 @@ public class SystemSensorManager extends SensorManager {
@Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
+ android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
if (listener == null || sensor == null) {
Log.e(TAG, "sensor or listener is null");
return false;
@@ -221,6 +222,7 @@ public class SystemSensorManager extends SensorManager {
/** @hide */
@Override
protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
+ android.util.SeempLog.record_sensor(382, sensor);
// Trigger Sensors should use the cancelTriggerSensor call.
if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
return;
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 3c1ec3e629a9..564c13ecdc8a 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -244,6 +244,10 @@ public abstract class CameraDevice implements AutoCloseable {
@NonNull CameraCaptureSession.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException;
+ /** @hide */
+ public abstract void setVendorStreamConfigMode(int index)
+ throws CameraAccessException;
+
/**
* <p>Create a new camera capture session by providing the target output set of Surfaces and
* its corresponding surface configuration to the camera device.</p>
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index b7c5644df107..0fca32196518 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -23,6 +23,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.ActivityThread;
import android.content.Context;
import android.hardware.CameraStatus;
import android.hardware.ICameraService;
@@ -47,6 +48,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -1520,8 +1523,22 @@ public final class CameraManager {
private String[] extractCameraIdListLocked() {
String[] cameraIds = null;
+ boolean exposeAuxCamera = false;
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist");
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ exposeAuxCamera = true;
+ break;
+ }
+ }
+ }
int idCount = 0;
for (int i = 0; i < mDeviceStatus.size(); i++) {
+ if(!exposeAuxCamera && (i == 2)) break;
int status = mDeviceStatus.valueAt(i);
if (status == ICameraServiceListener.STATUS_NOT_PRESENT
|| status == ICameraServiceListener.STATUS_ENUMERATING) continue;
@@ -1530,6 +1547,7 @@ public final class CameraManager {
cameraIds = new String[idCount];
idCount = 0;
for (int i = 0; i < mDeviceStatus.size(); i++) {
+ if(!exposeAuxCamera && (i == 2)) break;
int status = mDeviceStatus.valueAt(i);
if (status == ICameraServiceListener.STATUS_NOT_PRESENT
|| status == ICameraServiceListener.STATUS_ENUMERATING) continue;
@@ -1790,6 +1808,26 @@ public final class CameraManager {
throw new IllegalArgumentException("cameraId was null");
}
+ /* Force to expose only two cameras
+ * if the package name does not falls in this bucket
+ */
+ boolean exposeAuxCamera = false;
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist");
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ exposeAuxCamera = true;
+ break;
+ }
+ }
+ }
+ if (exposeAuxCamera == false && (Integer.parseInt(cameraId) >= 2)) {
+ throw new IllegalArgumentException("invalid cameraId");
+ }
+
ICameraService cameraService = getCameraService();
if (cameraService == null) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
@@ -1988,6 +2026,30 @@ public final class CameraManager {
}
private void onStatusChangedLocked(int status, String id) {
+ /* Force to ignore the last mono/aux camera status update
+ * if the package name does not falls in this bucket
+ */
+ boolean exposeMonoCamera = false;
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist");
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ exposeMonoCamera = true;
+ break;
+ }
+ }
+ }
+
+ if (exposeMonoCamera == false) {
+ if (Integer.parseInt(id) >= 2) {
+ Log.w(TAG, "[soar.cts] ignore the status update of camera: " + id);
+ return;
+ }
+ }
+
if (DEBUG) {
Log.v(TAG,
String.format("Camera id %s has status changed to 0x%x", id, status));
@@ -2119,6 +2181,31 @@ public final class CameraManager {
String.format("Camera id %s has torch status changed to 0x%x", id, status));
}
+ /* Force to ignore the aux or composite camera torch status update
+ * if the package name does not falls in this bucket
+ */
+ boolean exposeMonoCamera = false;
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist");
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ exposeMonoCamera = true;
+ break;
+ }
+ }
+ }
+
+ if (exposeMonoCamera == false) {
+ if (Integer.parseInt(id) >= 2) {
+ Log.w(TAG, "ignore the torch status update of camera: " + id);
+ return;
+ }
+ }
+
+
if (!validTorchStatus(status)) {
Log.e(TAG, String.format("Ignoring invalid device %s torch status 0x%x", id,
status));
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 9a9163c724ff..b2f118bce794 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -222,7 +222,8 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
} else if (request.isReprocess() && !isReprocessable()) {
throw new IllegalArgumentException("this capture session cannot handle reprocess " +
"requests");
- } else if (request.isReprocess() && request.getReprocessableSessionId() != mId) {
+ } else if (!mDeviceImpl.isPrivilegedApp() &&
+ request.isReprocess() && request.getReprocessableSessionId() != mId) {
throw new IllegalArgumentException("capture request was created for another session");
}
}
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index 2920e670f15b..9ac415b465ba 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -26,10 +26,12 @@ import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallbac
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.params.HighSpeedVideoConfiguration;
import android.hardware.camera2.utils.SurfaceUtils;
import android.os.Handler;
import android.os.ConditionVariable;
import android.util.Range;
+import android.util.Size;
import android.view.Surface;
import java.util.ArrayList;
@@ -95,10 +97,7 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl
StreamConfigurationMap config = mCharacteristics.get(ck);
SurfaceUtils.checkConstrainedHighSpeedSurfaces(outputSurfaces, fpsRange, config);
- // Request list size: to limit the preview to 30fps, need use maxFps/30; to maximize
- // the preview frame rate, should use maxBatch size for that high speed stream
- // configuration. We choose the former for now.
- int requestListSize = fpsRange.getUpper() / 30;
+ int requestListSize = getHighSpeedRequestListSize(fpsRange, outputSurfaces);
List<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
// Prepare the Request builders: need carry over the request controls.
@@ -177,6 +176,34 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl
return true;
}
+ private int getHighSpeedRequestListSize(Range<Integer> fpsRange, Collection<Surface> surfaces) {
+ int requestListSize = 0;
+
+ for (Surface surface : surfaces) {
+
+ if (SurfaceUtils.isSurfaceForHwVideoEncoder(surface)) {
+ Size surfaceSize = SurfaceUtils.getSurfaceSize(surface);
+ HighSpeedVideoConfiguration[] highSpeedVideoConfigurations =
+ mCharacteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
+
+ // Get the batchsize for matching FPS & video size
+ for (HighSpeedVideoConfiguration config : highSpeedVideoConfigurations) {
+ if (config.getSize().equals(surfaceSize) && config.getFpsRange().equals(fpsRange)) {
+ requestListSize = config.getBatchSizeMax();
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (requestListSize == 0) {
+ // If cant' find the matching batch size, limit the preview to 30fps.
+ requestListSize = fpsRange.getUpper() / 30;
+ }
+ return requestListSize;
+ }
+
@Override
public CameraDevice getDevice() {
return mSessionImpl.getDevice();
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 9b19fc4d3ef2..cabb14122e00 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -16,12 +16,15 @@
package android.hardware.camera2.impl;
+import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
import android.annotation.NonNull;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.ICameraService;
+import android.app.ActivityThread;
+import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -53,6 +56,8 @@ import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Range;
import android.util.Size;
@@ -84,7 +89,7 @@ public class CameraDeviceImpl extends CameraDevice
private final boolean DEBUG = false;
private static final int REQUEST_ID_NONE = -1;
-
+ private int customOpMode = 0;
// TODO: guard every function with if (!mRemoteDevice) check (if it was closed)
private ICameraDeviceUserWrapper mRemoteDevice;
@@ -151,6 +156,7 @@ public class CameraDeviceImpl extends CameraDevice
private int mNextSessionId = 0;
private final int mAppTargetSdkVersion;
+ private boolean mIsPrivilegedApp = false;
private ExecutorService mOfflineSwitchService;
private CameraOfflineSessionImpl mOfflineSessionImpl;
@@ -301,6 +307,7 @@ public class CameraDeviceImpl extends CameraDevice
} else {
mTotalPartialCount = partialCount;
}
+ mIsPrivilegedApp = checkPrivilegedAppList();
}
public CameraDeviceCallbacks getCallbacks() {
@@ -389,6 +396,10 @@ public class CameraDeviceImpl extends CameraDevice
}
}
+ public void setVendorStreamConfigMode(int fpsrange) {
+ customOpMode = fpsrange;
+ }
+
@Override
public String getId() {
return mCameraId;
@@ -507,6 +518,7 @@ public class CameraDeviceImpl extends CameraDevice
mConfiguredOutputs.put(streamId, outConfig);
}
}
+ operatingMode = (operatingMode | (customOpMode << 16));
int offlineStreamIds[];
if (sessionParams != null) {
@@ -1503,6 +1515,27 @@ public class CameraDeviceImpl extends CameraDevice
return false;
}
+ private boolean checkPrivilegedAppList() {
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("persist.vendor.camera.privapp.list");
+
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isPrivilegedApp() {
+ return mIsPrivilegedApp;
+ }
+
private void checkInputConfiguration(InputConfiguration inputConfig) {
if (inputConfig == null) {
return;
@@ -1540,6 +1573,14 @@ public class CameraDeviceImpl extends CameraDevice
inputConfig.getWidth() + "x" + inputConfig.getHeight() + " is not valid");
}
} else {
+ /*
+ * don't check input format and size,
+ * if the package name is in the white list
+ */
+ if (isPrivilegedApp()) {
+ Log.w(TAG, "ignore input format/size check for white listed app");
+ return;
+ }
if (!checkInputConfigurationWithStreamConfigurations(inputConfig, /*maxRes*/false) &&
!checkInputConfigurationWithStreamConfigurations(inputConfig, /*maxRes*/true)) {
throw new IllegalArgumentException("Input config with format " +
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index fd1a33161740..d2d33c2de63e 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -34,6 +34,11 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import android.app.ActivityThread;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+
+
/**
* Various Surface utilities.
*/
@@ -78,8 +83,8 @@ public class SurfaceUtils {
public static boolean isSurfaceForHwVideoEncoder(Surface surface) {
checkNotNull(surface);
long usageFlags = nativeDetectSurfaceUsageFlags(surface);
- long disallowedFlags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE | USAGE_HW_COMPOSER
- | USAGE_RENDERSCRIPT | HardwareBuffer.USAGE_CPU_READ_OFTEN;
+ long disallowedFlags = USAGE_HW_COMPOSER | USAGE_RENDERSCRIPT |
+ HardwareBuffer.USAGE_CPU_READ_OFTEN;
long allowedFlags = HardwareBuffer.USAGE_VIDEO_ENCODE;
boolean videoEncoderConsumer = ((usageFlags & disallowedFlags) == 0
&& (usageFlags & allowedFlags) != 0);
@@ -241,7 +246,13 @@ public class SurfaceUtils {
+ " the size must be 1 or 2");
}
+ if (isPrivilegedApp()) {
+ //skip checks for privileged apps
+ return;
+ }
+
List<Size> highSpeedSizes = null;
+
if (fpsRange == null) {
highSpeedSizes = Arrays.asList(config.getHighSpeedVideoSizes());
} else {
@@ -303,4 +314,21 @@ public class SurfaceUtils {
/*out*/int[/*2*/] dimens);
private static native long nativeGetSurfaceId(Surface surface);
+
+ private static boolean isPrivilegedApp() {
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("persist.camera.privapp.list");
+
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 288b06ee52c8..6630463002cb 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -930,6 +930,7 @@ public final class NetworkStats implements Parcelable {
entry.operations += operations[i];
}
}
+
return entry;
}
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index f41306301d42..865503502325 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -256,6 +256,34 @@ public class NetworkStatsHistory implements Parcelable {
}
/**
+ * Safely multiple a value by a rational.
+ * <p>
+ * Internally it uses integer-based math whenever possible, but switches
+ * over to double-based math if values would overflow.
+ */
+ public static long multiplySafe(long value, long num, long den) {
+ if (den == 0) den = 1;
+ long x = value;
+ long y = num;
+
+ // Logic shamelessly borrowed from Math.multiplyExact()
+ long r = x * y;
+ long ax = Math.abs(x);
+ long ay = Math.abs(y);
+ if (((ax | ay) >>> 31 != 0)) {
+ // Some bits greater than 2^31 that might cause overflow
+ // Check the result using the divide operator
+ // and check for the special case of Long.MIN_VALUE * -1
+ if (((y != 0) && (r / y != x)) ||
+ (x == Long.MIN_VALUE && y == -1)) {
+ // Use double math to avoid overflowing
+ return (long) (((double) num / den) * value);
+ }
+ }
+ return r / den;
+ }
+
+ /**
* Return index of bucket that contains or is immediately before the
* requested time.
*/
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index cb9a3e43db81..37ba09b381ea 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,6 +35,7 @@ import android.nfc.INfcUnlockHandler;
import android.nfc.ITagRemovedCallback;
import android.nfc.INfcDta;
import android.os.Bundle;
+import android.os.IBinder;
/**
* @hide
@@ -43,6 +47,8 @@ interface INfcAdapter
INfcFCardEmulation getNfcFCardEmulationInterface();
INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
INfcDta getNfcDtaInterface(in String pkg);
+ IBinder getNfcAdapterVendorInterface(in String vendor);
+
int getState();
boolean disable(boolean saveState);
boolean enable();
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index 2436e57b74bc..d4c966be04b8 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,7 +42,7 @@ import java.util.List;
*
* @hide
*/
-public final class AidGroup implements Parcelable {
+public class AidGroup implements Parcelable {
/**
* The maximum number of AIDs that can be present in any one group.
*/
@@ -48,11 +51,11 @@ public final class AidGroup implements Parcelable {
static final String TAG = "AidGroup";
@UnsupportedAppUsage
- final List<String> aids;
+ protected List<String> aids;
@UnsupportedAppUsage
- final String category;
+ protected String category;
@UnsupportedAppUsage
- final String description;
+ protected String description;
/**
* Creates a new AidGroup object.
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 0af322e885b1..3de6f43bc7ea 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -49,24 +52,24 @@ import java.util.Map;
/**
* @hide
*/
-public final class ApduServiceInfo implements Parcelable {
+public class ApduServiceInfo implements Parcelable {
static final String TAG = "ApduServiceInfo";
/**
* The service that implements this
*/
@UnsupportedAppUsage
- final ResolveInfo mService;
+ protected ResolveInfo mService;
/**
* Description of the service
*/
- final String mDescription;
+ protected String mDescription;
/**
* Whether this service represents AIDs running on the host CPU
*/
- final boolean mOnHost;
+ protected boolean mOnHost;
/**
* Offhost reader name.
@@ -84,18 +87,18 @@ public final class ApduServiceInfo implements Parcelable {
* Mapping from category to static AID group
*/
@UnsupportedAppUsage
- final HashMap<String, AidGroup> mStaticAidGroups;
+ protected HashMap<String, AidGroup> mStaticAidGroups;
/**
* Mapping from category to dynamic AID group
*/
@UnsupportedAppUsage
- final HashMap<String, AidGroup> mDynamicAidGroups;
+ protected HashMap<String, AidGroup> mDynamicAidGroups;
/**
* Whether this service should only be started when the device is unlocked.
*/
- final boolean mRequiresDeviceUnlock;
+ protected boolean mRequiresDeviceUnlock;
/**
* Whether this service should only be started when the device is screen on.
@@ -105,17 +108,17 @@ public final class ApduServiceInfo implements Parcelable {
/**
* The id of the service banner specified in XML.
*/
- final int mBannerResourceId;
+ protected int mBannerResourceId;
/**
* The uid of the package the service belongs to
*/
- final int mUid;
+ protected int mUid;
/**
* Settings Activity for this service
*/
- final String mSettingsActivityName;
+ protected String mSettingsActivityName;
/**
* @hide
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 080e058737b6..9cae043c4bdd 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2018 NXP Semiconductors
+ * The original Work has been changed by NXP Semiconductors.
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -173,6 +175,10 @@ public final class MifareClassic extends BasicTagTechnology {
mType = TYPE_CLASSIC;
mSize = SIZE_4K;
break;
+ case 0x19:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_2K;
+ break;
case 0x28:
mType = TYPE_CLASSIC;
mSize = SIZE_1K;
diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java
index 88730f9af3df..819e9e31b6e6 100644
--- a/core/java/android/nfc/tech/NfcA.java
+++ b/core/java/android/nfc/tech/NfcA.java
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2018 NXP Semiconductors
+ * The original Work has been changed by NXP Semiconductors.
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,8 +68,15 @@ public final class NfcA extends BasicTagTechnology {
/** @hide */
public NfcA(Tag tag) throws RemoteException {
super(tag, TagTechnology.NFC_A);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_A);
- mSak = extras.getShort(EXTRA_SAK);
+ Bundle extras;
+ mSak = 0;
+ if(tag.hasTech(TagTechnology.MIFARE_CLASSIC))
+ {
+ extras = tag.getTechExtras(TagTechnology.MIFARE_CLASSIC);
+ mSak = extras.getShort(EXTRA_SAK);
+ }
+ extras = tag.getTechExtras(TagTechnology.NFC_A);
+ mSak |= extras.getShort(EXTRA_SAK);
mAtqa = extras.getByteArray(EXTRA_ATQA);
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 9f37c4877199..1945a54128b6 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -964,6 +964,31 @@ public class Process {
throws IllegalArgumentException, SecurityException;
/**
+ * Sets the scheduling group for processes in the same cgroup.procs of uid and pid
+ * @hide
+ * @param uid The user identifier of the process to change.
+ * @param pid The identifier of the process to change.
+ * @param group The target group for this process from THREAD_GROUP_*.
+ * @param dex2oat_only is the cgroup apply for all or for dex2oat only.
+ *
+ * @throws IllegalArgumentException Throws IllegalArgumentException if
+ * <var>tid</var> does not exist.
+ * @throws SecurityException Throws SecurityException if your process does
+ * not have permission to modify the given thread, or to use the given
+ * priority.
+ *
+ * group == THREAD_GROUP_DEFAULT means to move all non-background priority
+ * threads to the foreground scheduling group, but to leave background
+ * priority threads alone. group == THREAD_GROUP_BG_NONINTERACTIVE moves all
+ * threads, regardless of priority, to the background scheduling group.
+ * group == THREAD_GROUP_FOREGROUND is not allowed.
+ *
+ * Always sets cpusets.
+ */
+ public static final native void setCgroupProcsProcessGroup(int uid, int pid, int group, boolean dex2oat_only)
+ throws IllegalArgumentException, SecurityException;
+
+ /**
* Freeze or unfreeze the specified process.
*
* @param pid Identifier of the process to freeze or unfreeze.
diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java
index d32928cbeb38..b751e821c78d 100644
--- a/core/java/android/os/storage/DiskInfo.java
+++ b/core/java/android/os/storage/DiskInfo.java
@@ -50,6 +50,8 @@ public class DiskInfo implements Parcelable {
public static final int FLAG_DEFAULT_PRIMARY = 1 << 1;
public static final int FLAG_SD = 1 << 2;
public static final int FLAG_USB = 1 << 3;
+ public static final int FLAG_EMMC = 1 << 4;
+ public static final int FLAG_UFS_CARD = 1 << 5;
/** The FLAG_STUB_VISIBLE is set from vold, which gets the flag from outside (e.g., ChromeOS) */
public static final int FLAG_STUB_VISIBLE = 1 << 6;
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index afa7b80f58a0..472c0fb110f9 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -242,6 +242,7 @@ public class Browser {
*/
public static final Cursor getAllBookmarks(ContentResolver cr) throws
IllegalStateException {
+ android.util.SeempLog.record(32);
return new MatrixCursor(new String[]{Bookmarks.URL}, 0);
}
@@ -254,6 +255,7 @@ public class Browser {
*/
public static final Cursor getAllVisitedUrls(ContentResolver cr) throws
IllegalStateException {
+ android.util.SeempLog.record(33);
return new MatrixCursor(new String[]{Combined.URL}, 0);
}
@@ -262,6 +264,7 @@ public class Browser {
}
private static final Cursor getVisitedLike(ContentResolver cr, String url) {
+ android.util.SeempLog.record(34);
boolean secure = false;
String compareString = url;
if (compareString.startsWith("http://")) {
@@ -323,6 +326,7 @@ public class Browser {
@Deprecated
@UnsupportedAppUsage
public static final String[] getVisitedHistory(ContentResolver cr) {
+ android.util.SeempLog.record(35);
return new String[0];
}
@@ -358,6 +362,7 @@ public class Browser {
* @removed
*/
public static final void clearHistory(ContentResolver cr) {
+ android.util.SeempLog.record(37);
}
@@ -419,6 +424,7 @@ public class Browser {
*/
public static final void requestAllIcons(ContentResolver cr, String where,
WebIconDatabase.IconListener listener) {
+ android.util.SeempLog.record(36);
// Do nothing: this is no longer used.
}
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 92a18836653a..1b1e30c71374 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -984,6 +984,7 @@ public final class CalendarContract {
* @return A Cursor containing all attendees for the event
*/
public static final Cursor query(ContentResolver cr, long eventId, String[] projection) {
+ android.util.SeempLog.record(54);
String[] attArgs = {Long.toString(eventId)};
return cr.query(CONTENT_URI, projection, ATTENDEES_WHERE, attArgs /* selection args */,
null /* sort order */);
@@ -1916,6 +1917,7 @@ public final class CalendarContract {
*/
public static final Cursor query(ContentResolver cr, String[] projection,
long begin, long end) {
+ android.util.SeempLog.record(54);
Uri.Builder builder = CONTENT_URI.buildUpon();
ContentUris.appendId(builder, begin);
ContentUris.appendId(builder, end);
@@ -1945,6 +1947,7 @@ public final class CalendarContract {
*/
public static final Cursor query(ContentResolver cr, String[] projection,
long begin, long end, String searchQuery) {
+ android.util.SeempLog.record(54);
Uri.Builder builder = CONTENT_SEARCH_URI.buildUpon();
ContentUris.appendId(builder, begin);
ContentUris.appendId(builder, end);
@@ -2255,6 +2258,7 @@ public final class CalendarContract {
*/
public static final Cursor query(ContentResolver cr, int startDay, int numDays,
String[] projection) {
+ android.util.SeempLog.record(54);
if (numDays < 1) {
return null;
}
@@ -2338,6 +2342,7 @@ public final class CalendarContract {
* @return A Cursor containing all reminders for the event
*/
public static final Cursor query(ContentResolver cr, long eventId, String[] projection) {
+ android.util.SeempLog.record(54);
String[] remArgs = {Long.toString(eventId)};
return cr.query(CONTENT_URI, projection, REMINDERS_WHERE, remArgs /*selection args*/,
null /* sort order */);
@@ -2488,6 +2493,7 @@ public final class CalendarContract {
*/
public static final Uri insert(ContentResolver cr, long eventId,
long begin, long end, long alarmTime, int minutes) {
+ android.util.SeempLog.record(51);
ContentValues values = new ContentValues();
values.put(CalendarAlerts.EVENT_ID, eventId);
values.put(CalendarAlerts.BEGIN, begin);
@@ -2516,6 +2522,7 @@ public final class CalendarContract {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final long findNextAlarmTime(ContentResolver cr, long millis) {
+ android.util.SeempLog.record(53);
String selection = ALARM_TIME + ">=" + millis;
// TODO: construct an explicit SQL query so that we can add
// "LIMIT 1" to the end and get just one result.
@@ -2647,6 +2654,7 @@ public final class CalendarContract {
*/
public static final boolean alarmExists(ContentResolver cr, long eventId,
long begin, long alarmTime) {
+ android.util.SeempLog.record(52);
// TODO: construct an explicit SQL query so that we can add
// "LIMIT 1" to the end and get just one result.
String[] projection = new String[] { ALARM_TIME };
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 376d9421e8d3..87bb32ce8afa 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1638,6 +1638,7 @@ public final class ContactsContract {
* {@link #CONTENT_LOOKUP_URI} to attempt refreshing.
*/
public static Uri getLookupUri(ContentResolver resolver, Uri contactUri) {
+ android.util.SeempLog.record(86);
final Cursor c = resolver.query(contactUri, new String[] {
Contacts.LOOKUP_KEY, Contacts._ID
}, null, null, null);
@@ -1665,6 +1666,7 @@ public final class ContactsContract {
* provided parameters.
*/
public static Uri getLookupUri(long contactId, String lookupKey) {
+ android.util.SeempLog.record(86);
if (TextUtils.isEmpty(lookupKey)) {
return null;
}
@@ -1678,6 +1680,7 @@ public final class ContactsContract {
* Returns null if the contact cannot be found.
*/
public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) {
+ android.util.SeempLog.record(87);
if (lookupUri == null) {
return null;
}
@@ -2170,6 +2173,7 @@ public final class ContactsContract {
*/
public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri,
boolean preferHighres) {
+ android.util.SeempLog.record(88);
if (preferHighres) {
final Uri displayPhotoUri = Uri.withAppendedPath(contactUri,
Contacts.Photo.DISPLAY_PHOTO);
@@ -2218,6 +2222,7 @@ public final class ContactsContract {
* of the thumbnail the high-res picture is preferred
*/
public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri) {
+ android.util.SeempLog.record(88);
return openContactPhotoInputStream(cr, contactUri, false);
}
@@ -2920,6 +2925,7 @@ public final class ContactsContract {
* entry of the given {@link RawContacts} entry.
*/
public static Uri getContactLookupUri(ContentResolver resolver, Uri rawContactUri) {
+ android.util.SeempLog.record(89);
// TODO: use a lighter query by joining rawcontacts with contacts in provider
final Uri dataUri = Uri.withAppendedPath(rawContactUri, Data.CONTENT_DIRECTORY);
final Cursor cursor = resolver.query(dataUri, new String[] {
@@ -4978,6 +4984,7 @@ public final class ContactsContract {
* </p>
*/
public static Uri getContactLookupUri(ContentResolver resolver, Uri dataUri) {
+ android.util.SeempLog.record(89);
final Cursor cursor = resolver.query(dataUri, new String[] {
RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY
}, null, null, null);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 54952fc2dc39..042445b5011f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3504,6 +3504,7 @@ public final class Settings {
@UnsupportedAppUsage
public static String getStringForUser(ContentResolver resolver, String name,
int userHandle) {
+ android.util.SeempLog.record(android.util.SeempLog.getSeempGetApiIdFromValue(name));
if (MOVED_TO_SECURE.contains(name)) {
Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System"
+ " to android.provider.Settings.Secure, returning read-only value.");
@@ -3559,6 +3560,7 @@ public final class Settings {
private static boolean putStringForUser(ContentResolver resolver, String name, String value,
int userHandle, boolean overrideableByRestore) {
+ android.util.SeempLog.record(android.util.SeempLog.getSeempPutApiIdFromValue(name));
if (MOVED_TO_SECURE.contains(name)) {
Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System"
+ " to android.provider.Settings.Secure, value is unchanged.");
@@ -4290,6 +4292,13 @@ public final class Settings {
"display_color_mode_vendor_hint";
/**
+ * Whether to play tone while outgoing call is accepted.
+ * The value 1 - vibrate, 0 - not
+ * @hide
+ */
+ public static final String CALL_CONNECTED_TONE_ENABLED = "call_connected_tone_enabled";
+
+ /**
* The user selected min refresh rate in frames per second.
*
* If this isn't set, 0 will be used.
@@ -5326,6 +5335,7 @@ public final class Settings {
PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT);
PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE);
PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE_VENDOR_HINT);
+ PRIVATE_SETTINGS.add(CALL_CONNECTED_TONE_ENABLED);
}
/**
@@ -5731,6 +5741,7 @@ public final class Settings {
MOVED_TO_GLOBAL.add(Settings.Global.NITZ_UPDATE_SPACING);
MOVED_TO_GLOBAL.add(Settings.Global.NTP_SERVER);
MOVED_TO_GLOBAL.add(Settings.Global.NTP_TIMEOUT);
+ MOVED_TO_GLOBAL.add(Settings.Global.NTP_SERVER_2);
MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_ERROR_POLL_COUNT);
MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS);
MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT);
@@ -11233,6 +11244,15 @@ public final class Settings {
public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
/**
+ * Whether to allow modem to intelligently switch DDS without user direction
+ *
+ * (0 = disabled, 1 = enabled)
+ * @hide
+ */
+ @Readable
+ public static final String SMART_DDS_SWITCH = "smart_dds_switch";
+
+ /**
* Whether the wifi data connection should remain active even when higher
* priority networks like Ethernet are active, to keep both networks.
* In the case where higher priority networks are connected, wifi will be
@@ -11385,12 +11405,15 @@ public final class Settings {
@Readable
public static final String NITZ_UPDATE_SPACING = "nitz_update_spacing";
- /** Preferred NTP server. {@hide} */
- @Readable
- public static final String NTP_SERVER = "ntp_server";
- /** Timeout in milliseconds to wait for NTP server. {@hide} */
- @Readable
- public static final String NTP_TIMEOUT = "ntp_timeout";
+ /** Preferred NTP server. {@hide} */
+ @Readable
+ public static final String NTP_SERVER = "ntp_server";
+ /** Timeout in milliseconds to wait for NTP server. {@hide} */
+ @Readable
+ public static final String NTP_TIMEOUT = "ntp_timeout";
+ /** Secondary NTP server. {@hide} */
+ @Readable
+ public static final String NTP_SERVER_2 = "ntp_server_2";
/** {@hide} */
@Readable
@@ -15703,6 +15726,14 @@ public final class Settings {
public static final String CELL_ON = "cell_on";
/**
+ * Whether to vibrate while outgoing call is accepted
+ * The value 1 - vibrate, 0 - not
+ * @hide
+ */
+ public static final String VIBRATING_FOR_OUTGOING_CALL_ACCEPTED =
+ "vibrating_for_outgoing_call_accepted";
+
+ /**
* Global settings which can be accessed by instant apps.
* @hide
*/
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 9f3a847e12eb..3baecf0acc7f 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -282,6 +282,13 @@ public final class Telephony {
* <p>Type: TEXT</p>
*/
public static final String CREATOR = "creator";
+
+ /**
+ * The priority of the message.
+ * <P>Type: INTEGER</P>
+ * @hide
+ */
+ public static final String PRIORITY = "priority";
}
/**
@@ -390,6 +397,7 @@ public final class Telephony {
* @hide
*/
public static Cursor query(ContentResolver cr, String[] projection) {
+ android.util.SeempLog.record(10);
return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
}
@@ -400,6 +408,7 @@ public final class Telephony {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static Cursor query(ContentResolver cr, String[] projection,
String where, String orderBy) {
+ android.util.SeempLog.record(10);
return cr.query(CONTENT_URI, projection, where,
null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
}
@@ -503,6 +512,31 @@ public final class Telephony {
public static Uri addMessageToUri(int subId, ContentResolver resolver,
Uri uri, String address, String body, String subject,
Long date, boolean read, boolean deliveryReport, long threadId) {
+ return addMessageToUri(subId, resolver, uri, address, body, subject,
+ date, read, deliveryReport, threadId, -1);
+ }
+
+ /**
+ * Add an SMS to the given URI with thread_id specified.
+ *
+ * @param resolver the content resolver to use
+ * @param uri the URI to add the message to
+ * @param address the address of the sender
+ * @param body the body of the message
+ * @param subject the psuedo-subject of the message
+ * @param date the timestamp for the message
+ * @param read true if the message has been read, false if not
+ * @param deliveryReport true if a delivery report was requested, false if not
+ * @param threadId the thread_id of the message
+ * @param subId the subscription which the message belongs to
+ * @param priority the priority of the message
+ * @return the URI for the new message
+ * @hide
+ */
+ public static Uri addMessageToUri(int subId, ContentResolver resolver,
+ Uri uri, String address, String body, String subject,
+ Long date, boolean read, boolean deliveryReport,
+ long threadId, int priority) {
ContentValues values = new ContentValues(8);
Rlog.v(TAG,"Telephony addMessageToUri sub id: " + subId);
@@ -514,6 +548,7 @@ public final class Telephony {
values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
values.put(SUBJECT, subject);
values.put(BODY, body);
+ values.put(PRIORITY, priority);
if (deliveryReport) {
values.put(STATUS, STATUS_PENDING);
}
@@ -2127,6 +2162,20 @@ public final class Telephony {
* <P>Type: INTEGER (boolean)</P>
*/
public static final String ARCHIVED = "archived";
+
+ /**
+ * Indicates the last mms type in the thread.
+ * <P>Type: TEXT</P>
+ * @hide
+ */
+ public static final String ATTACHMENT_INFO = "attachment_info";
+
+ /**
+ * Indicates whether this thread is a notification thread.
+ * <P>Type: INTEGER</P>
+ * @hide
+ */
+ public static final String NOTIFICATION = "notification";
}
/**
@@ -2927,6 +2976,7 @@ public final class Telephony {
*/
public static Cursor query(
ContentResolver cr, String[] projection) {
+ android.util.SeempLog.record(10);
return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
}
@@ -2937,6 +2987,7 @@ public final class Telephony {
public static Cursor query(
ContentResolver cr, String[] projection,
String where, String orderBy) {
+ android.util.SeempLog.record(10);
return cr.query(CONTENT_URI, projection,
where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index b68717a9b457..8a2b15de6757 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -2250,7 +2250,7 @@ public abstract class WallpaperService extends Service {
return;
}
case MSG_UPDATE_SURFACE:
- mEngine.updateSurface(true, false, false);
+ mEngine.updateSurface(true, false, true/*false*/);
break;
case MSG_ZOOM:
mEngine.setZoom(Float.intBitsToFloat(message.arg1));
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index 3cdd8b8d8436..b907596427d8 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -401,6 +401,7 @@ public class SpeechRecognizer {
*/
@MainThread
public void startListening(final Intent recognizerIntent) {
+ android.util.SeempLog.record(72);
if (recognizerIntent == null) {
throw new IllegalArgumentException("intent must not be null");
}
diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java
new file mode 100644
index 000000000000..ee29434f55ca
--- /dev/null
+++ b/core/java/android/util/BoostFramework.java
@@ -0,0 +1,790 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package android.util;
+
+import android.content.Context;
+import android.graphics.BLASTBufferQueue;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import dalvik.system.PathClassLoader;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/** @hide */
+public class BoostFramework {
+
+ private static final String TAG = "BoostFramework";
+ private static final String PERFORMANCE_JAR = "/system/framework/QPerformance.jar";
+ private static final String PERFORMANCE_CLASS = "com.qualcomm.qti.Performance";
+
+ private static final String UXPERFORMANCE_JAR = "/system/framework/UxPerformance.jar";
+ private static final String UXPERFORMANCE_CLASS = "com.qualcomm.qti.UxPerformance";
+ public static final float PERF_HAL_V22 = 2.2f;
+ public static final float PERF_HAL_V23 = 2.3f;
+
+/** @hide */
+ private static boolean sIsLoaded = false;
+ private static Class<?> sPerfClass = null;
+ private static Method sAcquireFunc = null;
+ private static Method sPerfHintFunc = null;
+ private static Method sReleaseFunc = null;
+ private static Method sReleaseHandlerFunc = null;
+ private static Method sFeedbackFunc = null;
+ private static Method sFeedbackFuncExtn = null;
+ private static Method sPerfGetPropFunc = null;
+ private static Method sAcqAndReleaseFunc = null;
+ private static Method sperfHintAcqRelFunc = null;
+ private static Method sperfHintRenewFunc = null;
+ private static Method sPerfEventFunc = null;
+ private static Method sPerfGetPerfHalVerFunc = null;
+
+ private static Method sIOPStart = null;
+ private static Method sIOPStop = null;
+ private static Method sUXEngineEvents = null;
+ private static Method sUXEngineTrigger = null;
+
+ private static boolean sUxIsLoaded = false;
+ private static Class<?> sUxPerfClass = null;
+ private static Method sUxIOPStart = null;
+
+/** @hide */
+ private Object mPerf = null;
+ private Object mUxPerf = null;
+
+ //perf hints
+ public static final int VENDOR_HINT_SCROLL_BOOST = 0x00001080;
+ public static final int VENDOR_HINT_FIRST_LAUNCH_BOOST = 0x00001081;
+ public static final int VENDOR_HINT_SUBSEQ_LAUNCH_BOOST = 0x00001082;
+ public static final int VENDOR_HINT_ANIM_BOOST = 0x00001083;
+ public static final int VENDOR_HINT_ACTIVITY_BOOST = 0x00001084;
+ public static final int VENDOR_HINT_TOUCH_BOOST = 0x00001085;
+ public static final int VENDOR_HINT_MTP_BOOST = 0x00001086;
+ public static final int VENDOR_HINT_DRAG_BOOST = 0x00001087;
+ public static final int VENDOR_HINT_PACKAGE_INSTALL_BOOST = 0x00001088;
+ public static final int VENDOR_HINT_ROTATION_LATENCY_BOOST = 0x00001089;
+ public static final int VENDOR_HINT_ROTATION_ANIM_BOOST = 0x00001090;
+ public static final int VENDOR_HINT_PERFORMANCE_MODE = 0x00001091;
+ public static final int VENDOR_HINT_APP_UPDATE = 0x00001092;
+ public static final int VENDOR_HINT_KILL = 0x00001093;
+ public static final int VENDOR_HINT_BOOST_RENDERTHREAD = 0x00001096;
+ //perf events
+ public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042;
+ public static final int VENDOR_HINT_TAP_EVENT = 0x00001043;
+ public static final int VENDOR_HINT_DRAG_START = 0x00001051;
+ public static final int VENDOR_HINT_DRAG_END = 0x00001052;
+ //feedback hints
+ public static final int VENDOR_FEEDBACK_WORKLOAD_TYPE = 0x00001601;
+ public static final int VENDOR_FEEDBACK_LAUNCH_END_POINT = 0x00001602;
+
+ //UXE Events and Triggers
+ public static final int UXE_TRIGGER = 1;
+ public static final int UXE_EVENT_BINDAPP = 2;
+ public static final int UXE_EVENT_DISPLAYED_ACT = 3;
+ public static final int UXE_EVENT_KILL = 4;
+ public static final int UXE_EVENT_GAME = 5;
+ public static final int UXE_EVENT_SUB_LAUNCH = 6;
+ public static final int UXE_EVENT_PKG_UNINSTALL = 7;
+ public static final int UXE_EVENT_PKG_INSTALL = 8;
+
+ //perf opcodes
+ public static final int MPCTLV3_GPU_IS_APP_FG = 0X42820000;
+ public static final int MPCTLV3_GPU_IS_APP_BG = 0X42824000;
+
+ public class Scroll {
+ public static final int VERTICAL = 1;
+ public static final int HORIZONTAL = 2;
+ public static final int PANEL_VIEW = 3;
+ public static final int PREFILING = 4;
+ };
+
+ public class Launch {
+ public static final int BOOST_V1 = 1;
+ public static final int BOOST_V2 = 2;
+ public static final int BOOST_V3 = 3;
+ public static final int BOOST_GAME = 4;
+ public static final int RESERVED_1 = 5;
+ public static final int RESERVED_2 = 6;
+ public static final int RESERVED_3 = 7;
+ public static final int RESERVED_4 = 8;
+ public static final int RESERVED_5 = 9;
+ public static final int TYPE_SERVICE_START = 100;
+ public static final int TYPE_START_PROC = 101;
+ public static final int TYPE_START_APP_FROM_BG = 102;
+ public static final int TYPE_ATTACH_APPLICATION = 103;
+ };
+
+ public class Draw {
+ public static final int EVENT_TYPE_V1 = 1;
+ };
+
+ public class WorkloadType {
+ public static final int NOT_KNOWN = 0;
+ public static final int APP = 1;
+ public static final int GAME = 2;
+ public static final int BROWSER = 3;
+ public static final int PREPROAPP = 4;
+ };
+
+/** @hide */
+ public BoostFramework() {
+ initFunctions();
+
+ try {
+ if (sPerfClass != null) {
+ mPerf = sPerfClass.newInstance();
+ }
+ if (sUxPerfClass != null) {
+ mUxPerf = sUxPerfClass.newInstance();
+ }
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_2 = " + e);
+ }
+ }
+
+/** @hide */
+ public BoostFramework(Context context) {
+ this(context, false);
+ }
+
+/** @hide */
+ public BoostFramework(Context context, boolean isTrusted) {
+ initFunctions();
+
+ try {
+ if (sPerfClass != null) {
+ Constructor cons = sPerfClass.getConstructor(Context.class);
+ if (cons != null)
+ mPerf = cons.newInstance(context);
+ }
+ if (sUxPerfClass != null) {
+ if (isTrusted) {
+ Constructor cons = sUxPerfClass.getConstructor(Context.class);
+ if (cons != null)
+ mUxPerf = cons.newInstance(context);
+ } else {
+ mUxPerf = sUxPerfClass.newInstance();
+ }
+ }
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_3 = " + e);
+ }
+ }
+
+/** @hide */
+ public BoostFramework(boolean isUntrustedDomain) {
+ initFunctions();
+
+ try {
+ if (sPerfClass != null) {
+ Constructor cons = sPerfClass.getConstructor(boolean.class);
+ if (cons != null)
+ mPerf = cons.newInstance(isUntrustedDomain);
+ }
+ if (sUxPerfClass != null) {
+ mUxPerf = sUxPerfClass.newInstance();
+ }
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_5 = " + e);
+ }
+ }
+
+ private void initFunctions () {
+ synchronized(BoostFramework.class) {
+ if (sIsLoaded == false) {
+ try {
+ sPerfClass = Class.forName(PERFORMANCE_CLASS);
+
+ Class[] argClasses = new Class[] {int.class, int[].class};
+ sAcquireFunc = sPerfClass.getMethod("perfLockAcquire", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, int.class, int.class};
+ sPerfHintFunc = sPerfClass.getMethod("perfHint", argClasses);
+
+ argClasses = new Class[] {};
+ sReleaseFunc = sPerfClass.getMethod("perfLockRelease", argClasses);
+
+ argClasses = new Class[] {int.class};
+ sReleaseHandlerFunc = sPerfClass.getDeclaredMethod("perfLockReleaseHandler", argClasses);
+
+ argClasses = new Class[] {int.class, String.class};
+ sFeedbackFunc = sPerfClass.getMethod("perfGetFeedback", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, int.class, int[].class};
+ sFeedbackFuncExtn = sPerfClass.getMethod("perfGetFeedbackExtn", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, String.class};
+ sIOPStart = sPerfClass.getDeclaredMethod("perfIOPrefetchStart", argClasses);
+
+ argClasses = new Class[] {};
+ sIOPStop = sPerfClass.getDeclaredMethod("perfIOPrefetchStop", argClasses);
+
+ argClasses = new Class[] {String.class, String.class};
+ sPerfGetPropFunc = sPerfClass.getMethod("perfGetProp", argClasses);
+
+ argClasses = new Class[] {int.class, int.class, int.class, int.class, int[].class};
+ sAcqAndReleaseFunc = sPerfClass.getMethod("perfLockAcqAndRelease", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, int.class, int[].class};
+ sPerfEventFunc = sPerfClass.getMethod("perfEvent", argClasses);
+
+ argClasses = new Class[] {int.class, int.class, String.class, int.class,
+ int.class, int.class, int[].class};
+ sperfHintAcqRelFunc = sPerfClass.getMethod("perfHintAcqRel", argClasses);
+
+ argClasses = new Class[] {int.class, int.class, String.class, int.class,
+ int.class, int.class, int[].class};
+ sperfHintRenewFunc = sPerfClass.getMethod("perfHintRenew", argClasses);
+
+ try {
+ argClasses = new Class[] {};
+ sPerfGetPerfHalVerFunc = sPerfClass.getMethod("perfGetHalVer", argClasses);
+
+ } catch (Exception e) {
+ Log.i(TAG, "BoostFramework() : Exception_1 = perfGetHalVer not supported");
+ sPerfGetPerfHalVerFunc = null;
+ }
+
+ try {
+ argClasses = new Class[] {int.class, int.class, String.class, int.class, String.class};
+ sUXEngineEvents = sPerfClass.getDeclaredMethod("perfUXEngine_events",
+ argClasses);
+
+ argClasses = new Class[] {int.class};
+ sUXEngineTrigger = sPerfClass.getDeclaredMethod("perfUXEngine_trigger",
+ argClasses);
+ } catch (Exception e) {
+ Log.i(TAG, "BoostFramework() : Exception_4 = PreferredApps not supported");
+ }
+
+ sIsLoaded = true;
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_1 = " + e);
+ }
+ // Load UXE Class now Adding new try/catch block to avoid
+ // any interference with Qperformance
+ try {
+ sUxPerfClass = Class.forName(UXPERFORMANCE_CLASS);
+
+ Class[] argUxClasses = new Class[] {int.class, String.class, String.class};
+ sUxIOPStart = sUxPerfClass.getDeclaredMethod("perfIOPrefetchStart", argUxClasses);
+
+ sUxIsLoaded = true;
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() Ux Perf: Exception = " + e);
+ }
+ }
+ }
+ }
+
+/** @hide */
+ public int perfLockAcquire(int duration, int... list) {
+ int ret = -1;
+ try {
+ if (sAcquireFunc != null) {
+ Object retVal = sAcquireFunc.invoke(mPerf, duration, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfLockRelease() {
+ int ret = -1;
+ try {
+ if (sReleaseFunc != null) {
+ Object retVal = sReleaseFunc.invoke(mPerf);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfLockReleaseHandler(int handle) {
+ int ret = -1;
+ try {
+ if (sReleaseHandlerFunc != null) {
+ Object retVal = sReleaseHandlerFunc.invoke(mPerf, handle);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfHint(int hint, String userDataStr) {
+ return perfHint(hint, userDataStr, -1, -1);
+ }
+
+/** @hide */
+ public int perfHint(int hint, String userDataStr, int userData) {
+ return perfHint(hint, userDataStr, userData, -1);
+ }
+
+/** @hide */
+ public int perfHint(int hint, String userDataStr, int userData1, int userData2) {
+ int ret = -1;
+ try {
+ if (sPerfHintFunc != null) {
+ Object retVal = sPerfHintFunc.invoke(mPerf, hint, userDataStr, userData1, userData2);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public double getPerfHalVersion() {
+ double retVal = PERF_HAL_V22;
+ try {
+ if (sPerfGetPerfHalVerFunc != null) {
+ Object ret = sPerfGetPerfHalVerFunc.invoke(mPerf);
+ retVal = (double)ret;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return retVal;
+ }
+
+/** @hide */
+ public int perfGetFeedback(int req, String pkg_name) {
+ int ret = -1;
+ try {
+ if (sFeedbackFunc != null) {
+ Object retVal = sFeedbackFunc.invoke(mPerf, req, pkg_name);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfGetFeedbackExtn(int req, String pkg_name, int numArgs, int... list) {
+ int ret = -1;
+ try {
+ if (sFeedbackFuncExtn != null) {
+ Object retVal = sFeedbackFuncExtn.invoke(mPerf, req, pkg_name, numArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfIOPrefetchStart(int pid, String pkgName, String codePath) {
+ int ret = -1;
+ try {
+ Object retVal = sIOPStart.invoke(mPerf, pid, pkgName, codePath);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ try {
+ Object retVal = sUxIOPStart.invoke(mUxPerf, pid, pkgName, codePath);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Ux Perf Exception " + e);
+ }
+
+ return ret;
+ }
+
+/** @hide */
+ public int perfIOPrefetchStop() {
+ int ret = -1;
+ try {
+ Object retVal = sIOPStop.invoke(mPerf);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat) {
+ return perfUXEngine_events(opcode, pid, pkgName, lat, null);
+ }
+
+/** @hide */
+ public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat, String codePath) {
+ int ret = -1;
+ try {
+ if (sUXEngineEvents == null) {
+ return ret;
+ }
+
+ Object retVal = sUXEngineEvents.invoke(mPerf, opcode, pid, pkgName, lat,codePath);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+
+/** @hide */
+ public String perfUXEngine_trigger(int opcode) {
+ String ret = null;
+ try {
+ if (sUXEngineTrigger == null) {
+ return ret;
+ }
+ Object retVal = sUXEngineTrigger.invoke(mPerf, opcode);
+ ret = (String) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+
+/** @hide */
+ public String perfGetProp(String prop_name, String def_val) {
+ String ret = "";
+ try {
+ if (sPerfGetPropFunc != null) {
+ Object retVal = sPerfGetPropFunc.invoke(mPerf, prop_name, def_val);
+ ret = (String)retVal;
+ }else {
+ ret = def_val;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfLockAcqAndRelease(int handle, int duration, int numArgs,int reserveNumArgs, int... list) {
+ int ret = -1;
+ try {
+ if (sAcqAndReleaseFunc != null) {
+ Object retVal = sAcqAndReleaseFunc.invoke(mPerf, handle, duration, numArgs, reserveNumArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public void perfEvent(int eventId, String pkg_name) {
+ perfEvent(eventId, pkg_name, 0);
+ }
+
+/** @hide */
+ public void perfEvent(int eventId, String pkg_name, int numArgs, int... list) {
+ try {
+ if (sPerfEventFunc != null) {
+ sPerfEventFunc.invoke(mPerf, eventId, pkg_name, numArgs, list);
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name) {
+ return perfHintAcqRel(handle, hint, pkg_name, -1, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name, int duration) {
+ return perfHintAcqRel(handle, hint, pkg_name, duration, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name, int duration, int hintType) {
+ return perfHintAcqRel(handle, hint, pkg_name, duration, hintType, 0);
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name, int duration,
+ int hintType, int numArgs, int... list) {
+ int ret = -1;
+ try {
+ if (sperfHintAcqRelFunc != null) {
+ Object retVal = sperfHintAcqRelFunc.invoke(mPerf,handle, hint, pkg_name,
+ duration, hintType, numArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name) {
+ return perfHintRenew(handle, hint, pkg_name, -1, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name, int duration) {
+ return perfHintRenew(handle, hint, pkg_name, duration, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name, int duration, int hintType) {
+ return perfHintRenew(handle, hint, pkg_name, duration, hintType, 0);
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name, int duration,
+ int hintType, int numArgs, int... list) {
+ int ret = -1;
+ try {
+ if (sperfHintRenewFunc != null) {
+ Object retVal = sperfHintRenewFunc.invoke(mPerf,handle, hint, pkg_name,
+ duration, hintType, numArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+ /** @hide */
+ public static class ScrollOptimizer {
+ /** @hide */
+ public static final int FLING_START = 1;
+ /** @hide */
+ public static final int FLING_END = 0;
+ private static final String SCROLL_OPT_PROP = "ro.vendor.perf.scroll_opt";
+ private static final String QXPERFORMANCE_JAR =
+ "/system/framework/QXPerformance.jar";
+ private static final String SCROLL_OPT_CLASS =
+ "com.qualcomm.qti.QXPerformance.ScrollOptimizer";
+ private static boolean sScrollOptProp = false;
+ private static boolean sScrollOptEnable = false;
+ private static boolean sQXIsLoaded = false;
+ private static Class<?> sQXPerfClass = null;
+ private static Method sSetFrameInterval = null;
+ private static Method sSetBLASTBufferQueue = null;
+ private static Method sSetMotionType = null;
+ private static Method sSetVsyncTime = null;
+ private static Method sSetUITaskStatus = null;
+ private static Method sSetFlingFlag = null;
+ private static Method sShouldUseVsync = null;
+ private static Method sGetFrameDelay = null;
+ private static Method sGetAdjustedAnimationClock = null;
+
+ private static void initQXPerfFuncs() {
+ if (sQXIsLoaded) return;
+
+ try {
+ sScrollOptProp = SystemProperties.getBoolean(SCROLL_OPT_PROP, false);
+ if (!sScrollOptProp) {
+ sScrollOptEnable = false;
+ sQXIsLoaded = true;
+ return;
+ }
+
+ PathClassLoader qXPerfClassLoader = new PathClassLoader(
+ QXPERFORMANCE_JAR, ClassLoader.getSystemClassLoader());
+ sQXPerfClass = qXPerfClassLoader.loadClass(SCROLL_OPT_CLASS);
+ Class[] argClasses = new Class[]{long.class};
+ sSetFrameInterval = sQXPerfClass.getMethod(
+ "setFrameInterval", argClasses);
+
+ argClasses = new Class[]{BLASTBufferQueue.class};
+ sSetBLASTBufferQueue = sQXPerfClass.getMethod("setBLASTBufferQueue", argClasses);
+
+ argClasses = new Class[]{int.class};
+ sSetMotionType = sQXPerfClass.getMethod("setMotionType", argClasses);
+
+ argClasses = new Class[]{long.class};
+ sSetVsyncTime = sQXPerfClass.getMethod("setVsyncTime", argClasses);
+
+ argClasses = new Class[]{boolean.class};
+ sSetUITaskStatus = sQXPerfClass.getMethod("setUITaskStatus", argClasses);
+
+ argClasses = new Class[]{int.class};
+ sSetFlingFlag = sQXPerfClass.getMethod("setFlingFlag", argClasses);
+
+ sShouldUseVsync = sQXPerfClass.getMethod("shouldUseVsync");
+
+ argClasses = new Class[]{long.class};
+ sGetFrameDelay = sQXPerfClass.getMethod("getFrameDelay", argClasses);
+
+ argClasses = new Class[]{long.class};
+ sGetAdjustedAnimationClock = sQXPerfClass.getMethod(
+ "getAdjustedAnimationClock", argClasses);
+
+ sQXIsLoaded = true;
+ } catch (Exception e) {
+ Log.e(TAG, "initQXPerfFuncs failed");
+ e.printStackTrace();
+ }
+ }
+
+ /** @hide */
+ public static void setFrameInterval(long frameIntervalNanos) {
+ Thread initThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ initQXPerfFuncs();
+ if (sScrollOptProp && sSetFrameInterval != null) {
+ sSetFrameInterval.invoke(null, frameIntervalNanos);
+ sScrollOptEnable = true;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to run initThread.");
+ e.printStackTrace();
+ }
+ }
+ });
+ initThread.start();
+ }
+
+ /** @hide */
+ public static void setBLASTBufferQueue(BLASTBufferQueue blastBufferQueue) {
+ if (sScrollOptEnable && sSetBLASTBufferQueue != null) {
+ try {
+ sSetBLASTBufferQueue.invoke(null, blastBufferQueue);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setMotionType(int eventType) {
+ if (sScrollOptEnable && sSetMotionType != null) {
+ try {
+ sSetMotionType.invoke(null, eventType);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setVsyncTime(long vsyncTimeNanos) {
+ if (sScrollOptEnable && sSetVsyncTime != null) {
+ try {
+ sSetVsyncTime.invoke(null, vsyncTimeNanos);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setUITaskStatus(boolean running) {
+ if (sScrollOptEnable && sSetUITaskStatus != null) {
+ try {
+ sSetUITaskStatus.invoke(null, running);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setFlingFlag(int flag) {
+ if (sScrollOptEnable && sSetFlingFlag != null) {
+ try {
+ sSetFlingFlag.invoke(null, flag);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static boolean shouldUseVsync(boolean defaultVsyncFlag) {
+ boolean useVsync = defaultVsyncFlag;
+ if (sScrollOptEnable && sShouldUseVsync != null) {
+ try {
+ Object retVal = sShouldUseVsync.invoke(null);
+ useVsync = (boolean)retVal;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return useVsync;
+ }
+
+ /** @hide */
+ public static long getFrameDelay(long defaultDelay, long lastFrameTimeNanos) {
+ long frameDelay = defaultDelay;
+ if (sScrollOptEnable && sGetFrameDelay != null) {
+ try {
+ Object retVal = sGetFrameDelay.invoke(null, lastFrameTimeNanos);
+ frameDelay = (long)retVal;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return frameDelay;
+ }
+
+ /** @hide */
+ public static long getAdjustedAnimationClock(long frameTimeNanos) {
+ long newFrameTimeNanos = frameTimeNanos;
+ if (sScrollOptEnable && sGetAdjustedAnimationClock != null) {
+ try {
+ Object retVal = sGetAdjustedAnimationClock.invoke(null,
+ frameTimeNanos);
+ newFrameTimeNanos = (long)retVal;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return newFrameTimeNanos;
+ }
+ }
+};
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index e08b913fe248..871fd51b5968 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -76,7 +76,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put("settings_tether_all_in_one", "false");
DEFAULT_FLAGS.put("settings_contextual_home", "false");
- DEFAULT_FLAGS.put(SETTINGS_PROVIDER_MODEL, "true");
+ DEFAULT_FLAGS.put(SETTINGS_PROVIDER_MODEL, "false");
DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true");
DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true");
@@ -98,6 +98,11 @@ public class FeatureFlagUtils {
* @return true if the flag is enabled (either by default in system, or override by user)
*/
public static boolean isEnabled(Context context, String feature) {
+ // Hide feature in SC Developer Preview
+ if (SETTINGS_PROVIDER_MODEL.equals(feature)) {
+ return false;
+ }
+
// Override precedence:
// Settings.Global -> sys.fflag.override.* -> static list
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 4ac3178ecb4c..519fd2b9a171 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -28,6 +28,7 @@ import android.net.NetworkInfo;
import android.net.SntpClient;
import android.os.Build;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.provider.Settings;
import android.text.TextUtils;
@@ -126,6 +127,12 @@ public class NtpTrustedTime implements TrustedTime {
// forceRefresh().
private volatile TimeResult mTimeResult;
+ private boolean mBackupmode = false;
+ private static String mBackupServer = "";
+ private static int mNtpRetries = 0;
+ private static int mNtpRetriesMax = 0;
+ private static final String BACKUP_SERVER = "persist.backup.ntpServer";
+
private NtpTrustedTime(Context context) {
mContext = Objects.requireNonNull(context);
}
@@ -133,14 +140,39 @@ public class NtpTrustedTime implements TrustedTime {
@UnsupportedAppUsage
public static synchronized NtpTrustedTime getInstance(Context context) {
if (sSingleton == null) {
+ final Resources res = context.getResources();
+ final ContentResolver resolver = context.getContentResolver();
+
Context appContext = context.getApplicationContext();
sSingleton = new NtpTrustedTime(appContext);
+
+ final String sserver_prop = Settings.Global.getString(
+ resolver, Settings.Global.NTP_SERVER_2);
+
+ final String secondServer_prop = ((null != sserver_prop)
+ && (0 < sserver_prop.length()))
+ ? sserver_prop : BACKUP_SERVER;
+
+ final String backupServer = SystemProperties.get(secondServer_prop);
+
+ if ((null != backupServer) && (0 < backupServer.length())) {
+ int retryMax = res.getInteger(com.android.internal.R.integer.config_ntpRetry);
+ if (0 < retryMax) {
+ sSingleton.mNtpRetriesMax = retryMax;
+ sSingleton.mBackupServer = (backupServer.trim()).replace("\"", "");
+ }
+ }
}
return sSingleton;
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean forceRefresh() {
+ return hasCache() ? forceSync() : false;
+ }
+
+ @Override
+ public boolean forceSync() {
synchronized (this) {
NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
if (connectionInfo == null) {
@@ -163,14 +195,21 @@ public class NtpTrustedTime implements TrustedTime {
if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
final SntpClient client = new SntpClient();
- final String serverName = connectionInfo.getServer();
+ String serverName = connectionInfo.getServer();
final int timeoutMillis = connectionInfo.getTimeoutMillis();
+
+ if (getBackupmode()) {
+ setBackupmode(false);
+ serverName = mBackupServer;
+ }
+ if (LOGD) Log.d(TAG, "Ntp Server to access at:" + serverName);
if (client.requestTime(serverName, timeoutMillis, network)) {
long ntpCertainty = client.getRoundTripTime() / 2;
mTimeResult = new TimeResult(
client.getNtpTime(), client.getNtpTimeReference(), ntpCertainty);
return true;
} else {
+ countInBackupmode();
return false;
}
}
@@ -294,4 +333,32 @@ public class NtpTrustedTime implements TrustedTime {
final String server = secureServer != null ? secureServer : defaultServer;
return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis);
}
+
+ public void setBackupmode(boolean mode) {
+ if (isBackupSupported()) {
+ mBackupmode = mode;
+ }
+ if (LOGD) Log.d(TAG, "setBackupmode() set the backup mode to be:" + mBackupmode);
+ }
+
+ private boolean getBackupmode() {
+ return mBackupmode;
+ }
+
+ private boolean isBackupSupported() {
+ return ((0 < mNtpRetriesMax) &&
+ (null != mBackupServer) &&
+ (0 != mBackupServer.length()));
+ }
+
+ private void countInBackupmode() {
+ if (isBackupSupported()) {
+ mNtpRetries++;
+ if (mNtpRetries >= mNtpRetriesMax) {
+ mNtpRetries = 0;
+ setBackupmode(true);
+ }
+ }
+ if (LOGD) Log.d(TAG, "countInBackupmode() func");
+ }
}
diff --git a/core/java/android/util/SeempLog.java b/core/java/android/util/SeempLog.java
new file mode 100644
index 000000000000..3764882644d8
--- /dev/null
+++ b/core/java/android/util/SeempLog.java
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package android.util;
+
+import com.android.internal.os.RuntimeInit;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.UnknownHostException;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.List;
+import java.util.Iterator;
+import android.util.Log;
+import android.provider.Settings;
+
+/**
+ * SeempLog
+ *
+ * @hide
+ */
+public final class SeempLog {
+ private SeempLog() {
+ }
+
+ /**
+ * Send a log message to the seemp log.
+ * @param api The api triggering this message.
+ */
+ public static int record(int api) {
+ return seemp_println_native(api, "");
+ }
+
+ /**
+ * Send a log message to the seemp log.
+ * @param api The api triggering this message.
+ * @param msg The message you would like logged.
+ */
+ public static int record_str(int api, String msg) {
+ if ( msg != null ) {
+ return seemp_println_native(api, msg);
+ }
+ else {
+ return seemp_println_native(api, "");
+ }
+ }
+
+ public static int record_sensor(int api,
+ android.hardware.Sensor sensor) {
+ if ( sensor != null ) {
+ return seemp_println_native(api, "sensor="+sensor.getType());
+ }
+ else {
+ return seemp_println_native(api, "sensor=-1");
+ }
+ }
+
+ public static int record_sensor_rate(int api,
+ android.hardware.Sensor sensor, int rate) {
+ if ( sensor != null ) {
+ return seemp_println_native(api,
+ "sensor="+sensor.getType() + ",rate="+rate);
+ }
+ else {
+ return seemp_println_native(api, "sensor=-1,rate=" + rate);
+ }
+ }
+
+ public static int record_uri(int api, android.net.Uri uri) {
+ if ( uri != null ) {
+ return seemp_println_native(api, "uri, " + uri.toString());
+ }
+ else {
+ return seemp_println_native(api, "uri, null" );
+ }
+ }
+
+ public static int record_vg_layout(int api,
+ android.view.ViewGroup.LayoutParams params) {
+ try {
+ android.view.WindowManager.LayoutParams p =
+ (android.view.WindowManager.LayoutParams) params;
+ if ( p != null ) {
+ return seemp_println_native(api,
+ "window_type=" + p.type + ",window_flag=" + p.flags);
+ }
+ else {
+ return seemp_println_native(api, "");
+ }
+ } catch (ClassCastException cce) {
+ return seemp_println_native(api, "");
+ }
+ }
+
+ /** @hide */ public static native int seemp_println_native(int api, String msg);
+
+ public static final int SEEMP_API_android_provider_Settings__get_ANDROID_ID_ = 7;
+ public static final int SEEMP_API_android_provider_Settings__get_ACCELEROMETER_ROTATION_ = 96;
+ public static final int SEEMP_API_android_provider_Settings__get_USER_ROTATION_ = 97;
+ public static final int SEEMP_API_android_provider_Settings__get_ADB_ENABLED_ = 98;
+ public static final int SEEMP_API_android_provider_Settings__get_DEBUG_APP_ = 99;
+ public static final int SEEMP_API_android_provider_Settings__get_WAIT_FOR_DEBUGGER_ = 100;
+ public static final int SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_ON_ = 101;
+ public static final int SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_RADIOS_ = 102;
+ public static final int SEEMP_API_android_provider_Settings__get_ALARM_ALERT_ = 103;
+ public static final int SEEMP_API_android_provider_Settings__get_NEXT_ALARM_FORMATTED_ = 104;
+ public static final int SEEMP_API_android_provider_Settings__get_ALWAYS_FINISH_ACTIVITIES_ = 105;
+ public static final int SEEMP_API_android_provider_Settings__get_LOGGING_ID_ = 106;
+ public static final int SEEMP_API_android_provider_Settings__get_ANIMATOR_DURATION_SCALE_ = 107;
+ public static final int SEEMP_API_android_provider_Settings__get_WINDOW_ANIMATION_SCALE_ = 108;
+ public static final int SEEMP_API_android_provider_Settings__get_FONT_SCALE_ = 109;
+ public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_ = 110;
+ public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_ = 111;
+ public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ = 112;
+ public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_MANUAL_ = 113;
+ public static final int SEEMP_API_android_provider_Settings__get_SCREEN_OFF_TIMEOUT_ = 114;
+ public static final int SEEMP_API_android_provider_Settings__get_DIM_SCREEN_ = 115;
+ public static final int SEEMP_API_android_provider_Settings__get_TRANSITION_ANIMATION_SCALE_ = 116;
+ public static final int SEEMP_API_android_provider_Settings__get_STAY_ON_WHILE_PLUGGED_IN_ = 117;
+ public static final int SEEMP_API_android_provider_Settings__get_WALLPAPER_ACTIVITY_ = 118;
+ public static final int SEEMP_API_android_provider_Settings__get_SHOW_PROCESSES_ = 119;
+ public static final int SEEMP_API_android_provider_Settings__get_SHOW_WEB_SUGGESTIONS_ = 120;
+ public static final int SEEMP_API_android_provider_Settings__get_SHOW_GTALK_SERVICE_STATUS_ = 121;
+ public static final int SEEMP_API_android_provider_Settings__get_USE_GOOGLE_MAIL_ = 122;
+ public static final int SEEMP_API_android_provider_Settings__get_AUTO_TIME_ = 123;
+ public static final int SEEMP_API_android_provider_Settings__get_AUTO_TIME_ZONE_ = 124;
+ public static final int SEEMP_API_android_provider_Settings__get_DATE_FORMAT_ = 125;
+ public static final int SEEMP_API_android_provider_Settings__get_TIME_12_24_ = 126;
+ public static final int SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_ = 127;
+ public static final int SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ = 128;
+ public static final int SEEMP_API_android_provider_Settings__get_BLUETOOTH_ON_ = 129;
+ public static final int SEEMP_API_android_provider_Settings__get_DEVICE_PROVISIONED_ = 130;
+ public static final int SEEMP_API_android_provider_Settings__get_SETUP_WIZARD_HAS_RUN_ = 131;
+ public static final int SEEMP_API_android_provider_Settings__get_DTMF_TONE_WHEN_DIALING_ = 132;
+ public static final int SEEMP_API_android_provider_Settings__get_END_BUTTON_BEHAVIOR_ = 133;
+ public static final int SEEMP_API_android_provider_Settings__get_RINGTONE_ = 134;
+ public static final int SEEMP_API_android_provider_Settings__get_MODE_RINGER_ = 135;
+ public static final int SEEMP_API_android_provider_Settings__get_INSTALL_NON_MARKET_APPS_ = 136;
+ public static final int SEEMP_API_android_provider_Settings__get_LOCATION_PROVIDERS_ALLOWED_ = 137;
+ public static final int SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_ENABLED_ = 138;
+ public static final int SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ = 139;
+ public static final int SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_VISIBLE_ = 140;
+ public static final int SEEMP_API_android_provider_Settings__get_NETWORK_PREFERENCE_ = 141;
+ public static final int SEEMP_API_android_provider_Settings__get_DATA_ROAMING_ = 142;
+ public static final int SEEMP_API_android_provider_Settings__get_HTTP_PROXY_ = 143;
+ public static final int SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_ENABLED_ = 144;
+ public static final int SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_LAST_UPDATE_ = 145;
+ public static final int SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_REDIRECT_URL_ = 146;
+ public static final int SEEMP_API_android_provider_Settings__get_RADIO_BLUETOOTH_ = 147;
+ public static final int SEEMP_API_android_provider_Settings__get_RADIO_CELL_ = 148;
+ public static final int SEEMP_API_android_provider_Settings__get_RADIO_NFC_ = 149;
+ public static final int SEEMP_API_android_provider_Settings__get_RADIO_WIFI_ = 150;
+ public static final int SEEMP_API_android_provider_Settings__get_SYS_PROP_SETTING_VERSION_ = 151;
+ public static final int SEEMP_API_android_provider_Settings__get_SETTINGS_CLASSNAME_ = 152;
+ public static final int SEEMP_API_android_provider_Settings__get_TEXT_AUTO_CAPS_ = 153;
+ public static final int SEEMP_API_android_provider_Settings__get_TEXT_AUTO_PUNCTUATE_ = 154;
+ public static final int SEEMP_API_android_provider_Settings__get_TEXT_AUTO_REPLACE_ = 155;
+ public static final int SEEMP_API_android_provider_Settings__get_TEXT_SHOW_PASSWORD_ = 156;
+ public static final int SEEMP_API_android_provider_Settings__get_USB_MASS_STORAGE_ENABLED_ = 157;
+ public static final int SEEMP_API_android_provider_Settings__get_VIBRATE_ON_ = 158;
+ public static final int SEEMP_API_android_provider_Settings__get_HAPTIC_FEEDBACK_ENABLED_ = 159;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_ALARM_ = 160;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_BLUETOOTH_SCO_ = 161;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_MUSIC_ = 162;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_NOTIFICATION_ = 163;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_RING_ = 164;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_SYSTEM_ = 165;
+ public static final int SEEMP_API_android_provider_Settings__get_VOLUME_VOICE_ = 166;
+ public static final int SEEMP_API_android_provider_Settings__get_SOUND_EFFECTS_ENABLED_ = 167;
+ public static final int SEEMP_API_android_provider_Settings__get_MODE_RINGER_STREAMS_AFFECTED_ = 168;
+ public static final int SEEMP_API_android_provider_Settings__get_MUTE_STREAMS_AFFECTED_ = 169;
+ public static final int SEEMP_API_android_provider_Settings__get_NOTIFICATION_SOUND_ = 170;
+ public static final int SEEMP_API_android_provider_Settings__get_APPEND_FOR_LAST_AUDIBLE_ = 171;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_MAX_DHCP_RETRY_COUNT_ = 172;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_ = 173;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ = 174;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ = 175;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_NUM_OPEN_NETWORKS_KEPT_ = 176;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_ON_ = 177;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_ = 178;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_DEFAULT_ = 179;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_NEVER_ = 180;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ = 181;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS1_ = 182;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS2_ = 183;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_GATEWAY_ = 184;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_IP_ = 185;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_NETMASK_ = 186;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_USE_STATIC_IP_ = 187;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_ = 188;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_AP_COUNT_ = 189;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ = 190;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ = 191;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ = 192;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ = 193;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_MAX_AP_CHECKS_ = 194;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ON_ = 195;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_COUNT_ = 196;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_DELAY_MS_ = 197;
+ public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_TIMEOUT_MS_ = 198;
+ public static final int SEEMP_API_android_provider_Settings__put_ACCELEROMETER_ROTATION_ = 199;
+ public static final int SEEMP_API_android_provider_Settings__put_USER_ROTATION_ = 200;
+ public static final int SEEMP_API_android_provider_Settings__put_ADB_ENABLED_ = 201;
+ public static final int SEEMP_API_android_provider_Settings__put_DEBUG_APP_ = 202;
+ public static final int SEEMP_API_android_provider_Settings__put_WAIT_FOR_DEBUGGER_ = 203;
+ public static final int SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_ON_ = 204;
+ public static final int SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_RADIOS_ = 205;
+ public static final int SEEMP_API_android_provider_Settings__put_ALARM_ALERT_ = 206;
+ public static final int SEEMP_API_android_provider_Settings__put_NEXT_ALARM_FORMATTED_ = 207;
+ public static final int SEEMP_API_android_provider_Settings__put_ALWAYS_FINISH_ACTIVITIES_ = 208;
+ public static final int SEEMP_API_android_provider_Settings__put_ANDROID_ID_ = 209;
+ public static final int SEEMP_API_android_provider_Settings__put_LOGGING_ID_ = 210;
+ public static final int SEEMP_API_android_provider_Settings__put_ANIMATOR_DURATION_SCALE_ = 211;
+ public static final int SEEMP_API_android_provider_Settings__put_WINDOW_ANIMATION_SCALE_ = 212;
+ public static final int SEEMP_API_android_provider_Settings__put_FONT_SCALE_ = 213;
+ public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_ = 214;
+ public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_ = 215;
+ public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ = 216;
+ public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_MANUAL_ = 217;
+ public static final int SEEMP_API_android_provider_Settings__put_SCREEN_OFF_TIMEOUT_ = 218;
+ public static final int SEEMP_API_android_provider_Settings__put_DIM_SCREEN_ = 219;
+ public static final int SEEMP_API_android_provider_Settings__put_TRANSITION_ANIMATION_SCALE_ = 220;
+ public static final int SEEMP_API_android_provider_Settings__put_STAY_ON_WHILE_PLUGGED_IN_ = 221;
+ public static final int SEEMP_API_android_provider_Settings__put_WALLPAPER_ACTIVITY_ = 222;
+ public static final int SEEMP_API_android_provider_Settings__put_SHOW_PROCESSES_ = 223;
+ public static final int SEEMP_API_android_provider_Settings__put_SHOW_WEB_SUGGESTIONS_ = 224;
+ public static final int SEEMP_API_android_provider_Settings__put_SHOW_GTALK_SERVICE_STATUS_ = 225;
+ public static final int SEEMP_API_android_provider_Settings__put_USE_GOOGLE_MAIL_ = 226;
+ public static final int SEEMP_API_android_provider_Settings__put_AUTO_TIME_ = 227;
+ public static final int SEEMP_API_android_provider_Settings__put_AUTO_TIME_ZONE_ = 228;
+ public static final int SEEMP_API_android_provider_Settings__put_DATE_FORMAT_ = 229;
+ public static final int SEEMP_API_android_provider_Settings__put_TIME_12_24_ = 230;
+ public static final int SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_ = 231;
+ public static final int SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ = 232;
+ public static final int SEEMP_API_android_provider_Settings__put_BLUETOOTH_ON_ = 233;
+ public static final int SEEMP_API_android_provider_Settings__put_DEVICE_PROVISIONED_ = 234;
+ public static final int SEEMP_API_android_provider_Settings__put_SETUP_WIZARD_HAS_RUN_ = 235;
+ public static final int SEEMP_API_android_provider_Settings__put_DTMF_TONE_WHEN_DIALING_ = 236;
+ public static final int SEEMP_API_android_provider_Settings__put_END_BUTTON_BEHAVIOR_ = 237;
+ public static final int SEEMP_API_android_provider_Settings__put_RINGTONE_ = 238;
+ public static final int SEEMP_API_android_provider_Settings__put_MODE_RINGER_ = 239;
+ public static final int SEEMP_API_android_provider_Settings__put_INSTALL_NON_MARKET_APPS_ = 240;
+ public static final int SEEMP_API_android_provider_Settings__put_LOCATION_PROVIDERS_ALLOWED_ = 241;
+ public static final int SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_ENABLED_ = 242;
+ public static final int SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ = 243;
+ public static final int SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_VISIBLE_ = 244;
+ public static final int SEEMP_API_android_provider_Settings__put_NETWORK_PREFERENCE_ = 245;
+ public static final int SEEMP_API_android_provider_Settings__put_DATA_ROAMING_ = 246;
+ public static final int SEEMP_API_android_provider_Settings__put_HTTP_PROXY_ = 247;
+ public static final int SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_ENABLED_ = 248;
+ public static final int SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_LAST_UPDATE_ = 249;
+ public static final int SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_REDIRECT_URL_ = 250;
+ public static final int SEEMP_API_android_provider_Settings__put_RADIO_BLUETOOTH_ = 251;
+ public static final int SEEMP_API_android_provider_Settings__put_RADIO_CELL_ = 252;
+ public static final int SEEMP_API_android_provider_Settings__put_RADIO_NFC_ = 253;
+ public static final int SEEMP_API_android_provider_Settings__put_RADIO_WIFI_ = 254;
+ public static final int SEEMP_API_android_provider_Settings__put_SYS_PROP_SETTING_VERSION_ = 255;
+ public static final int SEEMP_API_android_provider_Settings__put_SETTINGS_CLASSNAME_ = 256;
+ public static final int SEEMP_API_android_provider_Settings__put_TEXT_AUTO_CAPS_ = 257;
+ public static final int SEEMP_API_android_provider_Settings__put_TEXT_AUTO_PUNCTUATE_ = 258;
+ public static final int SEEMP_API_android_provider_Settings__put_TEXT_AUTO_REPLACE_ = 259;
+ public static final int SEEMP_API_android_provider_Settings__put_TEXT_SHOW_PASSWORD_ = 260;
+ public static final int SEEMP_API_android_provider_Settings__put_USB_MASS_STORAGE_ENABLED_ = 261;
+ public static final int SEEMP_API_android_provider_Settings__put_VIBRATE_ON_ = 262;
+ public static final int SEEMP_API_android_provider_Settings__put_HAPTIC_FEEDBACK_ENABLED_ = 263;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_ALARM_ = 264;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_BLUETOOTH_SCO_ = 265;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_MUSIC_ = 266;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_NOTIFICATION_ = 267;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_RING_ = 268;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_SYSTEM_ = 269;
+ public static final int SEEMP_API_android_provider_Settings__put_VOLUME_VOICE_ = 270;
+ public static final int SEEMP_API_android_provider_Settings__put_SOUND_EFFECTS_ENABLED_ = 271;
+ public static final int SEEMP_API_android_provider_Settings__put_MODE_RINGER_STREAMS_AFFECTED_ = 272;
+ public static final int SEEMP_API_android_provider_Settings__put_MUTE_STREAMS_AFFECTED_ = 273;
+ public static final int SEEMP_API_android_provider_Settings__put_NOTIFICATION_SOUND_ = 274;
+ public static final int SEEMP_API_android_provider_Settings__put_APPEND_FOR_LAST_AUDIBLE_ = 275;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_MAX_DHCP_RETRY_COUNT_ = 276;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_ = 277;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ = 278;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ = 279;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_NUM_OPEN_NETWORKS_KEPT_ = 280;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_ON_ = 281;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_ = 282;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_DEFAULT_ = 283;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_NEVER_ = 284;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ = 285;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS1_ = 286;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS2_ = 287;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_GATEWAY_ = 288;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_IP_ = 289;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_NETMASK_ = 290;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_USE_STATIC_IP_ = 291;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_ = 292;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_AP_COUNT_ = 293;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ = 294;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ = 295;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ = 296;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ = 297;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_MAX_AP_CHECKS_ = 298;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ON_ = 299;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_COUNT_ = 300;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_DELAY_MS_ = 301;
+ public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_TIMEOUT_MS_ = 302;
+
+ private final static java.util.Map<String,Integer> value_to_get_map;
+ static {
+ value_to_get_map = new java.util.HashMap<String,Integer>( 198 );
+ value_to_get_map.put(Settings.System.NOTIFICATION_SOUND,
+ SEEMP_API_android_provider_Settings__get_NOTIFICATION_SOUND_);
+ value_to_get_map.put(Settings.System.DTMF_TONE_WHEN_DIALING,
+ SEEMP_API_android_provider_Settings__get_DTMF_TONE_WHEN_DIALING_);
+ value_to_get_map.put(Settings.System.LOCK_PATTERN_ENABLED,
+ SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_ENABLED_);
+ value_to_get_map.put(Settings.System.WIFI_MAX_DHCP_RETRY_COUNT,
+ SEEMP_API_android_provider_Settings__get_WIFI_MAX_DHCP_RETRY_COUNT_);
+ value_to_get_map.put(Settings.System.AUTO_TIME,
+ SEEMP_API_android_provider_Settings__get_AUTO_TIME_);
+ value_to_get_map.put(Settings.System.SETUP_WIZARD_HAS_RUN,
+ SEEMP_API_android_provider_Settings__get_SETUP_WIZARD_HAS_RUN_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_);
+ value_to_get_map.put(Settings.System.LOCATION_PROVIDERS_ALLOWED,
+ SEEMP_API_android_provider_Settings__get_LOCATION_PROVIDERS_ALLOWED_);
+ value_to_get_map.put(Settings.System.ALARM_ALERT,
+ SEEMP_API_android_provider_Settings__get_ALARM_ALERT_);
+ value_to_get_map.put(Settings.System.VIBRATE_ON,
+ SEEMP_API_android_provider_Settings__get_VIBRATE_ON_);
+ value_to_get_map.put(Settings.System.USB_MASS_STORAGE_ENABLED,
+ SEEMP_API_android_provider_Settings__get_USB_MASS_STORAGE_ENABLED_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_PING_DELAY_MS,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_DELAY_MS_);
+ value_to_get_map.put(Settings.System.FONT_SCALE,
+ SEEMP_API_android_provider_Settings__get_FONT_SCALE_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_AP_COUNT,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_AP_COUNT_);
+ value_to_get_map.put(Settings.System.ALWAYS_FINISH_ACTIVITIES,
+ SEEMP_API_android_provider_Settings__get_ALWAYS_FINISH_ACTIVITIES_);
+ value_to_get_map.put(Settings.System.ACCELEROMETER_ROTATION,
+ SEEMP_API_android_provider_Settings__get_ACCELEROMETER_ROTATION_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_PING_TIMEOUT_MS,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_TIMEOUT_MS_);
+ value_to_get_map.put(Settings.System.VOLUME_NOTIFICATION,
+ SEEMP_API_android_provider_Settings__get_VOLUME_NOTIFICATION_);
+ value_to_get_map.put(Settings.System.AIRPLANE_MODE_ON,
+ SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_ON_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_);
+ value_to_get_map.put(Settings.System.WIFI_STATIC_IP,
+ SEEMP_API_android_provider_Settings__get_WIFI_STATIC_IP_);
+ value_to_get_map.put(Settings.System.RADIO_BLUETOOTH,
+ SEEMP_API_android_provider_Settings__get_RADIO_BLUETOOTH_);
+ value_to_get_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
+ SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_TIMEOUT_);
+ value_to_get_map.put(Settings.System.VOLUME_RING,
+ SEEMP_API_android_provider_Settings__get_VOLUME_RING_);
+ value_to_get_map.put(Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ SEEMP_API_android_provider_Settings__get_MODE_RINGER_STREAMS_AFFECTED_);
+ value_to_get_map.put(Settings.System.VOLUME_SYSTEM,
+ SEEMP_API_android_provider_Settings__get_VOLUME_SYSTEM_);
+ value_to_get_map.put(Settings.System.SCREEN_OFF_TIMEOUT,
+ SEEMP_API_android_provider_Settings__get_SCREEN_OFF_TIMEOUT_);
+ value_to_get_map.put(Settings.System.RADIO_WIFI,
+ SEEMP_API_android_provider_Settings__get_RADIO_WIFI_);
+ value_to_get_map.put(Settings.System.AUTO_TIME_ZONE,
+ SEEMP_API_android_provider_Settings__get_AUTO_TIME_ZONE_);
+ value_to_get_map.put(Settings.System.TEXT_AUTO_CAPS,
+ SEEMP_API_android_provider_Settings__get_TEXT_AUTO_CAPS_);
+ value_to_get_map.put(Settings.System.WALLPAPER_ACTIVITY,
+ SEEMP_API_android_provider_Settings__get_WALLPAPER_ACTIVITY_);
+ value_to_get_map.put(Settings.System.ANIMATOR_DURATION_SCALE,
+ SEEMP_API_android_provider_Settings__get_ANIMATOR_DURATION_SCALE_);
+ value_to_get_map.put(Settings.System.WIFI_NUM_OPEN_NETWORKS_KEPT,
+ SEEMP_API_android_provider_Settings__get_WIFI_NUM_OPEN_NETWORKS_KEPT_);
+ value_to_get_map.put(Settings.System.LOCK_PATTERN_VISIBLE,
+ SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_VISIBLE_);
+ value_to_get_map.put(Settings.System.VOLUME_VOICE,
+ SEEMP_API_android_provider_Settings__get_VOLUME_VOICE_);
+ value_to_get_map.put(Settings.System.DEBUG_APP,
+ SEEMP_API_android_provider_Settings__get_DEBUG_APP_);
+ value_to_get_map.put(Settings.System.WIFI_ON,
+ SEEMP_API_android_provider_Settings__get_WIFI_ON_);
+ value_to_get_map.put(Settings.System.TEXT_SHOW_PASSWORD,
+ SEEMP_API_android_provider_Settings__get_TEXT_SHOW_PASSWORD_);
+ value_to_get_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
+ SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_);
+ value_to_get_map.put(Settings.System.WIFI_SLEEP_POLICY,
+ SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_);
+ value_to_get_map.put(Settings.System.VOLUME_MUSIC,
+ SEEMP_API_android_provider_Settings__get_VOLUME_MUSIC_);
+ value_to_get_map.put(Settings.System.PARENTAL_CONTROL_LAST_UPDATE,
+ SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_LAST_UPDATE_);
+ value_to_get_map.put(Settings.System.DEVICE_PROVISIONED,
+ SEEMP_API_android_provider_Settings__get_DEVICE_PROVISIONED_);
+ value_to_get_map.put(Settings.System.HTTP_PROXY,
+ SEEMP_API_android_provider_Settings__get_HTTP_PROXY_);
+ value_to_get_map.put(Settings.System.ANDROID_ID,
+ SEEMP_API_android_provider_Settings__get_ANDROID_ID_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_MAX_AP_CHECKS,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_MAX_AP_CHECKS_);
+ value_to_get_map.put(Settings.System.END_BUTTON_BEHAVIOR,
+ SEEMP_API_android_provider_Settings__get_END_BUTTON_BEHAVIOR_);
+ value_to_get_map.put(Settings.System.NEXT_ALARM_FORMATTED,
+ SEEMP_API_android_provider_Settings__get_NEXT_ALARM_FORMATTED_);
+ value_to_get_map.put(Settings.System.RADIO_CELL,
+ SEEMP_API_android_provider_Settings__get_RADIO_CELL_);
+ value_to_get_map.put(Settings.System.PARENTAL_CONTROL_ENABLED,
+ SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_ENABLED_);
+ value_to_get_map.put(Settings.System.BLUETOOTH_ON,
+ SEEMP_API_android_provider_Settings__get_BLUETOOTH_ON_);
+ value_to_get_map.put(Settings.System.WINDOW_ANIMATION_SCALE,
+ SEEMP_API_android_provider_Settings__get_WINDOW_ANIMATION_SCALE_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_);
+ value_to_get_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY,
+ SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_);
+ value_to_get_map.put(Settings.System.WIFI_STATIC_DNS1,
+ SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS1_);
+ value_to_get_map.put(Settings.System.WIFI_STATIC_DNS2,
+ SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS2_);
+ value_to_get_map.put(Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ SEEMP_API_android_provider_Settings__get_HAPTIC_FEEDBACK_ENABLED_);
+ value_to_get_map.put(Settings.System.SHOW_WEB_SUGGESTIONS,
+ SEEMP_API_android_provider_Settings__get_SHOW_WEB_SUGGESTIONS_);
+ value_to_get_map.put(Settings.System.PARENTAL_CONTROL_REDIRECT_URL,
+ SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_REDIRECT_URL_);
+ value_to_get_map.put(Settings.System.DATE_FORMAT,
+ SEEMP_API_android_provider_Settings__get_DATE_FORMAT_);
+ value_to_get_map.put(Settings.System.RADIO_NFC,
+ SEEMP_API_android_provider_Settings__get_RADIO_NFC_);
+ value_to_get_map.put(Settings.System.AIRPLANE_MODE_RADIOS,
+ SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_RADIOS_);
+ value_to_get_map.put(Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
+ SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_);
+ value_to_get_map.put(Settings.System.TIME_12_24,
+ SEEMP_API_android_provider_Settings__get_TIME_12_24_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_);
+ value_to_get_map.put(Settings.System.VOLUME_BLUETOOTH_SCO,
+ SEEMP_API_android_provider_Settings__get_VOLUME_BLUETOOTH_SCO_);
+ value_to_get_map.put(Settings.System.USER_ROTATION,
+ SEEMP_API_android_provider_Settings__get_USER_ROTATION_);
+ value_to_get_map.put(Settings.System.WIFI_STATIC_GATEWAY,
+ SEEMP_API_android_provider_Settings__get_WIFI_STATIC_GATEWAY_);
+ value_to_get_map.put(Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+ SEEMP_API_android_provider_Settings__get_STAY_ON_WHILE_PLUGGED_IN_);
+ value_to_get_map.put(Settings.System.SOUND_EFFECTS_ENABLED,
+ SEEMP_API_android_provider_Settings__get_SOUND_EFFECTS_ENABLED_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_PING_COUNT,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_COUNT_);
+ value_to_get_map.put(Settings.System.DATA_ROAMING,
+ SEEMP_API_android_provider_Settings__get_DATA_ROAMING_);
+ value_to_get_map.put(Settings.System.SETTINGS_CLASSNAME,
+ SEEMP_API_android_provider_Settings__get_SETTINGS_CLASSNAME_);
+ value_to_get_map.put(Settings.System.TRANSITION_ANIMATION_SCALE,
+ SEEMP_API_android_provider_Settings__get_TRANSITION_ANIMATION_SCALE_);
+ value_to_get_map.put(Settings.System.WAIT_FOR_DEBUGGER,
+ SEEMP_API_android_provider_Settings__get_WAIT_FOR_DEBUGGER_);
+ value_to_get_map.put(Settings.System.INSTALL_NON_MARKET_APPS,
+ SEEMP_API_android_provider_Settings__get_INSTALL_NON_MARKET_APPS_);
+ value_to_get_map.put(Settings.System.ADB_ENABLED,
+ SEEMP_API_android_provider_Settings__get_ADB_ENABLED_);
+ value_to_get_map.put(Settings.System.WIFI_USE_STATIC_IP,
+ SEEMP_API_android_provider_Settings__get_WIFI_USE_STATIC_IP_);
+ value_to_get_map.put(Settings.System.DIM_SCREEN,
+ SEEMP_API_android_provider_Settings__get_DIM_SCREEN_);
+ value_to_get_map.put(Settings.System.VOLUME_ALARM,
+ SEEMP_API_android_provider_Settings__get_VOLUME_ALARM_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_ON,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ON_);
+ value_to_get_map.put(Settings.System.WIFI_STATIC_NETMASK,
+ SEEMP_API_android_provider_Settings__get_WIFI_STATIC_NETMASK_);
+ value_to_get_map.put(Settings.System.NETWORK_PREFERENCE,
+ SEEMP_API_android_provider_Settings__get_NETWORK_PREFERENCE_);
+ value_to_get_map.put(Settings.System.SHOW_PROCESSES,
+ SEEMP_API_android_provider_Settings__get_SHOW_PROCESSES_);
+ value_to_get_map.put(Settings.System.TEXT_AUTO_REPLACE,
+ SEEMP_API_android_provider_Settings__get_TEXT_AUTO_REPLACE_);
+ value_to_get_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+ SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_);
+ value_to_get_map.put(Settings.System.APPEND_FOR_LAST_AUDIBLE,
+ SEEMP_API_android_provider_Settings__get_APPEND_FOR_LAST_AUDIBLE_);
+ value_to_get_map.put(Settings.System.SHOW_GTALK_SERVICE_STATUS,
+ SEEMP_API_android_provider_Settings__get_SHOW_GTALK_SERVICE_STATUS_);
+ value_to_get_map.put(Settings.System.SCREEN_BRIGHTNESS,
+ SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_);
+ value_to_get_map.put(Settings.System.USE_GOOGLE_MAIL,
+ SEEMP_API_android_provider_Settings__get_USE_GOOGLE_MAIL_);
+ value_to_get_map.put(Settings.System.RINGTONE,
+ SEEMP_API_android_provider_Settings__get_RINGTONE_);
+ value_to_get_map.put(Settings.System.LOGGING_ID,
+ SEEMP_API_android_provider_Settings__get_LOGGING_ID_);
+ value_to_get_map.put(Settings.System.MODE_RINGER,
+ SEEMP_API_android_provider_Settings__get_MODE_RINGER_);
+ value_to_get_map.put(Settings.System.MUTE_STREAMS_AFFECTED,
+ SEEMP_API_android_provider_Settings__get_MUTE_STREAMS_AFFECTED_);
+ value_to_get_map.put(Settings.System.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
+ SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_);
+ value_to_get_map.put(Settings.System.TEXT_AUTO_PUNCTUATE,
+ SEEMP_API_android_provider_Settings__get_TEXT_AUTO_PUNCTUATE_);
+ value_to_get_map.put(Settings.System.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS,
+ SEEMP_API_android_provider_Settings__get_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_);
+ value_to_get_map.put(Settings.System.SCREEN_BRIGHTNESS_MODE,
+ SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_);
+ }
+
+ public static int getSeempGetApiIdFromValue( String v )
+ {
+ Integer result = value_to_get_map.get( v );
+ if (result == null)
+ {
+ result = -1;
+ }
+ return result;
+ }
+
+ private final static java.util.Map<String,Integer> value_to_put_map;
+ static {
+ value_to_put_map = new java.util.HashMap<String,Integer>( 198 );
+ value_to_put_map.put(Settings.System.NOTIFICATION_SOUND,
+ SEEMP_API_android_provider_Settings__put_NOTIFICATION_SOUND_);
+ value_to_put_map.put(Settings.System.DTMF_TONE_WHEN_DIALING,
+ SEEMP_API_android_provider_Settings__put_DTMF_TONE_WHEN_DIALING_);
+ value_to_put_map.put(Settings.System.LOCK_PATTERN_ENABLED,
+ SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_ENABLED_);
+ value_to_put_map.put(Settings.System.WIFI_MAX_DHCP_RETRY_COUNT,
+ SEEMP_API_android_provider_Settings__put_WIFI_MAX_DHCP_RETRY_COUNT_);
+ value_to_put_map.put(Settings.System.AUTO_TIME,
+ SEEMP_API_android_provider_Settings__put_AUTO_TIME_);
+ value_to_put_map.put(Settings.System.SETUP_WIZARD_HAS_RUN,
+ SEEMP_API_android_provider_Settings__put_SETUP_WIZARD_HAS_RUN_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_);
+ value_to_put_map.put(Settings.System.LOCATION_PROVIDERS_ALLOWED,
+ SEEMP_API_android_provider_Settings__put_LOCATION_PROVIDERS_ALLOWED_);
+ value_to_put_map.put(Settings.System.ALARM_ALERT,
+ SEEMP_API_android_provider_Settings__put_ALARM_ALERT_);
+ value_to_put_map.put(Settings.System.VIBRATE_ON,
+ SEEMP_API_android_provider_Settings__put_VIBRATE_ON_);
+ value_to_put_map.put(Settings.System.USB_MASS_STORAGE_ENABLED,
+ SEEMP_API_android_provider_Settings__put_USB_MASS_STORAGE_ENABLED_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_PING_DELAY_MS,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_DELAY_MS_);
+ value_to_put_map.put(Settings.System.FONT_SCALE,
+ SEEMP_API_android_provider_Settings__put_FONT_SCALE_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_AP_COUNT,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_AP_COUNT_);
+ value_to_put_map.put(Settings.System.ALWAYS_FINISH_ACTIVITIES,
+ SEEMP_API_android_provider_Settings__put_ALWAYS_FINISH_ACTIVITIES_);
+ value_to_put_map.put(Settings.System.ACCELEROMETER_ROTATION,
+ SEEMP_API_android_provider_Settings__put_ACCELEROMETER_ROTATION_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_PING_TIMEOUT_MS,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_TIMEOUT_MS_);
+ value_to_put_map.put(Settings.System.VOLUME_NOTIFICATION,
+ SEEMP_API_android_provider_Settings__put_VOLUME_NOTIFICATION_);
+ value_to_put_map.put(Settings.System.AIRPLANE_MODE_ON,
+ SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_ON_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_);
+ value_to_put_map.put(Settings.System.WIFI_STATIC_IP,
+ SEEMP_API_android_provider_Settings__put_WIFI_STATIC_IP_);
+ value_to_put_map.put(Settings.System.RADIO_BLUETOOTH,
+ SEEMP_API_android_provider_Settings__put_RADIO_BLUETOOTH_);
+ value_to_put_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
+ SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_TIMEOUT_);
+ value_to_put_map.put(Settings.System.VOLUME_RING,
+ SEEMP_API_android_provider_Settings__put_VOLUME_RING_);
+ value_to_put_map.put(Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ SEEMP_API_android_provider_Settings__put_MODE_RINGER_STREAMS_AFFECTED_);
+ value_to_put_map.put(Settings.System.VOLUME_SYSTEM,
+ SEEMP_API_android_provider_Settings__put_VOLUME_SYSTEM_);
+ value_to_put_map.put(Settings.System.SCREEN_OFF_TIMEOUT,
+ SEEMP_API_android_provider_Settings__put_SCREEN_OFF_TIMEOUT_);
+ value_to_put_map.put(Settings.System.RADIO_WIFI,
+ SEEMP_API_android_provider_Settings__put_RADIO_WIFI_);
+ value_to_put_map.put(Settings.System.AUTO_TIME_ZONE,
+ SEEMP_API_android_provider_Settings__put_AUTO_TIME_ZONE_);
+ value_to_put_map.put(Settings.System.TEXT_AUTO_CAPS,
+ SEEMP_API_android_provider_Settings__put_TEXT_AUTO_CAPS_);
+ value_to_put_map.put(Settings.System.WALLPAPER_ACTIVITY,
+ SEEMP_API_android_provider_Settings__put_WALLPAPER_ACTIVITY_);
+ value_to_put_map.put(Settings.System.ANIMATOR_DURATION_SCALE,
+ SEEMP_API_android_provider_Settings__put_ANIMATOR_DURATION_SCALE_);
+ value_to_put_map.put(Settings.System.WIFI_NUM_OPEN_NETWORKS_KEPT,
+ SEEMP_API_android_provider_Settings__put_WIFI_NUM_OPEN_NETWORKS_KEPT_);
+ value_to_put_map.put(Settings.System.LOCK_PATTERN_VISIBLE,
+ SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_VISIBLE_);
+ value_to_put_map.put(Settings.System.VOLUME_VOICE,
+ SEEMP_API_android_provider_Settings__put_VOLUME_VOICE_);
+ value_to_put_map.put(Settings.System.DEBUG_APP,
+ SEEMP_API_android_provider_Settings__put_DEBUG_APP_);
+ value_to_put_map.put(Settings.System.WIFI_ON,
+ SEEMP_API_android_provider_Settings__put_WIFI_ON_);
+ value_to_put_map.put(Settings.System.TEXT_SHOW_PASSWORD,
+ SEEMP_API_android_provider_Settings__put_TEXT_SHOW_PASSWORD_);
+ value_to_put_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
+ SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_);
+ value_to_put_map.put(Settings.System.WIFI_SLEEP_POLICY,
+ SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_);
+ value_to_put_map.put(Settings.System.VOLUME_MUSIC,
+ SEEMP_API_android_provider_Settings__put_VOLUME_MUSIC_);
+ value_to_put_map.put(Settings.System.PARENTAL_CONTROL_LAST_UPDATE,
+ SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_LAST_UPDATE_);
+ value_to_put_map.put(Settings.System.DEVICE_PROVISIONED,
+ SEEMP_API_android_provider_Settings__put_DEVICE_PROVISIONED_);
+ value_to_put_map.put(Settings.System.HTTP_PROXY,
+ SEEMP_API_android_provider_Settings__put_HTTP_PROXY_);
+ value_to_put_map.put(Settings.System.ANDROID_ID,
+ SEEMP_API_android_provider_Settings__put_ANDROID_ID_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_MAX_AP_CHECKS,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_MAX_AP_CHECKS_);
+ value_to_put_map.put(Settings.System.END_BUTTON_BEHAVIOR,
+ SEEMP_API_android_provider_Settings__put_END_BUTTON_BEHAVIOR_);
+ value_to_put_map.put(Settings.System.NEXT_ALARM_FORMATTED,
+ SEEMP_API_android_provider_Settings__put_NEXT_ALARM_FORMATTED_);
+ value_to_put_map.put(Settings.System.RADIO_CELL,
+ SEEMP_API_android_provider_Settings__put_RADIO_CELL_);
+ value_to_put_map.put(Settings.System.PARENTAL_CONTROL_ENABLED,
+ SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_ENABLED_);
+ value_to_put_map.put(Settings.System.BLUETOOTH_ON,
+ SEEMP_API_android_provider_Settings__put_BLUETOOTH_ON_);
+ value_to_put_map.put(Settings.System.WINDOW_ANIMATION_SCALE,
+ SEEMP_API_android_provider_Settings__put_WINDOW_ANIMATION_SCALE_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_);
+ value_to_put_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY,
+ SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_);
+ value_to_put_map.put(Settings.System.WIFI_STATIC_DNS1,
+ SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS1_);
+ value_to_put_map.put(Settings.System.WIFI_STATIC_DNS2,
+ SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS2_);
+ value_to_put_map.put(Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ SEEMP_API_android_provider_Settings__put_HAPTIC_FEEDBACK_ENABLED_);
+ value_to_put_map.put(Settings.System.SHOW_WEB_SUGGESTIONS,
+ SEEMP_API_android_provider_Settings__put_SHOW_WEB_SUGGESTIONS_);
+ value_to_put_map.put(Settings.System.PARENTAL_CONTROL_REDIRECT_URL,
+ SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_REDIRECT_URL_);
+ value_to_put_map.put(Settings.System.DATE_FORMAT,
+ SEEMP_API_android_provider_Settings__put_DATE_FORMAT_);
+ value_to_put_map.put(Settings.System.RADIO_NFC,
+ SEEMP_API_android_provider_Settings__put_RADIO_NFC_);
+ value_to_put_map.put(Settings.System.AIRPLANE_MODE_RADIOS,
+ SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_RADIOS_);
+ value_to_put_map.put(Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
+ SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_);
+ value_to_put_map.put(Settings.System.TIME_12_24,
+ SEEMP_API_android_provider_Settings__put_TIME_12_24_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_);
+ value_to_put_map.put(Settings.System.VOLUME_BLUETOOTH_SCO,
+ SEEMP_API_android_provider_Settings__put_VOLUME_BLUETOOTH_SCO_);
+ value_to_put_map.put(Settings.System.USER_ROTATION,
+ SEEMP_API_android_provider_Settings__put_USER_ROTATION_);
+ value_to_put_map.put(Settings.System.WIFI_STATIC_GATEWAY,
+ SEEMP_API_android_provider_Settings__put_WIFI_STATIC_GATEWAY_);
+ value_to_put_map.put(Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+ SEEMP_API_android_provider_Settings__put_STAY_ON_WHILE_PLUGGED_IN_);
+ value_to_put_map.put(Settings.System.SOUND_EFFECTS_ENABLED,
+ SEEMP_API_android_provider_Settings__put_SOUND_EFFECTS_ENABLED_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_PING_COUNT,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_COUNT_);
+ value_to_put_map.put(Settings.System.DATA_ROAMING,
+ SEEMP_API_android_provider_Settings__put_DATA_ROAMING_);
+ value_to_put_map.put(Settings.System.SETTINGS_CLASSNAME,
+ SEEMP_API_android_provider_Settings__put_SETTINGS_CLASSNAME_);
+ value_to_put_map.put(Settings.System.TRANSITION_ANIMATION_SCALE,
+ SEEMP_API_android_provider_Settings__put_TRANSITION_ANIMATION_SCALE_);
+ value_to_put_map.put(Settings.System.WAIT_FOR_DEBUGGER,
+ SEEMP_API_android_provider_Settings__put_WAIT_FOR_DEBUGGER_);
+ value_to_put_map.put(Settings.System.INSTALL_NON_MARKET_APPS,
+ SEEMP_API_android_provider_Settings__put_INSTALL_NON_MARKET_APPS_);
+ value_to_put_map.put(Settings.System.ADB_ENABLED,
+ SEEMP_API_android_provider_Settings__put_ADB_ENABLED_);
+ value_to_put_map.put(Settings.System.WIFI_USE_STATIC_IP,
+ SEEMP_API_android_provider_Settings__put_WIFI_USE_STATIC_IP_);
+ value_to_put_map.put(Settings.System.DIM_SCREEN,
+ SEEMP_API_android_provider_Settings__put_DIM_SCREEN_);
+ value_to_put_map.put(Settings.System.VOLUME_ALARM,
+ SEEMP_API_android_provider_Settings__put_VOLUME_ALARM_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_ON,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ON_);
+ value_to_put_map.put(Settings.System.WIFI_STATIC_NETMASK,
+ SEEMP_API_android_provider_Settings__put_WIFI_STATIC_NETMASK_);
+ value_to_put_map.put(Settings.System.NETWORK_PREFERENCE,
+ SEEMP_API_android_provider_Settings__put_NETWORK_PREFERENCE_);
+ value_to_put_map.put(Settings.System.SHOW_PROCESSES,
+ SEEMP_API_android_provider_Settings__put_SHOW_PROCESSES_);
+ value_to_put_map.put(Settings.System.TEXT_AUTO_REPLACE,
+ SEEMP_API_android_provider_Settings__put_TEXT_AUTO_REPLACE_);
+ value_to_put_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+ SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_);
+ value_to_put_map.put(Settings.System.APPEND_FOR_LAST_AUDIBLE,
+ SEEMP_API_android_provider_Settings__put_APPEND_FOR_LAST_AUDIBLE_);
+ value_to_put_map.put(Settings.System.SHOW_GTALK_SERVICE_STATUS,
+ SEEMP_API_android_provider_Settings__put_SHOW_GTALK_SERVICE_STATUS_);
+ value_to_put_map.put(Settings.System.SCREEN_BRIGHTNESS,
+ SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_);
+ value_to_put_map.put(Settings.System.USE_GOOGLE_MAIL,
+ SEEMP_API_android_provider_Settings__put_USE_GOOGLE_MAIL_);
+ value_to_put_map.put(Settings.System.RINGTONE,
+ SEEMP_API_android_provider_Settings__put_RINGTONE_);
+ value_to_put_map.put(Settings.System.LOGGING_ID,
+ SEEMP_API_android_provider_Settings__put_LOGGING_ID_);
+ value_to_put_map.put(Settings.System.MODE_RINGER,
+ SEEMP_API_android_provider_Settings__put_MODE_RINGER_);
+ value_to_put_map.put(Settings.System.MUTE_STREAMS_AFFECTED,
+ SEEMP_API_android_provider_Settings__put_MUTE_STREAMS_AFFECTED_);
+ value_to_put_map.put(Settings.System.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
+ SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_);
+ value_to_put_map.put(Settings.System.TEXT_AUTO_PUNCTUATE,
+ SEEMP_API_android_provider_Settings__put_TEXT_AUTO_PUNCTUATE_);
+ value_to_put_map.put(Settings.System.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS,
+ SEEMP_API_android_provider_Settings__put_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_);
+ value_to_put_map.put(Settings.System.SCREEN_BRIGHTNESS_MODE,
+ SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_);
+ }
+
+ public static int getSeempPutApiIdFromValue( String v )
+ {
+ Integer result = value_to_put_map.get( v );
+ if (result == null)
+ {
+ result = -1;
+ }
+ return result;
+ }
+}
diff --git a/core/java/android/util/SparseArrayMap.java b/core/java/android/util/SparseArrayMap.java
index 3287c279c87f..17a4c3aa865c 100644
--- a/core/java/android/util/SparseArrayMap.java
+++ b/core/java/android/util/SparseArrayMap.java
@@ -18,6 +18,7 @@ package android.util;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
import java.util.function.Consumer;
@@ -78,6 +79,7 @@ public class SparseArrayMap<K, V> {
/**
* Get the value associated with the int-K pair.
*/
+ @SuppressLint("KotlinOperator")
@Nullable
public V get(int key, @NonNull K mapKey) {
ArrayMap<K, V> data = mData.get(key);
diff --git a/core/java/android/util/TrustedTime.java b/core/java/android/util/TrustedTime.java
index f279bdb79420..ca236ed7e42f 100644
--- a/core/java/android/util/TrustedTime.java
+++ b/core/java/android/util/TrustedTime.java
@@ -30,6 +30,12 @@ public interface TrustedTime {
/**
* Force update with an external trusted time source, returning {@code true}
* when successful.
+ */
+ public boolean forceSync();
+
+ /**
+ * Force update the cached time with an external trusted time source,
+ * returning {@code true} when successful.
*
* @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime}
*/
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index 73f7543ba819..36d97af6fb0d 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -30,7 +30,10 @@ import android.content.pm.Signature;
import android.content.pm.parsing.ParsingPackageUtils;
import android.os.Build;
import android.os.Trace;
+import android.util.ArrayMap;
+import android.util.Slog;
import android.util.jar.StrictJarFile;
+import android.util.BoostFramework;
import com.android.internal.util.ArrayUtils;
@@ -49,6 +52,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.ZipEntry;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* Facade class that takes care of the details of APK verification on
@@ -60,6 +66,12 @@ public class ApkSignatureVerifier {
private static final AtomicReference<byte[]> sBuffer = new AtomicReference<>();
+ private static final String TAG = "ApkSignatureVerifier";
+ // multithread verification
+ private static final int NUMBER_OF_CORES =
+ Runtime.getRuntime().availableProcessors() >= 4 ? 4 : Runtime.getRuntime().availableProcessors() ;
+ private static BoostFramework sPerfBoost = null;
+ private static boolean sIsPerfLockAcquired = false;
/**
* Verifies the provided APK and returns the certificates associated with each signer.
*
@@ -354,31 +366,44 @@ public class ApkSignatureVerifier {
*/
private static SigningDetailsWithDigests verifyV1Signature(String apkPath, boolean verifyFull)
throws PackageParserException {
- StrictJarFile jarFile = null;
-
+ int objectNumber = verifyFull ? NUMBER_OF_CORES : 1;
+ StrictJarFile[] jarFile = new StrictJarFile[objectNumber];
+ final ArrayMap<String, StrictJarFile> strictJarFiles = new ArrayMap<String, StrictJarFile>();
try {
final Certificate[][] lastCerts;
final Signature[] lastSigs;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
+ if (sPerfBoost == null) {
+ sPerfBoost = new BoostFramework();
+ }
+ if (sPerfBoost != null && !sIsPerfLockAcquired && verifyFull) {
+ //Use big enough number here to hold the perflock for entire PackageInstall session
+ sPerfBoost.perfHint(BoostFramework.VENDOR_HINT_PACKAGE_INSTALL_BOOST,
+ null, Integer.MAX_VALUE, -1);
+ Slog.d(TAG, "Perflock acquired for PackageInstall ");
+ sIsPerfLockAcquired = true;
+ }
// we still pass verify = true to ctor to collect certs, even though we're not checking
// the whole jar.
- jarFile = new StrictJarFile(
- apkPath,
- true, // collect certs
- verifyFull); // whether to reject APK with stripped v2 signatures (b/27887819)
+ for (int i = 0; i < objectNumber; i++) {
+ jarFile[i] = new StrictJarFile(
+ apkPath,
+ true, // collect certs
+ verifyFull); // whether to reject APK with stripped v2 signatures (b/27887819)
+ }
final List<ZipEntry> toVerify = new ArrayList<>();
// Gather certs from AndroidManifest.xml, which every APK must have, as an optimization
// to not need to verify the whole APK when verifyFUll == false.
- final ZipEntry manifestEntry = jarFile.findEntry(
+ final ZipEntry manifestEntry = jarFile[0].findEntry(
ParsingPackageUtils.ANDROID_MANIFEST_FILENAME);
if (manifestEntry == null) {
throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
"Package " + apkPath + " has no manifest");
}
- lastCerts = loadCertificates(jarFile, manifestEntry);
+ lastCerts = loadCertificates(jarFile[0], manifestEntry);
if (ArrayUtils.isEmpty(lastCerts)) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, "Package "
+ apkPath + " has no certificates at entry "
@@ -388,7 +413,7 @@ public class ApkSignatureVerifier {
// fully verify all contents, except for AndroidManifest.xml and the META-INF/ files.
if (verifyFull) {
- final Iterator<ZipEntry> i = jarFile.iterator();
+ final Iterator<ZipEntry> i = jarFile[0].iterator();
while (i.hasNext()) {
final ZipEntry entry = i.next();
if (entry.isDirectory()) continue;
@@ -399,24 +424,93 @@ public class ApkSignatureVerifier {
toVerify.add(entry);
}
-
+ class VerificationData {
+ public Exception exception;
+ public int exceptionFlag;
+ public boolean wait;
+ public int index;
+ public Object objWaitAll;
+ public boolean shutDown;
+ }
+ VerificationData vData = new VerificationData();
+ vData.objWaitAll = new Object();
+ final ThreadPoolExecutor verificationExecutor = new ThreadPoolExecutor(
+ NUMBER_OF_CORES,
+ NUMBER_OF_CORES,
+ 1,/*keep alive time*/
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>());
for (ZipEntry entry : toVerify) {
- final Certificate[][] entryCerts = loadCertificates(jarFile, entry);
- if (ArrayUtils.isEmpty(entryCerts)) {
- throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "Package " + apkPath + " has no certificates at entry "
- + entry.getName());
+ Runnable verifyTask = new Runnable(){
+ public void run() {
+ try {
+ if (vData.exceptionFlag != 0 ) {
+ Slog.w(TAG, "VerifyV1 exit with exception " + vData.exceptionFlag);
+ return;
+ }
+ String tid = Long.toString(Thread.currentThread().getId());
+ StrictJarFile tempJarFile;
+ synchronized (strictJarFiles) {
+ tempJarFile = strictJarFiles.get(tid);
+ if (tempJarFile == null) {
+ if (vData.index >= NUMBER_OF_CORES) {
+ vData.index = 0;
+ }
+ tempJarFile = jarFile[vData.index++];
+ strictJarFiles.put(tid, tempJarFile);
+ }
+ }
+ final Certificate[][] entryCerts = loadCertificates(tempJarFile, entry);
+ if (ArrayUtils.isEmpty(entryCerts)) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+ "Package " + apkPath + " has no certificates at entry "
+ + entry.getName());
+ }
+
+ // make sure all entries use the same signing certs
+ final Signature[] entrySigs = convertToSignatures(entryCerts);
+ if (!Signature.areExactMatch(lastSigs, entrySigs)) {
+ throw new PackageParserException(
+ INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+ "Package " + apkPath + " has mismatched certificates at entry "
+ + entry.getName());
+ }
+ } catch (GeneralSecurityException e) {
+ synchronized (vData.objWaitAll) {
+ vData.exceptionFlag = INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
+ vData.exception = e;
+ }
+ } catch (PackageParserException e) {
+ synchronized (vData.objWaitAll) {
+ vData.exceptionFlag = INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
+ vData.exception = e;
+ }
+ }
+ }};
+ synchronized (vData.objWaitAll) {
+ if (vData.exceptionFlag == 0) {
+ verificationExecutor.execute(verifyTask);
+ }
}
-
- // make sure all entries use the same signing certs
- final Signature[] entrySigs = convertToSignatures(entryCerts);
- if (!Signature.areExactMatch(lastSigs, entrySigs)) {
- throw new PackageParserException(
- INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
- "Package " + apkPath + " has mismatched certificates at entry "
- + entry.getName());
+ }
+ vData.wait = true;
+ verificationExecutor.shutdown();
+ while (vData.wait) {
+ try {
+ if (vData.exceptionFlag != 0 && !vData.shutDown) {
+ Slog.w(TAG, "verifyV1 Exception " + vData.exceptionFlag);
+ verificationExecutor.shutdownNow();
+ vData.shutDown = true;
+ }
+ vData.wait = !verificationExecutor.awaitTermination(50,
+ TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.w(TAG,"VerifyV1 interrupted while awaiting all threads done...");
}
}
+ if (vData.exceptionFlag != 0)
+ throw new PackageParserException(vData.exceptionFlag,
+ "Failed to collect certificates from " + apkPath, vData.exception);
}
return new SigningDetailsWithDigests(
new PackageParser.SigningDetails(lastSigs, SignatureSchemeVersion.JAR), null);
@@ -427,8 +521,16 @@ public class ApkSignatureVerifier {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"Failed to collect certificates from " + apkPath, e);
} finally {
+ if (sIsPerfLockAcquired && sPerfBoost != null) {
+ sPerfBoost.perfLockRelease();
+ sIsPerfLockAcquired = false;
+ Slog.d(TAG, "Perflock released for PackageInstall ");
+ }
+ strictJarFiles.clear();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- closeQuietly(jarFile);
+ for (int i = 0; i < objectNumber ; i++) {
+ closeQuietly(jarFile[i]);
+ }
}
}
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index be172f748b55..39beeeae11de 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -31,6 +31,7 @@ import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
+import android.util.BoostFramework.ScrollOptimizer;
import android.util.Log;
import android.util.TimeUtils;
import android.view.animation.AnimationUtils;
@@ -84,6 +85,7 @@ public final class Choreographer {
// Prints debug messages about jank which was detected (low volume).
private static final boolean DEBUG_JANK = false;
+ private static final boolean OPTS_INPUT = true;
// Prints debug messages about every frame and callback registered (high volume).
private static final boolean DEBUG_FRAMES = false;
@@ -151,6 +153,11 @@ public final class Choreographer {
private static final int MSG_DO_SCHEDULE_VSYNC = 1;
private static final int MSG_DO_SCHEDULE_CALLBACK = 2;
+ private static final int MOTION_EVENT_ACTION_DOWN = 0;
+ private static final int MOTION_EVENT_ACTION_UP = 1;
+ private static final int MOTION_EVENT_ACTION_MOVE = 2;
+ private static final int MOTION_EVENT_ACTION_CANCEL = 3;
+
// All frame callbacks posted by applications have this token.
private static final Object FRAME_CALLBACK_TOKEN = new Object() {
public String toString() { return "FRAME_CALLBACK_TOKEN"; }
@@ -189,6 +196,13 @@ public final class Choreographer {
private int mFPSDivisor = 1;
private DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
new DisplayEventReceiver.VsyncEventData();
+ private int mTouchMoveNum = -1;
+ private int mMotionEventType = -1;
+ private boolean mConsumedMove = false;
+ private boolean mConsumedDown = false;
+ private boolean mIsVsyncScheduled = false;
+ private long mLastTouchOptTimeNanos = 0;
+ private boolean mIsDoFrameProcessing = false;
/**
* Contains information about the current frame for jank-tracking,
@@ -270,6 +284,7 @@ public final class Choreographer {
mLastFrameTimeNanos = Long.MIN_VALUE;
mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
+ ScrollOptimizer.setFrameInterval(mFrameIntervalNanos);
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
@@ -305,6 +320,17 @@ public final class Choreographer {
}
/**
+ * {@hide}
+ */
+ public void setMotionEventInfo(int motionEventType, int touchMoveNum) {
+ synchronized(this) {
+ mTouchMoveNum = touchMoveNum;
+ mMotionEventType = motionEventType;
+ ScrollOptimizer.setMotionType(mMotionEventType);
+ }
+ }
+
+ /**
* @return The Choreographer of the main thread, if it exists, or {@code null} otherwise.
* @hide
*/
@@ -636,7 +662,55 @@ public final class Choreographer {
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
- if (USE_VSYNC) {
+ if (OPTS_INPUT) {
+ if (!mIsVsyncScheduled) {
+ long curr = System.nanoTime();
+ boolean skipFlag = curr - mLastTouchOptTimeNanos < mFrameIntervalNanos;
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "scheduleFrameLocked-mMotionEventType:"
+ + mMotionEventType + " mTouchMoveNum:"+ mTouchMoveNum
+ + " mConsumedDown:" + mConsumedDown
+ + " mConsumedMove:" + mConsumedMove
+ + " mIsDoFrameProcessing:" + mIsDoFrameProcessing
+ + " skip:" + skipFlag
+ + " diff:" + (curr - mLastTouchOptTimeNanos));
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ synchronized(this) {
+ switch(mMotionEventType) {
+ case MOTION_EVENT_ACTION_DOWN:
+ mConsumedMove = false;
+ if (!mConsumedDown && !skipFlag && !mIsDoFrameProcessing) {
+ Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtFrontOfQueue(msg);
+ mLastTouchOptTimeNanos = System.nanoTime();
+ mConsumedDown = true;
+ return;
+ }
+ break;
+ case MOTION_EVENT_ACTION_MOVE:
+ mConsumedDown = false;
+ //if ((mTouchMoveNum == 1) && !mConsumedMove && !skipFlag) {
+ if (!mConsumedMove && !skipFlag && !mIsDoFrameProcessing) {
+ Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtFrontOfQueue(msg);
+ mLastTouchOptTimeNanos = System.nanoTime();
+ mConsumedMove = true;
+ return;
+ }
+ break;
+ case MOTION_EVENT_ACTION_UP:
+ case MOTION_EVENT_ACTION_CANCEL:
+ mConsumedMove = false;
+ mConsumedDown = false;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ if (ScrollOptimizer.shouldUseVsync(USE_VSYNC)) {
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame on vsync.");
}
@@ -652,6 +726,8 @@ public final class Choreographer {
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
+ sFrameDelay = ScrollOptimizer.getFrameDelay(sFrameDelay,
+ mLastFrameTimeNanos);
final long nextFrameTime = Math.max(
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
if (DEBUG_FRAMES) {
@@ -703,11 +779,13 @@ public final class Choreographer {
final long startNanos;
final long frameIntervalNanos = vsyncEventData.frameInterval;
try {
+ mIsDoFrameProcessing = true;
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW,
"Choreographer#doFrame " + vsyncEventData.id);
}
synchronized (mLock) {
+ mIsVsyncScheduled = false;
if (!mFrameScheduled) {
traceMessage("Frame not scheduled");
return; // no work to do
@@ -766,6 +844,7 @@ public final class Choreographer {
mLastVsyncEventData = vsyncEventData;
}
+ ScrollOptimizer.setUITaskStatus(true);
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
mFrameInfo.markInputHandlingStart();
@@ -780,6 +859,7 @@ public final class Choreographer {
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, frameIntervalNanos);
doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, frameIntervalNanos);
+ ScrollOptimizer.setUITaskStatus(false);
} finally {
AnimationUtils.unlockAnimationClock();
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
@@ -791,6 +871,7 @@ public final class Choreographer {
+ (endNanos - startNanos) * 0.000001f + " ms, latency "
+ (startNanos - frameTimeNanos) * 0.000001f + " ms.");
}
+ mIsDoFrameProcessing = false;
}
void doCallbacks(int callbackType, long frameTimeNanos, long frameIntervalNanos) {
@@ -881,6 +962,7 @@ public final class Choreographer {
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#scheduleVsyncLocked");
mDisplayEventReceiver.scheduleVsync();
+ mIsVsyncScheduled = true;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
@@ -1008,6 +1090,7 @@ public final class Choreographer {
mTimestampNanos = timestampNanos;
mFrame = frame;
mLastVsyncEventData = vsyncEventData;
+ ScrollOptimizer.setVsyncTime(mTimestampNanos);
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index c1a5636b7b34..0632dbc6b691 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -38,6 +38,7 @@ import android.graphics.Path;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.DisplayUtils;
import android.util.Pair;
@@ -1038,7 +1039,11 @@ public final class DisplayCutout {
if (TextUtils.isEmpty(spec) && waterfallInsets.equals(Insets.NONE)) {
return NULL_PAIR;
}
-
+ int disableRoundedCorner =
+ SystemProperties.getInt("vendor.display.disable_rounded_corner", 0);
+ if (disableRoundedCorner == 1) {
+ return NULL_PAIR;
+ }
synchronized (CACHE_LOCK) {
if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
&& sCachedDisplayHeight == displayHeight
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 25dda5b2e0bb..f28242aa8215 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -49,6 +49,7 @@ public abstract class InputEventReceiver {
// Map from InputEvent sequence numbers to dispatcher sequence numbers.
private final SparseIntArray mSeqMap = new SparseIntArray();
+ Choreographer mChoreographer;
private static native long nativeInit(WeakReference<InputEventReceiver> receiver,
InputChannel inputChannel, MessageQueue messageQueue);
@@ -259,6 +260,19 @@ public abstract class InputEventReceiver {
onInputEvent(event);
}
+ // Called from native code.
+ @SuppressWarnings("unused")
+ private void dispatchMotionEventInfo(int motionEventType, int touchMoveNum) {
+ try {
+ if (mChoreographer == null)
+ mChoreographer = Choreographer.getInstance();
+
+ if (mChoreographer != null)
+ mChoreographer.setMotionEventInfo(motionEventType, touchMoveNum);
+ } catch (Exception e) {
+ Log.e(TAG, "cannot invoke setMotionEventInfo.");
+ }
+ }
/**
* Dump the state of this InputEventReceiver to the writer.
* @param prefix the prefix (typically whitespace padding) to append in front of each line
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 0e49cc967656..49a55a43b7ab 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -859,6 +859,26 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
+ /**
+ * Control whether the surface view's content should flow through
+ * protected hardware path to display disallowing access from non-secure
+ * execution environments.
+ *
+ * <p>Note that this must be set before the surface view's containing
+ * window is attached to the window manager.
+ *
+ * @param isProtected True if the surface view is protected.
+ *
+ * @hide
+ */
+ public void setProtected(boolean isProtected) {
+ if (isProtected) {
+ mSurfaceFlags |= SurfaceControl.PROTECTED_APP;
+ } else {
+ mSurfaceFlags &= ~SurfaceControl.PROTECTED_APP;
+ }
+ }
+
private void updateOpaqueFlag() {
if (!PixelFormat.formatHasAlpha(mRequestedFormat)) {
mSurfaceFlags |= SurfaceControl.OPAQUE;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f4386099a550..79e52995ade3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14580,6 +14580,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
+ android.util.SeempLog.record(3);
// Defensive cleanup for new gesture
stopNestedScroll();
}
@@ -15260,6 +15261,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param event the KeyEvent object that defines the button action
*/
public boolean onKeyDown(int keyCode, KeyEvent event) {
+ android.util.SeempLog.record(4);
if (KeyEvent.isConfirmKey(keyCode)) {
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
return true;
@@ -15317,6 +15319,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param event The KeyEvent object that defines the button action.
*/
public boolean onKeyUp(int keyCode, KeyEvent event) {
+ android.util.SeempLog.record(5);
if (KeyEvent.isConfirmKey(keyCode)) {
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
return true;
@@ -15961,6 +15964,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return True if the event was handled, false otherwise.
*/
public boolean onTouchEvent(MotionEvent event) {
+ android.util.SeempLog.record(3);
final float x = event.getX();
final float y = event.getY();
final int viewFlags = mViewFlags;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f1eb783726db..6aa85a6cc1d4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -141,6 +141,7 @@ import android.os.UserHandle;
import android.sysprop.DisplayProperties;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
+import android.util.BoostFramework.ScrollOptimizer;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.IndentingPrintWriter;
@@ -791,6 +792,7 @@ public final class ViewRootImpl implements ViewParent,
private int mSurfaceSequenceId = 0;
private String mTag = TAG;
+ boolean mHaveMoveEvent = false;
public ViewRootImpl(Context context, Display display) {
this(context, display, WindowManagerGlobal.getWindowSession(),
@@ -2026,6 +2028,7 @@ public final class ViewRootImpl implements ViewParent,
mSurfaceSize.x, mSurfaceSize.y,
mWindowAttributes.format);
}
+ ScrollOptimizer.setBLASTBufferQueue(mBlastBufferQueue);
return ret;
}
@@ -6444,6 +6447,12 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mUnbufferedDispatchRequested = false;
mAttachInfo.mHandlingPointerEvent = true;
boolean handled = mView.dispatchPointerEvent(event);
+ int action = event.getActionMasked();
+ if (action == MotionEvent.ACTION_MOVE) {
+ mHaveMoveEvent = true;
+ } else if (action == MotionEvent.ACTION_UP) {
+ mHaveMoveEvent = false;
+ }
maybeUpdatePointerIcon(event);
maybeUpdateTooltip(event);
mAttachInfo.mHandlingPointerEvent = false;
@@ -8629,6 +8638,7 @@ public final class ViewRootImpl implements ViewParent,
}
void doProcessInputEvents() {
+ ScrollOptimizer.setBLASTBufferQueue(mBlastBufferQueue);
// Deliver all pending input events in the queue.
while (mPendingInputEventHead != null) {
QueuedInputEvent q = mPendingInputEventHead;
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index a2d3e3447354..3ad4e353f0cb 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -134,6 +134,7 @@ public final class WindowManagerImpl implements WindowManager {
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
+ android.util.SeempLog.record_vg_layout(383,params);
applyTokens(params);
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId());
@@ -141,6 +142,7 @@ public final class WindowManagerImpl implements WindowManager {
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
+ android.util.SeempLog.record_vg_layout(384,params);
applyTokens(params);
mGlobal.updateViewLayout(view, params);
}
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 4a6551176198..5a5709d65c8f 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -402,7 +402,9 @@ public class WebChromeClient {
* origin.
*/
public void onGeolocationPermissionsShowPrompt(String origin,
- GeolocationPermissions.Callback callback) {}
+ GeolocationPermissions.Callback callback) {
+ android.util.SeempLog.record(54);
+ }
/**
* Notify the host application that a request for Geolocation permissions,
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1244d750e164..ac21d952765d 100644..100755
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,6 +36,7 @@ import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.StrictMode;
+import android.os.SystemProperties;
import android.os.Trace;
import android.text.Editable;
import android.text.InputType;
@@ -116,6 +117,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@SuppressWarnings("UnusedDeclaration")
private static final String TAG = "AbsListView";
+ private static final boolean OPTS_INPUT = true;
+ private static final double MOVE_TOUCH_SLOP = 0.6;
+ private static final double TOUCH_SLOP_MIN = 0.6;
+ private static final double TOUCH_SLOP_MAX = 1.0;
/**
* Disables the transcript mode.
@@ -785,6 +790,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*/
private boolean mIsDetaching;
+ private boolean mIsFirstTouchMoveEvent = false;
+ private int mMoveAcceleration;
+ private int mNumTouchMoveEvent = 0;
+
/**
* Interface definition for a callback to be invoked when the list or grid
* has been scrolled.
@@ -932,6 +941,20 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop();
mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor();
+ if (OPTS_INPUT) {
+ double touchslopprop = MOVE_TOUCH_SLOP;
+ if (touchslopprop > 0) {
+ if (touchslopprop < TOUCH_SLOP_MIN) {
+ mMoveAcceleration = (int)(mTouchSlop * TOUCH_SLOP_MIN);
+ } else if ((touchslopprop >= TOUCH_SLOP_MIN) && (touchslopprop < TOUCH_SLOP_MAX)){
+ mMoveAcceleration = (int)(mTouchSlop * touchslopprop);
+ } else {
+ mMoveAcceleration = mTouchSlop;
+ }
+ } else {
+ mMoveAcceleration = mTouchSlop;
+ }
+ }
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance();
@@ -3541,7 +3564,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int deltaY = y - mMotionY;
final int distance = Math.abs(deltaY);
final boolean overscroll = mScrollY != 0;
- if ((overscroll || distance > mTouchSlop) &&
+ boolean isFarEnough = false;
+ if (OPTS_INPUT) {
+ if (mIsFirstTouchMoveEvent) {
+ isFarEnough = distance > mMoveAcceleration;
+ } else {
+ isFarEnough = distance > mTouchSlop;
+ }
+ } else {
+ isFarEnough = distance > mTouchSlop;
+ }
+
+ if ((overscroll || isFarEnough) &&
(getNestedScrollAxes() & SCROLL_AXIS_VERTICAL) == 0) {
createScrollingCache();
if (overscroll) {
@@ -3549,7 +3583,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mMotionCorrection = 0;
} else {
mTouchMode = TOUCH_MODE_SCROLL;
- mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
+ if (mIsFirstTouchMoveEvent) {
+ mMotionCorrection = deltaY > 0 ? mMoveAcceleration : -mMoveAcceleration;
+ } else {
+ mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
+ }
}
removeCallbacks(mPendingCheckForLongPress);
setPressed(false);
@@ -3897,21 +3935,38 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
switch (actionMasked) {
case MotionEvent.ACTION_DOWN: {
onTouchDown(ev);
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
break;
}
case MotionEvent.ACTION_MOVE: {
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent++;
+ if (mNumTouchMoveEvent == 1) {
+ mIsFirstTouchMoveEvent = true;
+ } else {
+ mIsFirstTouchMoveEvent = false;
+ }
+ }
onTouchMove(ev, vtev);
break;
}
case MotionEvent.ACTION_UP: {
onTouchUp(ev);
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
break;
}
case MotionEvent.ACTION_CANCEL: {
onTouchCancel();
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
break;
}
@@ -3927,6 +3982,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mMotionPosition = motionPosition;
}
mLastY = y;
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
break;
}
@@ -3948,6 +4006,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mMotionPosition = motionPosition;
}
mLastY = y;
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
break;
}
}
@@ -4552,6 +4613,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
switch (actionMasked) {
case MotionEvent.ACTION_DOWN: {
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
int touchMode = mTouchMode;
if (touchMode == TOUCH_MODE_OVERFLING || touchMode == TOUCH_MODE_OVERSCROLL) {
mMotionCorrection = 0;
@@ -4589,6 +4653,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
case MotionEvent.ACTION_MOVE: {
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent++;
+ if (mNumTouchMoveEvent == 1) {
+ mIsFirstTouchMoveEvent = true;
+ } else {
+ mIsFirstTouchMoveEvent = false;
+ }
+ }
switch (mTouchMode) {
case TOUCH_MODE_DOWN:
int pointerIndex = ev.findPointerIndex(mActivePointerId);
@@ -4609,6 +4681,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
mTouchMode = TOUCH_MODE_REST;
mActivePointerId = INVALID_POINTER;
recycleVelocityTracker();
@@ -4618,6 +4693,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
case MotionEvent.ACTION_POINTER_UP: {
+ if (OPTS_INPUT) {
+ mNumTouchMoveEvent = 0;
+ }
onSecondaryPointerUp(ev);
break;
}
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 1683878cd8b2..bf4c73ca4740 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -20,10 +20,12 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
+import android.util.BoostFramework.ScrollOptimizer;
import android.util.Log;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.os.SystemProperties;
/**
* This class encapsulates scrolling with the ability to overshoot the bounds
@@ -162,6 +164,9 @@ public class OverScroller {
*/
public final void forceFinished(boolean finished) {
mScrollerX.mFinished = mScrollerY.mFinished = finished;
+ if (finished && mMode == FLING_MODE) {
+ ScrollOptimizer.setFlingFlag(ScrollOptimizer.FLING_END);
+ }
}
/**
@@ -286,6 +291,9 @@ public class OverScroller {
*/
public boolean computeScrollOffset() {
if (isFinished()) {
+ if (mMode == FLING_MODE) {
+ ScrollOptimizer.setFlingFlag(ScrollOptimizer.FLING_END);
+ }
return false;
}
@@ -323,6 +331,9 @@ public class OverScroller {
}
}
+ if (isFinished()) {
+ ScrollOptimizer.setFlingFlag(ScrollOptimizer.FLING_END);
+ }
break;
}
@@ -432,6 +443,8 @@ public class OverScroller {
}
}
+ ScrollOptimizer.setFlingFlag(ScrollOptimizer.FLING_START);
+
mMode = FLING_MODE;
mScrollerX.fling(startX, velocityX, minX, maxX, overX);
mScrollerY.fling(startY, velocityY, minY, maxY, overY);
@@ -499,6 +512,9 @@ public class OverScroller {
* @see #forceFinished(boolean)
*/
public void abortAnimation() {
+ if (mMode == FLING_MODE) {
+ ScrollOptimizer.setFlingFlag(ScrollOptimizer.FLING_END);
+ }
mScrollerX.finish();
mScrollerY.finish();
}
@@ -529,6 +545,7 @@ public class OverScroller {
static class SplineOverScroller {
// Initial position
+ private Context mContext;
private int mStart;
// Current position
@@ -630,6 +647,7 @@ public class OverScroller {
}
SplineOverScroller(Context context) {
+ mContext = context;
mFinished = true;
final float ppi = context.getResources().getDisplayMetrics().density * 160.0f;
mPhysicalCoeff = SensorManager.GRAVITY_EARTH // g (m/s^2)
@@ -832,7 +850,7 @@ public class OverScroller {
}
void notifyEdgeReached(int start, int end, int over) {
- // mState is used to detect successive notifications
+ // mState is used to detect successive notifications
if (mState == SPLINE) {
mOver = over;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
@@ -897,9 +915,10 @@ public class OverScroller {
*/
boolean update() {
final long time = AnimationUtils.currentAnimationTimeMillis();
- final long currentTime = time - mStartTime;
+ final long adjustedTime = ScrollOptimizer.getAdjustedAnimationClock(time);
+ final long currentTime = adjustedTime - mStartTime;
- if (currentTime == 0) {
+ if (currentTime <= 0) {
// Skip work but report that we're still going if we have a nonzero duration.
return mDuration > 0;
}
@@ -939,8 +958,8 @@ public class OverScroller {
final float t = (float) (currentTime) / mDuration;
final float t2 = t * t;
final float sign = Math.signum(mVelocity);
- distance = sign * mOver * (3.0f * t2 - 2.0f * t * t2);
- mCurrVelocity = sign * mOver * 6.0f * (- t + t2);
+ distance = sign * mOver * (3.0f * t2 - 2.0f * t * t2);
+ mCurrVelocity = sign * mOver * 6.0f * (- t + t2);
break;
}
}
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 6ed5b7ebf4d0..33947217116a 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -24,7 +24,6 @@ import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-
/**
* <p>This class encapsulates scrolling. You can use scrollers ({@link Scroller}
* or {@link OverScroller}) to collect the data you need to produce a scrolling
@@ -64,6 +63,7 @@ public class Scroller {
@UnsupportedAppUsage
private final Interpolator mInterpolator;
+ private Context mContext;
private int mMode;
private int mStartX;
@@ -175,6 +175,7 @@ public class Scroller {
*/
public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
mFinished = true;
+ mContext = context;
if (interpolator == null) {
mInterpolator = new ViscousFluidInterpolator();
} else {
diff --git a/core/java/com/android/ims/internal/uce/common/CapInfo.java b/core/java/com/android/ims/internal/uce/common/CapInfo.java
index f5c4b1f5dbe9..11d837056bc4 100644
--- a/core/java/com/android/ims/internal/uce/common/CapInfo.java
+++ b/core/java/com/android/ims/internal/uce/common/CapInfo.java
@@ -251,7 +251,7 @@ public class CapInfo implements Parcelable {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isFtHttpSupported() {
return mFtHttpSupported;
- }
+ }
/**
* Sets File transfer HTTP as supported or not supported.
@@ -260,7 +260,7 @@ public class CapInfo implements Parcelable {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setFtHttpSupported(boolean ftHttpSupported) {
this.mFtHttpSupported = ftHttpSupported;
- }
+ }
/**
* Checks whether FT is supported.
@@ -428,7 +428,7 @@ public class CapInfo implements Parcelable {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void setGeoPullFtSupported(boolean geoPullFtSupported) {
this.mGeoPullFtSupported = geoPullFtSupported;
- }
+ }
/**
* Checks whether Geo Pull is supported.
diff --git a/core/java/com/android/internal/app/ActivityTrigger.java b/core/java/com/android/internal/app/ActivityTrigger.java
new file mode 100644
index 000000000000..dbcb13f49ef5
--- /dev/null
+++ b/core/java/com/android/internal/app/ActivityTrigger.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.util.Log;
+
+public class ActivityTrigger
+{
+ private static final String TAG = "ActivityTrigger";
+
+ /** @hide */
+ public ActivityTrigger() {
+ //Log.d(TAG, "ActivityTrigger initialized");
+ }
+
+ /** @hide */
+ protected void finalize() {
+ native_at_deinit();
+ }
+
+ /** @hide */
+ public void activityStartTrigger(ApplicationInfo appInfo, int pid) {
+ int reserved =0;
+ String activity = null;
+ activity = appInfo.packageName + "/" + appInfo.processName + "/" +
+ appInfo.longVersionCode + "/" + pid;
+ native_at_startApp(activity, reserved);
+ }
+
+ /** @hide */
+ public void activityResumeTrigger(Intent intent, ActivityInfo acInfo,
+ ApplicationInfo appInfo, boolean IsInFullScreen) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+
+ if (cn != null)
+ activity = cn.flattenToString() + "/" + appInfo.versionCode;
+ native_at_resumeActivity(activity);
+ }
+
+ public void activityPauseTrigger(Intent intent, ActivityInfo acInfo, ApplicationInfo appInfo) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+ Log.d(TAG, "ActivityTrigger activityPauseTrigger ");
+ if (null != cn && null != appInfo)
+ activity = cn.flattenToString() + "/" + appInfo.versionCode;
+ native_at_pauseActivity(activity);
+ }
+
+ public void activityStopTrigger(Intent intent, ActivityInfo acInfo, ApplicationInfo appInfo) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+ Log.d(TAG, "ActivityTrigger activityStopTrigger ");
+ if (null != cn && null != appInfo)
+ activity = cn.flattenToString() + "/" + appInfo.versionCode;
+ native_at_stopActivity(activity);
+ }
+
+ public float activityMiscTrigger(int func, String activity, int flag, int type) {
+ return native_at_miscActivity(func, activity, flag, type);
+ }
+
+ private native int native_at_startActivity(String activity, int flags);
+ private native int native_at_startApp(String activity, int flags);
+ private native void native_at_resumeActivity(String activity);
+ private native void native_at_pauseActivity(String activity);
+ private native void native_at_stopActivity(String activity);
+ private native void native_at_deinit();
+ private native float native_at_miscActivity(int func, String activity, int flag, int type);
+}
diff --git a/core/java/com/android/internal/os/BinderDeathDispatcher.java b/core/java/com/android/internal/os/BinderDeathDispatcher.java
index 8ca6241e63c6..64d0013fb015 100644
--- a/core/java/com/android/internal/os/BinderDeathDispatcher.java
+++ b/core/java/com/android/internal/os/BinderDeathDispatcher.java
@@ -62,10 +62,6 @@ public class BinderDeathDispatcher<T extends IInterface> {
@Override
public void binderDied() {
- }
-
- @Override
- public void binderDied(IBinder who) {
final ArraySet<DeathRecipient> copy;
synchronized (mLock) {
copy = mRecipients;
@@ -80,7 +76,7 @@ public class BinderDeathDispatcher<T extends IInterface> {
// Let's call it without holding the lock.
final int size = copy.size();
for (int i = 0; i < size; i++) {
- copy.valueAt(i).binderDied(who);
+ copy.valueAt(i).binderDied();
}
}
}
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index 5a5165ddd7e2..de04b375c4c4 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -22,16 +22,6 @@
},
{
"file_patterns": [
- "BinderDeathDispatcher\\.java"
- ],
- "name": "FrameworksCoreTests",
- "options": [
- { "include-filter": "com.android.internal.os.BinderDeathDispatcherTest" },
- { "exclude-annotation": "com.android.internal.os.SkipPresubmit" }
- ]
- },
- {
- "file_patterns": [
"Battery[^/]*\\.java",
"Kernel[^/]*\\.java",
"[^/]*Power[^/]*\\.java"
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 89b33590ab35..552777430347 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -189,6 +189,12 @@ public class ZygoteInit {
System.loadLibrary("android");
System.loadLibrary("compiler_rt");
System.loadLibrary("jnigraphics");
+
+ try {
+ System.loadLibrary("qti_performance");
+ } catch (UnsatisfiedLinkError e) {
+ Log.e(TAG, "Couldn't load qti_performance");
+ }
}
native private static void nativePreloadAppProcessHALs();
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index d16d9c619403..ac7eb9b4321d 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -96,4 +96,6 @@ interface ILockSettings {
boolean tryUnlockWithCachedUnifiedChallenge(int userId);
void removeCachedUnifiedChallenge(int userId);
void updateEncryptionPassword(int type, in byte[] password);
+ void sanitizePassword();
+ String getPassword();
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index cd1bbb6bc6fe..ea488947ae7b 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -701,6 +701,17 @@ public class LockPatternUtils {
return true;
}
+ /**
+ * clears stored password.
+ */
+ public void sanitizePassword() {
+ try {
+ getLockSettings().sanitizePassword();
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't sanitize password" + re);
+ }
+ }
+
private void updateCryptoUserInfo(int userId) {
if (userId != UserHandle.USER_SYSTEM) {
return;
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 6cbace4c65ba..4dd2b90db2b9 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -95,6 +95,9 @@ public class SystemConfig {
// property for runtime configuration differentiation in vendor
private static final String VENDOR_SKU_PROPERTY = "ro.boot.product.vendor.sku";
+ // property for runtime configuration differentiation based on baseband type
+ private static final String NO_RIL_PROPERTY = "ro.radio.noril";
+
// Group-ids that are given to all packages as read from etc/permissions/*.xml.
int[] mGlobalGids = EmptyArray.INT;
@@ -519,6 +522,17 @@ public class SystemConfig {
vendorPermissionFlag);
}
+ boolean noRilSupport = SystemProperties.getBoolean(NO_RIL_PROPERTY, false);
+ if (noRilSupport) {
+ String noRilDir = "noRil";
+ readPermissions(Environment.buildPath(
+ Environment.getVendorDirectory(), "etc", "sysconfig", noRilDir),
+ vendorPermissionFlag);
+ readPermissions(Environment.buildPath(
+ Environment.getVendorDirectory(), "etc", "permissions", noRilDir),
+ vendorPermissionFlag);
+ }
+
// Allow ODM to customize system configs as much as Vendor, because /odm is another
// vendor partition other than /vendor.
int odmPermissionFlag = vendorPermissionFlag;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 4f27d218f05c..05d8c98f575e 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -46,9 +46,11 @@ cc_library_shared {
"android_text_AndroidCharacter.cpp",
"android_util_EventLog.cpp",
"android_util_Log.cpp",
+ "android_util_SeempLog.cpp",
"android_util_StringBlock.cpp",
"android_util_XmlBlock.cpp",
"android_util_jar_StrictJarFile.cpp",
+ "com_android_internal_app_ActivityTrigger.cpp",
"com_android_internal_util_VirtualRefBasePtr.cpp",
":deviceproductinfoconstants_aidl",
],
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c18d227fa674..9d0715d6e82e 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -100,6 +100,7 @@ extern int register_android_media_ToneGenerator(JNIEnv *env);
extern int register_android_media_midi(JNIEnv *env);
namespace android {
+extern int register_android_util_SeempLog(JNIEnv* env);
/*
* JNI-based registration functions. Note these are properly contained in
@@ -208,6 +209,7 @@ extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
extern int register_android_window_WindowInfosListener(JNIEnv* env);
+extern int register_com_android_internal_app_ActivityTrigger(JNIEnv *env);
// Namespace for Android Runtime flags applied during boot time.
static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
@@ -1500,6 +1502,7 @@ static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env
}
static const RegJNIRec gRegJNI[] = {
+ REG_JNI(register_android_util_SeempLog),
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
@@ -1648,10 +1651,11 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_KernelCpuBpfTracking),
REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader),
REG_JNI(register_com_android_internal_os_KernelCpuUidBpfMapReader),
- REG_JNI(register_com_android_internal_os_KernelSingleProcessCpuThreadReader),
REG_JNI(register_com_android_internal_os_KernelSingleUidTimeReader),
REG_JNI(register_android_window_WindowInfosListener),
+ REG_JNI(register_com_android_internal_app_ActivityTrigger),
+ REG_JNI(register_com_android_internal_os_KernelSingleProcessCpuThreadReader),
};
/*
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index 1382a99c4673..35b9c2beef3c 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -96,6 +96,18 @@ static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr,
queue->getSurface(includeSurfaceControlHandle));
}
+static void nativeSetUndequeuedBufferCount(JNIEnv* env, jclass clazz, jlong ptr, jint count) {
+ sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+ if (queue == nullptr) return;
+ queue->setUndequeuedBufferCount(count);
+}
+
+static jint nativeGetUndequeuedBufferCount(JNIEnv* env, jclass clazz, jlong ptr) {
+ sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+ if (queue == nullptr) return -1;
+ return queue->getUndequeuedBufferCount();
+}
+
static void nativeSetNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong transactionPtr) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr);
@@ -143,6 +155,8 @@ static const JNINativeMethod gMethods[] = {
{"nativeCreate", "(Ljava/lang/String;)J", (void*)nativeCreate},
{"nativeCreateAndUpdate", "(Ljava/lang/String;JJJI)J", (void*)nativeCreateAndUpdate},
{"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
+ {"nativeSetUndequeuedBufferCount", "(JI)V", (void*)nativeSetUndequeuedBufferCount},
+ {"nativeGetUndequeuedBufferCount", "(J)I", (void*)nativeGetUndequeuedBufferCount},
{"nativeDestroy", "(J)V", (void*)nativeDestroy},
{"nativeSetNextTransaction", "(JJ)V", (void*)nativeSetNextTransaction},
{"nativeUpdate", "(JJJJIJ)V", (void*)nativeUpdate},
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 365a18d174c9..cd061e903603 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -62,6 +62,18 @@ struct fields_t {
jmethodID rect_constructor;
jmethodID face_constructor;
jmethodID point_constructor;
+ jfieldID face_sm_degree;
+ jfieldID face_sm_score;
+ jfieldID face_blink_detected;
+ jfieldID face_gaze_angle;
+ jfieldID face_updown_dir;
+ jfieldID face_leftright_dir;
+ jfieldID face_roll_dir;
+ jfieldID face_leye_blink;
+ jfieldID face_reye_blink;
+ jfieldID face_left_right_gaze;
+ jfieldID face_top_bottom_gaze;
+ jfieldID face_recognised;
};
static fields_t fields;
@@ -100,6 +112,7 @@ private:
jclass mFaceClass; // strong reference to Face class
jclass mRectClass; // strong reference to Rect class
jclass mPointClass; // strong reference to Point class
+ bool mIsExtendedFace;
Mutex mLock;
/*
@@ -151,8 +164,16 @@ JNICameraContext::JNICameraContext(JNIEnv* env, jobject weak_this, jclass clazz,
mCameraJClass = (jclass)env->NewGlobalRef(clazz);
mCamera = camera;
- jclass faceClazz = env->FindClass("android/hardware/Camera$Face");
- mFaceClass = (jclass) env->NewGlobalRef(faceClazz);
+ jclass extendedfaceClazz = env->FindClass("com/qualcomm/qti/camera/ExtendedFace");
+ if (NULL != extendedfaceClazz) {
+ mFaceClass = (jclass) env->NewGlobalRef(extendedfaceClazz);
+ mIsExtendedFace = true;
+ } else {
+ env->ExceptionClear();
+ jclass faceClazz = env->FindClass("android/hardware/Camera$Face");
+ mFaceClass = (jclass) env->NewGlobalRef(faceClazz);
+ mIsExtendedFace = false;
+ }
jclass rectClazz = env->FindClass("android/graphics/Rect");
mRectClass = (jclass) env->NewGlobalRef(rectClazz);
@@ -404,7 +425,6 @@ void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_m
env->SetIntField(rect, fields.rect_top, metadata->faces[i].rect[1]);
env->SetIntField(rect, fields.rect_right, metadata->faces[i].rect[2]);
env->SetIntField(rect, fields.rect_bottom, metadata->faces[i].rect[3]);
-
env->SetObjectField(face, fields.face_rect, rect);
env->SetIntField(face, fields.face_score, metadata->faces[i].score);
@@ -433,6 +453,21 @@ void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_m
env->SetIntField(mouth, fields.point_y, metadata->faces[i].mouth[1]);
env->SetObjectField(face, fields.face_mouth, mouth);
env->DeleteLocalRef(mouth);
+
+ if (mIsExtendedFace) {
+ env->SetIntField(face, fields.face_sm_degree, metadata->faces[i].smile_degree);
+ env->SetIntField(face, fields.face_sm_score, metadata->faces[i].smile_score);
+ env->SetIntField(face, fields.face_blink_detected, metadata->faces[i].blink_detected);
+ env->SetIntField(face, fields.face_recognised, metadata->faces[i].face_recognised);
+ env->SetIntField(face, fields.face_gaze_angle, metadata->faces[i].gaze_angle);
+ env->SetIntField(face, fields.face_updown_dir, metadata->faces[i].updown_dir);
+ env->SetIntField(face, fields.face_leftright_dir, metadata->faces[i].leftright_dir);
+ env->SetIntField(face, fields.face_roll_dir, metadata->faces[i].roll_dir);
+ env->SetIntField(face, fields.face_leye_blink, metadata->faces[i].leye_blink);
+ env->SetIntField(face, fields.face_reye_blink, metadata->faces[i].reye_blink);
+ env->SetIntField(face, fields.face_left_right_gaze, metadata->faces[i].left_right_gaze);
+ env->SetIntField(face, fields.face_top_bottom_gaze, metadata->faces[i].top_bottom_gaze);
+ }
}
env->DeleteLocalRef(face);
@@ -470,6 +505,56 @@ void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualM
}
}
+static void android_hardware_Camera_setLongshot(JNIEnv *env, jobject thiz, jboolean enable)
+{
+ ALOGV("setLongshot");
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ if ( enable ) {
+ rc = camera->sendCommand(CAMERA_CMD_LONGSHOT_ON, 0, 0);
+ } else {
+ rc = camera->sendCommand(CAMERA_CMD_LONGSHOT_OFF, 0, 0);
+ }
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "enabling longshot mode failed");
+ }
+}
+
+static void android_hardware_Camera_sendHistogramData(JNIEnv *env, jobject thiz)
+ {
+ ALOGV("sendHistogramData" );
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_SEND_DATA, 0, 0);
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "send histogram data failed");
+ }
+ }
+ static void android_hardware_Camera_setHistogramMode(JNIEnv *env, jobject thiz, jboolean mode)
+ {
+ ALOGV("setHistogramMode: mode:%d", (int)mode);
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ if(mode == true)
+ rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_ON, 0, 0);
+ else
+ rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_OFF, 0, 0);
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "set histogram mode failed");
+ }
+ }
void JNICameraContext::addCallbackBuffer(
JNIEnv *env, jbyteArray cbb, int msgType)
{
@@ -783,7 +868,25 @@ static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject t
context->setCallbackMode(env, installed, manualBuffer);
}
-static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, jint msgType) {
+static void android_hardware_Camera_setMetadataCb(JNIEnv *env, jobject thiz, jboolean mode)
+{
+ ALOGV("setMetadataCb: mode:%d", (int)mode);
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ if(mode == true)
+ rc = camera->sendCommand(CAMERA_CMD_METADATA_ON, 0, 0);
+ else
+ rc = camera->sendCommand(CAMERA_CMD_METADATA_OFF, 0, 0);
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "set metadata mode failed");
+ }
+}
+
+static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, int msgType) {
ALOGV("addCallbackBuffer: 0x%x", msgType);
JNICameraContext* context = reinterpret_cast<JNICameraContext*>(env->GetLongField(thiz, fields.context));
@@ -1051,7 +1154,7 @@ static int32_t android_hardware_Camera_getAudioRestriction(
//-------------------------------------------------
static const JNINativeMethod camMethods[] = {
- { "getNumberOfCameras",
+ { "_getNumberOfCameras",
"()I",
(void *)android_hardware_Camera_getNumberOfCameras },
{ "_getCameraInfo",
@@ -1096,6 +1199,18 @@ static const JNINativeMethod camMethods[] = {
{ "native_takePicture",
"(I)V",
(void *)android_hardware_Camera_takePicture },
+ { "native_setHistogramMode",
+ "(Z)V",
+ (void *)android_hardware_Camera_setHistogramMode },
+ { "native_setMetadataCb",
+ "(Z)V",
+ (void *)android_hardware_Camera_setMetadataCb },
+ { "native_sendHistogramData",
+ "()V",
+ (void *)android_hardware_Camera_sendHistogramData },
+ { "native_setLongshot",
+ "(Z)V",
+ (void *)android_hardware_Camera_setLongshot },
{ "native_setParameters",
"(Ljava/lang/String;)V",
(void *)android_hardware_Camera_setParameters },
@@ -1180,6 +1295,27 @@ int register_android_hardware_Camera(JNIEnv *env)
{ "android/graphics/Point", "y", "I", &fields.point_y},
};
+ field extendedfacefields_to_find[] = {
+ { "com/qualcomm/qti/camera/ExtendedFace", "rect", "Landroid/graphics/Rect;", &fields.face_rect },
+ { "com/qualcomm/qti/camera/ExtendedFace", "score", "I", &fields.face_score },
+ { "com/qualcomm/qti/camera/ExtendedFace", "id", "I", &fields.face_id },
+ { "com/qualcomm/qti/camera/ExtendedFace", "leftEye", "Landroid/graphics/Point;", &fields.face_left_eye },
+ { "com/qualcomm/qti/camera/ExtendedFace", "rightEye", "Landroid/graphics/Point;", &fields.face_right_eye },
+ { "com/qualcomm/qti/camera/ExtendedFace", "mouth", "Landroid/graphics/Point;", &fields.face_mouth },
+ { "com/qualcomm/qti/camera/ExtendedFace", "smileDegree", "I", &fields.face_sm_degree },
+ { "com/qualcomm/qti/camera/ExtendedFace", "smileScore", "I", &fields.face_sm_score },
+ { "com/qualcomm/qti/camera/ExtendedFace", "blinkDetected", "I", &fields.face_blink_detected },
+ { "com/qualcomm/qti/camera/ExtendedFace", "faceRecognized", "I", &fields.face_recognised },
+ { "com/qualcomm/qti/camera/ExtendedFace", "gazeAngle", "I", &fields.face_gaze_angle },
+ { "com/qualcomm/qti/camera/ExtendedFace", "updownDir", "I", &fields.face_updown_dir },
+ { "com/qualcomm/qti/camera/ExtendedFace", "leftrightDir", "I", &fields.face_leftright_dir },
+ { "com/qualcomm/qti/camera/ExtendedFace", "rollDir", "I", &fields.face_roll_dir },
+ { "com/qualcomm/qti/camera/ExtendedFace", "leyeBlink", "I", &fields.face_leye_blink },
+ { "com/qualcomm/qti/camera/ExtendedFace", "reyeBlink", "I", &fields.face_reye_blink },
+ { "com/qualcomm/qti/camera/ExtendedFace", "leftrightGaze", "I", &fields.face_left_right_gaze },
+ { "com/qualcomm/qti/camera/ExtendedFace", "topbottomGaze", "I", &fields.face_top_bottom_gaze },
+ };
+
find_fields(env, fields_to_find, NELEM(fields_to_find));
jclass clazz = FindClassOrDie(env, "android/hardware/Camera");
@@ -1199,6 +1335,14 @@ int register_android_hardware_Camera(JNIEnv *env)
return -1;
}
+ clazz = env->FindClass("com/qualcomm/qti/camera/ExtendedFace");
+ if (NULL != clazz) {
+ fields.face_constructor = env->GetMethodID(clazz, "<init>", "()V");
+ find_fields(env, extendedfacefields_to_find, NELEM(extendedfacefields_to_find));
+ }else {
+ env->ExceptionClear();
+ }
+
// Register native functions
return RegisterMethodsOrDie(env, "android/hardware/Camera", camMethods, NELEM(camMethods));
}
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index e4ef7d39d77c..29887067456a 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -32,6 +32,7 @@
#include "android_hardware_input_InputApplicationHandle.h"
#include "android_util_Binder.h"
#include "core_jni_helpers.h"
+#include "gui/WindowInfo.h"
#include "jni.h"
namespace android {
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index 0e6b587db945..284faa8307be 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -48,6 +48,13 @@
#define ENCODING_DTS_UHD 27
#define ENCODING_DRA 28
+#define ENCODING_AMR_NB 100
+#define ENCODING_AMR_WB 101
+#define ENCODING_EVRC 102
+#define ENCODING_EVRC_B 103
+#define ENCODING_EVRC_WB 104
+#define ENCODING_EVRC_NW 105
+
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1
@@ -92,6 +99,20 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
return AUDIO_FORMAT_AAC_XHE;
case ENCODING_AC4:
return AUDIO_FORMAT_AC4;
+ // case ENCODING_E_AC3_JOC: // FIXME Not defined on the native side yet
+ // return AUDIO_FORMAT_E_AC3_JOC;
+ case ENCODING_AMR_NB:
+ return AUDIO_FORMAT_AMR_NB;
+ case ENCODING_AMR_WB:
+ return AUDIO_FORMAT_AMR_WB;
+ case ENCODING_EVRC:
+ return AUDIO_FORMAT_EVRC;
+ case ENCODING_EVRC_B:
+ return AUDIO_FORMAT_EVRCB;
+ case ENCODING_EVRC_WB:
+ return AUDIO_FORMAT_EVRCWB;
+ case ENCODING_EVRC_NW:
+ return AUDIO_FORMAT_EVRCNW;
case ENCODING_E_AC3_JOC:
return AUDIO_FORMAT_E_AC3_JOC;
case ENCODING_DEFAULT:
@@ -168,6 +189,20 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
return ENCODING_AAC_XHE;
case AUDIO_FORMAT_AC4:
return ENCODING_AC4;
+ // case AUDIO_FORMAT_E_AC3_JOC: // FIXME Not defined on the native side yet
+ // return ENCODING_E_AC3_JOC;
+ case AUDIO_FORMAT_AMR_NB:
+ return ENCODING_AMR_NB;
+ case AUDIO_FORMAT_AMR_WB:
+ return ENCODING_AMR_WB;
+ case AUDIO_FORMAT_EVRC:
+ return ENCODING_EVRC;
+ case AUDIO_FORMAT_EVRCB:
+ return ENCODING_EVRC_B;
+ case AUDIO_FORMAT_EVRCWB:
+ return ENCODING_EVRC_WB;
+ case AUDIO_FORMAT_EVRCNW:
+ return ENCODING_EVRC_NW;
case AUDIO_FORMAT_E_AC3_JOC:
return ENCODING_E_AC3_JOC;
case AUDIO_FORMAT_MAT:
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index dd62bb1726c4..5365eb7e5e77 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -22,6 +22,7 @@
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <cutils/properties.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <meminfo/procmeminfo.h>
@@ -211,11 +212,19 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint
return;
}
+ SchedPolicy sp = (SchedPolicy) grp;
int res = SetTaskProfiles(tid, {get_sched_policy_profile_name((SchedPolicy)grp)}, true) ? 0 : -1;
if (res != NO_ERROR) {
signalExceptionForGroupError(env, -res, tid);
}
+
+ if ((grp == SP_AUDIO_APP) || (grp == SP_AUDIO_SYS)) {
+ res = set_cpuset_policy(tid, sp);
+ if (res != NO_ERROR) {
+ signalExceptionForGroupError(env, -res, tid);
+ }
+ }
}
void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int tid, jint grp)
@@ -353,6 +362,81 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
closedir(d);
}
+void android_os_Process_setCgroupProcsProcessGroup(JNIEnv* env, jobject clazz, int uid, int pid, jint grp, jboolean dex2oat_only)
+{
+ int fd;
+ char pathV1[255], pathV2[255];
+ static bool isCgroupV2 = false;
+ if ((grp == SP_FOREGROUND) || (grp > SP_MAX)) {
+ signalExceptionForGroupError(env, EINVAL, pid);
+ return;
+ }
+
+ //set process group for current process
+ android_os_Process_setProcessGroup(env, clazz, pid, grp);
+
+ //find processes in the same cgroup.procs of current uid and pid
+ snprintf(pathV1, sizeof(pathV1), "/acct/uid_%d/pid_%d/cgroup.procs", uid, pid);
+ snprintf(pathV2, sizeof(pathV2), "/sys/fs/cgroup/uid_%d/pid_%d/cgroup.procs", uid, pid);
+ if (isCgroupV2) {
+ // read from V2 only
+ fd = open(pathV2, O_RDONLY);
+ } else {
+ // first try V1
+ fd = open(pathV1, O_RDONLY);
+ if (fd < 0) {
+ fd = open(pathV2, O_RDONLY);
+ if (fd >= 0) {
+ isCgroupV2 = true;
+ }
+ }
+ }
+ if (fd >= 0) {
+ char buffer[256];
+ char ch;
+ int numRead;
+ size_t len=0;
+ for (;;) {
+ numRead=read(fd, &ch, 1);
+ if (numRead <= 0)
+ break;
+ if (ch != '\n') {
+ buffer[len++] = ch;
+ } else {
+ int temp_pid = atoi(buffer);
+ len=0;
+ if (temp_pid == pid)
+ continue;
+ if (dex2oat_only) {
+ // check if cmdline of temp_pid is dex2oat
+ char cmdline[64];
+ snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", temp_pid);
+ int cmdline_fd = open(cmdline, O_RDONLY);
+ if (cmdline_fd >= 0) {
+ size_t read_size = read(cmdline_fd, buffer, 255);
+ close(cmdline_fd);
+ buffer[read_size]='\0';
+ const char *dex2oat_name1 = "dex2oat"; //for plugins compiler
+ const char *dex2oat_name2 = "/system/bin/dex2oat"; //for installer
+ const char *dex2oat_name3 = "/apex/com.android.runtime/bin/dex2oat"; //for installer
+ if (strncmp(buffer, dex2oat_name1, strlen(dex2oat_name1)) != 0
+ && strncmp(buffer, dex2oat_name2, strlen(dex2oat_name2)) != 0
+ && strncmp(buffer, dex2oat_name3, strlen(dex2oat_name3)) != 0) {
+ continue;
+ }
+ } else {
+ //ALOGE("read %s failed", cmdline);
+ continue;
+ }
+ }
+ //set cgroup of temp_pid follow pid
+ android_os_Process_setProcessGroup(env, clazz, temp_pid, grp);
+ }
+ }
+ close(fd);
+ }
+}
+
void android_os_Process_setProcessFrozen(
JNIEnv *env, jobject clazz, jint pid, jint uid, jboolean freeze)
{
@@ -430,8 +514,21 @@ static void get_cpuset_cores_for_policy(SchedPolicy policy, cpu_set_t *cpu_set)
}
break;
case SP_FOREGROUND:
+ if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
+ return;
+ }
+ break;
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
+ if (!CgroupGetAttributePath("AudioAppCapacityCPUs", &filename)) {
+ return;
+ }
+ if (access(filename.c_str(), F_OK) != 0) {
+ if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
+ return;
+ }
+ }
+ break;
case SP_RT_APP:
if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
return;
@@ -1338,6 +1435,7 @@ static const JNINativeMethod methods[] = {
{"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup},
{"setThreadGroupAndCpuset", "(II)V", (void*)android_os_Process_setThreadGroupAndCpuset},
{"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup},
+ {"setCgroupProcsProcessGroup", "(IIIZ)V", (void*)android_os_Process_setCgroupProcsProcessGroup},
{"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup},
{"createProcessGroup", "(II)I", (void*)android_os_Process_createProcessGroup},
{"getExclusiveCores", "()[I", (void*)android_os_Process_getExclusiveCores},
diff --git a/core/jni/android_util_SeempLog.cpp b/core/jni/android_util_SeempLog.cpp
new file mode 100644
index 000000000000..e48d11472b82
--- /dev/null
+++ b/core/jni/android_util_SeempLog.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2007-2014 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.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <assert.h>
+#include <cutils/properties.h>
+#include <utils/String8.h>
+#include <android_runtime/Log.h>
+#include <utils/Log.h>
+#ifdef __BIONIC__
+#include <android/set_abort_message.h>
+#endif
+#include <utils/Log.h>
+
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+#include "utils/misc.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#define LOG_BUF_SIZE 1024
+#define SEEMP_SOCK_NAME "/dev/socket/seempdw"
+#define ZYGOTE_PARENT_PID 1
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
+static int __write_to_log_init(struct iovec *vec, size_t nr);
+static int (*write_to_log)(struct iovec *vec, size_t nr) = __write_to_log_init;
+static int logd_fd = -1;
+
+/* give up, resources too limited */
+static int __write_to_log_null(struct iovec *vec __unused,
+ size_t nr __unused)
+{
+ return -1;
+}
+
+/* log_init_lock assumed */
+static int __write_to_log_initialize()
+{
+ int i, ret = 0;
+ if (logd_fd >= 0) {
+ i = logd_fd;
+ logd_fd = -1;
+ close(i);
+ }
+
+ i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (i < 0) {
+ ret = -errno;
+ write_to_log = __write_to_log_null;
+ } else if (fcntl(i, F_SETFL, O_NONBLOCK) < 0) {
+ ret = -errno;
+ close(i);
+ i = -1;
+ write_to_log = __write_to_log_null;
+ } else {
+ struct sockaddr_un un;
+ memset(&un, 0, sizeof(struct sockaddr_un));
+ un.sun_family = AF_UNIX;
+ strlcpy(un.sun_path, SEEMP_SOCK_NAME, sizeof(un.sun_path));
+ if (connect(i, (struct sockaddr *)&un, sizeof(struct sockaddr_un)) < 0) {
+ ret = -errno;
+ close(i);
+ i = -1;
+ }
+ }
+ logd_fd = i;
+ return ret;
+}
+
+static int __write_to_log_socket(struct iovec *vec, size_t nr)
+{
+ ssize_t ret;
+ if (logd_fd < 0) {
+ return -EBADF;
+ }
+
+ /*
+ * The write below could be lost, but will never block.
+ *
+ * ENOTCONN occurs if logd dies.
+ * EAGAIN occurs if logd is overloaded.
+ */
+ ret = writev(logd_fd, vec, nr);
+ if (ret < 0) {
+ ret = -errno;
+ if (ret == -ENOTCONN) {
+ ret = __write_to_log_initialize();
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = writev(logd_fd, vec, nr);
+ if (ret < 0) {
+ ret = -errno;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int __write_to_log_init(struct iovec *vec, size_t nr)
+{
+ if (write_to_log == __write_to_log_init) {
+
+ if (getppid() == ZYGOTE_PARENT_PID) {
+ return 0;
+ }
+
+ int ret;
+
+ ret = __write_to_log_initialize();
+ if (ret < 0) {
+ return ret;
+ }
+
+ write_to_log = __write_to_log_socket;
+ }
+ return write_to_log(vec, nr);
+}
+
+int __android_seemp_socket_write(int len, const char *msg)
+{
+ struct iovec vec;
+ vec.iov_base = (void *) msg;
+ vec.iov_len = len;
+
+ return write_to_log(&vec, 1);
+}
+
+namespace android {
+
+/*
+ * In class android.util.Log:
+ * public static native int println_native(int buffer, int priority, String tag, String msg)
+ */
+static jint android_util_SeempLog_println_native(JNIEnv* env, jobject clazz,
+ jint api, jstring msgObj)
+{
+ if (msgObj == NULL) {
+ jniThrowNullPointerException(env, "seemp_println needs a message");
+ return -1;
+ }
+
+ int apiId = (int)api;
+ int apiIdLen = sizeof(apiId);
+ int utf8MsgLen = env->GetStringUTFLength(msgObj);
+ int len = apiIdLen + 1 + utf8MsgLen + 1;
+ char *msg = (char*)malloc(len);
+ if ( NULL == msg )
+ {
+ return -1;
+ }
+ char *params = msg + apiIdLen + 1; // api_id + encoding byte + params
+
+ *((int*)msg) = apiId; // copy api id
+ // // skip encoding byte
+ env->GetStringUTFRegion(msgObj, 0, env->GetStringLength(msgObj), params); // copy message
+ msg[len - 1] = 0; // copy terminating zero
+
+ int res = __android_seemp_socket_write(len, msg); // send message
+
+ free(msg);
+
+ return res;
+}
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ { "seemp_println_native", "(ILjava/lang/String;)I",
+ (void*) android_util_SeempLog_println_native },
+};
+
+int register_android_util_SeempLog(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/util/SeempLog");
+ if (clazz == NULL) {
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env, "android/util/SeempLog", gMethods,
+ NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index a699f912806d..ce419b104c57 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -54,6 +54,7 @@ static struct {
jmethodID onPointerCaptureEvent;
jmethodID onDragEvent;
jmethodID onBatchedInputEventPending;
+ jmethodID dispatchMotionEventInfo;
} gInputEventReceiverClassInfo;
// Add prefix to the beginning of each line in 'str'
@@ -108,6 +109,8 @@ private:
bool mBatchedInputEventPending;
int mFdEvents;
std::vector<OutboundEvent> mOutboundQueue;
+ int mLastMotionEventType = -1;
+ int mLastTouchMoveNum = -1;
void setFdEvents(int events);
@@ -314,10 +317,34 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
bool skipCallbacks = false;
for (;;) {
uint32_t seq;
+ int motionEventType = -1;
+ int touchMoveNum = -1;
+ bool flag = false;
+
InputEvent* inputEvent;
status_t status = mInputConsumer.consume(&mInputEventFactory,
- consumeBatches, frameTime, &seq, &inputEvent);
+ consumeBatches, frameTime, &seq, &inputEvent,
+ &motionEventType, &touchMoveNum, &flag);
+
+ if (!receiverObj.get()) {
+ receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
+ if (!receiverObj.get()) {
+ ALOGW("channel '%s' ~ Receiver object was finalized "
+ "without being disposed.", getInputChannelName().c_str());
+ return DEAD_OBJECT;
+ }
+ }
+
+ if (flag && ((mLastMotionEventType != motionEventType) ||
+ (mLastTouchMoveNum != touchMoveNum))) {
+ env->CallVoidMethod(receiverObj.get(),
+ gInputEventReceiverClassInfo.dispatchMotionEventInfo, motionEventType, touchMoveNum);
+ mLastMotionEventType = motionEventType;
+ mLastTouchMoveNum = touchMoveNum;
+ flag = false;
+ }
+
if (status != OK && status != WOULD_BLOCK) {
ALOGE("channel '%s' ~ Failed to consume input event. status=%s(%d)",
getInputChannelName().c_str(), statusToString(status).c_str(), status);
@@ -611,6 +638,8 @@ int register_android_view_InputEventReceiver(JNIEnv* env) {
gInputEventReceiverClassInfo.onBatchedInputEventPending =
GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onBatchedInputEventPending",
"(I)V");
+ gInputEventReceiverClassInfo.dispatchMotionEventInfo = GetMethodIDOrDie(env,
+ gInputEventReceiverClassInfo.clazz, "dispatchMotionEventInfo", "(II)V");
return res;
}
diff --git a/core/jni/com_android_internal_app_ActivityTrigger.cpp b/core/jni/com_android_internal_app_ActivityTrigger.cpp
new file mode 100644
index 000000000000..9d22f69d91ea
--- /dev/null
+++ b/core/jni/com_android_internal_app_ActivityTrigger.cpp
@@ -0,0 +1,256 @@
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_TAG "ActTriggerJNI"
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <dlfcn.h>
+#include <limits.h>
+#include <string.h>
+
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+namespace android
+{
+
+// ----------------------------------------------------------------------------
+/*
+ * Stuct containing handle to dynamically loaded lib as well as function
+ * pointers to key interfaces.
+ */
+typedef struct dlLibHandler {
+ void *dlhandle;
+ void (*startActivity)(const char *, int *);
+ void (*startApp)(const char *, int *);
+ void (*resumeActivity)(const char *);
+ void (*pauseActivity)(const char *);
+ void (*stopActivity)(const char *);
+ void (*init)(void);
+ void (*deinit)(void);
+ void (*miscActivity)(int, const char *, int, int, float *);
+ const char *dlname;
+}dlLibHandler;
+
+/*
+ * Init for activity trigger library
+ */
+static dlLibHandler mDlLibHandler = {
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "libqti-at.so"
+};
+
+// ----------------------------------------------------------------------------
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_init()
+{
+ bool errored = false;
+
+ mDlLibHandler.dlhandle = dlopen(mDlLibHandler.dlname, RTLD_NOW | RTLD_LOCAL);
+ if (mDlLibHandler.dlhandle == NULL) {
+ return;
+ }
+
+ *(void **) (&mDlLibHandler.startActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_start");
+ if (mDlLibHandler.startActivity == NULL) {
+ errored = true;
+ }
+
+ *(void **) (&mDlLibHandler.startApp) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_qspm_start");
+
+ if (!errored) {
+ *(void **) (&mDlLibHandler.resumeActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_resume");
+ if (mDlLibHandler.resumeActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.pauseActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_pause");
+ if (mDlLibHandler.pauseActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.stopActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_stop");
+ if (mDlLibHandler.stopActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.init) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_init");
+ if (mDlLibHandler.init == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.miscActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_misc");
+ if (mDlLibHandler.miscActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (errored) {
+ mDlLibHandler.startActivity = NULL;
+ mDlLibHandler.startApp = NULL;
+ mDlLibHandler.resumeActivity = NULL;
+ mDlLibHandler.pauseActivity = NULL;
+ mDlLibHandler.stopActivity = NULL;
+ mDlLibHandler.miscActivity = NULL;
+ if (mDlLibHandler.dlhandle) {
+ dlclose(mDlLibHandler.dlhandle);
+ mDlLibHandler.dlhandle = NULL;
+ }
+ } else {
+ (*mDlLibHandler.init)();
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_deinit(JNIEnv *env, jobject clazz)
+{
+ if (mDlLibHandler.dlhandle) {
+ mDlLibHandler.startActivity = NULL;
+ mDlLibHandler.startApp = NULL;
+ mDlLibHandler.resumeActivity = NULL;
+ mDlLibHandler.pauseActivity = NULL;
+ mDlLibHandler.stopActivity = NULL;
+ mDlLibHandler.miscActivity = NULL;
+
+ *(void **) (&mDlLibHandler.deinit) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_deinit");
+ if (mDlLibHandler.deinit) {
+ (*mDlLibHandler.deinit)();
+ }
+
+ dlclose(mDlLibHandler.dlhandle);
+ mDlLibHandler.dlhandle = NULL;
+ }
+}
+
+static jint
+com_android_internal_app_ActivityTrigger_native_at_startActivity(JNIEnv *env, jobject clazz, jstring activity, jint flags)
+{
+ int activiyFlags = flags;
+ if(mDlLibHandler.startActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.startActivity)(actStr, &activiyFlags);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+ return activiyFlags;
+}
+
+static jint
+com_android_internal_app_ActivityTrigger_native_at_startApp(JNIEnv *env, jobject clazz, jstring activity, jint flags)
+{
+ int activiyFlags = flags;
+ if(mDlLibHandler.startApp && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.startApp)(actStr, &activiyFlags);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+ return activiyFlags;
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_resumeActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if(mDlLibHandler.resumeActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.resumeActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_pauseActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if(mDlLibHandler.pauseActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (NULL != actStr) {
+ (*mDlLibHandler.pauseActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_stopActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if(mDlLibHandler.stopActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (NULL != actStr) {
+ (*mDlLibHandler.stopActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static jfloat
+com_android_internal_app_ActivityTrigger_native_at_miscActivity(JNIEnv *env, jobject clazz, jint func, jstring activity, jint type, jint flag)
+{
+ float scaleValue = -1.0f;
+ if (mDlLibHandler.miscActivity && activity && func) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.miscActivity)(func, actStr, type, flag, &scaleValue);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+ return scaleValue;
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"native_at_startActivity", "(Ljava/lang/String;I)I", (void *)com_android_internal_app_ActivityTrigger_native_at_startActivity},
+ {"native_at_startApp", "(Ljava/lang/String;I)I", (void *)com_android_internal_app_ActivityTrigger_native_at_startApp},
+ {"native_at_resumeActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_resumeActivity},
+ {"native_at_pauseActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_pauseActivity},
+ {"native_at_stopActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_stopActivity},
+ {"native_at_deinit", "()V", (void *)com_android_internal_app_ActivityTrigger_native_at_deinit},
+ {"native_at_miscActivity", "(ILjava/lang/String;II)F", (void *)com_android_internal_app_ActivityTrigger_native_at_miscActivity},
+};
+
+int register_com_android_internal_app_ActivityTrigger(JNIEnv *env)
+{
+ com_android_internal_app_ActivityTrigger_native_at_init();
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "com/android/internal/app/ActivityTrigger", gMethods, NELEM(gMethods));
+}
+
+} // namespace android
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index bed0aae074a4..e28cbd8cf1a1 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -75,6 +75,8 @@
#include <bionic/mte.h>
#include <cutils/fs.h>
#include <cutils/multiuser.h>
+#include <cutils/properties.h>
+#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
#include <processgroup/processgroup.h>
@@ -84,6 +86,7 @@
#include <stats_socket.h>
#include <utils/String8.h>
#include <utils/Trace.h>
+#include <dlfcn.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
@@ -613,7 +616,14 @@ static void EnableDebugger() {
if (getrlimit(RLIMIT_CORE, &rl) == -1) {
ALOGE("getrlimit(RLIMIT_CORE) failed");
} else {
- rl.rlim_cur = 0;
+ char prop_value[PROPERTY_VALUE_MAX];
+ property_get("persist.debug.trace", prop_value, "0");
+ if (prop_value[0] == '1') {
+ ALOGI("setting RLIM to infinity");
+ rl.rlim_cur = RLIM_INFINITY;
+ } else {
+ rl.rlim_cur = 0;
+ }
if (setrlimit(RLIMIT_CORE, &rl) == -1) {
ALOGE("setrlimit(RLIMIT_CORE) failed");
}
@@ -627,6 +637,19 @@ static void PreApplicationInit() {
// Set the jemalloc decay time to 1.
mallopt(M_DECAY_TIME, 1);
+
+ void *mBelugaHandle = nullptr;
+ void (*mBeluga)() = nullptr;
+ mBelugaHandle = dlopen("libbeluga.so", RTLD_NOW);
+ if (!mBelugaHandle) {
+ ALOGW("Unable to open libbeluga.so: %s.", dlerror());
+ }
+ else {
+ mBeluga = (void (*) ())dlsym(mBelugaHandle, "beluga");
+ if (mBeluga)
+ mBeluga();
+ dlclose(mBelugaHandle);
+ }
}
static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
@@ -1836,6 +1859,7 @@ static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gi
capabilities |= (1LL << CAP_NET_RAW);
capabilities |= (1LL << CAP_NET_BIND_SERVICE);
capabilities |= (1LL << CAP_SYS_NICE);
+ capabilities |= (1LL << CAP_NET_ADMIN);
}
if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) {
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 83e26f66fd62..2a27b0998d4a 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -712,6 +712,8 @@ message GlobalSettingsProto {
optional SettingProto server = 1;
// Timeout in milliseconds to wait for NTP server.
optional SettingProto timeout_ms = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Secondary NTP server.
+ optional SettingProto server_2 = 3;
}
optional Ntp ntp = 84;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f525315dd5fa..03fa20ecde2b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -52,6 +52,7 @@
<protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
<protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION" />
<protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION" />
+ <protected-broadcast android:name="com.qualcomm.qti.intent.action.PACKAGE_NEEDS_OPTIONAL_VERIFICATION" />
<protected-broadcast android:name="android.intent.action.PACKAGE_VERIFIED" />
<protected-broadcast android:name="android.intent.action.PACKAGES_SUSPENDED" />
<protected-broadcast android:name="android.intent.action.PACKAGES_UNSUSPENDED" />
@@ -172,8 +173,10 @@
<protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
<protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" />
<protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.device.action.TWS_PLUS_DEVICE_PAIR" />
<protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
<protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
+ <protected-broadcast android:name="org.codeaurora.intent.bluetooth.action.REMOTE_ISSUE_OCCURRED" />
<protected-broadcast
android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast
@@ -185,6 +188,8 @@
<protected-broadcast
android:name="android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED" />
<protected-broadcast
+ android:name="android.bluetooth.headset.action.HF_TWSP_BATTERY_STATE_CHANGED" />
+ <protected-broadcast
android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast
android:name="android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED" />
@@ -384,7 +389,28 @@
<protected-broadcast android:name="com.android.server.wifi.wakeup.OPEN_WIFI_PREFERENCES" />
<protected-broadcast android:name="com.android.server.wifi.wakeup.OPEN_WIFI_SETTINGS" />
<protected-broadcast android:name="com.android.server.wifi.wakeup.TURN_OFF_WIFI_WAKE" />
+
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.WIGIG_CREDENTIAL_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.WIGIG_STATE_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.WIGIG_AP_STATE_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.supplicant.CONNECTION_CHANGE" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.STATE_CHANGE" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.CONFIGURED_NETWORKS_CHANGE" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.SCAN_RESULTS" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.LINK_CONFIGURATION_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.WIGIG_RATE_UPGRADE_STATE_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.wigig.RSSI_CHANGED" />
+ <protected-broadcast android:name="wigig_scan_available" />
+ <protected-broadcast android:name="android.net.wigig.p2p.STATE_CHANGED" />
+ <protected-broadcast android:name="android.net.wigig.p2p.CONNECTION_STATE_CHANGE" />
+ <protected-broadcast android:name="android.net.wigig.p2p.PEERS_CHANGED" />
+ <protected-broadcast android:name="android.net.wigig.p2p.DISCOVERY_STATE_CHANGE" />
+ <protected-broadcast android:name="android.net.wigig.p2p.THIS_DEVICE_CHANGED" />
+ <protected-broadcast android:name="android.net.wigig.p2p.PERSISTENT_GROUPS_CHANGED" />
+
<protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.net.wifi.WIFI_ALERT" />
+ <protected-broadcast android:name="com.qualcomm.qti.net.wifi.WIFI_NETWORK_DISCONNECTION" />
<protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
<protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
<protected-broadcast android:name="android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED" />
@@ -411,6 +437,9 @@
<protected-broadcast android:name="android.net.wifi.p2p.PEERS_CHANGED" />
<protected-broadcast android:name="android.net.wifi.p2p.CONNECTION_STATE_CHANGE" />
<protected-broadcast android:name="android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED" />
+ <protected-broadcast android:name="com.qualcomm.qti.net.wifi.DPP_EVENT" />
+ <protected-broadcast android:name="com.qualcomm.qti.net.wifi.PARTIAL_SCAN_RESULTS" />
+ <protected-broadcast android:name="android.net.wifi.COUNTRY_CODE_CHANGED" />
<protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
<protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
<!-- This broadcast is no longer sent in S but it should stay protected to avoid third party
@@ -617,6 +646,11 @@
<protected-broadcast android:name="android.bluetooth.input.profile.action.HANDSHAKE" />
<protected-broadcast android:name="android.bluetooth.input.profile.action.REPORT" />
+ <protected-broadcast android:name="android.bluetooth.bat.profile.action.BA_STATE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.bat.profile.action.BA_ENC_KEY_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.bat.profile.action.BA_DIV_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.bat.profile.action.BA_STR_ID_CHANGED" />
+
<protected-broadcast android:name="android.intent.action.TWILIGHT_CHANGED" />
<protected-broadcast android:name="com.android.server.fingerprint.ACTION_LOCKOUT_RESET" />
@@ -1615,6 +1649,11 @@
<permission android:name="android.permission.MODIFY_CELL_BROADCASTS"
android:protectionLevel="signature|privileged" />
+ <!-- Allows an application to authorize outgoing SMS messages.
+ @hide -->
+ <permission android:name="com.qti.permission.AUTHORIZE_OUTGOING_SMS"
+ android:protectionLevel="signature" />
+
<!-- =============================================================== -->
<!-- Permissions for setting the device alarm -->
<!-- =============================================================== -->
diff --git a/core/res/res/drawable/ic_wifi_4_signal_0.xml b/core/res/res/drawable/ic_wifi_4_signal_0.xml
new file mode 100644
index 000000000000..bf077124f065
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_4_signal_0.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 12,2.001359 C 7.2499999,2.001359 2.9699999,4.079946 -1.25e-7,7.389946 L 12,21.998641 15.048913,18.289401 A 6.2033902,6.4067802 0 0 1 14.192935,16.186142 L 12,18.851901 2.6983696,7.528533 C 5.2683695,5.268533 8.5799999,3.998641 12,3.998641 c 3.42,0 6.73163,1.269892 9.30163,3.529892 l -0.709239,0.86413 a 6.2033902,6.4067802 0 0 1 2.148097,0.529891 L 24,7.389946 c -2.97,-3.31 -7.25,-5.388587 -12,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 24.401344,17.117563 h -1.056598 v 1.849791 h -1.506209 v -1.849791 h -3.602534 v -1.359946 l 3.344006,-5.8716006 h 1.764737 v 5.8844916 h 1.056598 z M 21.838537,15.770508 V 12.79926 q 0,-0.348044 0.01967,-0.754093 0.01968,-0.406048 0.03092,-0.522067 v 0 q -0.146131,0.360936 -0.528296,1.044134 v 0 l -1.83781,3.203274 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_4_signal_1.xml b/core/res/res/drawable/ic_wifi_4_signal_1.xml
new file mode 100644
index 000000000000..619614f90a53
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_4_signal_1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 24.401344,17.117563 h -1.056598 v 1.849791 h -1.506209 v -1.849791 h -3.602534 v -1.359946 l 3.344006,-5.8716006 h 1.764737 v 5.8844916 h 1.056598 z M 21.838537,15.770508 V 12.79926 q 0,-0.348044 0.01967,-0.754093 0.01968,-0.406048 0.03092,-0.522067 v 0 q -0.146131,0.360936 -0.528296,1.044134 v 0 l -1.83781,3.203274 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 13.100543,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 13.10054,18.860054 3.79891,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 13.100543,13.300272 c -3.2,0 -5.2986406,1.799456 -5.4986408,1.899456 l 5.4986408,6.798914 4.043479,-4.997283 a 7.7288137,8.3389834 0 0 1 -0.06114,-0.933424 7.7288137,8.3389834 0 0 1 0.171196,-1.732337 c -0.961558,-0.505425 -2.35688,-1.035326 -4.153535,-1.035326 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_4_signal_2.xml b/core/res/res/drawable/ic_wifi_4_signal_2.xml
new file mode 100644
index 000000000000..e6fd9e862349
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_4_signal_2.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 24.401344,17.117563 h -1.056598 v 1.849791 h -1.506209 v -1.849791 h -3.602534 v -1.359946 l 3.344006,-5.8716006 h 1.764737 v 5.8844916 h 1.056598 z M 21.838537,15.770508 V 12.79926 q 0,-0.348044 0.01967,-0.754093 0.01968,-0.406048 0.03092,-0.522067 v 0 q -0.146131,0.360936 -0.528296,1.044134 v 0 l -1.83781,3.203274 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 12.998638,18.860054 3.697008,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,9.998641 c -4.3999993,0 -7.297826,2.402446 -7.597826,2.702446 l 7.597826,9.297555 4.133152,-5.111414 a 7.7288137,8.3389834 0 0 1 -0.04891,-0.847826 7.7288137,8.3389834 0 0 1 1.377718,-4.744565 C 17.138647,10.644289 15.284639,9.998641 12.998644,9.998641 Z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_4_signal_3.xml b/core/res/res/drawable/ic_wifi_4_signal_3.xml
new file mode 100644
index 000000000000..1b2eb8efee0a
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_4_signal_3.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 24.401344,17.117563 h -1.056598 v 1.849791 h -1.506209 v -1.849791 h -3.602534 v -1.359946 l 3.344006,-5.8716006 h 1.764737 v 5.8844916 h 1.056598 z M 21.838537,15.770508 V 12.79926 q 0,-0.348044 0.01967,-0.754093 0.01968,-0.406048 0.03092,-0.522067 v 0 q -0.146131,0.360936 -0.528296,1.044134 v 0 l -1.83781,3.203274 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,7.398098 c -5.3000001,0 -8.8997284,3.003804 -9.1997284,3.203804 l 9.1997284,11.39674 4.03125,-4.997283 A 7.7288137,8.3389834 0 0 1 16.968751,16.039402 7.7288137,8.3389834 0 0 1 20.164403,9.30163 C 18.559413,8.406307 16.154773,7.398098 12.998641,7.398098 Z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 12.998638,18.860054 3.697008,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_4_signal_4.xml b/core/res/res/drawable/ic_wifi_4_signal_4.xml
new file mode 100644
index 000000000000..d264adbd140d
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_4_signal_4.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 24.401344,17.117563 h -1.056598 v 1.849791 h -1.506209 v -1.849791 h -3.602534 v -1.359946 l 3.344006,-5.8716006 h 1.764737 v 5.8844916 h 1.056598 z M 21.838537,15.770508 V 12.79926 q 0,-0.348044 0.01967,-0.754093 0.01968,-0.406048 0.03092,-0.522067 v 0 q -0.146131,0.360936 -0.528296,1.044134 v 0 l -1.83781,3.203274 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.099185 c -7.3000003,0 -12.0991851,4.002174 -12.59918509,4.402174 L 12.998641,21.998642 16.944293,17.148098 a 7.7288137,8.3389834 0 0 1 -0.06114,-0.978261 7.7288137,8.3389834 0 0 1 7.634511,-8.335597 l 1.084238,-1.332881 c -0.499999,-0.4 -5.303261,-4.402174 -12.603261,-4.402174 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_5_signal_0.xml b/core/res/res/drawable/ic_wifi_5_signal_0.xml
new file mode 100644
index 000000000000..dde3ec85d286
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_5_signal_0.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 12,2.001359 C 7.2499999,2.001359 2.9699999,4.079946 -1.25e-7,7.389946 L 12,21.998641 15.048913,18.289401 A 6.2033902,6.4067802 0 0 1 14.192935,16.186142 L 12,18.851901 2.6983696,7.528533 C 5.2683695,5.268533 8.5799999,3.998641 12,3.998641 c 3.42,0 6.73163,1.269892 9.30163,3.529892 l -0.709239,0.86413 a 6.2033902,6.4067802 0 0 1 2.148097,0.529891 L 24,7.389946 c -2.97,-3.31 -7.25,-5.388587 -12,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.626571,16.969114 v 0 q 0,1.36304 -0.84885,2.1693 -0.84886,0.80626 -2.32751,0.80626 v 0 q -1.29001,0 -2.06585,-0.58112 -0.77583,-0.58112 -0.95838,-1.6825 v 0 l 1.70988,-0.13995 q 0.13387,0.54765 0.47462,0.79713 0.34076,0.24949 0.85799,0.24949 v 0 q 0.63892,0 1.01923,-0.4077 0.38031,-0.40769 0.38031,-1.1744 v 0 q 0,-0.67543 -0.35901,-1.08008 -0.35902,-0.40465 -1.00402,-0.40465 v 0 q -0.71195,0 -1.16223,0.55373 v 0 h -1.66729 l 0.29817,-4.825391 h 5.15397 v 1.27176 h -3.6023 l -0.13996,2.166251 q 0.62067,-0.54764 1.55167,-0.54764 v 0 q 1.22308,0 1.95632,0.76062 0.73324,0.76062 0.73324,2.06889 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_5_signal_1.xml b/core/res/res/drawable/ic_wifi_5_signal_1.xml
new file mode 100644
index 000000000000..5ab3be132f45
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_5_signal_1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.626571,16.969114 v 0 q 0,1.36304 -0.84885,2.1693 -0.84886,0.80626 -2.32751,0.80626 v 0 q -1.29001,0 -2.06585,-0.58112 -0.77583,-0.58112 -0.95838,-1.6825 v 0 l 1.70988,-0.13995 q 0.13387,0.54765 0.47462,0.79713 0.34076,0.24949 0.85799,0.24949 v 0 q 0.63892,0 1.01923,-0.4077 0.38031,-0.40769 0.38031,-1.1744 v 0 q 0,-0.67543 -0.35901,-1.08008 -0.35902,-0.40465 -1.00402,-0.40465 v 0 q -0.71195,0 -1.16223,0.55373 v 0 h -1.66729 l 0.29817,-4.825391 h 5.15397 v 1.27176 h -3.6023 l -0.13996,2.166251 q 0.62067,-0.54764 1.55167,-0.54764 v 0 q 1.22308,0 1.95632,0.76062 0.73324,0.76062 0.73324,2.06889 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 13.100543,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 13.10054,18.860054 3.79891,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 13.100543,13.300272 c -3.2,0 -5.2986406,1.799456 -5.4986408,1.899456 l 5.4986408,6.798914 4.043479,-4.997283 a 7.7288137,8.3389834 0 0 1 -0.06114,-0.933424 7.7288137,8.3389834 0 0 1 0.171196,-1.732337 c -0.961558,-0.505425 -2.35688,-1.035326 -4.153535,-1.035326 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_5_signal_2.xml b/core/res/res/drawable/ic_wifi_5_signal_2.xml
new file mode 100644
index 000000000000..31f09222d13a
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_5_signal_2.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.626571,16.969114 v 0 q 0,1.36304 -0.84885,2.1693 -0.84886,0.80626 -2.32751,0.80626 v 0 q -1.29001,0 -2.06585,-0.58112 -0.77583,-0.58112 -0.95838,-1.6825 v 0 l 1.70988,-0.13995 q 0.13387,0.54765 0.47462,0.79713 0.34076,0.24949 0.85799,0.24949 v 0 q 0.63892,0 1.01923,-0.4077 0.38031,-0.40769 0.38031,-1.1744 v 0 q 0,-0.67543 -0.35901,-1.08008 -0.35902,-0.40465 -1.00402,-0.40465 v 0 q -0.71195,0 -1.16223,0.55373 v 0 h -1.66729 l 0.29817,-4.825391 h 5.15397 v 1.27176 h -3.6023 l -0.13996,2.166251 q 0.62067,-0.54764 1.55167,-0.54764 v 0 q 1.22308,0 1.95632,0.76062 0.73324,0.76062 0.73324,2.06889 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 12.998638,18.860054 3.697008,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,9.998641 c -4.3999993,0 -7.297826,2.402446 -7.597826,2.702446 l 7.597826,9.297555 4.133152,-5.111414 a 7.7288137,8.3389834 0 0 1 -0.04891,-0.847826 7.7288137,8.3389834 0 0 1 1.377718,-4.744565 C 17.138647,10.644289 15.284639,9.998641 12.998644,9.998641 Z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_5_signal_3.xml b/core/res/res/drawable/ic_wifi_5_signal_3.xml
new file mode 100644
index 000000000000..706af960fc2b
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_5_signal_3.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.626571,16.969114 v 0 q 0,1.36304 -0.84885,2.1693 -0.84886,0.80626 -2.32751,0.80626 v 0 q -1.29001,0 -2.06585,-0.58112 -0.77583,-0.58112 -0.95838,-1.6825 v 0 l 1.70988,-0.13995 q 0.13387,0.54765 0.47462,0.79713 0.34076,0.24949 0.85799,0.24949 v 0 q 0.63892,0 1.01923,-0.4077 0.38031,-0.40769 0.38031,-1.1744 v 0 q 0,-0.67543 -0.35901,-1.08008 -0.35902,-0.40465 -1.00402,-0.40465 v 0 q -0.71195,0 -1.16223,0.55373 v 0 h -1.66729 l 0.29817,-4.825391 h 5.15397 v 1.27176 h -3.6023 l -0.13996,2.166251 q 0.62067,-0.54764 1.55167,-0.54764 v 0 q 1.22308,0 1.95632,0.76062 0.73324,0.76062 0.73324,2.06889 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,7.398098 c -5.3000001,0 -8.8997284,3.003804 -9.1997284,3.203804 l 9.1997284,11.39674 4.03125,-4.997283 A 7.7288137,8.3389834 0 0 1 16.968751,16.039402 7.7288137,8.3389834 0 0 1 20.164403,9.30163 C 18.559413,8.406307 16.154773,7.398098 12.998641,7.398098 Z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 12.998638,18.860054 3.697008,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_5_signal_4.xml b/core/res/res/drawable/ic_wifi_5_signal_4.xml
new file mode 100644
index 000000000000..6997bbe202b4
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_5_signal_4.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.626571,16.969114 v 0 q 0,1.36304 -0.84885,2.1693 -0.84886,0.80626 -2.32751,0.80626 v 0 q -1.29001,0 -2.06585,-0.58112 -0.77583,-0.58112 -0.95838,-1.6825 v 0 l 1.70988,-0.13995 q 0.13387,0.54765 0.47462,0.79713 0.34076,0.24949 0.85799,0.24949 v 0 q 0.63892,0 1.01923,-0.4077 0.38031,-0.40769 0.38031,-1.1744 v 0 q 0,-0.67543 -0.35901,-1.08008 -0.35902,-0.40465 -1.00402,-0.40465 v 0 q -0.71195,0 -1.16223,0.55373 v 0 h -1.66729 l 0.29817,-4.825391 h 5.15397 v 1.27176 h -3.6023 l -0.13996,2.166251 q 0.62067,-0.54764 1.55167,-0.54764 v 0 q 1.22308,0 1.95632,0.76062 0.73324,0.76062 0.73324,2.06889 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.099185 c -7.3000003,0 -12.0991851,4.002174 -12.59918509,4.402174 L 12.998641,21.998642 16.944293,17.148098 a 7.7288137,8.3389834 0 0 1 -0.06114,-0.978261 7.7288137,8.3389834 0 0 1 7.634511,-8.335597 l 1.084238,-1.332881 c -0.499999,-0.4 -5.303261,-4.402174 -12.603261,-4.402174 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_6_signal_0.xml b/core/res/res/drawable/ic_wifi_6_signal_0.xml
new file mode 100644
index 000000000000..0d24f5b5251a
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_6_signal_0.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 12,2.001359 C 7.2499999,2.001359 2.9699999,4.079946 -1.25e-7,7.389946 L 12,21.998641 15.048913,18.289401 A 6.2033902,6.4067802 0 0 1 14.192935,16.186142 L 12,18.851901 2.6983696,7.528533 C 5.2683695,5.268533 8.5799999,3.998641 12,3.998641 c 3.42,0 6.73163,1.269892 9.30163,3.529892 l -0.709239,0.86413 a 6.2033902,6.4067802 0 0 1 2.148097,0.529891 L 24,7.389946 c -2.97,-3.31 -7.25,-5.388587 -12,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.217756,16.274066 v 0 q 0,1.31751 -0.814213,2.067022 -0.814212,0.749513 -2.248777,0.749513 v 0 q -1.609039,0 -2.471717,-1.0218 Q 18.820372,17.047 18.820372,15.038537 v 0 q 0,-2.207557 0.875601,-3.323047 Q 20.571575,10.6 22.2,10.6 v 0 q 1.156698,0 1.825516,0.462592 0.668817,0.462591 0.946684,1.434619 v 0 l -1.712431,0.216656 Q 23.014213,11.89994 22.161228,11.89994 v 0 q -0.730207,0 -1.147005,0.661682 -0.4168,0.661682 -0.4168,2.008467 v 0 q 0.29079,-0.439168 0.807751,-0.673393 0.51696,-0.234223 1.169623,-0.234223 v 0 q 1.221318,0 1.932139,0.702671 0.71082,0.702671 0.71082,1.908922 z m -1.822285,0.04685 v 0 q 0,-0.70267 -0.358641,-1.0745 -0.358642,-0.37183 -0.985456,-0.37183 v 0 q -0.600966,0 -0.962838,0.348408 -0.361873,0.348407 -0.361873,0.922255 v 0 q 0,0.720242 0.378028,1.191617 0.378026,0.471375 0.991917,0.471375 v 0 q 0.61389,0 0.956377,-0.395255 0.342486,-0.395254 0.342486,-1.09207 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_6_signal_1.xml b/core/res/res/drawable/ic_wifi_6_signal_1.xml
new file mode 100644
index 000000000000..6c580ee4574f
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_6_signal_1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.217756,16.274066 v 0 q 0,1.31751 -0.814213,2.067022 -0.814212,0.749513 -2.248777,0.749513 v 0 q -1.609039,0 -2.471717,-1.0218 Q 18.820372,17.047 18.820372,15.038537 v 0 q 0,-2.207557 0.875601,-3.323047 Q 20.571575,10.6 22.2,10.6 v 0 q 1.156698,0 1.825516,0.462592 0.668817,0.462591 0.946684,1.434619 v 0 l -1.712431,0.216656 Q 23.014213,11.89994 22.161228,11.89994 v 0 q -0.730207,0 -1.147005,0.661682 -0.4168,0.661682 -0.4168,2.008467 v 0 q 0.29079,-0.439168 0.807751,-0.673393 0.51696,-0.234223 1.169623,-0.234223 v 0 q 1.221318,0 1.932139,0.702671 0.71082,0.702671 0.71082,1.908922 z m -1.822285,0.04685 v 0 q 0,-0.70267 -0.358641,-1.0745 -0.358642,-0.37183 -0.985456,-0.37183 v 0 q -0.600966,0 -0.962838,0.348408 -0.361873,0.348407 -0.361873,0.922255 v 0 q 0,0.720242 0.378028,1.191617 0.378026,0.471375 0.991917,0.471375 v 0 q 0.61389,0 0.956377,-0.395255 0.342486,-0.395254 0.342486,-1.09207 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 13.100543,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 13.10054,18.860054 3.79891,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 13.100543,13.300272 c -3.2,0 -5.2986406,1.799456 -5.4986408,1.899456 l 5.4986408,6.798914 4.043479,-4.997283 a 7.7288137,8.3389834 0 0 1 -0.06114,-0.933424 7.7288137,8.3389834 0 0 1 0.171196,-1.732337 c -0.961558,-0.505425 -2.35688,-1.035326 -4.153535,-1.035326 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_6_signal_2.xml b/core/res/res/drawable/ic_wifi_6_signal_2.xml
new file mode 100644
index 000000000000..345b89824d84
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_6_signal_2.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.217756,16.274066 v 0 q 0,1.31751 -0.814213,2.067022 -0.814212,0.749513 -2.248777,0.749513 v 0 q -1.609039,0 -2.471717,-1.0218 Q 18.820372,17.047 18.820372,15.038537 v 0 q 0,-2.207557 0.875601,-3.323047 Q 20.571575,10.6 22.2,10.6 v 0 q 1.156698,0 1.825516,0.462592 0.668817,0.462591 0.946684,1.434619 v 0 l -1.712431,0.216656 Q 23.014213,11.89994 22.161228,11.89994 v 0 q -0.730207,0 -1.147005,0.661682 -0.4168,0.661682 -0.4168,2.008467 v 0 q 0.29079,-0.439168 0.807751,-0.673393 0.51696,-0.234223 1.169623,-0.234223 v 0 q 1.221318,0 1.932139,0.702671 0.71082,0.702671 0.71082,1.908922 z m -1.822285,0.04685 v 0 q 0,-0.70267 -0.358641,-1.0745 -0.358642,-0.37183 -0.985456,-0.37183 v 0 q -0.600966,0 -0.962838,0.348408 -0.361873,0.348407 -0.361873,0.922255 v 0 q 0,0.720242 0.378028,1.191617 0.378026,0.471375 0.991917,0.471375 v 0 q 0.61389,0 0.956377,-0.395255 0.342486,-0.395254 0.342486,-1.09207 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 12.998638,18.860054 3.697008,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,9.998641 c -4.3999993,0 -7.297826,2.402446 -7.597826,2.702446 l 7.597826,9.297555 4.133152,-5.111414 a 7.7288137,8.3389834 0 0 1 -0.04891,-0.847826 7.7288137,8.3389834 0 0 1 1.377718,-4.744565 C 17.138647,10.644289 15.284639,9.998641 12.998644,9.998641 Z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_6_signal_3.xml b/core/res/res/drawable/ic_wifi_6_signal_3.xml
new file mode 100644
index 000000000000..3eda6ff9407e
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_6_signal_3.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.217756,16.274066 v 0 q 0,1.31751 -0.814213,2.067022 -0.814212,0.749513 -2.248777,0.749513 v 0 q -1.609039,0 -2.471717,-1.0218 Q 18.820372,17.047 18.820372,15.038537 v 0 q 0,-2.207557 0.875601,-3.323047 Q 20.571575,10.6 22.2,10.6 v 0 q 1.156698,0 1.825516,0.462592 0.668817,0.462591 0.946684,1.434619 v 0 l -1.712431,0.216656 Q 23.014213,11.89994 22.161228,11.89994 v 0 q -0.730207,0 -1.147005,0.661682 -0.4168,0.661682 -0.4168,2.008467 v 0 q 0.29079,-0.439168 0.807751,-0.673393 0.51696,-0.234223 1.169623,-0.234223 v 0 q 1.221318,0 1.932139,0.702671 0.71082,0.702671 0.71082,1.908922 z m -1.822285,0.04685 v 0 q 0,-0.70267 -0.358641,-1.0745 -0.358642,-0.37183 -0.985456,-0.37183 v 0 q -0.600966,0 -0.962838,0.348408 -0.361873,0.348407 -0.361873,0.922255 v 0 q 0,0.720242 0.378028,1.191617 0.378026,0.471375 0.991917,0.471375 v 0 q 0.61389,0 0.956377,-0.395255 0.342486,-0.395254 0.342486,-1.09207 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,7.398098 c -5.3000001,0 -8.8997284,3.003804 -9.1997284,3.203804 l 9.1997284,11.39674 4.03125,-4.997283 A 7.7288137,8.3389834 0 0 1 16.968751,16.039402 7.7288137,8.3389834 0 0 1 20.164403,9.30163 C 18.559413,8.406307 16.154773,7.398098 12.998641,7.398098 Z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.0095112 c -4.75,0 -9.029999,2.078587 -12,5.388587 l 12,14.6005438 3.827446,-4.654892 a 7.7288136,8.3389834 0 0 1 -0.04484,-0.835598 7.7288136,8.3389834 0 0 1 0.460598,-2.816576 L 12.998638,18.860054 3.697008,7.5366842 c 2.57,-2.259999 5.88163,-3.529891 9.30163,-3.529891 3.42,0 6.731631,1.269892 9.301631,3.529891 l -1.247282,1.516305 a 7.7288136,8.3389834 0 0 1 3.305705,-0.876359 l 0.639947,-0.778532 c -2.97,-3.31 -7.250001,-5.388587 -12.000001,-5.388587 z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_wifi_6_signal_4.xml b/core/res/res/drawable/ic_wifi_6_signal_4.xml
new file mode 100644
index 000000000000..dc9ff4eb70b6
--- /dev/null
+++ b/core/res/res/drawable/ic_wifi_6_signal_4.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="26"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 25.217756,16.274066 v 0 q 0,1.31751 -0.814213,2.067022 -0.814212,0.749513 -2.248777,0.749513 v 0 q -1.609039,0 -2.471717,-1.0218 Q 18.820372,17.047 18.820372,15.038537 v 0 q 0,-2.207557 0.875601,-3.323047 Q 20.571575,10.6 22.2,10.6 v 0 q 1.156698,0 1.825516,0.462592 0.668817,0.462591 0.946684,1.434619 v 0 l -1.712431,0.216656 Q 23.014213,11.89994 22.161228,11.89994 v 0 q -0.730207,0 -1.147005,0.661682 -0.4168,0.661682 -0.4168,2.008467 v 0 q 0.29079,-0.439168 0.807751,-0.673393 0.51696,-0.234223 1.169623,-0.234223 v 0 q 1.221318,0 1.932139,0.702671 0.71082,0.702671 0.71082,1.908922 z m -1.822285,0.04685 v 0 q 0,-0.70267 -0.358641,-1.0745 -0.358642,-0.37183 -0.985456,-0.37183 v 0 q -0.600966,0 -0.962838,0.348408 -0.361873,0.348407 -0.361873,0.922255 v 0 q 0,0.720242 0.378028,1.191617 0.378026,0.471375 0.991917,0.471375 v 0 q 0.61389,0 0.956377,-0.395255 0.342486,-0.395254 0.342486,-1.09207 z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 12.998641,2.099185 c -7.3000003,0 -12.0991851,4.002174 -12.59918509,4.402174 L 12.998641,21.998642 16.944293,17.148098 a 7.7288137,8.3389834 0 0 1 -0.06114,-0.978261 7.7288137,8.3389834 0 0 1 7.634511,-8.335597 l 1.084238,-1.332881 c -0.499999,-0.4 -5.303261,-4.402174 -12.603261,-4.402174 z"/>
+</vector>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index fe296c704095..303b326e0153 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -30,4 +30,5 @@
lockscreen, setting this to true should come with customized drawables. -->
<bool name="use_lock_pattern_drawable">false</bool>
<bool name="resolver_landscape_phone">true</bool>
+ <bool name="config_wifi_dual_sap_mode_enabled">false</bool>
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d9007e50c7c6..2533199978e5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1848,6 +1848,9 @@
<!-- Integer to set a max latency the accelerometer will batch sensor requests with. -->
<integer name="config_flipToScreenOffMaxLatencyMicros">2000000</integer>
+ <!-- Component name of the combo network location provider. -->
+ <string name="config_comboNetworkLocationProvider" translatable="false">com.qualcomm.location</string>
+
<!-- Boolean indicating if current platform supports bluetooth SCO for off call
use cases -->
<bool name="config_bluetooth_sco_off_call">true</bool>
@@ -3099,6 +3102,9 @@
<!-- Flag indicating which package name can access DeviceConfig table -->
<string name="config_deviceConfiguratorPackageName" translatable="false"></string>
+ <!-- Define optional package verifier name -->
+ <string name="config_optionalPackageVerifierName" translatable="false"></string>
+
<!-- Flag indicating apps will skip sending hold request before merge. In this case
IMS service implementation will do both.i.e.hold followed by merge. -->
<bool name="skipHoldBeforeMerge">true</bool>
@@ -3247,6 +3253,10 @@
phone object irrespective of this config -->
<bool name="config_switch_phone_on_voice_reg_state_change">true</bool>
+ <!-- Config determines whether to add 3 seconds delay for ims deregistration
+ before sending RADIO POWER OFF in APM ON and shutdown scenarios -->
+ <bool name="config_wait_for_ims_deregistration_before_radio_poweroff">false</bool>
+
<bool name="config_sms_force_7bit_encoding">false</bool>
<!-- Number of physical SIM slots on the device. This includes both eSIM and pSIM slots, and
@@ -4227,6 +4237,15 @@
<!-- Package name for ManagedProvisioning which is responsible for provisioning work profiles. -->
<string name="config_managed_provisioning_package" translatable="false">com.android.managedprovisioning</string>
+ <!-- The duration (in milliseconds) for the outgoing sms authorization request to timeout.-->
+ <integer name="config_sms_authorization_timeout_ms">0</integer>
+
+ <!-- Enable sms authorization framework-->
+ <bool name="config_sms_authorization_enabled">false</bool>
+
+ <!-- whether to enable primarycard -->
+ <bool name="config_primarycard">false</bool>
+
<!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
<bool name="config_swipe_up_gesture_setting_available">true</bool>
@@ -4262,6 +4281,10 @@
<!-- Whether or not the "SMS app service" feature is enabled -->
<bool name="config_useSmsAppService">true</bool>
+ <!-- List of names that represent dual SoftAp interfaces. -->
+ <string-array translatable="false" name="config_wifi_dual_sap_interfaces">
+ </string-array>
+
<!-- Class name for the InputEvent compatibility processor override.
Empty string means use the default compatibility processor
(android.view.InputEventCompatProcessor). -->
@@ -5160,6 +5183,10 @@
<!-- the number of the max cached processes in the system. -->
<integer name="config_customizedMaxCachedProcesses">32</integer>
+ <!-- Maximum time in millisecs for telephony should wait to deactivate data call
+ when user turned off mobile data or data roaming during CIWLAN -->
+ <integer name="config_maximumDelayTimeToDeactivateDataCall">7000</integer>
+
<!-- The display cutout configs for secondary built-in display. -->
<string name="config_secondaryBuiltInDisplayCutout" translatable="false"></string>
<string name="config_secondaryBuiltInDisplayCutoutRectApproximation" translatable="false">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 166d6abd1809..d497593ad5ec 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -291,6 +291,8 @@
<string name="wfc_mode_cellular_preferred_summary">Call over mobile network</string>
<!-- WFC, summary for Wi-Fi Only -->
<string name="wfc_mode_wifi_only_summary">Wi-Fi only</string>
+ <!-- WFC, summary for Ims Preferred -->
+ <string name="wfc_mode_ims_preferred_summary">Ims Preferred</string>
<!-- Template for showing mobile network operator name while Cross SIM calling is active -->
<string-array name="crossSimSpnFormats" translatable="false">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f68c26d76610..3ea2cc0cb544 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -896,6 +896,7 @@
<java-symbol type="string" name="wifi_calling_off_summary" />
<java-symbol type="string" name="wfc_mode_wifi_preferred_summary" />
<java-symbol type="string" name="wfc_mode_cellular_preferred_summary" />
+ <java-symbol type="string" name="wfc_mode_ims_preferred_summary" />
<java-symbol type="string" name="wfc_mode_wifi_only_summary" />
<java-symbol type="array" name="crossSimSpnFormats" />
<java-symbol type="string" name="policydesc_disableCamera" />
@@ -1384,6 +1385,21 @@
<java-symbol type="drawable" name="ic_wifi_signal_2" />
<java-symbol type="drawable" name="ic_wifi_signal_3" />
<java-symbol type="drawable" name="ic_wifi_signal_4" />
+ <java-symbol type="drawable" name="ic_wifi_4_signal_0" />
+ <java-symbol type="drawable" name="ic_wifi_4_signal_1" />
+ <java-symbol type="drawable" name="ic_wifi_4_signal_2" />
+ <java-symbol type="drawable" name="ic_wifi_4_signal_3" />
+ <java-symbol type="drawable" name="ic_wifi_4_signal_4" />
+ <java-symbol type="drawable" name="ic_wifi_5_signal_0" />
+ <java-symbol type="drawable" name="ic_wifi_5_signal_1" />
+ <java-symbol type="drawable" name="ic_wifi_5_signal_2" />
+ <java-symbol type="drawable" name="ic_wifi_5_signal_3" />
+ <java-symbol type="drawable" name="ic_wifi_5_signal_4" />
+ <java-symbol type="drawable" name="ic_wifi_6_signal_0" />
+ <java-symbol type="drawable" name="ic_wifi_6_signal_1" />
+ <java-symbol type="drawable" name="ic_wifi_6_signal_2" />
+ <java-symbol type="drawable" name="ic_wifi_6_signal_3" />
+ <java-symbol type="drawable" name="ic_wifi_6_signal_4" />
<java-symbol type="drawable" name="ic_signal_wifi_transient_animation" />
<java-symbol type="drawable" name="ic_hotspot_transient_animation" />
<java-symbol type="drawable" name="ic_bluetooth_transient_animation" />
@@ -2101,6 +2117,7 @@
<java-symbol type="string" name="config_geocoderProviderPackageName" />
<java-symbol type="string" name="config_geofenceProviderPackageName" />
<java-symbol type="string" name="config_networkLocationProviderPackageName" />
+ <java-symbol type="string" name="config_comboNetworkLocationProvider" />
<java-symbol type="string" name="config_wimaxManagerClassname" />
<java-symbol type="string" name="config_wimaxNativeLibLocation" />
<java-symbol type="string" name="config_wimaxServiceClassname" />
@@ -2230,6 +2247,7 @@
<java-symbol type="string" name="config_primaryLocationTimeZoneProviderPackageName" />
<java-symbol type="bool" name="config_enableSecondaryLocationTimeZoneProvider" />
<java-symbol type="string" name="config_secondaryLocationTimeZoneProviderPackageName" />
+ <java-symbol type="string" name="config_optionalPackageVerifierName" />
<java-symbol type="bool" name="config_autoResetAirplaneMode" />
<java-symbol type="string" name="config_notificationAccessConfirmationActivity" />
@@ -2721,6 +2739,7 @@
<java-symbol type="bool" name="config_restart_radio_on_pdp_fail_regular_deactivation" />
<java-symbol type="array" name="networks_not_clear_data" />
<java-symbol type="bool" name="config_switch_phone_on_voice_reg_state_change" />
+ <java-symbol type="bool" name="config_wait_for_ims_deregistration_before_radio_poweroff" />
<java-symbol type="string" name="whichHomeApplicationNamed" />
<java-symbol type="string" name="whichHomeApplicationLabel" />
<java-symbol type="bool" name="config_sms_force_7bit_encoding" />
@@ -3836,7 +3855,11 @@
<java-symbol type="dimen" name="car_padding_4" />
<java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" />
+ <java-symbol type="integer" name="config_sms_authorization_timeout_ms" />
+ <java-symbol type="bool" name="config_sms_authorization_enabled" />
+
<java-symbol type="string" name="battery_saver_description_with_learn_more" />
+ <java-symbol type="bool" name="config_primarycard" />
<java-symbol type="string" name="confirm_battery_saver" />
<java-symbol type="attr" name="opticalInsetLeft" />
@@ -3848,6 +3871,10 @@
<java-symbol type="drawable" name="ic_arrow_forward" />
<java-symbol type="drawable" name="ic_permission" />
+ <!-- For Dual SoftaAp -->
+ <java-symbol type="array" name="config_wifi_dual_sap_interfaces" />
+ <java-symbol type="bool" name="config_wifi_dual_sap_mode_enabled" />
+
<java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" />
<java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" />
<java-symbol type="integer" name="config_defaultRingVibrationIntensity" />
@@ -4460,6 +4487,8 @@
<java-symbol type="color" name="overview_background"/>
+ <java-symbol type="integer" name="config_maximumDelayTimeToDeactivateDataCall" />
+
<java-symbol type="string" name="config_secondaryBuiltInDisplayCutout" />
<java-symbol type="string" name="config_secondaryBuiltInDisplayCutoutRectApproximation" />
<java-symbol type="bool" name="config_fillSecondaryBuiltInDisplayCutout" />
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 796d7e8ff407..b647191c2aec 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -83,5 +83,6 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" />
</manifest>
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
index 83103333f68b..942045c8bf35 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
@@ -17,7 +17,6 @@ package com.android.internal.os;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -32,14 +31,14 @@ import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.FileDescriptor;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BinderDeathDispatcherTest {
@@ -121,7 +120,7 @@ public class BinderDeathDispatcherTest {
public void die() {
isAlive = false;
if (mRecipient != null) {
- mRecipient.binderDied(this);
+ mRecipient.binderDied();
}
mRecipient = null;
}
@@ -228,33 +227,33 @@ public class BinderDeathDispatcherTest {
// Kill the targets.
t1.die();
- verify(r1, times(1)).binderDied(t1);
- verify(r2, times(1)).binderDied(t1);
- verify(r3, times(1)).binderDied(t1);
- verify(r4, times(0)).binderDied(any());
- verify(r5, times(0)).binderDied(any());
+ verify(r1, times(1)).binderDied();
+ verify(r2, times(1)).binderDied();
+ verify(r3, times(1)).binderDied();
+ verify(r4, times(0)).binderDied();
+ verify(r5, times(0)).binderDied();
assertThat(d.getTargetsForTest().size()).isEqualTo(2);
reset(r1, r2, r3, r4, r5);
t2.die();
- verify(r1, times(1)).binderDied(t2);
- verify(r2, times(0)).binderDied(any());
- verify(r3, times(0)).binderDied(any());
- verify(r4, times(0)).binderDied(any());
- verify(r5, times(0)).binderDied(any());
+ verify(r1, times(1)).binderDied();
+ verify(r2, times(0)).binderDied();
+ verify(r3, times(0)).binderDied();
+ verify(r4, times(0)).binderDied();
+ verify(r5, times(0)).binderDied();
assertThat(d.getTargetsForTest().size()).isEqualTo(1);
reset(r1, r2, r3, r4, r5);
t3.die();
- verify(r1, times(0)).binderDied(any());
- verify(r2, times(0)).binderDied(any());
- verify(r3, times(1)).binderDied(t3);
- verify(r4, times(0)).binderDied(any());
- verify(r5, times(1)).binderDied(t3);
+ verify(r1, times(0)).binderDied();
+ verify(r2, times(0)).binderDied();
+ verify(r3, times(1)).binderDied();
+ verify(r4, times(0)).binderDied();
+ verify(r5, times(1)).binderDied();
assertThat(d.getTargetsForTest().size()).isEqualTo(0);
@@ -263,27 +262,4 @@ public class BinderDeathDispatcherTest {
assertThat(d.getTargetsForTest().size()).isEqualTo(0);
}
-
- @Test
- public void duplicateRegistrations() {
- BinderDeathDispatcher<MyTarget> d = new BinderDeathDispatcher<>();
-
- MyTarget t1 = new MyTarget();
-
- DeathRecipient r1 = mock(DeathRecipient.class);
- DeathRecipient r2 = mock(DeathRecipient.class);
-
- for (int i = 0; i < 5; i++) {
- assertThat(d.linkToDeath(t1, r1)).isEqualTo(1);
- }
- assertThat(d.linkToDeath(t1, r2)).isEqualTo(2);
-
- t1.die();
- verify(r1, times(1)).binderDied(t1);
- verify(r2, times(1)).binderDied(t1);
-
- d.unlinkToDeath(t1, r1);
- d.unlinkToDeath(t1, r2);
- assertThat(d.getTargetsForTest()).isEmpty();
- }
}