Merge changes from topic "networkagent"
* changes:
Rename NetworkMisc to NetworkAgentConfig.
Make NetworkAgent stop subclassing Handler.
diff --git a/Android.bp b/Android.bp
index 8c85631..abd7d2d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -487,7 +487,7 @@
"framework-minus-apex",
"updatable_media_stubs",
"framework_mediaprovider_stubs",
- "framework-appsearch", // TODO(b/146218515): should be framework-appsearch-stubs
+ "framework-appsearch-stubs",
"framework-sdkextensions-stubs-systemapi",
// TODO(b/146167933): Use framework-statsd-stubs instead.
"framework-statsd",
diff --git a/StubLibraries.bp b/StubLibraries.bp
index d195047..baa3c61 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -41,10 +41,9 @@
]
stubs_defaults {
- name: "metalava-api-stubs-default",
+ name: "metalava-non-updatable-api-stubs-default",
srcs: [
":framework-non-updatable-sources",
- ":framework-updatable-sources",
"core/java/**/*.logtags",
":opt-telephony-srcs",
":opt-net-voip-srcs",
@@ -64,14 +63,23 @@
"sdk-dir",
"api-versions-jars-dir",
],
- sdk_version: "core_platform",
filter_packages: packages_to_document,
}
+stubs_defaults {
+ name: "metalava-api-stubs-default",
+ defaults: ["metalava-non-updatable-api-stubs-default"],
+ srcs: [":framework-updatable-sources"],
+ sdk_version: "core_platform",
+}
+
/////////////////////////////////////////////////////////////////////
// *-api-stubs-docs modules providing source files for the stub libraries
/////////////////////////////////////////////////////////////////////
+// api-stubs-docs, system-api-stubs-docs, and test-api-stubs-docs have APIs
+// from the non-updatable part of the platform as well as from the updatable
+// modules
droidstubs {
name: "api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
@@ -112,7 +120,10 @@
arg_files: [
"core/res/AndroidManifest.xml",
],
- args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS,process=android.annotation.SystemApi.Process.ALL\\)",
+ args: metalava_framework_docs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\)",
check_api: {
current: {
api_file: "api/system-current.txt",
@@ -155,6 +166,111 @@
}
/////////////////////////////////////////////////////////////////////
+// Following droidstubs modules are for extra APIs for modules.
+// The framework currently have two more API surfaces for modules:
+// @SystemApi(client=MODULE_APPS) and @SystemApi(client=MODULE_LIBRARIES)
+/////////////////////////////////////////////////////////////////////
+
+// TODO(b/146727827) remove the *-api modules when we can teach metalava
+// about the relationship among the API surfaces. Currently, these modules are only to generate
+// the API signature files and ensure that the APIs evolve in a backwards compatible manner.
+// They however are NOT used for building the API stub.
+droidstubs {
+ name: "module-app-api",
+ defaults: ["metalava-non-updatable-api-stubs-default"],
+ libs: ["framework-all"],
+ arg_files: ["core/res/AndroidManifest.xml"],
+ args: metalava_framework_docs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\)",
+ check_api: {
+ current: {
+ api_file: "api/module-app-current.txt",
+ removed_api_file: "api/module-app-removed.txt",
+ },
+ // TODO(b/147559833) enable the compatibility check against the last release API
+ // and the API lint
+ //last_released: {
+ // api_file: ":last-released-module-app-api",
+ // removed_api_file: "api/module-app-removed.txt",
+ // baseline_file: ":module-app-api-incompatibilities-with-last-released"
+ //},
+ //api_lint: {
+ // enabled: true,
+ // new_since: ":last-released-module-app-api",
+ // baseline_file: "api/module-app-lint-baseline.txt",
+ //},
+ },
+ //jdiff_enabled: true,
+}
+
+droidstubs {
+ name: "module-lib-api",
+ defaults: ["metalava-non-updatable-api-stubs-default"],
+ libs: ["framework-all"],
+ arg_files: ["core/res/AndroidManifest.xml"],
+ args: metalava_framework_docs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES," +
+ "process=android.annotation.SystemApi.Process.ALL\\)",
+ check_api: {
+ current: {
+ api_file: "api/module-lib-current.txt",
+ removed_api_file: "api/module-lib-removed.txt",
+ },
+ // TODO(b/147559833) enable the compatibility check against the last release API
+ // and the API lint
+ //last_released: {
+ // api_file: ":last-released-module-lib-api",
+ // removed_api_file: "api/module-lib-removed.txt",
+ // baseline_file: ":module-lib-api-incompatibilities-with-last-released"
+ //},
+ //api_lint: {
+ // enabled: true,
+ // new_since: ":last-released-module-lib-api",
+ // baseline_file: "api/module-lib-lint-baseline.txt",
+ //},
+ },
+ //jdiff_enabled: true,
+}
+
+// The following two droidstubs modules generate source files for the API stub libraries for
+// modules. Note that they not only include their own APIs but also other APIs that have
+// narrower scope. For example, module-lib-api-stubs-docs includes all @SystemApis not just
+// the ones with 'client=MODULE_LIBRARIES'.
+droidstubs {
+ name: "module-app-api-stubs-docs",
+ defaults: ["metalava-non-updatable-api-stubs-default"],
+ libs: ["framework-all"],
+ arg_files: ["core/res/AndroidManifest.xml"],
+ args: metalava_framework_docs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\)" +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\)",
+}
+
+droidstubs {
+ name: "module-lib-api-stubs-docs",
+ defaults: ["metalava-non-updatable-api-stubs-default"],
+ libs: ["framework-all"],
+ arg_files: ["core/res/AndroidManifest.xml"],
+ args: metalava_framework_docs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\)" +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\)" +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES," +
+ "process=android.annotation.SystemApi.Process.ALL\\)",
+}
+
+/////////////////////////////////////////////////////////////////////
// android_*_stubs_current modules are the stubs libraries compiled
// from *-api-stubs-docs
/////////////////////////////////////////////////////////////////////
@@ -169,7 +285,6 @@
java_resources: [
":notices-for-framework-stubs",
],
- sdk_version: "core_current",
system_modules: "none",
java_version: "1.8",
compile_dex: true,
@@ -187,6 +302,7 @@
"private-stub-annotations-jar",
],
defaults: ["framework-stubs-default"],
+ sdk_version: "core_current",
}
java_library_static {
@@ -201,6 +317,7 @@
"private-stub-annotations-jar",
],
defaults: ["framework-stubs-default"],
+ sdk_version: "core_current",
}
java_library_static {
@@ -215,6 +332,37 @@
"private-stub-annotations-jar",
],
defaults: ["framework-stubs-default"],
+ sdk_version: "core_current",
+}
+
+java_library_static {
+ name: "framework_module_app_stubs_current",
+ srcs: [
+ ":module-app-api-stubs-docs",
+ ],
+ libs: [
+ "stub-annotations",
+ "framework-all",
+ ],
+ static_libs: [
+ "private-stub-annotations-jar",
+ ],
+ defaults: ["framework-stubs-default"],
+}
+
+java_library_static {
+ name: "framework_module_lib_stubs_current",
+ srcs: [
+ ":module-lib-api-stubs-docs",
+ ],
+ libs: [
+ "stub-annotations",
+ "framework-all",
+ ],
+ static_libs: [
+ "private-stub-annotations-jar",
+ ],
+ defaults: ["framework-stubs-default"],
}
/////////////////////////////////////////////////////////////////////
diff --git a/apex/Android.bp b/apex/Android.bp
index 56f7db2..abebfa3 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -37,6 +37,36 @@
stubs_defaults {
name: "framework-module-stubs-defaults-systemapi",
- args: mainline_stubs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS,process=android.annotation.SystemApi.Process.ALL\\) ",
+ args: mainline_stubs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\) ",
+ installable: false,
+}
+
+stubs_defaults {
+ name: "framework-module-stubs-defaults-module_apps_api",
+ args: mainline_stubs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\) " +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\) ",
+ installable: false,
+}
+
+stubs_defaults {
+ name: "framework-module-stubs-defaults-module_libs_api",
+ args: mainline_stubs_args +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\) " +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_APPS," +
+ "process=android.annotation.SystemApi.Process.ALL\\) " +
+ " --show-annotation android.annotation.SystemApi\\(" +
+ "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES," +
+ "process=android.annotation.SystemApi.Process.ALL\\) ",
installable: false,
}
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp
index 1f30dda..60cc3be 100644
--- a/apex/appsearch/framework/Android.bp
+++ b/apex/appsearch/framework/Android.bp
@@ -30,29 +30,10 @@
libs: [
"framework-minus-apex", // TODO(b/146218515) should be framework-system-stubs
],
- visibility: [
- "//frameworks/base/apex/appsearch:__subpackages__",
- // TODO(b/146218515) remove this when framework is built with the stub of appsearch
- "//frameworks/base",
- ],
+ visibility: ["//frameworks/base/apex/appsearch:__subpackages__"],
apex_available: ["com.android.appsearch"],
}
-metalava_appsearch_docs_args =
- "--hide-package com.android.server " +
- "--error UnhiddenSystemApi " +
- "--hide RequiresPermission " +
- "--hide MissingPermission " +
- "--hide BroadcastBehavior " +
- "--hide HiddenSuperclass " +
- "--hide DeprecationMismatch " +
- "--hide UnavailableSymbol " +
- "--hide SdkConstant " +
- "--hide HiddenTypeParameter " +
- "--hide Todo --hide Typo " +
- "--hide HiddenTypedefConstant " +
- "--show-annotation android.annotation.SystemApi "
-
droidstubs {
name: "framework-appsearch-stubs-srcs",
srcs: [
@@ -62,9 +43,8 @@
aidl: {
include_dirs: ["frameworks/base/core/java"],
},
- args: metalava_appsearch_docs_args,
- sdk_version: "core_current",
- libs: ["android_system_stubs_current"],
+ defaults: ["framework-module-stubs-defaults-systemapi"],
+ sdk_version: "system_current",
}
java_library {
@@ -75,7 +55,6 @@
"java",
],
},
- sdk_version: "core_current",
- libs: ["android_system_stubs_current"],
+ sdk_version: "system_current",
installable: false,
}
diff --git a/apex/appsearch/service/Android.bp b/apex/appsearch/service/Android.bp
index 4ebafce8..e7abcd9 100644
--- a/apex/appsearch/service/Android.bp
+++ b/apex/appsearch/service/Android.bp
@@ -20,8 +20,10 @@
libs: [
"framework",
"services.core",
+ "framework-appsearch",
],
static_libs: [
"icing-java-proto-lite",
- ]
+ ],
+ apex_available: [ "com.android.appsearch" ],
}
diff --git a/apex/statsd/service/Android.bp b/apex/statsd/service/Android.bp
index f3a8989..9103848 100644
--- a/apex/statsd/service/Android.bp
+++ b/apex/statsd/service/Android.bp
@@ -13,4 +13,8 @@
"framework-minus-apex",
"services.core",
],
+ apex_available: [
+ "com.android.os.statsd",
+ "test_com.android.os.statsd",
+ ],
}
diff --git a/api/module-app-current.txt b/api/module-app-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/api/module-app-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/api/module-app-removed.txt b/api/module-app-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/api/module-app-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/api/module-lib-removed.txt b/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/api/system-current.txt b/api/system-current.txt
index b14b2d8..a7d5b79 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4618,6 +4618,28 @@
method public abstract int getType();
}
+ public class Lnb implements java.lang.AutoCloseable {
+ method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void close();
+ method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int sendDiseqcMessage(@NonNull byte[]);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int setSatellitePosition(int);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int setTone(int);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int setVoltage(int);
+ field public static final int POSITION_A = 1; // 0x1
+ field public static final int POSITION_B = 2; // 0x2
+ field public static final int POSITION_UNDEFINED = 0; // 0x0
+ field public static final int TONE_CONTINUOUS = 1; // 0x1
+ field public static final int TONE_NONE = 0; // 0x0
+ field public static final int VOLTAGE_11V = 2; // 0x2
+ field public static final int VOLTAGE_12V = 3; // 0x3
+ field public static final int VOLTAGE_13V = 4; // 0x4
+ field public static final int VOLTAGE_14V = 5; // 0x5
+ field public static final int VOLTAGE_15V = 6; // 0x6
+ field public static final int VOLTAGE_18V = 7; // 0x7
+ field public static final int VOLTAGE_19V = 8; // 0x8
+ field public static final int VOLTAGE_5V = 1; // 0x1
+ field public static final int VOLTAGE_NONE = 0; // 0x0
+ }
+
public final class Tuner implements java.lang.AutoCloseable {
ctor public Tuner(@NonNull android.content.Context);
method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.Tuner.Descrambler openDescrambler();
@@ -4640,6 +4662,13 @@
field public static final int FILTER_STATUS_HIGH_WATER = 4; // 0x4
field public static final int FILTER_STATUS_LOW_WATER = 2; // 0x2
field public static final int FILTER_STATUS_OVERFLOW = 8; // 0x8
+ field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
+ field public static final int RESULT_INVALID_STATE = 3; // 0x3
+ field public static final int RESULT_NOT_INITIALIZED = 2; // 0x2
+ field public static final int RESULT_OUT_OF_MEMORY = 5; // 0x5
+ field public static final int RESULT_SUCCESS = 0; // 0x0
+ field public static final int RESULT_UNAVAILABLE = 1; // 0x1
+ field public static final int RESULT_UNKNOWN_ERROR = 6; // 0x6
}
}
@@ -10525,7 +10554,6 @@
field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE";
field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED";
- field public static final String ACTION_NETWORK_SET_TIME = "android.telephony.action.NETWORK_SET_TIME";
field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE";
field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS";
field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index d646e23..00060ab 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -22,14 +22,11 @@
package android.se.omapi;
-import android.app.ActivityThread;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -143,10 +140,6 @@
throw new NullPointerException("Arguments must not be null");
}
- if (!hasOMAPIReaders()) {
- throw new UnsupportedOperationException("Device does not support any OMAPI reader");
- }
-
mContext = context;
mSEListener.mListener = listener;
mSEListener.mExecutor = executor;
@@ -277,23 +270,4 @@
throw new IllegalStateException(e.getMessage());
}
}
-
- /**
- * Helper to check if this device support any OMAPI readers
- */
- private static boolean hasOMAPIReaders() {
- IPackageManager pm = ActivityThread.getPackageManager();
- if (pm == null) {
- Log.e(TAG, "Cannot get package manager, assuming OMAPI readers supported");
- return true;
- }
- try {
- return pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_UICC, 0)
- || pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_ESE, 0)
- || pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_SD, 0);
- } catch (RemoteException e) {
- Log.e(TAG, "Package manager query failed, assuming OMAPI readers supported", e);
- return true;
- }
- }
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5039213..466544c 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -746,9 +746,6 @@
const userid_t user_id = multiuser_get_user_id(uid);
const std::string user_source = StringPrintf("/mnt/user/%d", user_id);
- const std::string pass_through_source = StringPrintf("/mnt/pass_through/%d", user_id);
- bool isFuse = GetBoolProperty(kPropFuse, false);
-
// Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
// /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
// AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
@@ -757,9 +754,15 @@
PrepareDir(user_source, 0710, user_id ? AID_ROOT : AID_SHELL,
multiuser_get_uid(user_id, AID_EVERYBODY), fail_fn);
+ bool isFuse = GetBoolProperty(kPropFuse, false);
+
if (isFuse) {
if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH) {
+ const std::string pass_through_source = StringPrintf("/mnt/pass_through/%d", user_id);
BindMount(pass_through_source, "/storage", fail_fn);
+ } else if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
+ const std::string installer_source = StringPrintf("/mnt/installer/%d", user_id);
+ BindMount(installer_source, "/storage", fail_fn);
} else {
BindMount(user_source, "/storage", fail_fn);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d68ce32..0e4cea1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -640,10 +640,6 @@
<protected-broadcast android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY" />
- <!-- NETWORK_SET_TIME moved from com.android.phone to system server. It should ultimately be
- removed. -->
- <protected-broadcast android:name="android.telephony.action.NETWORK_SET_TIME" />
-
<!-- For tether entitlement recheck-->
<protected-broadcast
android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" />
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index f181b49..c7cc9e6d 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.content.Context;
import android.hardware.tv.tuner.V1_0.Constants;
import android.media.tv.tuner.Tuner.LnbCallback;
@@ -37,6 +38,7 @@
*
* @hide
*/
+@SystemApi
public class Lnb implements AutoCloseable {
/** @hide */
@IntDef({VOLTAGE_NONE, VOLTAGE_5V, VOLTAGE_11V, VOLTAGE_12V, VOLTAGE_13V, VOLTAGE_14V,
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
index 944ed8c..c2d6c58c 100644
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ b/media/java/android/media/tv/tuner/TunerConstants.java
@@ -1298,37 +1298,30 @@
/**
* Operation succeeded.
- * @hide
*/
public static final int RESULT_SUCCESS = Constants.Result.SUCCESS;
/**
* Operation failed because the corresponding resources are not available.
- * @hide
*/
public static final int RESULT_UNAVAILABLE = Constants.Result.UNAVAILABLE;
/**
* Operation failed because the corresponding resources are not initialized.
- * @hide
*/
public static final int RESULT_NOT_INITIALIZED = Constants.Result.NOT_INITIALIZED;
/**
* Operation failed because it's not in a valid state.
- * @hide
*/
public static final int RESULT_INVALID_STATE = Constants.Result.INVALID_STATE;
/**
* Operation failed because there are invalid arguments.
- * @hide
*/
public static final int RESULT_INVALID_ARGUMENT = Constants.Result.INVALID_ARGUMENT;
/**
* Memory allocation failed.
- * @hide
*/
public static final int RESULT_OUT_OF_MEMORY = Constants.Result.OUT_OF_MEMORY;
/**
* Operation failed due to unknown errors.
- * @hide
*/
public static final int RESULT_UNKNOWN_ERROR = Constants.Result.UNKNOWN_ERROR;
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
index 69bd0ed..ff00fb3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -16,8 +16,6 @@
package com.android.settingslib;
-import static android.content.Context.TELEPHONY_SERVICE;
-
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -172,36 +170,38 @@
}
}
- public static String getFormattedPhoneNumber(Context context, SubscriptionInfo subscriptionInfo) {
+ /**
+ * Format a phone number.
+ * @param subscriptionInfo {@link SubscriptionInfo} subscription information.
+ * @return Returns formatted phone number.
+ */
+ public static String getFormattedPhoneNumber(Context context,
+ SubscriptionInfo subscriptionInfo) {
String formattedNumber = null;
if (subscriptionInfo != null) {
- final TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
- final String rawNumber =
- telephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId());
+ final TelephonyManager telephonyManager = context.getSystemService(
+ TelephonyManager.class);
+ final String rawNumber = telephonyManager.createForSubscriptionId(
+ subscriptionInfo.getSubscriptionId()).getLine1Number();
if (!TextUtils.isEmpty(rawNumber)) {
formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
}
-
}
return formattedNumber;
}
public static String getFormattedPhoneNumbers(Context context,
- List<SubscriptionInfo> subscriptionInfo) {
+ List<SubscriptionInfo> subscriptionInfoList) {
StringBuilder sb = new StringBuilder();
- if (subscriptionInfo != null) {
- final TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
- final int count = subscriptionInfo.size();
- for (int i = 0; i < count; i++) {
- final String rawNumber = telephonyManager.getLine1Number(
- subscriptionInfo.get(i).getSubscriptionId());
+ if (subscriptionInfoList != null) {
+ final TelephonyManager telephonyManager = context.getSystemService(
+ TelephonyManager.class);
+ final int count = subscriptionInfoList.size();
+ for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) {
+ final String rawNumber = telephonyManager.createForSubscriptionId(
+ subscriptionInfo.getSubscriptionId()).getLine1Number();
if (!TextUtils.isEmpty(rawNumber)) {
- sb.append(PhoneNumberUtils.formatNumber(rawNumber));
- if (i < count - 1) {
- sb.append("\n");
- }
+ sb.append(PhoneNumberUtils.formatNumber(rawNumber)).append("\n");
}
}
}
diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml
index ca866a9..792bce9 100644
--- a/packages/Tethering/res/values/strings.xml
+++ b/packages/Tethering/res/values/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
<resources>
<!-- Shown when the device is tethered -->
<!-- Strings for tethered notification title [CHAR LIMIT=200] -->
@@ -9,8 +23,11 @@
<!-- This notification is shown when tethering has been disabled on a user's device.
The device is managed by the user's employer. Tethering can't be turned on unless the
IT administrator allows it. The noun "admin" is another reference for "IT administrator." -->
- <!-- Strings for tether disabling notification title [CHAR LIMIT=200] -->
+ <!-- Strings for tether disabling notification title [CHAR LIMIT=200] -->
<string name="disable_tether_notification_title">Tethering is disabled</string>
- <!-- Strings for tether disabling notification message [CHAR LIMIT=200] -->
+ <!-- Strings for tether disabling notification message [CHAR LIMIT=200] -->
<string name="disable_tether_notification_message">Contact your admin for details</string>
+
+ <!-- Strings for tether notification channel name [CHAR LIMIT=200] -->
+ <string name="notification_channel_tethering_status">Hotspot & tethering status</string>
</resources>
\ No newline at end of file
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index d6abfb9..038d7ae 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -50,6 +50,7 @@
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
@@ -106,8 +107,6 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.State;
@@ -663,19 +662,19 @@
if (usbTethered) {
if (wifiTethered || bluetoothTethered) {
- showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
+ showTetheredNotification(R.drawable.stat_sys_tether_general);
} else {
- showTetheredNotification(SystemMessage.NOTE_TETHER_USB);
+ showTetheredNotification(R.drawable.stat_sys_tether_usb);
}
} else if (wifiTethered) {
if (bluetoothTethered) {
- showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
+ showTetheredNotification(R.drawable.stat_sys_tether_general);
} else {
/* We now have a status bar icon for WifiTethering, so drop the notification */
clearTetheredNotification();
}
} else if (bluetoothTethered) {
- showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH);
+ showTetheredNotification(R.drawable.stat_sys_tether_bluetooth);
} else {
clearTetheredNotification();
}
@@ -688,30 +687,22 @@
@VisibleForTesting
protected void showTetheredNotification(int id, boolean tetheringOn) {
NotificationManager notificationManager =
- (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0)
+ .getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) {
return;
}
- int icon = 0;
- switch(id) {
- case SystemMessage.NOTE_TETHER_USB:
- icon = R.drawable.stat_sys_tether_usb;
- break;
- case SystemMessage.NOTE_TETHER_BLUETOOTH:
- icon = R.drawable.stat_sys_tether_bluetooth;
- break;
- case SystemMessage.NOTE_TETHER_GENERAL:
- default:
- icon = R.drawable.stat_sys_tether_general;
- break;
- }
+ final NotificationChannel channel = new NotificationChannel(
+ "TETHERING_STATUS",
+ mContext.getResources().getString(R.string.notification_channel_tethering_status),
+ NotificationManager.IMPORTANCE_LOW);
+ notificationManager.createNotificationChannel(channel);
if (mLastNotificationId != 0) {
- if (mLastNotificationId == icon) {
+ if (mLastNotificationId == id) {
return;
}
- notificationManager.cancelAsUser(null, mLastNotificationId,
- UserHandle.ALL);
+ notificationManager.cancel(null, mLastNotificationId);
mLastNotificationId = 0;
}
@@ -719,8 +710,8 @@
intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
- PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0,
- null, UserHandle.CURRENT);
+ PendingIntent pi = PendingIntent.getActivity(
+ mContext.createContextAsUser(UserHandle.CURRENT, 0), 0, intent, 0, null);
Resources r = mContext.getResources();
final CharSequence title;
@@ -735,32 +726,31 @@
}
if (mTetheredNotificationBuilder == null) {
- mTetheredNotificationBuilder = new Notification.Builder(mContext,
- SystemNotificationChannels.NETWORK_STATUS);
+ mTetheredNotificationBuilder = new Notification.Builder(mContext, channel.getId());
mTetheredNotificationBuilder.setWhen(0)
.setOngoing(true)
.setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color))
+ android.R.color.system_notification_accent_color))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setCategory(Notification.CATEGORY_STATUS);
}
- mTetheredNotificationBuilder.setSmallIcon(icon)
+ mTetheredNotificationBuilder.setSmallIcon(id)
.setContentTitle(title)
.setContentText(message)
.setContentIntent(pi);
mLastNotificationId = id;
- notificationManager.notifyAsUser(null, mLastNotificationId,
- mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
+ notificationManager.notify(null, mLastNotificationId,
+ mTetheredNotificationBuilder.buildInto(new Notification()));
}
@VisibleForTesting
protected void clearTetheredNotification() {
NotificationManager notificationManager =
- (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0)
+ .getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null && mLastNotificationId != 0) {
- notificationManager.cancelAsUser(null, mLastNotificationId,
- UserHandle.ALL);
+ notificationManager.cancel(null, mLastNotificationId);
mLastNotificationId = 0;
}
}
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index 7af48a8..271769e 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -224,6 +224,11 @@
if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
return super.getSystemServiceName(serviceClass);
}
+
+ @Override
+ public Context createContextAsUser(UserHandle user, int flags) {
+ return mContext;
+ }
}
public class MockIpServerDependencies extends IpServer.Dependencies {
@@ -432,6 +437,7 @@
.thenReturn(true);
mServiceContext = new TestContext(mContext);
+ when(mContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(null);
mContentResolver = new MockContentResolver(mServiceContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d45a54e..b13bef2 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1406,10 +1406,7 @@
long oldId = Binder.clearCallingIdentity();
final int[] userIds;
try {
- userIds =
- mContext
- .getSystemService(UserManager.class)
- .getProfileIds(callingUserId, false);
+ userIds = getUserManager().getProfileIds(callingUserId, false);
} finally {
Binder.restoreCallingIdentity(oldId);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index b9f2e76..e11008c 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1562,8 +1562,7 @@
throw e.rethrowAsRuntimeException();
}
int numGids = 3;
- if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER
- || mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
+ if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
numGids++;
}
/*
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
index f964d4c..d3588d3 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
@@ -48,6 +48,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -82,28 +83,28 @@
Map<Integer, TreeMap<String, List<Rule>>> indexedRules =
RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets(rules);
+ // Serialize the rules.
ByteTrackedOutputStream ruleFileByteTrackedOutputStream =
new ByteTrackedOutputStream(rulesFileOutputStream);
-
serializeRuleFileMetadata(formatVersion, ruleFileByteTrackedOutputStream);
-
Map<String, Integer> packageNameIndexes =
serializeRuleList(indexedRules.get(PACKAGE_NAME_INDEXED),
ruleFileByteTrackedOutputStream);
- indexingFileOutputStream.write(
- serializeIndexes(packageNameIndexes, /* isIndexed= */true));
-
Map<String, Integer> appCertificateIndexes =
serializeRuleList(indexedRules.get(APP_CERTIFICATE_INDEXED),
ruleFileByteTrackedOutputStream);
- indexingFileOutputStream.write(
- serializeIndexes(appCertificateIndexes, /* isIndexed= */true));
-
Map<String, Integer> unindexedRulesIndexes =
serializeRuleList(indexedRules.get(NOT_INDEXED),
ruleFileByteTrackedOutputStream);
- indexingFileOutputStream.write(
- serializeIndexes(unindexedRulesIndexes, /* isIndexed= */false));
+
+ // Serialize their indexes.
+ BitOutputStream indexingBitOutputStream = new BitOutputStream();
+ serializeIndexGroup(packageNameIndexes, indexingBitOutputStream, /* isIndexed= */true);
+ serializeIndexGroup(appCertificateIndexes, indexingBitOutputStream, /* isIndexed= */
+ true);
+ serializeIndexGroup(unindexedRulesIndexes, indexingBitOutputStream, /* isIndexed= */
+ false);
+ indexingFileOutputStream.write(indexingBitOutputStream.toByteArray());
} catch (Exception e) {
throw new RuleSerializeException(e.getMessage(), e);
}
@@ -126,7 +127,7 @@
"serializeRuleList should never be called with null rule list.");
BitOutputStream bitOutputStream = new BitOutputStream();
- Map<String, Integer> indexMapping = new TreeMap();
+ Map<String, Integer> indexMapping = new LinkedHashMap();
int indexTracker = 0;
indexMapping.put(START_INDEXING_KEY, outputStream.getWrittenBytesCount());
@@ -220,8 +221,8 @@
}
}
- private byte[] serializeIndexes(Map<String, Integer> indexes, boolean isIndexed) {
- BitOutputStream bitOutputStream = new BitOutputStream();
+ private void serializeIndexGroup(
+ Map<String, Integer> indexes, BitOutputStream bitOutputStream, boolean isIndexed) {
// Output the starting location of this indexing group.
serializeStringValue(START_INDEXING_KEY, /* isHashedValue= */false,
@@ -244,7 +245,8 @@
serializeStringValue(END_INDEXING_KEY, /*isHashedValue= */ false, bitOutputStream);
serializeIntValue(indexes.get(END_INDEXING_KEY), bitOutputStream);
- return bitOutputStream.toByteArray();
+ // This dummy bit is set for fixing the padding issue. songpan@ will fix it and remove it.
+ bitOutputStream.setNext();
}
private void serializeStringValue(
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
new file mode 100644
index 0000000..5191833
--- /dev/null
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2020 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 com.android.server.media;
+
+import android.annotation.NonNull;
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.MediaRoute2Info;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.R;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+class BluetoothRouteProvider {
+ private static final String TAG = "BTRouteProvider";
+ private static BluetoothRouteProvider sInstance;
+
+ @SuppressWarnings("WeakerAccess") /* synthetic access */
+ final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
+ @SuppressWarnings("WeakerAccess") /* synthetic access */
+ BluetoothA2dp mA2dpProfile;
+ @SuppressWarnings("WeakerAccess") /* synthetic access */
+ BluetoothHearingAid mHearingAidProfile;
+
+ private final Context mContext;
+ private final BluetoothAdapter mBluetoothAdapter;
+ private final BluetoothRoutesUpdatedListener mListener;
+ private final Map<String, BluetoothEventReceiver> mEventReceiverMap = new HashMap<>();
+ private final IntentFilter mIntentFilter = new IntentFilter();
+ private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
+ private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener();
+
+ private BluetoothDevice mActiveDevice = null;
+
+ static synchronized BluetoothRouteProvider getInstance(@NonNull Context context,
+ @NonNull BluetoothRoutesUpdatedListener listener) {
+ Objects.requireNonNull(context);
+ Objects.requireNonNull(listener);
+
+ if (sInstance == null) {
+ BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (btAdapter == null) {
+ return null;
+ }
+ sInstance = new BluetoothRouteProvider(context, btAdapter, listener);
+ }
+ return sInstance;
+ }
+
+ private BluetoothRouteProvider(Context context, BluetoothAdapter btAdapter,
+ BluetoothRoutesUpdatedListener listener) {
+ mContext = context;
+ mBluetoothAdapter = btAdapter;
+ mListener = listener;
+ buildBluetoothRoutes();
+
+ mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
+ mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID);
+
+ // Bluetooth on/off broadcasts
+ addEventReceiver(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedReceiver());
+
+ // Pairing broadcasts
+ addEventReceiver(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedReceiver());
+
+ DeviceStateChangedRecevier deviceStateChangedReceiver = new DeviceStateChangedRecevier();
+ addEventReceiver(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, deviceStateChangedReceiver);
+ addEventReceiver(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, deviceStateChangedReceiver);
+ addEventReceiver(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED,
+ deviceStateChangedReceiver);
+ addEventReceiver(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED,
+ deviceStateChangedReceiver);
+
+ mContext.registerReceiver(mBroadcastReceiver, mIntentFilter, null, null);
+ }
+
+ private void addEventReceiver(String action, BluetoothEventReceiver eventReceiver) {
+ mEventReceiverMap.put(action, eventReceiver);
+ mIntentFilter.addAction(action);
+ }
+
+ private void buildBluetoothRoutes() {
+ mBluetoothRoutes.clear();
+ for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) {
+ if (device.isConnected()) {
+ BluetoothRouteInfo newBtRoute = createBluetoothRoute(device);
+ mBluetoothRoutes.put(device.getAddress(), newBtRoute);
+ }
+ }
+ }
+
+ @NonNull List<MediaRoute2Info> getBluetoothRoutes() {
+ ArrayList<MediaRoute2Info> routes = new ArrayList<>();
+ for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
+ routes.add(btRoute.route);
+ }
+ return routes;
+ }
+
+ private void notifyBluetoothRoutesUpdated() {
+ if (mListener != null) {
+ mListener.onBluetoothRoutesUpdated(getBluetoothRoutes());
+ }
+ }
+
+ private BluetoothRouteInfo createBluetoothRoute(BluetoothDevice device) {
+ BluetoothRouteInfo newBtRoute = new BluetoothRouteInfo();
+ newBtRoute.btDevice = device;
+ newBtRoute.route = new MediaRoute2Info.Builder(device.getAddress(), device.getName())
+ .addFeature(SystemMediaRoute2Provider.TYPE_LIVE_AUDIO)
+ .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
+ .setDescription(mContext.getResources().getText(
+ R.string.bluetooth_a2dp_audio_route_name).toString())
+ .build();
+ newBtRoute.connectedProfiles = new SparseBooleanArray();
+ return newBtRoute;
+ }
+
+ private void setRouteConnectionStateForDevice(BluetoothDevice device,
+ @MediaRoute2Info.ConnectionState int state) {
+ if (device == null) {
+ Log.w(TAG, "setRouteConnectionStateForDevice: device shouldn't be null");
+ return;
+ }
+ BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
+ if (btRoute == null) {
+ Log.w(TAG, "setRouteConnectionStateForDevice: route shouldn't be null");
+ return;
+ }
+ if (btRoute.route.getConnectionState() != state) {
+ btRoute.route = new MediaRoute2Info.Builder(btRoute.route)
+ .setConnectionState(state).build();
+ }
+ }
+
+ interface BluetoothRoutesUpdatedListener {
+ void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes);
+ }
+
+ private class BluetoothRouteInfo {
+ public BluetoothDevice btDevice;
+ public MediaRoute2Info route;
+ public SparseBooleanArray connectedProfiles;
+ }
+
+ // These callbacks run on the main thread.
+ private final class BluetoothProfileListener implements BluetoothProfile.ServiceListener {
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ switch (profile) {
+ case BluetoothProfile.A2DP:
+ mA2dpProfile = (BluetoothA2dp) proxy;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mHearingAidProfile = (BluetoothHearingAid) proxy;
+ break;
+ default:
+ return;
+ }
+ for (BluetoothDevice device : proxy.getConnectedDevices()) {
+ BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
+ if (btRoute == null) {
+ btRoute = createBluetoothRoute(device);
+ mBluetoothRoutes.put(device.getAddress(), btRoute);
+ }
+ btRoute.connectedProfiles.put(profile, true);
+ }
+ }
+
+ public void onServiceDisconnected(int profile) {
+ switch (profile) {
+ case BluetoothProfile.A2DP:
+ mA2dpProfile = null;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mHearingAidProfile = null;
+ break;
+ default:
+ return;
+ }
+ }
+ }
+ private class BluetoothBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+ BluetoothEventReceiver receiver = mEventReceiverMap.get(action);
+ if (receiver != null) {
+ receiver.onReceive(context, intent, device);
+ }
+ }
+ }
+
+ private interface BluetoothEventReceiver {
+ void onReceive(Context context, Intent intent, BluetoothDevice device);
+ }
+
+ private class AdapterStateChangedReceiver implements BluetoothEventReceiver {
+ public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+ int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
+ if (state == BluetoothAdapter.STATE_OFF
+ || state == BluetoothAdapter.STATE_TURNING_OFF) {
+ mBluetoothRoutes.clear();
+ notifyBluetoothRoutesUpdated();
+ } else if (state == BluetoothAdapter.STATE_ON) {
+ buildBluetoothRoutes();
+ if (!mBluetoothRoutes.isEmpty()) {
+ notifyBluetoothRoutesUpdated();
+ }
+ }
+ }
+ }
+
+ private class BondStateChangedReceiver implements BluetoothEventReceiver {
+ public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+ int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+ BluetoothDevice.ERROR);
+ BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
+ if (bondState == BluetoothDevice.BOND_BONDED && btRoute == null) {
+ btRoute = createBluetoothRoute(device);
+ if (mA2dpProfile != null && mA2dpProfile.getConnectedDevices().contains(device)) {
+ btRoute.connectedProfiles.put(BluetoothProfile.A2DP, true);
+ }
+ if (mHearingAidProfile != null
+ && mHearingAidProfile.getConnectedDevices().contains(device)) {
+ btRoute.connectedProfiles.put(BluetoothProfile.HEARING_AID, true);
+ }
+ mBluetoothRoutes.put(device.getAddress(), btRoute);
+ notifyBluetoothRoutesUpdated();
+ } else if (bondState == BluetoothDevice.BOND_NONE
+ && mBluetoothRoutes.remove(device.getAddress()) != null) {
+ notifyBluetoothRoutesUpdated();
+ }
+ }
+ }
+
+ private class DeviceStateChangedRecevier implements BluetoothEventReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+ switch (intent.getAction()) {
+ case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
+ String prevActiveDeviceAddress =
+ (mActiveDevice == null) ? null : mActiveDevice.getAddress();
+ String curActiveDeviceAddress =
+ (device == null) ? null : device.getAddress();
+ if (!TextUtils.equals(prevActiveDeviceAddress, curActiveDeviceAddress)) {
+ if (mActiveDevice != null) {
+ setRouteConnectionStateForDevice(mActiveDevice,
+ MediaRoute2Info.CONNECTION_STATE_DISCONNECTED);
+ }
+ if (device != null) {
+ setRouteConnectionStateForDevice(device,
+ MediaRoute2Info.CONNECTION_STATE_CONNECTED);
+ }
+ notifyBluetoothRoutesUpdated();
+ mActiveDevice = device;
+ }
+ break;
+ case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+ handleConnectionStateChanged(BluetoothProfile.A2DP, intent, device);
+ break;
+ }
+ }
+
+ private void handleConnectionStateChanged(int profile, Intent intent,
+ BluetoothDevice device) {
+ int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+ BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
+ if (state == BluetoothProfile.STATE_CONNECTED) {
+ if (btRoute == null) {
+ btRoute = createBluetoothRoute(device);
+ mBluetoothRoutes.put(device.getAddress(), btRoute);
+ btRoute.connectedProfiles.put(profile, true);
+ notifyBluetoothRoutesUpdated();
+ } else {
+ btRoute.connectedProfiles.put(profile, true);
+ }
+ } else if (state == BluetoothProfile.STATE_DISCONNECTING
+ || state == BluetoothProfile.STATE_DISCONNECTED) {
+ btRoute.connectedProfiles.delete(profile);
+ if (btRoute.connectedProfiles.size() == 0) {
+ mBluetoothRoutes.remove(device.getAddress());
+ if (mActiveDevice != null
+ && TextUtils.equals(mActiveDevice.getAddress(), device.getAddress())) {
+ mActiveDevice = null;
+ }
+ notifyBluetoothRoutesUpdated();
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index 2c9d702..0d315cd 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -72,7 +72,7 @@
return mSessionInfos;
}
- void setAndNotifyProviderState(MediaRoute2ProviderInfo providerInfo,
+ void setProviderState(MediaRoute2ProviderInfo providerInfo,
List<RoutingSessionInfo> sessionInfos) {
if (providerInfo == null) {
mProviderInfo = null;
@@ -89,12 +89,20 @@
.build());
}
mSessionInfos = sessionInfoWithProviderId;
+ }
+ void notifyProviderState() {
if (mCallback != null) {
mCallback.onProviderStateChanged(this);
}
}
+ void setAndNotifyProviderState(MediaRoute2ProviderInfo providerInfo,
+ List<RoutingSessionInfo> sessionInfos) {
+ setProviderState(providerInfo, sessionInfos);
+ notifyProviderState();
+ }
+
public boolean hasComponentName(String packageName, String className) {
return mComponentName.getPackageName().equals(packageName)
&& mComponentName.getClassName().equals(className);
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index be0272c..961d3d0 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -30,12 +30,12 @@
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
import java.util.Collections;
+import java.util.List;
/**
* Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers.
@@ -55,6 +55,7 @@
private final IAudioService mAudioService;
private final Handler mHandler;
private final Context mContext;
+ private final BluetoothRouteProvider mBtRouteProvider;
private static ComponentName sComponentName = new ComponentName(
SystemMediaRoute2Provider.class.getPackageName$(),
@@ -62,7 +63,7 @@
//TODO: Clean up these when audio manager support multiple bt devices
MediaRoute2Info mDefaultRoute;
- MediaRoute2Info mBluetoothA2dpRoute;
+ @NonNull List<MediaRoute2Info> mBluetoothRoutes = Collections.EMPTY_LIST;
final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
@@ -87,6 +88,10 @@
mAudioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
+ mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> {
+ mBluetoothRoutes = routes;
+ publishRoutes();
+ });
initializeRoutes();
}
@@ -157,7 +162,15 @@
updateAudioRoutes(newAudioRoutes);
}
- publishRoutes();
+ mBluetoothRoutes = mBtRouteProvider.getBluetoothRoutes();
+
+ MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
+ builder.addRoute(mDefaultRoute);
+ for (MediaRoute2Info route : mBluetoothRoutes) {
+ builder.addRoute(route);
+ }
+ setProviderState(builder.build(), Collections.emptyList());
+ mHandler.post(() -> notifyProviderState());
}
void updateAudioRoutes(AudioRoutesInfo newRoutes) {
@@ -185,21 +198,6 @@
.addFeature(TYPE_LIVE_VIDEO)
.build();
- if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
- mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
- if (mCurAudioRoutesInfo.bluetoothName != null) {
- //TODO: mark as bluetooth once MediaRoute2Info has device type
- mBluetoothA2dpRoute = new MediaRoute2Info.Builder(BLUETOOTH_ROUTE_ID,
- mCurAudioRoutesInfo.bluetoothName)
- .setDescription(mContext.getResources().getText(
- R.string.bluetooth_a2dp_audio_route_name).toString())
- .addFeature(TYPE_LIVE_AUDIO)
- .build();
- } else {
- mBluetoothA2dpRoute = null;
- }
- }
-
publishRoutes();
}
@@ -207,15 +205,13 @@
* The first route should be the currently selected system route.
* For example, if there are two system routes (BT and device speaker),
* BT will be the first route in the list.
- *
- * TODO: Support multiple BT devices
*/
void publishRoutes() {
MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
- if (mBluetoothA2dpRoute != null) {
- builder.addRoute(mBluetoothA2dpRoute);
- }
builder.addRoute(mDefaultRoute);
+ for (MediaRoute2Info route : mBluetoothRoutes) {
+ builder.addRoute(route);
+ }
setAndNotifyProviderState(builder.build(), Collections.emptyList());
}
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index f661b5e..c964795 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -21,7 +21,6 @@
import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.PhoneTimeSuggestion;
-import android.content.Intent;
import android.os.TimestampedValue;
import java.io.PrintWriter;
@@ -73,9 +72,6 @@
/** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */
void releaseWakeLock();
-
- /** Send the supplied intent as a stick broadcast. */
- void sendStickyBroadcast(@NonNull Intent intent);
}
/** Initialize the strategy. */
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
index 42d59d5..9b89d94 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
@@ -20,11 +20,9 @@
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
@@ -112,11 +110,6 @@
mWakeLock.release();
}
- @Override
- public void sendStickyBroadcast(@NonNull Intent intent) {
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
private void checkWakeLockHeld() {
if (!mWakeLock.isHeld()) {
Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held");
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index da848d8..e95fc4a 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -23,9 +23,7 @@
import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.PhoneTimeSuggestion;
-import android.content.Intent;
import android.os.TimestampedValue;
-import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Slog;
@@ -535,17 +533,6 @@
} else {
mLastAutoSystemClockTimeSet = null;
}
-
- // Historically, Android has sent a TelephonyManager.ACTION_NETWORK_SET_TIME broadcast only
- // when setting the time using NITZ.
- if (origin == ORIGIN_PHONE) {
- // Send a broadcast that telephony code used to send after setting the clock.
- // TODO Remove this broadcast as soon as there are no remaining listeners.
- Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_SET_TIME);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time", newSystemClockMillis);
- mCallback.sendStickyBroadcast(intent);
- }
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java
index d44476e..3de006c 100644
--- a/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -57,7 +57,6 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
@@ -523,7 +522,6 @@
* Test that {@link BackupManagerService#dump()} dumps system user information before non-system
* user information.
*/
-
@Test
public void testDump_systemUserFirst() {
String[] args = new String[0];
@@ -539,16 +537,31 @@
}
@Test
- @Ignore("b/147012496")
- public void testGetUserForAncestralSerialNumber() {
+ public void testGetUserForAncestralSerialNumber_forSystemUser() {
BackupManagerServiceTestable.sBackupDisabled = false;
BackupManagerService backupManagerService =
new BackupManagerServiceTestable(mContextMock, mUserServices);
+ when(mUserManagerMock.getProfileIds(UserHandle.getCallingUserId(), false))
+ .thenReturn(new int[] {UserHandle.USER_SYSTEM, NON_USER_SYSTEM});
when(mUserBackupManagerService.getAncestralSerialNumber()).thenReturn(11L);
UserHandle user = backupManagerService.getUserForAncestralSerialNumber(11L);
- assertThat(user).isEqualTo(UserHandle.of(1));
+ assertThat(user).isEqualTo(UserHandle.of(UserHandle.USER_SYSTEM));
+ }
+
+ @Test
+ public void testGetUserForAncestralSerialNumber_forNonSystemUser() {
+ BackupManagerServiceTestable.sBackupDisabled = false;
+ BackupManagerService backupManagerService =
+ new BackupManagerServiceTestable(mContextMock, mUserServices);
+ when(mUserManagerMock.getProfileIds(UserHandle.getCallingUserId(), false))
+ .thenReturn(new int[] {UserHandle.USER_SYSTEM, NON_USER_SYSTEM});
+ when(mNonSystemUserBackupManagerService.getAncestralSerialNumber()).thenReturn(11L);
+
+ UserHandle user = backupManagerService.getUserForAncestralSerialNumber(11L);
+
+ assertThat(user).isEqualTo(UserHandle.of(NON_USER_SYSTEM));
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java b/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java
index 63189e7..dd69c66 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java
@@ -16,14 +16,7 @@
package com.android.server.integrity;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasItems;
-import static org.junit.Assert.assertThat;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import android.content.integrity.AppInstallMetadata;
import android.content.integrity.AtomicFormula;
@@ -33,26 +26,26 @@
import android.content.integrity.Rule;
import android.util.Slog;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.server.integrity.parser.RuleXmlParser;
-import com.android.server.integrity.serializer.RuleXmlSerializer;
+import com.android.server.integrity.parser.RuleBinaryParser;
+import com.android.server.integrity.serializer.RuleBinarySerializer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/** Unit test for {@link IntegrityFileManager} */
-@RunWith(AndroidJUnit4.class)
+@RunWith(JUnit4.class)
public class IntegrityFileManagerTest {
private static final String TAG = "IntegrityFileManagerTest";
@@ -72,7 +65,7 @@
// Use Xml Parser/Serializer to help with debugging since we can just print the file.
mIntegrityFileManager =
new IntegrityFileManager(
- new RuleXmlParser(), new RuleXmlSerializer(), mTmpDir);
+ new RuleBinaryParser(), new RuleBinarySerializer(), mTmpDir);
Files.walk(mTmpDir.toPath())
.forEach(
path -> {
@@ -97,12 +90,19 @@
@Test
public void testGetMetadata() throws Exception {
- assertNull(mIntegrityFileManager.readMetadata());
+ assertThat(mIntegrityFileManager.readMetadata()).isNull();
mIntegrityFileManager.writeRules(VERSION, RULE_PROVIDER, Collections.EMPTY_LIST);
- assertNotNull(mIntegrityFileManager.readMetadata());
- assertEquals(VERSION, mIntegrityFileManager.readMetadata().getVersion());
- assertEquals(RULE_PROVIDER, mIntegrityFileManager.readMetadata().getRuleProvider());
+ assertThat(mIntegrityFileManager.readMetadata()).isNotNull();
+ assertThat(mIntegrityFileManager.readMetadata().getVersion()).isEqualTo(VERSION);
+ assertThat(mIntegrityFileManager.readMetadata().getRuleProvider()).isEqualTo(RULE_PROVIDER);
+ }
+
+ @Test
+ public void testIsInitialized() throws Exception {
+ assertThat(mIntegrityFileManager.initialized()).isFalse();
+ mIntegrityFileManager.writeRules(VERSION, RULE_PROVIDER, Collections.EMPTY_LIST);
+ assertThat(mIntegrityFileManager.initialized()).isTrue();
}
@Test
@@ -110,20 +110,8 @@
String packageName = "package";
String packageCert = "cert";
int version = 123;
- Rule packageNameRule =
- new Rule(
- new StringAtomicFormula(
- AtomicFormula.PACKAGE_NAME,
- packageName,
- /* isHashedValue= */ false),
- Rule.DENY);
- Rule packageCertRule =
- new Rule(
- new StringAtomicFormula(
- AtomicFormula.APP_CERTIFICATE,
- packageCert,
- /* isHashedValue= */ false),
- Rule.DENY);
+ Rule packageNameRule = getPackageNameIndexedRule(packageName);
+ Rule packageCertRule = getAppCertificateIndexedRule(packageCert);
Rule versionCodeRule =
new Rule(
new IntAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.LE, version),
@@ -142,9 +130,7 @@
AtomicFormula.LE,
version))),
Rule.DENY);
- // We will test the specifics of indexing in other classes. Here, we just require that all
- // rules that are related to the given AppInstallMetadata are returned and do not assert
- // anything on other rules.
+
List<Rule> rules =
Arrays.asList(packageNameRule, packageCertRule, versionCodeRule, randomRule);
mIntegrityFileManager.writeRules(VERSION, RULE_PROVIDER, rules);
@@ -159,17 +145,77 @@
.build();
List<Rule> rulesFetched = mIntegrityFileManager.readRules(appInstallMetadata);
- assertThat(rulesFetched, hasItems(
- equalTo(packageNameRule),
- equalTo(packageCertRule),
- equalTo(versionCodeRule)
- ));
+ assertThat(rulesFetched)
+ .containsExactly(packageNameRule, packageCertRule, versionCodeRule, randomRule);
}
@Test
- public void testIsInitialized() throws Exception {
- assertFalse(mIntegrityFileManager.initialized());
- mIntegrityFileManager.writeRules(VERSION, RULE_PROVIDER, Collections.EMPTY_LIST);
- assertTrue(mIntegrityFileManager.initialized());
+ public void testGetRules_indexedForManyRules() throws Exception {
+ String packageName = "package";
+ String installerName = "installer";
+ String appCertificate = "cert";
+
+ // Create a rule set with 2500 package name indexed, 2500 app certificate indexed and
+ // 500 unindexed rules.
+ List<Rule> rules = new ArrayList<>();
+
+ for (int i = 0; i < 2500; i++) {
+ rules.add(getPackageNameIndexedRule(String.format("%s%04d", packageName, i)));
+ rules.add(getAppCertificateIndexedRule(String.format("%s%04d", appCertificate, i)));
+ }
+
+ for (int i = 0; i < 70; i++) {
+ rules.add(getInstallerCertificateRule(String.format("%s%04d", installerName, i)));
+ }
+
+ // Write the rules and get them indexed.
+ mIntegrityFileManager.writeRules(VERSION, RULE_PROVIDER, rules);
+
+ // Read the rules for a specific rule.
+ String installedPackageName = String.format("%s%04d", packageName, 264);
+ String installedAppCertificate = String.format("%s%04d", appCertificate, 1264);
+ AppInstallMetadata appInstallMetadata = new AppInstallMetadata.Builder()
+ .setPackageName(installedPackageName)
+ .setAppCertificate(installedAppCertificate)
+ .setVersionCode(250)
+ .setInstallerName("abc")
+ .setInstallerCertificate("abc")
+ .setIsPreInstalled(true)
+ .build();
+ List<Rule> rulesFetched = mIntegrityFileManager.readRules(appInstallMetadata);
+
+ // Verify that we do not load all the rules and we have the necessary rules to evaluate.
+ assertThat(rulesFetched.size()).isEqualTo(170);
+ assertThat(rulesFetched)
+ .containsAllOf(
+ getPackageNameIndexedRule(installedPackageName),
+ getAppCertificateIndexedRule(installedAppCertificate));
+ }
+
+ private Rule getPackageNameIndexedRule(String packageName) {
+ return new Rule(
+ new StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ Rule.DENY);
+ }
+
+ private Rule getAppCertificateIndexedRule(String appCertificate) {
+ return new Rule(
+ new StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ appCertificate,
+ /* isHashedValue= */ false),
+ Rule.DENY);
+ }
+
+ private Rule getInstallerCertificateRule(String installerCert) {
+ return new Rule(
+ new StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ installerCert,
+ /* isHashedValue= */ false),
+ Rule.DENY);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
index 51f5c75..881b3d6 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
@@ -48,7 +48,6 @@
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -656,65 +655,4 @@
/* expectedExceptionMessageRegex */ "A rule must end with a '1' bit",
() -> binaryParser.parse(rule.array()));
}
-
- @Test
- public void testBinaryStream_multipleRules_indexingIdentifiesParsesIndexRangeCorrectly()
- throws Exception {
- String packageName2 = "com.test.2";
-
- byte[] ruleBytes1 = getBytes(getRulesWithPackageName("com.test.1"));
- byte[] ruleBytes2 = getBytes(getRulesWithPackageName(packageName2));
- byte[] ruleBytes3 = getBytes(getRulesWithPackageName("com.test.3"));
-
- ByteBuffer rule =
- ByteBuffer.allocate(
- DEFAULT_FORMAT_VERSION_BYTES.length
- + ruleBytes1.length
- + ruleBytes2.length
- + ruleBytes3.length);
- rule.put(DEFAULT_FORMAT_VERSION_BYTES);
- rule.put(ruleBytes1);
- rule.put(ruleBytes2);
- rule.put(ruleBytes3);
- InputStream inputStream = new ByteArrayInputStream(rule.array());
-
- RuleParser binaryParser = new RuleBinaryParser();
-
- List<RuleIndexRange> indexRanges = new ArrayList<>();
- indexRanges.add(
- new RuleIndexRange(
- DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes1.length,
- DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes1.length
- + ruleBytes2.length));
- List<Rule> rules = binaryParser.parse(inputStream, indexRanges);
-
- Rule expectedRule =
- new Rule(
- new CompoundFormula(
- CompoundFormula.NOT,
- Collections.singletonList(
- new AtomicFormula.StringAtomicFormula(
- AtomicFormula.PACKAGE_NAME,
- packageName2,
- /* isHashedValue= */ false))),
- Rule.DENY);
-
- assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
- }
-
- private static String getRulesWithPackageName(String packageName) {
- return START_BIT
- + COMPOUND_FORMULA_START_BITS
- + NOT
- + ATOMIC_FORMULA_START_BITS
- + PACKAGE_NAME
- + EQ
- + IS_NOT_HASHED
- + getBits(packageName.length(), VALUE_SIZE_BITS)
- + getValueBits(packageName)
- + COMPOUND_FORMULA_END_BITS
- + DENY
- + END_BIT;
-
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index aaf9799..8a3183f 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -18,7 +18,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -26,7 +25,6 @@
import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.PhoneTimeSuggestion;
-import android.content.Intent;
import android.icu.util.Calendar;
import android.icu.util.GregorianCalendar;
import android.icu.util.TimeZone;
@@ -78,8 +76,7 @@
long expectedSystemClockMillis =
mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
- mScript.verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, true /* expectNetworkBroadcast */)
+ mScript.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion);
}
@@ -118,8 +115,7 @@
mScript.calculateTimeInMillisForNow(timeSuggestion1.getUtcTime());
mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis1, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
}
@@ -146,8 +142,7 @@
mScript.calculateTimeInMillisForNow(timeSuggestion3.getUtcTime());
mScript.simulatePhoneTimeSuggestion(timeSuggestion3)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis3, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis3)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion3);
}
}
@@ -175,8 +170,7 @@
mScript.calculateTimeInMillisForNow(phone2TimeSuggestion.getUtcTime());
mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
.assertLatestPhoneSuggestion(phone1Id, null)
.assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion);
}
@@ -193,8 +187,7 @@
mScript.calculateTimeInMillisForNow(phone1TimeSuggestion.getUtcTime());
mScript.simulatePhoneTimeSuggestion(phone1TimeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
.assertLatestPhoneSuggestion(phone1Id, phone1TimeSuggestion);
}
@@ -227,8 +220,7 @@
mScript.calculateTimeInMillisForNow(phone2TimeSuggestion.getUtcTime());
mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
.assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion);
}
}
@@ -265,8 +257,7 @@
mScript.simulateTimePassing();
long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1);
mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis1, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
// The UTC time increment should be larger than the system clock update threshold so we
@@ -304,8 +295,7 @@
PhoneTimeSuggestion timeSuggestion4 =
createPhoneTimeSuggestion(phoneId, utcTime4);
mScript.simulatePhoneTimeSuggestion(timeSuggestion4)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis4, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion4);
}
@@ -339,8 +329,7 @@
// Turn on auto time detection.
mScript.simulateAutoTimeDetectionToggle()
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis1, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
// Turn off auto time detection.
@@ -367,8 +356,7 @@
// Turn on auto time detection.
mScript.simulateAutoTimeDetectionToggle()
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis2, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis2)
.assertLatestPhoneSuggestion(phoneId, timeSuggestion2);
}
@@ -388,7 +376,7 @@
mScript.calculateTimeInMillisForNow(phoneSuggestion.getUtcTime());
mScript.simulatePhoneTimeSuggestion(phoneSuggestion)
.verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, true /* expectedNetworkBroadcast */)
+ expectedSystemClockMillis /* expectedNetworkBroadcast */)
.assertLatestPhoneSuggestion(phoneId, phoneSuggestion);
// Look inside and check what the strategy considers the current best phone suggestion.
@@ -416,8 +404,7 @@
long expectedSystemClockMillis =
mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
mScript.simulateManualTimeSuggestion(timeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, false /* expectNetworkBroadcast */);
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
}
@Test
@@ -439,8 +426,7 @@
long expectedAutoClockMillis =
mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime());
mScript.simulatePhoneTimeSuggestion(phoneTimeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedAutoClockMillis, true /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis)
.assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
// Simulate the passage of time.
@@ -463,8 +449,7 @@
long expectedManualClockMillis =
mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUtcTime());
mScript.simulateManualTimeSuggestion(manualTimeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedManualClockMillis, false /* expectNetworkBroadcast */)
+ .verifySystemClockWasSetAndResetCallTracking(expectedManualClockMillis)
.assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
// Simulate the passage of time.
@@ -475,8 +460,7 @@
expectedAutoClockMillis =
mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime());
- mScript.verifySystemClockWasSetAndResetCallTracking(
- expectedAutoClockMillis, true /* expectNetworkBroadcast */)
+ mScript.verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis)
.assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
// Switch back to manual - nothing should happen to the clock.
@@ -514,8 +498,7 @@
long expectedSystemClockMillis =
mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
mScript.simulateNetworkTimeSuggestion(timeSuggestion)
- .verifySystemClockWasSetAndResetCallTracking(
- expectedSystemClockMillis, false /* expectNetworkBroadcast */);
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
}
@Test
@@ -550,8 +533,7 @@
mScript.simulateTimePassing(smallTimeIncrementMillis)
.simulateNetworkTimeSuggestion(networkTimeSuggestion1)
.verifySystemClockWasSetAndResetCallTracking(
- mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime()),
- false /* expectNetworkBroadcast */);
+ mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime()));
// Check internal state.
mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, null)
@@ -570,8 +552,7 @@
mScript.simulateTimePassing(smallTimeIncrementMillis)
.simulatePhoneTimeSuggestion(phoneTimeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(
- mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime()),
- true /* expectNetworkBroadcast */);
+ mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime()));
// Check internal state.
mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion)
@@ -622,8 +603,7 @@
// Verify the latest network time now wins.
mScript.verifySystemClockWasSetAndResetCallTracking(
- mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime()),
- false /* expectNetworkTimeBroadcast */);
+ mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime()));
// Check internal state.
mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion)
@@ -645,7 +625,6 @@
// Tracking operations.
private boolean mSystemClockWasSet;
- private Intent mBroadcastSent;
@Override
public int systemClockUpdateThresholdMillis() {
@@ -689,12 +668,6 @@
mWakeLockAcquired = false;
}
- @Override
- public void sendStickyBroadcast(Intent intent) {
- assertNotNull(intent);
- mBroadcastSent = intent;
- }
-
// Methods below are for managing the fake's behavior.
void pokeSystemClockUpdateThreshold(int thresholdMillis) {
@@ -739,17 +712,8 @@
assertEquals(expectedSystemClockMillis, mSystemClockMillis);
}
- void verifyIntentWasBroadcast() {
- assertTrue(mBroadcastSent != null);
- }
-
- void verifyIntentWasNotBroadcast() {
- assertNull(mBroadcastSent);
- }
-
void resetCallTracking() {
mSystemClockWasSet = false;
- mBroadcastSent = null;
}
private void assertWakeLockAcquired() {
@@ -832,17 +796,12 @@
Script verifySystemClockWasNotSetAndResetCallTracking() {
mFakeCallback.verifySystemClockNotSet();
- mFakeCallback.verifyIntentWasNotBroadcast();
mFakeCallback.resetCallTracking();
return this;
}
- Script verifySystemClockWasSetAndResetCallTracking(
- long expectedSystemClockMillis, boolean expectNetworkBroadcast) {
+ Script verifySystemClockWasSetAndResetCallTracking(long expectedSystemClockMillis) {
mFakeCallback.verifySystemClockWasSet(expectedSystemClockMillis);
- if (expectNetworkBroadcast) {
- mFakeCallback.verifyIntentWasBroadcast();
- }
mFakeCallback.resetCallTracking();
return this;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f321427..157d92d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1444,24 +1444,6 @@
"android.telephony.extra.SIM_COMBINATION_NAMES";
/**
- * Broadcast Action: The time was set by the carrier (typically by the NITZ string).
- * This is a sticky broadcast.
- * The intent will have the following extra values:</p>
- * <ul>
- * <li><em>time</em> - The time as a long in UTC milliseconds.</li>
- * </ul>
- *
- * <p class="note">
- * Requires the READ_PHONE_STATE permission.
- *
- * <p class="note">This is a protected intent that can only be sent by the system.
- *
- * @hide
- */
- @SystemApi
- public static final String ACTION_NETWORK_SET_TIME = "android.telephony.action.NETWORK_SET_TIME";
-
- /**
* <p>Broadcast Action: The emergency callback mode is changed.
* <ul>
* <li><em>phoneinECMState</em> - A boolean value,true=phone in ECM, false=ECM off</li>