Merge "Fix title of PRIVATE_DNS_BROKEN notification when connecting VPN"
diff --git a/Android.bp b/Android.bp
index 284e701..5f06a63 100644
--- a/Android.bp
+++ b/Android.bp
@@ -418,6 +418,7 @@
name: "framework-minus-apex",
defaults: ["framework-defaults"],
srcs: [":framework-non-updatable-sources"],
+ libs: ["app-compat-annotations"],
installable: true,
javac_shard_size: 150,
required: [
@@ -454,12 +455,14 @@
defaults: ["framework-defaults"],
srcs: [":framework-all-sources"],
installable: false,
+ libs: ["app-compat-annotations"],
}
java_library {
name: "framework-annotation-proc",
defaults: ["framework-defaults"],
srcs: [":framework-all-sources"],
+ libs: ["app-compat-annotations"],
installable: false,
plugins: [
"unsupportedappusage-annotation-processor",
@@ -500,6 +503,7 @@
java_library {
name: "framework-atb-backward-compatibility",
installable: true,
+ libs: ["app-compat-annotations"],
srcs: [
"core/java/android/content/pm/AndroidTestBaseUpdater.java",
],
@@ -516,24 +520,22 @@
name: "framework-javastream-protos",
depfile: true,
- tool_files: ["tools/genprotos.sh"],
tools: [
"aprotoc",
"protoc-gen-javastream",
"soong_zip",
],
- // TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can
- // end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to
- // the way sbox rewrites the command. See b/70221552.
- cmd: "$(location tools/genprotos.sh) " +
- " $(location aprotoc) " +
- " $(location protoc-gen-javastream) " +
- " $(location soong_zip) " +
- " $(genDir) " +
- " $(depfile) " +
- " $(in) " +
- " $(out)",
+ cmd: "mkdir -p $(genDir)/$(in) " +
+ "&& $(location aprotoc) " +
+ " --plugin=$(location protoc-gen-javastream) " +
+ " --dependency_out=$(depfile) " +
+ " --javastream_out=$(genDir)/$(in) " +
+ " -Iexternal/protobuf/src " +
+ " -I . " +
+ " $(in) " +
+ "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
+
srcs: [
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
@@ -814,11 +816,13 @@
srcs: [
"core/java/android/os/HidlSupport.java",
"core/java/android/annotation/IntDef.java",
+ "core/java/android/annotation/IntRange.java",
"core/java/android/annotation/NonNull.java",
"core/java/android/annotation/Nullable.java",
"core/java/android/annotation/SystemApi.java",
"core/java/android/annotation/TestApi.java",
"core/java/android/annotation/UnsupportedAppUsage.java",
+ "core/java/android/os/HidlMemory.java",
"core/java/android/os/HwBinder.java",
"core/java/android/os/HwBlob.java",
"core/java/android/os/HwParcel.java",
@@ -861,28 +865,6 @@
],
}
-// TODO: Don't rely on this list by switching package.html into package-info.java
-frameworks_base_subdirs = [
- "core/java",
- "graphics/java",
- "location/java",
- "media/java",
- "media/mca/effect/java",
- "media/mca/filterfw/java",
- "media/mca/filterpacks/java",
- "drm/java",
- "mms/java",
- "opengl/java",
- "sax/java",
- "telecomm/java",
- "telephony/common",
- "telephony/java",
- "wifi/java",
- "lowpan/java",
- "keystore/java",
- "rs/java",
-]
-
// Make the api/current.txt file available for use by modules in other
// directories.
filegroup {
@@ -915,7 +897,10 @@
"-overview $(location core/java/overview.html) " +
// Federate Support Library references against local API file.
"-federate SupportLib https://developer.android.com " +
- "-federationapi SupportLib $(location :current-support-api) "
+ "-federationapi SupportLib $(location :current-support-api) " +
+ // Federate Support Library references against local API file.
+ "-federate AndroidX https://developer.android.com " +
+ "-federationapi AndroidX $(location :current-androidx-api) "
framework_docs_only_libs = [
"voip-common",
@@ -966,21 +951,6 @@
"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
"--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo "
-// http://b/129765390 Rewrite links to "platform" or "technotes" folders
-// which are siblings (and thus outside of) {@docRoot}.
-//
-// We have to escape \ as \\ and $ as $$ here because they get resolved by
-// different layers of the build tooling. The arguments are wrapped in '' so
-// that the shell doesn't add yet another level of escaping.
-metalava_framework_docs_args += " --replace-documentation " +
- // packages whose descendants to apply replacement to (all packages from
- // libcore/ojluni/src/main/java that contribute to documentation).
- "com.sun:java:javax:jdk.net:sun " +
- // regex of the string to replace
- "'(<a\\s+href\\s?=[\\*\\s]*\")(?:(?:\\{@docRoot\\}/\\.\\./)|(?:(?:\\.\\./)+))((?:platform|technotes).+)\">' " +
- // replacement (with $1, $2 backreferences to the regex groups)
- "'$$1https://docs.oracle.com/javase/8/docs/$$2\">' "
-
packages_to_document = [
"android",
"dalvik",
@@ -1009,7 +979,6 @@
"test-runner/src/**/*.java",
],
libs: framework_docs_only_libs,
- local_sourcepaths: frameworks_base_subdirs,
create_doc_stubs: true,
annotations_enabled: true,
api_levels_annotations_enabled: true,
@@ -1049,6 +1018,7 @@
"core/res/AndroidManifest.xml",
"core/java/overview.html",
":current-support-api",
+ ":current-androidx-api",
],
create_stubs: false,
}
@@ -1068,9 +1038,9 @@
":core-current-stubs-source",
":core_public_api_files",
":updatable-media-srcs",
+ ":ike-api-srcs",
],
libs: ["framework-internal-utils"],
- local_sourcepaths: frameworks_base_subdirs,
installable: false,
annotations_enabled: true,
previous_api: ":last-released-public-api",
@@ -1391,8 +1361,10 @@
srcs: [
"core/java/android/os/HidlSupport.java",
"core/java/android/annotation/IntDef.java",
+ "core/java/android/annotation/IntRange.java",
"core/java/android/annotation/NonNull.java",
"core/java/android/annotation/SystemApi.java",
+ "core/java/android/os/HidlMemory.java",
"core/java/android/os/HwBinder.java",
"core/java/android/os/HwBlob.java",
"core/java/android/os/HwParcel.java",
diff --git a/api/current.txt b/api/current.txt
index d1ea665..5098324 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2023,7 +2023,7 @@
field public static final int fingerprint_icon_content_description = 17039384; // 0x1040018
field public static final int httpErrorBadUrl = 17039367; // 0x1040007
field public static final int httpErrorUnsupportedScheme = 17039368; // 0x1040008
- field public static final int no = 17039369; // 0x1040009
+ field @Deprecated public static final int no = 17039369; // 0x1040009
field public static final int ok = 17039370; // 0x104000a
field public static final int paste = 17039371; // 0x104000b
field public static final int paste_as_plain_text = 17039385; // 0x1040019
@@ -2033,7 +2033,7 @@
field public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017
field public static final int unknownName = 17039374; // 0x104000e
field public static final int untitled = 17039375; // 0x104000f
- field public static final int yes = 17039379; // 0x1040013
+ field @Deprecated public static final int yes = 17039379; // 0x1040013
}
public static final class R.style {
@@ -3021,9 +3021,9 @@
field public final String type;
}
- public class AccountAuthenticatorActivity extends android.app.Activity {
- ctor public AccountAuthenticatorActivity();
- method public final void setAccountAuthenticatorResult(android.os.Bundle);
+ @Deprecated public class AccountAuthenticatorActivity extends android.app.Activity {
+ ctor @Deprecated public AccountAuthenticatorActivity();
+ method @Deprecated public final void setAccountAuthenticatorResult(android.os.Bundle);
}
public class AccountAuthenticatorResponse implements android.os.Parcelable {
@@ -4244,8 +4244,8 @@
method public android.app.AlertDialog show();
}
- public class AliasActivity extends android.app.Activity {
- ctor public AliasActivity();
+ @Deprecated public class AliasActivity extends android.app.Activity {
+ ctor @Deprecated public AliasActivity();
}
public class AppComponentFactory {
@@ -4698,18 +4698,18 @@
field public static final int VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION = 3; // 0x3
}
- public class ExpandableListActivity extends android.app.Activity implements android.widget.ExpandableListView.OnChildClickListener android.widget.ExpandableListView.OnGroupCollapseListener android.widget.ExpandableListView.OnGroupExpandListener android.view.View.OnCreateContextMenuListener {
- ctor public ExpandableListActivity();
- method public android.widget.ExpandableListAdapter getExpandableListAdapter();
- method public android.widget.ExpandableListView getExpandableListView();
- method public long getSelectedId();
- method public long getSelectedPosition();
- method public boolean onChildClick(android.widget.ExpandableListView, android.view.View, int, int, long);
- method public void onGroupCollapse(int);
- method public void onGroupExpand(int);
- method public void setListAdapter(android.widget.ExpandableListAdapter);
- method public boolean setSelectedChild(int, int, boolean);
- method public void setSelectedGroup(int);
+ @Deprecated public class ExpandableListActivity extends android.app.Activity implements android.widget.ExpandableListView.OnChildClickListener android.widget.ExpandableListView.OnGroupCollapseListener android.widget.ExpandableListView.OnGroupExpandListener android.view.View.OnCreateContextMenuListener {
+ ctor @Deprecated public ExpandableListActivity();
+ method @Deprecated public android.widget.ExpandableListAdapter getExpandableListAdapter();
+ method @Deprecated public android.widget.ExpandableListView getExpandableListView();
+ method @Deprecated public long getSelectedId();
+ method @Deprecated public long getSelectedPosition();
+ method @Deprecated public boolean onChildClick(android.widget.ExpandableListView, android.view.View, int, int, long);
+ method @Deprecated public void onGroupCollapse(int);
+ method @Deprecated public void onGroupExpand(int);
+ method @Deprecated public void setListAdapter(android.widget.ExpandableListAdapter);
+ method @Deprecated public boolean setSelectedChild(int, int, boolean);
+ method @Deprecated public void setSelectedGroup(int);
}
@Deprecated public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
@@ -5151,40 +5151,40 @@
method @Deprecated public void onKeyguardExitResult(boolean);
}
- public abstract class LauncherActivity extends android.app.ListActivity {
- ctor public LauncherActivity();
- method protected android.content.Intent getTargetIntent();
- method protected android.content.Intent intentForPosition(int);
- method protected android.app.LauncherActivity.ListItem itemForPosition(int);
- method public java.util.List<android.app.LauncherActivity.ListItem> makeListItems();
- method protected java.util.List<android.content.pm.ResolveInfo> onQueryPackageManager(android.content.Intent);
- method protected void onSetContentView();
+ @Deprecated public abstract class LauncherActivity extends android.app.ListActivity {
+ ctor @Deprecated public LauncherActivity();
+ method @Deprecated protected android.content.Intent getTargetIntent();
+ method @Deprecated protected android.content.Intent intentForPosition(int);
+ method @Deprecated protected android.app.LauncherActivity.ListItem itemForPosition(int);
+ method @Deprecated public java.util.List<android.app.LauncherActivity.ListItem> makeListItems();
+ method @Deprecated protected java.util.List<android.content.pm.ResolveInfo> onQueryPackageManager(android.content.Intent);
+ method @Deprecated protected void onSetContentView();
}
- public class LauncherActivity.IconResizer {
- ctor public LauncherActivity.IconResizer();
- method public android.graphics.drawable.Drawable createIconThumbnail(android.graphics.drawable.Drawable);
+ @Deprecated public class LauncherActivity.IconResizer {
+ ctor @Deprecated public LauncherActivity.IconResizer();
+ method @Deprecated public android.graphics.drawable.Drawable createIconThumbnail(android.graphics.drawable.Drawable);
}
- public static class LauncherActivity.ListItem {
- ctor public LauncherActivity.ListItem();
- field public String className;
- field public android.os.Bundle extras;
- field public android.graphics.drawable.Drawable icon;
- field public CharSequence label;
- field public String packageName;
- field public android.content.pm.ResolveInfo resolveInfo;
+ @Deprecated public static class LauncherActivity.ListItem {
+ ctor @Deprecated public LauncherActivity.ListItem();
+ field @Deprecated public String className;
+ field @Deprecated public android.os.Bundle extras;
+ field @Deprecated public android.graphics.drawable.Drawable icon;
+ field @Deprecated public CharSequence label;
+ field @Deprecated public String packageName;
+ field @Deprecated public android.content.pm.ResolveInfo resolveInfo;
}
- public class ListActivity extends android.app.Activity {
- ctor public ListActivity();
- method public android.widget.ListAdapter getListAdapter();
- method public android.widget.ListView getListView();
- method public long getSelectedItemId();
- method public int getSelectedItemPosition();
- method protected void onListItemClick(android.widget.ListView, android.view.View, int, long);
- method public void setListAdapter(android.widget.ListAdapter);
- method public void setSelection(int);
+ @Deprecated public class ListActivity extends android.app.Activity {
+ ctor @Deprecated public ListActivity();
+ method @Deprecated public android.widget.ListAdapter getListAdapter();
+ method @Deprecated public android.widget.ListView getListView();
+ method @Deprecated public long getSelectedItemId();
+ method @Deprecated public int getSelectedItemPosition();
+ method @Deprecated protected void onListItemClick(android.widget.ListView, android.view.View, int, long);
+ method @Deprecated public void setListAdapter(android.widget.ListAdapter);
+ method @Deprecated public void setSelection(int);
}
@Deprecated public class ListFragment extends android.app.Fragment {
@@ -5552,6 +5552,7 @@
method @Deprecated public android.app.Notification.Builder setDefaults(int);
method @NonNull public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
method @NonNull public android.app.Notification.Builder setExtras(android.os.Bundle);
+ method @NonNull public android.app.Notification.Builder setFlag(int, boolean);
method @NonNull public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
method @NonNull public android.app.Notification.Builder setGroup(String);
method @NonNull public android.app.Notification.Builder setGroupAlertBehavior(int);
@@ -8357,6 +8358,7 @@
method public int describeContents();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean fetchUuidsWithSdp();
method public String getAddress();
+ method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getAlias();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothClass getBluetoothClass();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getBondState();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getName();
@@ -8368,6 +8370,7 @@
field public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
field public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
field public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
+ field public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.action.ALIAS_CHANGED";
field public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED";
field public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED";
field public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
@@ -9769,7 +9772,7 @@
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String);
method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String);
method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
- method public void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
+ method public void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendOrderedBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void sendStickyBroadcast(@RequiresPermission android.content.Intent);
method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void sendStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
@@ -28933,14 +28936,17 @@
}
public class ProxyInfo implements android.os.Parcelable {
+ ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
method public static android.net.ProxyInfo buildDirectProxy(String, int);
method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List<java.lang.String>);
method public static android.net.ProxyInfo buildPacProxy(android.net.Uri);
+ method @NonNull public static android.net.ProxyInfo buildPacProxy(@NonNull android.net.Uri, int);
method public int describeContents();
method public String[] getExclusionList();
method public String getHost();
method public android.net.Uri getPacFileUrl();
method public int getPort();
+ method public boolean isValid();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
}
@@ -29889,6 +29895,7 @@
field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
+ field public static final String UNKNOWN_SSID = "<unknown ssid>";
field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
@@ -34533,8 +34540,8 @@
}
public final class FileUtils {
- method public static void closeQuietly(@Nullable AutoCloseable);
- method public static void closeQuietly(@Nullable java.io.FileDescriptor);
+ method @Deprecated public static void closeQuietly(@Nullable AutoCloseable);
+ method @Deprecated public static void closeQuietly(@Nullable java.io.FileDescriptor);
method public static long copy(@NonNull java.io.InputStream, @NonNull java.io.OutputStream) throws java.io.IOException;
method public static long copy(@NonNull java.io.InputStream, @NonNull java.io.OutputStream, @Nullable android.os.CancellationSignal, @Nullable java.util.concurrent.Executor, @Nullable android.os.FileUtils.ProgressListener) throws java.io.IOException;
method public static long copy(@NonNull java.io.FileDescriptor, @NonNull java.io.FileDescriptor) throws java.io.IOException;
@@ -34546,8 +34553,8 @@
}
public class Handler {
- ctor public Handler();
- ctor public Handler(@Nullable android.os.Handler.Callback);
+ ctor @Deprecated public Handler();
+ ctor @Deprecated public Handler(@Nullable android.os.Handler.Callback);
ctor public Handler(@NonNull android.os.Looper);
ctor public Handler(@NonNull android.os.Looper, @Nullable android.os.Handler.Callback);
method @NonNull public static android.os.Handler createAsync(@NonNull android.os.Looper);
@@ -34671,7 +34678,7 @@
method @Nullable public static android.os.Looper myLooper();
method @NonNull public static android.os.MessageQueue myQueue();
method public static void prepare();
- method public static void prepareMainLooper();
+ method @Deprecated public static void prepareMainLooper();
method public void quit();
method public void quitSafely();
method public void setMessageLogging(@Nullable android.util.Printer);
@@ -43518,6 +43525,7 @@
field public static final int LOCAL = 2; // 0x2
field public static final int MISSED = 5; // 0x5
field public static final int OTHER = 9; // 0x9
+ field public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED";
field public static final int REJECTED = 6; // 0x6
field public static final int REMOTE = 3; // 0x3
field public static final int RESTRICTED = 8; // 0x8
@@ -44038,11 +44046,15 @@
field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
field public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
field public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
+ field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array";
+ field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
+ field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
field public static final String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool";
field public static final String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL = "allow_emergency_video_calls_bool";
+ field public static final String KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL = "allow_hold_call_during_emergency_bool";
field public static final String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
field public static final String KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL = "allow_merge_wifi_calls_when_vowifi_off_bool";
field public static final String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool";
@@ -44059,7 +44071,7 @@
field public static final String KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS = "carrier_data_call_permanent_failure_strings";
field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = "carrier_default_wfc_ims_mode_int";
field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = "carrier_default_wfc_ims_roaming_mode_int";
- field public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool";
+ field @Deprecated public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool";
field public static final String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL = "carrier_ims_gba_required_bool";
field public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL = "carrier_instant_lettering_available_bool";
field public static final String KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING = "carrier_instant_lettering_encoding_string";
@@ -44169,6 +44181,7 @@
field public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT = "opportunistic_network_entry_threshold_rssnr_int";
field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT = "opportunistic_network_exit_threshold_rsrp_int";
field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT = "opportunistic_network_exit_threshold_rssnr_int";
+ field public static final String KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT = "parameters_use_for_5g_nr_signal_bar_int";
field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool";
field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array";
@@ -44947,6 +44960,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.os.ParcelUuid createSubscriptionGroup(@NonNull java.util.List<java.lang.Integer>);
method @Deprecated public static android.telephony.SubscriptionManager from(android.content.Context);
method public java.util.List<android.telephony.SubscriptionInfo> getAccessibleSubscriptionInfoList();
+ method public static int getActiveDataSubscriptionId();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getActiveSubscriptionInfoCount();
method public int getActiveSubscriptionInfoCountMax();
@@ -45045,7 +45059,7 @@
method public int getDataState();
method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDeviceId();
method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDeviceId(int);
- method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(int);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String[] getForbiddenPlmns();
@@ -45495,11 +45509,13 @@
method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void updateSubscriptionNickname(int, @Nullable String, @NonNull android.app.PendingIntent);
field public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
field public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
+ field public static final String ACTION_START_EUICC_ACTIVATION = "android.telephony.euicc.action.START_EUICC_ACTIVATION";
field public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; // 0x2
field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0
field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1
field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+ field public static final String EXTRA_USE_QR_SCANNER = "android.telephony.euicc.extra.USE_QR_SCANNER";
field public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
}
@@ -48514,12 +48530,12 @@
method @Nullable public static java.util.List<java.lang.String> getTimeZoneIdsForCountryCode(@NonNull String);
}
- public class TimingLogger {
- ctor public TimingLogger(String, String);
- method public void addSplit(String);
- method public void dumpToLog();
- method public void reset(String, String);
- method public void reset();
+ @Deprecated public class TimingLogger {
+ ctor @Deprecated public TimingLogger(String, String);
+ method @Deprecated public void addSplit(String);
+ method @Deprecated public void dumpToLog();
+ method @Deprecated public void reset(String, String);
+ method @Deprecated public void reset();
}
public class TypedValue {
diff --git a/api/removed.txt b/api/removed.txt
index b947918..a4ccfb6 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -595,10 +595,6 @@
field public static final String VOLUME_VOICE = "volume_voice";
}
- public static final class Telephony.Sms.Intents {
- field public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
- }
-
}
package android.speech.tts {
diff --git a/api/system-current.txt b/api/system-current.txt
index ecc9412..0b8cdf2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -66,6 +66,7 @@
field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
field public static final String DEVICE_POWER = "android.permission.DEVICE_POWER";
field public static final String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE";
+ field public static final String ENTER_CAR_MODE_PRIORITIZED = "android.permission.ENTER_CAR_MODE_PRIORITIZED";
field public static final String FORCE_BACK = "android.permission.FORCE_BACK";
field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
field public static final String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
@@ -74,6 +75,7 @@
field public static final String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
field public static final String GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS = "android.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS";
field public static final String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS";
+ field public static final String HANDLE_CAR_MODE_CHANGES = "android.permission.HANDLE_CAR_MODE_CHANGES";
field public static final String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
field public static final String HDMI_CEC = "android.permission.HDMI_CEC";
field public static final String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
@@ -602,6 +604,15 @@
method public boolean isStatusBarExpansionDisabled();
}
+ public class UiModeManager {
+ method @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) public void enableCarMode(@IntRange(from=0) int, int);
+ field public static final String ACTION_ENTER_CAR_MODE_PRIORITIZED = "android.app.action.ENTER_CAR_MODE_PRIORITIZED";
+ field public static final String ACTION_EXIT_CAR_MODE_PRIORITIZED = "android.app.action.EXIT_CAR_MODE_PRIORITIZED";
+ field public static final int DEFAULT_PRIORITY = 0; // 0x0
+ field public static final String EXTRA_CALLING_PACKAGE = "android.app.extra.CALLING_PACKAGE";
+ field public static final String EXTRA_PRIORITY = "android.app.extra.PRIORITY";
+ }
+
public final class Vr2dDisplayProperties implements android.os.Parcelable {
ctor public Vr2dDisplayProperties(int, int, int);
method public int describeContents();
@@ -1239,7 +1250,9 @@
public final class BluetoothAdapter {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
method public boolean disableBLE();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
method public boolean enableBLE();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset();
@@ -1264,6 +1277,7 @@
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean);
@@ -1297,7 +1311,23 @@
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
}
+ public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
+ method protected void finalize();
+ method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+ method public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice);
+ method public boolean isTetheringOn();
+ method public void setBluetoothTethering(boolean);
+ field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
+ field public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
+ field public static final int LOCAL_NAP_ROLE = 1; // 0x1
+ field public static final int LOCAL_PANU_ROLE = 2; // 0x2
+ field public static final int PAN_ROLE_NONE = 0; // 0x0
+ field public static final int REMOTE_NAP_ROLE = 1; // 0x1
+ field public static final int REMOTE_PANU_ROLE = 2; // 0x2
+ }
+
public interface BluetoothProfile {
+ field public static final int PAN = 5; // 0x5
field public static final int PRIORITY_OFF = 0; // 0x0
field public static final int PRIORITY_ON = 100; // 0x64
}
@@ -1352,8 +1382,9 @@
public abstract class Context {
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public boolean bindServiceAsUser(@RequiresPermission android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
+ method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int);
method public abstract android.content.Context createCredentialProtectedStorageContext();
- method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract java.io.File getPreloadsFileCache();
method public abstract boolean isCredentialProtectedStorage();
method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle);
@@ -1745,6 +1776,7 @@
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000
field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
+ field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000
field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
field @Nullable public final String backgroundPermission;
field @StringRes public int requestRes;
@@ -4048,6 +4080,33 @@
method public void onUpstreamChanged(@Nullable android.net.Network);
}
+ public final class IpConfiguration implements android.os.Parcelable {
+ ctor public IpConfiguration();
+ ctor public IpConfiguration(@NonNull android.net.IpConfiguration);
+ method @Nullable public android.net.ProxyInfo getHttpProxy();
+ method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
+ method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
+ method @Nullable public android.net.StaticIpConfiguration getStaticIpConfiguration();
+ method public void setHttpProxy(@Nullable android.net.ProxyInfo);
+ method public void setIpAssignment(@NonNull android.net.IpConfiguration.IpAssignment);
+ method public void setProxySettings(@NonNull android.net.IpConfiguration.ProxySettings);
+ method public void setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.IpConfiguration> CREATOR;
+ }
+
+ public enum IpConfiguration.IpAssignment {
+ enum_constant public static final android.net.IpConfiguration.IpAssignment DHCP;
+ enum_constant public static final android.net.IpConfiguration.IpAssignment STATIC;
+ enum_constant public static final android.net.IpConfiguration.IpAssignment UNASSIGNED;
+ }
+
+ public enum IpConfiguration.ProxySettings {
+ enum_constant public static final android.net.IpConfiguration.ProxySettings NONE;
+ enum_constant public static final android.net.IpConfiguration.ProxySettings PAC;
+ enum_constant public static final android.net.IpConfiguration.ProxySettings STATIC;
+ enum_constant public static final android.net.IpConfiguration.ProxySettings UNASSIGNED;
+ }
+
public final class IpPrefix implements android.os.Parcelable {
ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
ctor public IpPrefix(@NonNull String);
@@ -4120,6 +4179,7 @@
public class NetworkKey implements android.os.Parcelable {
ctor public NetworkKey(android.net.WifiKey);
+ method @Nullable public static android.net.NetworkKey createFromScanResult(@Nullable android.net.wifi.ScanResult);
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkKey> CREATOR;
@@ -4142,16 +4202,23 @@
method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, "android.permission.REQUEST_NETWORK_SCORES"}) public boolean clearScores() throws java.lang.SecurityException;
method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, "android.permission.REQUEST_NETWORK_SCORES"}) public void disableScoring() throws java.lang.SecurityException;
method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, "android.permission.REQUEST_NETWORK_SCORES"}) public String getActiveScorerPackage();
+ method @RequiresPermission("android.permission.REQUEST_NETWORK_SCORES") public void registerNetworkScoreCallback(int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.NetworkScoreManager.NetworkScoreCallback) throws java.lang.SecurityException;
+ method @RequiresPermission("android.permission.REQUEST_NETWORK_SCORES") public boolean requestScores(@NonNull android.net.NetworkKey[]) throws java.lang.SecurityException;
method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, "android.permission.REQUEST_NETWORK_SCORES"}) public boolean setActiveScorer(String) throws java.lang.SecurityException;
- method @RequiresPermission(android.Manifest.permission.SCORE_NETWORKS) public boolean updateScores(android.net.ScoredNetwork[]) throws java.lang.SecurityException;
- field public static final String ACTION_CHANGE_ACTIVE = "android.net.scoring.CHANGE_ACTIVE";
+ method @RequiresPermission(android.Manifest.permission.SCORE_NETWORKS) public boolean updateScores(@NonNull android.net.ScoredNetwork[]) throws java.lang.SecurityException;
+ field @Deprecated public static final String ACTION_CHANGE_ACTIVE = "android.net.scoring.CHANGE_ACTIVE";
field public static final String ACTION_CUSTOM_ENABLE = "android.net.scoring.CUSTOM_ENABLE";
field public static final String ACTION_RECOMMEND_NETWORKS = "android.net.action.RECOMMEND_NETWORKS";
field public static final String ACTION_SCORER_CHANGED = "android.net.scoring.SCORER_CHANGED";
- field public static final String ACTION_SCORE_NETWORKS = "android.net.scoring.SCORE_NETWORKS";
- field public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore";
+ field @Deprecated public static final String ACTION_SCORE_NETWORKS = "android.net.scoring.SCORE_NETWORKS";
+ field @Deprecated public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore";
field public static final String EXTRA_NEW_SCORER = "newScorer";
- field public static final String EXTRA_PACKAGE_NAME = "packageName";
+ field @Deprecated public static final String EXTRA_PACKAGE_NAME = "packageName";
+ }
+
+ public static interface NetworkScoreManager.NetworkScoreCallback {
+ method public void clearScores();
+ method public void updateScores(@NonNull java.util.List<android.net.ScoredNetwork>);
}
public class NetworkStack {
@@ -4273,6 +4340,258 @@
}
+package android.net.eap {
+
+ public final class EapSessionConfig {
+ }
+
+ public static final class EapSessionConfig.Builder {
+ ctor public EapSessionConfig.Builder();
+ method @NonNull public android.net.eap.EapSessionConfig build();
+ method @NonNull public android.net.eap.EapSessionConfig.Builder setEapAkaConfig(int, int);
+ method @NonNull public android.net.eap.EapSessionConfig.Builder setEapAkaPrimeConfig(int, int, @NonNull String, boolean);
+ method @NonNull public android.net.eap.EapSessionConfig.Builder setEapIdentity(@NonNull byte[]);
+ method @NonNull public android.net.eap.EapSessionConfig.Builder setEapMsChapV2Config(@NonNull String, @NonNull String);
+ method @NonNull public android.net.eap.EapSessionConfig.Builder setEapSimConfig(int, int);
+ }
+
+ public static class EapSessionConfig.EapAkaConfig extends android.net.eap.EapSessionConfig.EapUiccConfig {
+ }
+
+ public static class EapSessionConfig.EapAkaPrimeConfig extends android.net.eap.EapSessionConfig.EapAkaConfig {
+ method public boolean allowsMismatchedNetworkNames();
+ method @NonNull public String getNetworkName();
+ }
+
+ public abstract static class EapSessionConfig.EapMethodConfig {
+ method public int getMethodType();
+ }
+
+ public static class EapSessionConfig.EapMsChapV2Config extends android.net.eap.EapSessionConfig.EapMethodConfig {
+ method @NonNull public String getPassword();
+ method @NonNull public String getUsername();
+ }
+
+ public static class EapSessionConfig.EapSimConfig extends android.net.eap.EapSessionConfig.EapUiccConfig {
+ }
+
+ public abstract static class EapSessionConfig.EapUiccConfig extends android.net.eap.EapSessionConfig.EapMethodConfig {
+ method public int getAppType();
+ method public int getSubId();
+ }
+
+}
+
+package android.net.ipsec.ike {
+
+ public final class ChildSaProposal extends android.net.ipsec.ike.SaProposal {
+ }
+
+ public static final class ChildSaProposal.Builder {
+ ctor public ChildSaProposal.Builder();
+ method @NonNull public android.net.ipsec.ike.ChildSaProposal.Builder addDhGroup(int);
+ method @NonNull public android.net.ipsec.ike.ChildSaProposal.Builder addEncryptionAlgorithm(int, int);
+ method @NonNull public android.net.ipsec.ike.ChildSaProposal.Builder addIntegrityAlgorithm(int);
+ method @NonNull public android.net.ipsec.ike.ChildSaProposal build();
+ }
+
+ public interface ChildSessionCallback {
+ method public void onClosed();
+ method public void onClosedExceptionally(@NonNull android.net.ipsec.ike.exceptions.IkeException);
+ method public void onIpSecTransformCreated(@NonNull android.net.IpSecTransform, int);
+ method public void onIpSecTransformDeleted(@NonNull android.net.IpSecTransform, int);
+ method public void onOpened(@NonNull android.net.ipsec.ike.ChildSessionConfiguration);
+ }
+
+ public final class ChildSessionConfiguration {
+ method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getInboundTrafficSelectors();
+ method @NonNull public java.util.List<android.net.LinkAddress> getInternalAddresses();
+ method @NonNull public java.util.List<java.net.InetAddress> getInternalDhcpServers();
+ method @NonNull public java.util.List<java.net.InetAddress> getInternalDnsServers();
+ method @NonNull public java.util.List<android.net.LinkAddress> getInternalSubnets();
+ method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getOutboundTrafficSelectors();
+ }
+
+ public abstract class ChildSessionOptions {
+ }
+
+ public class IkeFqdnIdentification extends android.net.ipsec.ike.IkeIdentification {
+ ctor public IkeFqdnIdentification(@NonNull String);
+ field @NonNull public final String fqdn;
+ }
+
+ public abstract class IkeIdentification {
+ }
+
+ public final class IkeIpv4AddrIdentification extends android.net.ipsec.ike.IkeIdentification {
+ ctor public IkeIpv4AddrIdentification(@NonNull java.net.Inet4Address);
+ field @NonNull public final java.net.Inet4Address ipv4Address;
+ }
+
+ public class IkeIpv6AddrIdentification extends android.net.ipsec.ike.IkeIdentification {
+ ctor public IkeIpv6AddrIdentification(@NonNull java.net.Inet6Address);
+ field @NonNull public final java.net.Inet6Address ipv6Address;
+ }
+
+ public final class IkeKeyIdIdentification extends android.net.ipsec.ike.IkeIdentification {
+ ctor public IkeKeyIdIdentification(@NonNull byte[]);
+ field @NonNull public final byte[] keyId;
+ }
+
+ public final class IkeRfc822AddrIdentification extends android.net.ipsec.ike.IkeIdentification {
+ ctor public IkeRfc822AddrIdentification(@NonNull String);
+ field @NonNull public final String rfc822Name;
+ }
+
+ public final class IkeSaProposal extends android.net.ipsec.ike.SaProposal {
+ method @NonNull public java.util.List<java.lang.Integer> getPseudorandomFunctions();
+ }
+
+ public static final class IkeSaProposal.Builder {
+ ctor public IkeSaProposal.Builder();
+ method @NonNull public android.net.ipsec.ike.IkeSaProposal.Builder addDhGroup(int);
+ method @NonNull public android.net.ipsec.ike.IkeSaProposal.Builder addEncryptionAlgorithm(int, int);
+ method @NonNull public android.net.ipsec.ike.IkeSaProposal.Builder addIntegrityAlgorithm(int);
+ method @NonNull public android.net.ipsec.ike.IkeSaProposal.Builder addPseudorandomFunction(int);
+ method @NonNull public android.net.ipsec.ike.IkeSaProposal build();
+ }
+
+ public final class IkeSession implements java.lang.AutoCloseable {
+ ctor public IkeSession(@NonNull android.content.Context, @NonNull android.net.ipsec.ike.IkeSessionOptions, @NonNull android.net.ipsec.ike.ChildSessionOptions, @NonNull java.util.concurrent.Executor, @NonNull android.net.ipsec.ike.IkeSessionCallback, @NonNull android.net.ipsec.ike.ChildSessionCallback);
+ method public void close();
+ method public void closeChildSession(@NonNull android.net.ipsec.ike.ChildSessionCallback);
+ method public void kill();
+ method public void openChildSession(@NonNull android.net.ipsec.ike.ChildSessionOptions, @NonNull android.net.ipsec.ike.ChildSessionCallback);
+ }
+
+ public interface IkeSessionCallback {
+ method public void onClosed();
+ method public void onClosedExceptionally(@NonNull android.net.ipsec.ike.exceptions.IkeException);
+ method public void onError(@NonNull android.net.ipsec.ike.exceptions.IkeProtocolException);
+ method public void onOpened(@NonNull android.net.ipsec.ike.IkeSessionConfiguration);
+ }
+
+ public final class IkeSessionConfiguration {
+ ctor public IkeSessionConfiguration();
+ method @NonNull public String getRemoteApplicationVersion();
+ method public boolean isIkeExtensionEnabled(int);
+ field public static final int EXTENSION_TYPE_FRAGMENTATION = 1; // 0x1
+ field public static final int EXTENSION_TYPE_MOBIKE = 2; // 0x2
+ }
+
+ public final class IkeSessionOptions {
+ }
+
+ public static final class IkeSessionOptions.Builder {
+ ctor public IkeSessionOptions.Builder();
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder addSaProposal(@NonNull android.net.ipsec.ike.IkeSaProposal);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions build();
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.security.PrivateKey);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.util.List<java.security.cert.X509Certificate>, @NonNull java.security.PrivateKey);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthEap(@NonNull java.security.cert.X509Certificate, @NonNull android.net.eap.EapSessionConfig);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthPsk(@NonNull byte[]);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setLocalIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setRemoteIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setServerAddress(@NonNull java.net.InetAddress);
+ method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setUdpEncapsulationSocket(@NonNull android.net.IpSecManager.UdpEncapsulationSocket);
+ }
+
+ public final class IkeTrafficSelector {
+ ctor public IkeTrafficSelector(int, int, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress);
+ field public final int endPort;
+ field @NonNull public final java.net.InetAddress endingAddress;
+ field public final int startPort;
+ field @NonNull public final java.net.InetAddress startingAddress;
+ }
+
+ public abstract class SaProposal {
+ method @NonNull public java.util.List<java.lang.Integer> getDhGroups();
+ method @NonNull public java.util.List<android.util.Pair<java.lang.Integer,java.lang.Integer>> getEncryptionAlgorithms();
+ method @NonNull public java.util.List<java.lang.Integer> getIntegrityAlgorithms();
+ field public static final int DH_GROUP_1024_BIT_MODP = 2; // 0x2
+ field public static final int DH_GROUP_2048_BIT_MODP = 14; // 0xe
+ field public static final int DH_GROUP_NONE = 0; // 0x0
+ field public static final int ENCRYPTION_ALGORITHM_3DES = 3; // 0x3
+ field public static final int ENCRYPTION_ALGORITHM_AES_CBC = 12; // 0xc
+ field public static final int ENCRYPTION_ALGORITHM_AES_GCM_12 = 19; // 0x13
+ field public static final int ENCRYPTION_ALGORITHM_AES_GCM_16 = 20; // 0x14
+ field public static final int ENCRYPTION_ALGORITHM_AES_GCM_8 = 18; // 0x12
+ field public static final int INTEGRITY_ALGORITHM_AES_XCBC_96 = 5; // 0x5
+ field public static final int INTEGRITY_ALGORITHM_HMAC_SHA1_96 = 2; // 0x2
+ field public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_256_128 = 12; // 0xc
+ field public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_384_192 = 13; // 0xd
+ field public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 = 14; // 0xe
+ field public static final int INTEGRITY_ALGORITHM_NONE = 0; // 0x0
+ field public static final int KEY_LEN_AES_128 = 128; // 0x80
+ field public static final int KEY_LEN_AES_192 = 192; // 0xc0
+ field public static final int KEY_LEN_AES_256 = 256; // 0x100
+ field public static final int KEY_LEN_UNUSED = 0; // 0x0
+ field public static final int PSEUDORANDOM_FUNCTION_AES128_XCBC = 4; // 0x4
+ field public static final int PSEUDORANDOM_FUNCTION_HMAC_SHA1 = 2; // 0x2
+ }
+
+ public final class TransportModeChildSessionOptions extends android.net.ipsec.ike.ChildSessionOptions {
+ }
+
+ public static final class TransportModeChildSessionOptions.Builder {
+ ctor public TransportModeChildSessionOptions.Builder();
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions.Builder addInboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions build();
+ }
+
+ public final class TunnelModeChildSessionOptions extends android.net.ipsec.ike.ChildSessionOptions {
+ }
+
+ public static final class TunnelModeChildSessionOptions.Builder {
+ ctor public TunnelModeChildSessionOptions.Builder();
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalAddressRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalAddressRequest(@NonNull java.net.InetAddress, int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDhcpServerRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDhcpServerRequest(@NonNull java.net.InetAddress);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDnsServerRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDnsServerRequest(@NonNull java.net.InetAddress);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalSubnetRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions build();
+ }
+
+}
+
+package android.net.ipsec.ike.exceptions {
+
+ public abstract class IkeException extends java.lang.Exception {
+ }
+
+ public final class IkeInternalException extends android.net.ipsec.ike.exceptions.IkeException {
+ }
+
+ public abstract class IkeProtocolException extends android.net.ipsec.ike.exceptions.IkeException {
+ method @Nullable public byte[] getErrorData();
+ method public int getErrorType();
+ field public static final int ERROR_TYPE_AUTHENTICATION_FAILED = 24; // 0x18
+ field public static final int ERROR_TYPE_CHILD_SA_NOT_FOUND = 44; // 0x2c
+ field public static final int ERROR_TYPE_FAILED_CP_REQUIRED = 37; // 0x25
+ field public static final int ERROR_TYPE_INTERNAL_ADDRESS_FAILURE = 36; // 0x24
+ field public static final int ERROR_TYPE_INVALID_IKE_SPI = 4; // 0x4
+ field public static final int ERROR_TYPE_INVALID_KE_PAYLOAD = 17; // 0x11
+ field public static final int ERROR_TYPE_INVALID_MAJOR_VERSION = 5; // 0x5
+ field public static final int ERROR_TYPE_INVALID_MESSAGE_ID = 9; // 0x9
+ field public static final int ERROR_TYPE_INVALID_SELECTORS = 39; // 0x27
+ field public static final int ERROR_TYPE_INVALID_SYNTAX = 7; // 0x7
+ field public static final int ERROR_TYPE_NO_ADDITIONAL_SAS = 35; // 0x23
+ field public static final int ERROR_TYPE_NO_PROPOSAL_CHOSEN = 14; // 0xe
+ field public static final int ERROR_TYPE_SINGLE_PAIR_REQUIRED = 34; // 0x22
+ field public static final int ERROR_TYPE_TEMPORARY_FAILURE = 43; // 0x2b
+ field public static final int ERROR_TYPE_TS_UNACCEPTABLE = 38; // 0x26
+ field public static final int ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD = 1; // 0x1
+ }
+
+}
+
package android.net.metrics {
public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
@@ -4657,6 +4976,13 @@
field @Deprecated public byte id;
}
+ public final class WifiClient implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.net.MacAddress getMacAddress();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiClient> CREATOR;
+ }
+
@Deprecated public class WifiConfiguration implements android.os.Parcelable {
method @Deprecated public boolean hasNoInternetAccess();
method @Deprecated public boolean isEphemeral();
@@ -4697,6 +5023,7 @@
method public boolean isPortableHotspotSupported();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
method public boolean isWifiScannerSupported();
+ method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
method @RequiresPermission("android.permission.WIFI_SET_DEVICE_MOBILITY_STATE") public void setDeviceMobilityState(int);
@@ -4755,6 +5082,11 @@
method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
}
+ public static interface WifiManager.SoftApCallback {
+ method public void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
+ method public void onStateChanged(int, int);
+ }
+
public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
ctor public WifiNetworkConnectionStatistics(int, int);
ctor public WifiNetworkConnectionStatistics();
@@ -5190,6 +5522,17 @@
method @NonNull public static java.io.File getVendorDirectory();
}
+ public class HidlMemory implements java.io.Closeable {
+ ctor public HidlMemory(@NonNull String, @IntRange(from=0) long, @Nullable android.os.NativeHandle);
+ method public void close() throws java.io.IOException;
+ method @NonNull public android.os.HidlMemory dup() throws java.io.IOException;
+ method protected void finalize();
+ method @Nullable public android.os.NativeHandle getHandle();
+ method @NonNull public String getName();
+ method public long getSize();
+ method @NonNull public android.os.NativeHandle releaseHandle();
+ }
+
public class HidlSupport {
method public static boolean deepEquals(Object, Object);
method public static int deepHashCode(Object);
@@ -5220,6 +5563,7 @@
method public final void copyToInt8Array(long, byte[], int);
method public final boolean getBool(long);
method public final double getDouble(long);
+ method public final long getFieldHandle(long);
method public final float getFloat(long);
method public final short getInt16(long);
method public final int getInt32(long);
@@ -5234,6 +5578,7 @@
method public final void putDoubleArray(long, double[]);
method public final void putFloat(long, float);
method public final void putFloatArray(long, float[]);
+ method public final void putHidlMemory(long, @NonNull android.os.HidlMemory);
method public final void putInt16(long, short);
method public final void putInt16Array(long, short[]);
method public final void putInt32(long, int);
@@ -5262,9 +5607,11 @@
method public final double readDouble();
method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
+ method @NonNull @Nullable public final android.os.HidlMemory readEmbeddedHidlMemory(long, long, long);
method @Nullable public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
method public final float readFloat();
method public final java.util.ArrayList<java.lang.Float> readFloatVector();
+ method @NonNull public final android.os.HidlMemory readHidlMemory();
method public final short readInt16();
method public final java.util.ArrayList<java.lang.Short> readInt16Vector();
method public final int readInt32();
@@ -5289,6 +5636,7 @@
method public final void writeDoubleVector(java.util.ArrayList<java.lang.Double>);
method public final void writeFloat(float);
method public final void writeFloatVector(java.util.ArrayList<java.lang.Float>);
+ method public final void writeHidlMemory(@NonNull android.os.HidlMemory);
method public final void writeInt16(short);
method public final void writeInt16Vector(java.util.ArrayList<java.lang.Short>);
method public final void writeInt32(int);
@@ -5654,14 +6002,6 @@
}
-package android.os.telephony {
-
- public class TelephonyRegistryManager {
- method public void notifyCarrierNetworkChange(boolean);
- }
-
-}
-
package android.permission {
public final class PermissionControllerManager {
@@ -6113,15 +6453,25 @@
field public static final String DELIVERY_TIME = "date";
field public static final String ETWS_WARNING_TYPE = "etws_warning_type";
field public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
+ field public static final String GEOMETRIES = "geometries";
field public static final String LAC = "lac";
field public static final String LANGUAGE_CODE = "language";
+ field public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
field public static final String MESSAGE_BODY = "body";
+ field public static final String MESSAGE_BROADCASTED = "message_broadcasted";
field public static final String MESSAGE_FORMAT = "format";
+ field @NonNull @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) public static final android.net.Uri MESSAGE_HISTORY_URI;
field public static final String MESSAGE_PRIORITY = "priority";
field public static final String MESSAGE_READ = "read";
field public static final String PLMN = "plmn";
+ field public static final String RECEIVED_TIME = "received_time";
field public static final String SERIAL_NUMBER = "serial_number";
field public static final String SERVICE_CATEGORY = "service_category";
+ field public static final String SLOT_INDEX = "slot_index";
+ }
+
+ public static final class Telephony.Sms.Intents {
+ field public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED = "android.provider.action.SMS_EMERGENCY_CB_RECEIVED";
}
public final class TimeZoneRulesDataContract {
@@ -6543,7 +6893,7 @@
method public android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean, @Nullable android.os.Bundle);
method @Deprecated public int onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean);
method @Deprecated public abstract int onEraseSubscriptions(int);
- method public int onEraseSubscriptionsWithOptions(int, @android.telephony.euicc.EuiccCardManager.ResetOption int);
+ method public int onEraseSubscriptions(int, @android.telephony.euicc.EuiccCardManager.ResetOption int);
method public abstract android.service.euicc.GetDefaultDownloadableSubscriptionListResult onGetDefaultDownloadableSubscriptionList(int, boolean);
method public abstract android.service.euicc.GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(int, android.telephony.euicc.DownloadableSubscription, boolean);
method public abstract String onGetEid(int);
@@ -6563,6 +6913,8 @@
field public static final String ACTION_RESOLVE_DEACTIVATE_SIM = "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
field public static final String ACTION_RESOLVE_NO_PRIVILEGES = "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
field public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS = "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";
+ field public static final String ACTION_START_CARRIER_ACTIVATION = "android.service.euicc.action.START_CARRIER_ACTIVATION";
+ field public static final String ACTION_START_EUICC_ACTIVATION = "android.service.euicc.action.START_EUICC_ACTIVATION";
field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.service.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED";
field public static final String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI";
field public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
@@ -7293,6 +7645,21 @@
method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
}
+ public class CbGeoUtils {
+ }
+
+ public static interface CbGeoUtils.Geometry {
+ method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+ }
+
+ public static class CbGeoUtils.LatLng {
+ ctor public CbGeoUtils.LatLng(double, double);
+ method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng);
+ method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng);
+ field public final double lat;
+ field public final double lng;
+ }
+
public abstract class CellBroadcastService extends android.app.Service {
ctor public CellBroadcastService();
method @CallSuper @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent);
@@ -7648,6 +8015,7 @@
public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+ method public boolean isUsingCarrierAggregation();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
}
@@ -7715,6 +8083,7 @@
field public static final int NUMBER_UNREACHABLE = 8; // 0x8
field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c
field public static final int OUTGOING_CANCELED = 44; // 0x2c
+ field public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; // 0x50
field public static final int OUTGOING_FAILURE = 43; // 0x2b
field public static final int OUT_OF_NETWORK = 11; // 0xb
field public static final int OUT_OF_SERVICE = 18; // 0x12
@@ -7729,6 +8098,14 @@
field public static final int WIFI_LOST = 59; // 0x3b
}
+ public final class ImsiEncryptionInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getKeyIdentifier();
+ method @Nullable public java.security.PublicKey getPublicKey();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR;
+ }
+
public final class LteVopsSupportInfo implements android.os.Parcelable {
ctor public LteVopsSupportInfo(int, int);
method public int describeContents();
@@ -7760,6 +8137,7 @@
method @Nullable public android.telephony.CellIdentity getCellIdentity();
method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
method public int getDomain();
+ method public int getNrState();
method public int getRegistrationState();
method public int getRejectCause();
method public int getRoamingType();
@@ -8002,6 +8380,9 @@
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
+ method public int getNrFrequencyRange();
+ method @Nullable public String getOperatorAlphaLongRaw();
+ method @Nullable public String getOperatorAlphaShortRaw();
field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
@@ -8080,6 +8461,7 @@
}
public final class SmsCbLocation implements android.os.Parcelable {
+ ctor public SmsCbLocation(@NonNull String, int, int);
method public int describeContents();
method public int getCid();
method public int getLac();
@@ -8091,7 +8473,7 @@
}
public final class SmsCbMessage implements android.os.Parcelable {
- ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int);
+ ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int);
method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor);
method public int describeContents();
method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo();
@@ -8100,6 +8482,7 @@
method public int getGeographicalScope();
method @Nullable public String getLanguageCode();
method @NonNull public android.telephony.SmsCbLocation getLocation();
+ method public int getMaximumWaitingDuration();
method @Nullable public String getMessageBody();
method public int getMessageFormat();
method public int getMessagePriority();
@@ -8117,6 +8500,7 @@
field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0
field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2
field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1
+ field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff
field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1
field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2
field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3
@@ -8202,6 +8586,7 @@
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
@@ -8216,6 +8601,7 @@
method @Deprecated public boolean getDataEnabled();
method @Deprecated public boolean getDataEnabled(int);
method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean);
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
@@ -8250,13 +8636,14 @@
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isTetherApnRequired();
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isTetheringApnRequired();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
method public boolean needsOtaServiceProvisioning();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
@@ -8294,6 +8681,8 @@
field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+ field public static final int KEY_TYPE_EPDG = 1; // 0x1
+ field public static final int KEY_TYPE_WLAN = 2; // 0x2
field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
@@ -8334,6 +8723,15 @@
field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0
}
+ public class TelephonyRegistryManager {
+ method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor);
+ method public void addOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyCallStateChangedForAllSubscriptions(int, @Nullable String);
+ method public void notifyCarrierNetworkChange(boolean);
+ method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
+ method public void removeOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+ }
+
public final class UiccAccessRule implements android.os.Parcelable {
ctor public UiccAccessRule(byte[], @Nullable String, long);
method public int describeContents();
@@ -8590,7 +8988,7 @@
public class EuiccManager {
method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(android.content.Intent, android.os.Bundle);
method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@NonNull android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptionsWithOptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus();
@@ -8613,6 +9011,7 @@
field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION";
field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION";
field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID";
+ field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID";
field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME";
}
@@ -8865,7 +9264,7 @@
public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting();
diff --git a/api/test-current.txt b/api/test-current.txt
index 263dbae..d59d15a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -376,6 +376,7 @@
}
public class UiModeManager {
+ method @RequiresPermission("android.permission.ENTER_CAR_MODE_PRIORITIZED") public void enableCarMode(@IntRange(from=0) int, int);
method public boolean isNightModeLocked();
method public boolean isUiModeLocked();
}
@@ -639,7 +640,8 @@
}
public abstract class Context {
- method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int);
+ method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.view.Display getDisplay();
method public abstract int getDisplayId();
method public android.os.UserHandle getUser();
@@ -692,6 +694,7 @@
method public void setEnableRollback(boolean);
method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
+ method public void setRequestDowngrade(boolean);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
}
@@ -707,6 +710,7 @@
method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
+ method @Nullable public String[] getTelephonyPackageNames();
method @Nullable public String getWellbeingPackageName();
method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
@@ -739,6 +743,7 @@
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000
field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
+ field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000
field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000
field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
field @Nullable public final String backgroundPermission;
@@ -791,6 +796,7 @@
}
public final class RollbackManager {
+ method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void blockRollbackManager(long);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
@@ -1720,6 +1726,17 @@
method public static boolean contains(java.io.File, java.io.File);
}
+ public class HidlMemory implements java.io.Closeable {
+ ctor public HidlMemory(@NonNull String, @IntRange(from=0) long, @Nullable android.os.NativeHandle);
+ method public void close() throws java.io.IOException;
+ method @NonNull public android.os.HidlMemory dup() throws java.io.IOException;
+ method protected void finalize();
+ method @Nullable public android.os.NativeHandle getHandle();
+ method @NonNull public String getName();
+ method public long getSize();
+ method @NonNull public android.os.NativeHandle releaseHandle();
+ }
+
public abstract class HwBinder implements android.os.IHwBinder {
ctor public HwBinder();
method public static final void configureRpcThreadpool(long, boolean);
@@ -1743,6 +1760,7 @@
method public final void copyToInt8Array(long, byte[], int);
method public final boolean getBool(long);
method public final double getDouble(long);
+ method public final long getFieldHandle(long);
method public final float getFloat(long);
method public final short getInt16(long);
method public final int getInt32(long);
@@ -1757,6 +1775,7 @@
method public final void putDoubleArray(long, double[]);
method public final void putFloat(long, float);
method public final void putFloatArray(long, float[]);
+ method public final void putHidlMemory(long, @NonNull android.os.HidlMemory);
method public final void putInt16(long, short);
method public final void putInt16Array(long, short[]);
method public final void putInt32(long, int);
@@ -1785,9 +1804,11 @@
method public final double readDouble();
method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
+ method @NonNull @Nullable public final android.os.HidlMemory readEmbeddedHidlMemory(long, long, long);
method @Nullable public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
method public final float readFloat();
method public final java.util.ArrayList<java.lang.Float> readFloatVector();
+ method @NonNull public final android.os.HidlMemory readHidlMemory();
method public final short readInt16();
method public final java.util.ArrayList<java.lang.Short> readInt16Vector();
method public final int readInt32();
@@ -1812,6 +1833,7 @@
method public final void writeDoubleVector(java.util.ArrayList<java.lang.Double>);
method public final void writeFloat(float);
method public final void writeFloatVector(java.util.ArrayList<java.lang.Float>);
+ method public final void writeHidlMemory(@NonNull android.os.HidlMemory);
method public final void writeInt16(short);
method public final void writeInt16Vector(java.util.ArrayList<java.lang.Short>);
method public final void writeInt32(int);
@@ -2377,6 +2399,36 @@
field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
}
+ public static final class Telephony.CellBroadcasts implements android.provider.BaseColumns {
+ field public static final String CID = "cid";
+ field public static final String CMAS_CATEGORY = "cmas_category";
+ field public static final String CMAS_CERTAINTY = "cmas_certainty";
+ field public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
+ field public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
+ field public static final String CMAS_SEVERITY = "cmas_severity";
+ field public static final String CMAS_URGENCY = "cmas_urgency";
+ field @NonNull public static final android.net.Uri CONTENT_URI;
+ field public static final String DEFAULT_SORT_ORDER = "date DESC";
+ field public static final String DELIVERY_TIME = "date";
+ field public static final String ETWS_WARNING_TYPE = "etws_warning_type";
+ field public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
+ field public static final String GEOMETRIES = "geometries";
+ field public static final String LAC = "lac";
+ field public static final String LANGUAGE_CODE = "language";
+ field public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
+ field public static final String MESSAGE_BODY = "body";
+ field public static final String MESSAGE_BROADCASTED = "message_broadcasted";
+ field public static final String MESSAGE_FORMAT = "format";
+ field @NonNull @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) public static final android.net.Uri MESSAGE_HISTORY_URI;
+ field public static final String MESSAGE_PRIORITY = "priority";
+ field public static final String MESSAGE_READ = "read";
+ field public static final String PLMN = "plmn";
+ field public static final String RECEIVED_TIME = "received_time";
+ field public static final String SERIAL_NUMBER = "serial_number";
+ field public static final String SERVICE_CATEGORY = "service_category";
+ field public static final String SLOT_INDEX = "slot_index";
+ }
+
public static final class Telephony.Sms.Intents {
field public static final String SMS_CARRIER_PROVISION_ACTION = "android.provider.Telephony.SMS_CARRIER_PROVISION";
}
@@ -2810,10 +2862,35 @@
package android.telephony {
public final class AccessNetworkConstants {
+ field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
}
+ public final class CallQuality implements android.os.Parcelable {
+ ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
+ method public int describeContents();
+ method public int getAverageRelativeJitter();
+ method public int getAverageRoundTripTime();
+ method public int getCallDuration();
+ method public int getCodecType();
+ method public int getDownlinkCallQualityLevel();
+ method public int getMaxRelativeJitter();
+ method public int getNumRtpPacketsNotReceived();
+ method public int getNumRtpPacketsReceived();
+ method public int getNumRtpPacketsTransmitted();
+ method public int getNumRtpPacketsTransmittedLost();
+ method public int getUplinkCallQualityLevel();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CALL_QUALITY_BAD = 4; // 0x4
+ field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0
+ field public static final int CALL_QUALITY_FAIR = 2; // 0x2
+ field public static final int CALL_QUALITY_GOOD = 1; // 0x1
+ field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5
+ field public static final int CALL_QUALITY_POOR = 3; // 0x3
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
+ }
+
public class CarrierConfigManager {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
}
@@ -2931,11 +3008,18 @@
public class SubscriptionManager {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
+ field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
+ field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI;
+ field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
+ field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI;
+ field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI;
+ field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI;
}
public class TelephonyManager {
method public int checkCarrierPrivilegesForPackage(String);
method public int getCarrierIdListVersion();
+ method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
method @NonNull public String getNetworkCountryIso(int);
@@ -2960,6 +3044,963 @@
}
+package android.telephony.ims {
+
+ public final class ImsCallForwardInfo implements android.os.Parcelable {
+ ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
+ method public int describeContents();
+ method public int getCondition();
+ method public String getNumber();
+ method public int getServiceClass();
+ method public int getStatus();
+ method public int getTimeSeconds();
+ method public int getToA();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CDIV_CF_REASON_ALL = 4; // 0x4
+ field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5
+ field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1
+ field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6
+ field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3
+ field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2
+ field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR;
+ field public static final int STATUS_ACTIVE = 1; // 0x1
+ field public static final int STATUS_NOT_ACTIVE = 0; // 0x0
+ field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91
+ field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81
+ }
+
+ public final class ImsCallProfile implements android.os.Parcelable {
+ ctor public ImsCallProfile();
+ ctor public ImsCallProfile(int, int);
+ ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
+ method public int describeContents();
+ method public String getCallExtra(String);
+ method public String getCallExtra(String, String);
+ method public boolean getCallExtraBoolean(String);
+ method public boolean getCallExtraBoolean(String, boolean);
+ method public int getCallExtraInt(String);
+ method public int getCallExtraInt(String, int);
+ method public android.os.Bundle getCallExtras();
+ method public int getCallType();
+ method public static int getCallTypeFromVideoState(int);
+ method public int getCallerNumberVerificationStatus();
+ method public int getEmergencyCallRouting();
+ method public int getEmergencyServiceCategories();
+ method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
+ method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+ method public int getRestrictCause();
+ method public int getServiceType();
+ method public static int getVideoStateFromCallType(int);
+ method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile);
+ method public boolean hasKnownUserIntentEmergency();
+ method public boolean isEmergencyCallTesting();
+ method public boolean isVideoCall();
+ method public boolean isVideoPaused();
+ method public static int presentationToOir(int);
+ method public void setCallExtra(String, String);
+ method public void setCallExtraBoolean(String, boolean);
+ method public void setCallExtraInt(String, int);
+ method public void setCallRestrictCause(int);
+ method public void setCallerNumberVerificationStatus(int);
+ method public void setEmergencyCallRouting(int);
+ method public void setEmergencyCallTesting(boolean);
+ method public void setEmergencyServiceCategories(int);
+ method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
+ method public void setHasKnownUserIntentEmergency(boolean);
+ method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
+ method public void updateCallType(android.telephony.ims.ImsCallProfile);
+ method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2
+ field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
+ field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
+ field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
+ field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
+ field public static final int CALL_TYPE_VOICE = 2; // 0x2
+ field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
+ field public static final int CALL_TYPE_VS = 8; // 0x8
+ field public static final int CALL_TYPE_VS_RX = 10; // 0xa
+ field public static final int CALL_TYPE_VS_TX = 9; // 0x9
+ field public static final int CALL_TYPE_VT = 4; // 0x4
+ field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7
+ field public static final int CALL_TYPE_VT_RX = 6; // 0x6
+ field public static final int CALL_TYPE_VT_TX = 5; // 0x5
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR;
+ field public static final int DIALSTRING_NORMAL = 0; // 0x0
+ field public static final int DIALSTRING_SS_CONF = 1; // 0x1
+ field public static final int DIALSTRING_USSD = 2; // 0x2
+ field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
+ field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";
+ field public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
+ field public static final String EXTRA_CHILD_NUMBER = "ChildNum";
+ field public static final String EXTRA_CNA = "cna";
+ field public static final String EXTRA_CNAP = "cnap";
+ field public static final String EXTRA_CODEC = "Codec";
+ field public static final String EXTRA_DIALSTRING = "dialstring";
+ field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
+ field public static final String EXTRA_EMERGENCY_CALL = "e_call";
+ field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+ field public static final String EXTRA_OI = "oi";
+ field public static final String EXTRA_OIR = "oir";
+ field public static final String EXTRA_REMOTE_URI = "remote_uri";
+ field public static final String EXTRA_USSD = "ussd";
+ field public static final int OIR_DEFAULT = 0; // 0x0
+ field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2
+ field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4
+ field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1
+ field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3
+ field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2
+ field public static final int SERVICE_TYPE_NONE = 0; // 0x0
+ field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1
+ field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2
+ field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0
+ field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1
+ }
+
+ public class ImsCallSessionListener {
+ method public void callQualityChanged(@NonNull android.telephony.CallQuality);
+ method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+ method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+ method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+ method public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
+ method public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
+ method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
+ method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile);
+ method public void callSessionInitiated(android.telephony.ims.ImsCallProfile);
+ method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionInviteParticipantsRequestDelivered();
+ method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionMayHandover(int, int);
+ method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase);
+ method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+ method public void callSessionMultipartyStateChanged(boolean);
+ method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile);
+ method public void callSessionRemoveParticipantsRequestDelivered();
+ method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
+ method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+ method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
+ method public void callSessionRttMessageReceived(String);
+ method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
+ method public void callSessionRttModifyResponseReceived(int);
+ method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification);
+ method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionTtyModeReceived(int);
+ method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo);
+ method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile);
+ method public void callSessionUpdated(android.telephony.ims.ImsCallProfile);
+ method public void callSessionUssdMessageReceived(int, String);
+ }
+
+ public final class ImsConferenceState implements android.os.Parcelable {
+ method public int describeContents();
+ method public static int getConnectionStateForStatus(String);
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR;
+ field public static final String DISPLAY_TEXT = "display-text";
+ field public static final String ENDPOINT = "endpoint";
+ field public static final String SIP_STATUS_CODE = "sipstatuscode";
+ field public static final String STATUS = "status";
+ field public static final String STATUS_ALERTING = "alerting";
+ field public static final String STATUS_CONNECTED = "connected";
+ field public static final String STATUS_CONNECT_FAIL = "connect-fail";
+ field public static final String STATUS_DIALING_IN = "dialing-in";
+ field public static final String STATUS_DIALING_OUT = "dialing-out";
+ field public static final String STATUS_DISCONNECTED = "disconnected";
+ field public static final String STATUS_DISCONNECTING = "disconnecting";
+ field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
+ field public static final String STATUS_ON_HOLD = "on-hold";
+ field public static final String STATUS_PENDING = "pending";
+ field public static final String STATUS_SEND_ONLY = "sendonly";
+ field public static final String STATUS_SEND_RECV = "sendrecv";
+ field public static final String USER = "user";
+ field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants;
+ }
+
+ public final class ImsException extends java.lang.Exception {
+ ctor public ImsException(@Nullable String);
+ ctor public ImsException(@Nullable String, int);
+ ctor public ImsException(@Nullable String, int, @Nullable Throwable);
+ method public int getCode();
+ field public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; // 0x1
+ field public static final int CODE_ERROR_UNSPECIFIED = 0; // 0x0
+ field public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2; // 0x2
+ }
+
+ public final class ImsExternalCallState implements android.os.Parcelable {
+ ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
+ method public int describeContents();
+ method @NonNull public android.net.Uri getAddress();
+ method public int getCallId();
+ method public int getCallState();
+ method public int getCallType();
+ method @Nullable public android.net.Uri getLocalAddress();
+ method public boolean isCallHeld();
+ method public boolean isCallPullable();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CALL_STATE_CONFIRMED = 1; // 0x1
+ field public static final int CALL_STATE_TERMINATED = 2; // 0x2
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR;
+ }
+
+ public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
+ method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getVoWiFiModeSetting();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getVoWiFiRoamingModeSetting();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isAdvancedCallingSettingEnabled();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isAvailable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void isSupported(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isTtyOverVolteEnabled();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isVoWiFiRoamingSettingEnabled();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isVoWiFiSettingEnabled();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isVtSettingEnabled();
+ method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
+ method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterMmTelCapabilityCallback(@NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback);
+ field public static final int WIFI_MODE_CELLULAR_PREFERRED = 1; // 0x1
+ field public static final int WIFI_MODE_WIFI_ONLY = 0; // 0x0
+ field public static final int WIFI_MODE_WIFI_PREFERRED = 2; // 0x2
+ }
+
+ public static class ImsMmTelManager.CapabilityCallback {
+ ctor public ImsMmTelManager.CapabilityCallback();
+ method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+ }
+
+ @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
+ ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
+ }
+
+ public final class ImsReasonInfo implements android.os.Parcelable {
+ ctor public ImsReasonInfo(int, int, String);
+ method public int describeContents();
+ method public int getCode();
+ method public int getExtraCode();
+ method public String getExtraMessage();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CODE_ACCESS_CLASS_BLOCKED = 1512; // 0x5e8
+ field public static final int CODE_ANSWERED_ELSEWHERE = 1014; // 0x3f6
+ field public static final int CODE_BLACKLISTED_CALL_ID = 506; // 0x1fa
+ field public static final int CODE_CALL_BARRED = 240; // 0xf0
+ field public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; // 0x44c
+ field public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; // 0x3f8
+ field public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; // 0x3f7
+ field public static final int CODE_DATA_DISABLED = 1406; // 0x57e
+ field public static final int CODE_DATA_LIMIT_REACHED = 1405; // 0x57d
+ field public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; // 0xf6
+ field public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; // 0xf7
+ field public static final int CODE_DIAL_MODIFIED_TO_SS = 245; // 0xf5
+ field public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; // 0xf4
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; // 0xf8
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; // 0xf9
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; // 0xfa
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; // 0xfb
+ field public static final int CODE_ECBM_NOT_SUPPORTED = 901; // 0x385
+ field public static final int CODE_EMERGENCY_PERM_FAILURE = 364; // 0x16c
+ field public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; // 0x16b
+ field public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; // 0x578
+ field public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; // 0x57a
+ field public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; // 0x579
+ field public static final int CODE_FDN_BLOCKED = 241; // 0xf1
+ field public static final int CODE_IKEV2_AUTH_FAILURE = 1408; // 0x580
+ field public static final int CODE_IMEI_NOT_ACCEPTED = 243; // 0xf3
+ field public static final int CODE_IWLAN_DPD_FAILURE = 1300; // 0x514
+ field public static final int CODE_LOCAL_CALL_BUSY = 142; // 0x8e
+ field public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; // 0x92
+ field public static final int CODE_LOCAL_CALL_DECLINE = 143; // 0x8f
+ field public static final int CODE_LOCAL_CALL_EXCEEDED = 141; // 0x8d
+ field public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; // 0x91
+ field public static final int CODE_LOCAL_CALL_TERMINATED = 148; // 0x94
+ field public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; // 0x90
+ field public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; // 0x93
+ field public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; // 0x6c
+ field public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; // 0x95
+ field public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; // 0x65
+ field public static final int CODE_LOCAL_ILLEGAL_STATE = 102; // 0x66
+ field public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; // 0x6a
+ field public static final int CODE_LOCAL_INTERNAL_ERROR = 103; // 0x67
+ field public static final int CODE_LOCAL_LOW_BATTERY = 112; // 0x70
+ field public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; // 0x7c
+ field public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; // 0x7a
+ field public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; // 0x79
+ field public static final int CODE_LOCAL_NETWORK_ROAMING = 123; // 0x7b
+ field public static final int CODE_LOCAL_NOT_REGISTERED = 132; // 0x84
+ field public static final int CODE_LOCAL_NO_PENDING_CALL = 107; // 0x6b
+ field public static final int CODE_LOCAL_POWER_OFF = 111; // 0x6f
+ field public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; // 0x83
+ field public static final int CODE_LOW_BATTERY = 505; // 0x1f9
+ field public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403; // 0x57b
+ field public static final int CODE_MEDIA_INIT_FAILED = 401; // 0x191
+ field public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; // 0x193
+ field public static final int CODE_MEDIA_NO_DATA = 402; // 0x192
+ field public static final int CODE_MEDIA_UNSPECIFIED = 404; // 0x194
+ field public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; // 0x386
+ field public static final int CODE_NETWORK_DETACH = 1513; // 0x5e9
+ field public static final int CODE_NETWORK_REJECT = 1504; // 0x5e0
+ field public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; // 0x5df
+ field public static final int CODE_NO_CSFB_IN_CS_ROAM = 1516; // 0x5ec
+ field public static final int CODE_NO_VALID_SIM = 1501; // 0x5dd
+ field public static final int CODE_OEM_CAUSE_1 = 61441; // 0xf001
+ field public static final int CODE_OEM_CAUSE_10 = 61450; // 0xf00a
+ field public static final int CODE_OEM_CAUSE_11 = 61451; // 0xf00b
+ field public static final int CODE_OEM_CAUSE_12 = 61452; // 0xf00c
+ field public static final int CODE_OEM_CAUSE_13 = 61453; // 0xf00d
+ field public static final int CODE_OEM_CAUSE_14 = 61454; // 0xf00e
+ field public static final int CODE_OEM_CAUSE_15 = 61455; // 0xf00f
+ field public static final int CODE_OEM_CAUSE_2 = 61442; // 0xf002
+ field public static final int CODE_OEM_CAUSE_3 = 61443; // 0xf003
+ field public static final int CODE_OEM_CAUSE_4 = 61444; // 0xf004
+ field public static final int CODE_OEM_CAUSE_5 = 61445; // 0xf005
+ field public static final int CODE_OEM_CAUSE_6 = 61446; // 0xf006
+ field public static final int CODE_OEM_CAUSE_7 = 61447; // 0xf007
+ field public static final int CODE_OEM_CAUSE_8 = 61448; // 0xf008
+ field public static final int CODE_OEM_CAUSE_9 = 61449; // 0xf009
+ field public static final int CODE_RADIO_ACCESS_FAILURE = 1505; // 0x5e1
+ field public static final int CODE_RADIO_INTERNAL_ERROR = 1502; // 0x5de
+ field public static final int CODE_RADIO_LINK_FAILURE = 1506; // 0x5e2
+ field public static final int CODE_RADIO_LINK_LOST = 1507; // 0x5e3
+ field public static final int CODE_RADIO_OFF = 1500; // 0x5dc
+ field public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511; // 0x5e7
+ field public static final int CODE_RADIO_RELEASE_NORMAL = 1510; // 0x5e6
+ field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
+ field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
+ field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
+ field public static final int CODE_REJECTED_ELSEWHERE = 1017; // 0x3f9
+ field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
+ field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
+ field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
+ field public static final int CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED = 1617; // 0x651
+ field public static final int CODE_REJECT_INTERNAL_ERROR = 1612; // 0x64c
+ field public static final int CODE_REJECT_MAX_CALL_LIMIT_REACHED = 1608; // 0x648
+ field public static final int CODE_REJECT_ONGOING_CALL_SETUP = 1607; // 0x647
+ field public static final int CODE_REJECT_ONGOING_CALL_TRANSFER = 1611; // 0x64b
+ field public static final int CODE_REJECT_ONGOING_CALL_UPGRADE = 1616; // 0x650
+ field public static final int CODE_REJECT_ONGOING_CALL_WAITING_DISABLED = 1601; // 0x641
+ field public static final int CODE_REJECT_ONGOING_CONFERENCE_CALL = 1618; // 0x652
+ field public static final int CODE_REJECT_ONGOING_CS_CALL = 1621; // 0x655
+ field public static final int CODE_REJECT_ONGOING_E911_CALL = 1606; // 0x646
+ field public static final int CODE_REJECT_ONGOING_ENCRYPTED_CALL = 1620; // 0x654
+ field public static final int CODE_REJECT_ONGOING_HANDOVER = 1614; // 0x64e
+ field public static final int CODE_REJECT_QOS_FAILURE = 1613; // 0x64d
+ field public static final int CODE_REJECT_SERVICE_NOT_REGISTERED = 1604; // 0x644
+ field public static final int CODE_REJECT_UNKNOWN = 1600; // 0x640
+ field public static final int CODE_REJECT_UNSUPPORTED_SDP_HEADERS = 1610; // 0x64a
+ field public static final int CODE_REJECT_UNSUPPORTED_SIP_HEADERS = 1609; // 0x649
+ field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
+ field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
+ field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
+ field public static final int CODE_SESSION_MODIFICATION_FAILED = 1517; // 0x5ed
+ field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
+ field public static final int CODE_SIP_AMBIGUOUS = 376; // 0x178
+ field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
+ field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b
+ field public static final int CODE_SIP_BUSY = 338; // 0x152
+ field public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372; // 0x174
+ field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156
+ field public static final int CODE_SIP_EXTENSION_REQUIRED = 370; // 0x172
+ field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c
+ field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a
+ field public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371; // 0x173
+ field public static final int CODE_SIP_LOOP_DETECTED = 373; // 0x175
+ field public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366; // 0x16e
+ field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154
+ field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d
+ field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155
+ field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e
+ field public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367; // 0x16f
+ field public static final int CODE_SIP_REDIRECTED = 321; // 0x141
+ field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153
+ field public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368; // 0x170
+ field public static final int CODE_SIP_REQUEST_PENDING = 377; // 0x179
+ field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f
+ field public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369; // 0x171
+ field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162
+ field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f
+ field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
+ field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
+ field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
+ field public static final int CODE_SIP_TOO_MANY_HOPS = 374; // 0x176
+ field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
+ field public static final int CODE_SIP_UNDECIPHERABLE = 378; // 0x17a
+ field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
+ field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
+ field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
+ field public static final int CODE_SUPP_SVC_FAILED = 1201; // 0x4b1
+ field public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; // 0x4b3
+ field public static final int CODE_TIMEOUT_1XX_WAITING = 201; // 0xc9
+ field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca
+ field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb
+ field public static final int CODE_UNSPECIFIED = 0; // 0x0
+ field public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512; // 0x200
+ field public static final int CODE_USER_DECLINE = 504; // 0x1f8
+ field public static final int CODE_USER_IGNORE = 503; // 0x1f7
+ field public static final int CODE_USER_NOANSWER = 502; // 0x1f6
+ field public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511; // 0x1ff
+ field public static final int CODE_USER_TERMINATED = 501; // 0x1f5
+ field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe
+ field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335
+ field public static final int CODE_UT_NETWORK_ERROR = 804; // 0x324
+ field public static final int CODE_UT_NOT_SUPPORTED = 801; // 0x321
+ field public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; // 0x323
+ field public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; // 0x322
+ field public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; // 0x336
+ field public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; // 0x339
+ field public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; // 0x338
+ field public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; // 0x337
+ field public static final int CODE_WIFI_LOST = 1407; // 0x57f
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsReasonInfo> CREATOR;
+ field public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; // 0x3
+ field public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; // 0x1
+ field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
+ field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
+ }
+
+ public class ImsService extends android.app.Service {
+ ctor public ImsService();
+ method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
+ method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
+ method public void disableIms(int);
+ method public void enableIms(int);
+ method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
+ method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
+ method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
+ method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();
+ method public void readyForFeatureCreation();
+ }
+
+ public final class ImsSsData implements android.os.Parcelable {
+ ctor public ImsSsData(int, int, int, int, int);
+ method public int describeContents();
+ method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo();
+ method public int getRequestType();
+ method public int getResult();
+ method public int getServiceClass();
+ method public int getServiceType();
+ method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo();
+ method public int getTeleserviceType();
+ method public boolean isTypeBarring();
+ method public boolean isTypeCf();
+ method public boolean isTypeClip();
+ method public boolean isTypeClir();
+ method public boolean isTypeColp();
+ method public boolean isTypeColr();
+ method public boolean isTypeCw();
+ method public boolean isTypeIcb();
+ method public boolean isTypeInterrogation();
+ method public boolean isTypeUnConditional();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR;
+ field public static final int RESULT_SUCCESS = 0; // 0x0
+ field public static final int SERVICE_CLASS_DATA = 2; // 0x2
+ field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20
+ field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10
+ field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40
+ field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80
+ field public static final int SERVICE_CLASS_FAX = 4; // 0x4
+ field public static final int SERVICE_CLASS_NONE = 0; // 0x0
+ field public static final int SERVICE_CLASS_SMS = 8; // 0x8
+ field public static final int SERVICE_CLASS_VOICE = 1; // 0x1
+ field public static final int SS_ACTIVATION = 0; // 0x0
+ field public static final int SS_ALL_BARRING = 18; // 0x12
+ field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3
+ field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5
+ field public static final int SS_ALL_TELESEVICES = 1; // 0x1
+ field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0
+ field public static final int SS_BAIC = 16; // 0x10
+ field public static final int SS_BAIC_ROAMING = 17; // 0x11
+ field public static final int SS_BAOC = 13; // 0xd
+ field public static final int SS_BAOIC = 14; // 0xe
+ field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf
+ field public static final int SS_CFU = 0; // 0x0
+ field public static final int SS_CFUT = 6; // 0x6
+ field public static final int SS_CF_ALL = 4; // 0x4
+ field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5
+ field public static final int SS_CF_BUSY = 1; // 0x1
+ field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3
+ field public static final int SS_CF_NO_REPLY = 2; // 0x2
+ field public static final int SS_CLIP = 7; // 0x7
+ field public static final int SS_CLIR = 8; // 0x8
+ field public static final int SS_CNAP = 11; // 0xb
+ field public static final int SS_COLP = 9; // 0x9
+ field public static final int SS_COLR = 10; // 0xa
+ field public static final int SS_DEACTIVATION = 1; // 0x1
+ field public static final int SS_ERASURE = 4; // 0x4
+ field public static final int SS_INCOMING_BARRING = 20; // 0x14
+ field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16
+ field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15
+ field public static final int SS_INTERROGATION = 2; // 0x2
+ field public static final int SS_OUTGOING_BARRING = 19; // 0x13
+ field public static final int SS_REGISTRATION = 3; // 0x3
+ field public static final int SS_SMS_SERVICES = 4; // 0x4
+ field public static final int SS_TELEPHONY = 2; // 0x2
+ field public static final int SS_WAIT = 12; // 0xc
+ }
+
+ public static final class ImsSsData.Builder {
+ ctor public ImsSsData.Builder(int, int, int, int, int);
+ method @NonNull public android.telephony.ims.ImsSsData build();
+ method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>);
+ method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>);
+ }
+
+ public final class ImsSsInfo implements android.os.Parcelable {
+ ctor @Deprecated public ImsSsInfo(int, @Nullable String);
+ method public int describeContents();
+ method public int getClirInterrogationStatus();
+ method public int getClirOutgoingState();
+ method @Deprecated public String getIcbNum();
+ method @Nullable public String getIncomingCommunicationBarringNumber();
+ method public int getProvisionStatus();
+ method public int getStatus();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0
+ field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1
+ field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2
+ field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0
+ field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1
+ field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4
+ field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3
+ field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR;
+ field public static final int DISABLED = 0; // 0x0
+ field public static final int ENABLED = 1; // 0x1
+ field public static final int NOT_REGISTERED = -1; // 0xffffffff
+ field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0
+ field public static final int SERVICE_PROVISIONED = 1; // 0x1
+ field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
+ }
+
+ public static final class ImsSsInfo.Builder {
+ ctor public ImsSsInfo.Builder(int);
+ method @NonNull public android.telephony.ims.ImsSsInfo build();
+ method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int);
+ method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int);
+ method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String);
+ method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
+ }
+
+ public final class ImsStreamMediaProfile implements android.os.Parcelable {
+ ctor public ImsStreamMediaProfile(int, int, int, int, int);
+ method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
+ method public int describeContents();
+ method public int getAudioDirection();
+ method public int getAudioQuality();
+ method public int getRttMode();
+ method public int getVideoDirection();
+ method public int getVideoQuality();
+ method public boolean isReceivingRttAudio();
+ method public boolean isRttCall();
+ method public void setReceivingRttAudio(boolean);
+ method public void setRttMode(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int AUDIO_QUALITY_AMR = 1; // 0x1
+ field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2
+ field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4
+ field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5
+ field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7
+ field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6
+ field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14
+ field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11
+ field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13
+ field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12
+ field public static final int AUDIO_QUALITY_G711A = 13; // 0xd
+ field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf
+ field public static final int AUDIO_QUALITY_G711U = 11; // 0xb
+ field public static final int AUDIO_QUALITY_G722 = 14; // 0xe
+ field public static final int AUDIO_QUALITY_G723 = 12; // 0xc
+ field public static final int AUDIO_QUALITY_G729 = 16; // 0x10
+ field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8
+ field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9
+ field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa
+ field public static final int AUDIO_QUALITY_NONE = 0; // 0x0
+ field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR;
+ field public static final int DIRECTION_INACTIVE = 0; // 0x0
+ field public static final int DIRECTION_INVALID = -1; // 0xffffffff
+ field public static final int DIRECTION_RECEIVE = 1; // 0x1
+ field public static final int DIRECTION_SEND = 2; // 0x2
+ field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3
+ field public static final int RTT_MODE_DISABLED = 0; // 0x0
+ field public static final int RTT_MODE_FULL = 1; // 0x1
+ field public static final int VIDEO_QUALITY_NONE = 0; // 0x0
+ field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1
+ field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2
+ field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4
+ field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8
+ field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10
+ }
+
+ public final class ImsSuppServiceNotification implements android.os.Parcelable {
+ ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR;
+ field public final int code;
+ field public final String[] history;
+ field public final int index;
+ field public final int notificationType;
+ field public final String number;
+ field public final int type;
+ }
+
+ public class ImsUtListener {
+ method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo);
+ method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData);
+ method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]);
+ method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]);
+ method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]);
+ method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle);
+ method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo);
+ method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo);
+ method public void onUtConfigurationUpdated(int);
+ field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir";
+ field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
+ }
+
+ public abstract class ImsVideoCallProvider {
+ ctor public ImsVideoCallProvider();
+ method public void changeCallDataUsage(long);
+ method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
+ method public void changePeerDimensions(int, int);
+ method public void changeVideoQuality(int);
+ method public void handleCallSessionEvent(int);
+ method public abstract void onRequestCallDataUsage();
+ method public abstract void onRequestCameraCapabilities();
+ method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile);
+ method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile);
+ method public abstract void onSetCamera(String);
+ method public void onSetCamera(String, int);
+ method public abstract void onSetDeviceOrientation(int);
+ method public abstract void onSetDisplaySurface(android.view.Surface);
+ method public abstract void onSetPauseImage(android.net.Uri);
+ method public abstract void onSetPreviewSurface(android.view.Surface);
+ method public abstract void onSetZoom(float);
+ method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
+ method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
+ }
+
+ public class ProvisioningManager {
+ method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public int getProvisioningIntValue(int);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public boolean getProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @WorkerThread public String getProvisioningStringValue(int);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
+ field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
+ field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
+ field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
+ field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
+ field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
+ }
+
+ public static class ProvisioningManager.Callback {
+ ctor public ProvisioningManager.Callback();
+ method public void onProvisioningIntChanged(int, int);
+ method public void onProvisioningStringChanged(int, @NonNull String);
+ }
+
+ public interface RegistrationManager {
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+ field public static final int REGISTRATION_STATE_NOT_REGISTERED = 0; // 0x0
+ field public static final int REGISTRATION_STATE_REGISTERED = 2; // 0x2
+ field public static final int REGISTRATION_STATE_REGISTERING = 1; // 0x1
+ }
+
+ public static class RegistrationManager.RegistrationCallback {
+ ctor public RegistrationManager.RegistrationCallback();
+ method public void onRegistered(int);
+ method public void onRegistering(int);
+ method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
+ method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
+ }
+
+}
+
+package android.telephony.ims.feature {
+
+ public final class CapabilityChangeRequest implements android.os.Parcelable {
+ method public void addCapabilitiesToDisableForTech(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method public void addCapabilitiesToEnableForTech(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method public int describeContents();
+ method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable();
+ method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR;
+ }
+
+ public static class CapabilityChangeRequest.CapabilityPair {
+ ctor public CapabilityChangeRequest.CapabilityPair(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method @android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability public int getCapability();
+ method public int getRadioTech();
+ }
+
+ public abstract class ImsFeature {
+ ctor public ImsFeature();
+ method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+ method public final int getSlotIndex();
+ method public abstract void onFeatureReady();
+ method public abstract void onFeatureRemoved();
+ method public final void setFeatureState(int);
+ field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff
+ field public static final int CAPABILITY_SUCCESS = 0; // 0x0
+ field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0
+ field public static final int FEATURE_MMTEL = 1; // 0x1
+ field public static final int FEATURE_RCS = 2; // 0x2
+ field public static final int STATE_INITIALIZING = 1; // 0x1
+ field public static final int STATE_READY = 2; // 0x2
+ field public static final int STATE_UNAVAILABLE = 0; // 0x0
+ }
+
+ @Deprecated public static class ImsFeature.Capabilities {
+ field @Deprecated protected int mCapabilities;
+ }
+
+ protected static class ImsFeature.CapabilityCallbackProxy {
+ method public void onChangeCapabilityConfigurationError(int, int, int);
+ }
+
+ public class MmTelFeature extends android.telephony.ims.feature.ImsFeature {
+ ctor public MmTelFeature();
+ method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+ method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int);
+ method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile);
+ method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm();
+ method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint();
+ method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation();
+ method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt();
+ method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+ method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle);
+ method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo);
+ method public final void notifyVoiceMessageCountUpdate(int);
+ method public void onFeatureReady();
+ method public void onFeatureRemoved();
+ method public boolean queryCapabilityConfiguration(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
+ method public void setUiTtyMode(int, @Nullable android.os.Message);
+ method @android.telephony.ims.feature.MmTelFeature.ProcessCallResult public int shouldProcessCall(@NonNull String[]);
+ field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
+ field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
+ field public static final int PROCESS_CALL_CSFB = 1; // 0x1
+ field public static final int PROCESS_CALL_IMS = 0; // 0x0
+ }
+
+ public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
+ ctor public MmTelFeature.MmTelCapabilities();
+ ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
+ ctor public MmTelFeature.MmTelCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
+ method public final void addCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
+ method public final boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
+ method public final void removeCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
+ field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8
+ field public static final int CAPABILITY_TYPE_UT = 4; // 0x4
+ field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2
+ field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1
+ }
+
+ @IntDef(flag=true, value={android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MmTelFeature.MmTelCapabilities.MmTelCapability {
+ }
+
+ @IntDef(flag=true, value={android.telephony.ims.feature.MmTelFeature.PROCESS_CALL_IMS, android.telephony.ims.feature.MmTelFeature.PROCESS_CALL_CSFB}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MmTelFeature.ProcessCallResult {
+ }
+
+ public class RcsFeature extends android.telephony.ims.feature.ImsFeature {
+ ctor public RcsFeature();
+ method public void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+ method public void onFeatureReady();
+ method public void onFeatureRemoved();
+ }
+
+}
+
+package android.telephony.ims.stub {
+
+ public class ImsCallSessionImplBase implements java.lang.AutoCloseable {
+ ctor public ImsCallSessionImplBase();
+ method public void accept(int, android.telephony.ims.ImsStreamMediaProfile);
+ method public void close();
+ method public void deflect(String);
+ method public void extendToConference(String[]);
+ method public String getCallId();
+ method public android.telephony.ims.ImsCallProfile getCallProfile();
+ method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider();
+ method public android.telephony.ims.ImsCallProfile getLocalCallProfile();
+ method public String getProperty(String);
+ method public android.telephony.ims.ImsCallProfile getRemoteCallProfile();
+ method public int getState();
+ method public void hold(android.telephony.ims.ImsStreamMediaProfile);
+ method public void inviteParticipants(String[]);
+ method public boolean isInCall();
+ method public boolean isMultiparty();
+ method public void merge();
+ method public void reject(int);
+ method public void removeParticipants(String[]);
+ method public void resume(android.telephony.ims.ImsStreamMediaProfile);
+ method public void sendDtmf(char, android.os.Message);
+ method public void sendRttMessage(String);
+ method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
+ method public void sendRttModifyResponse(boolean);
+ method public void sendUssd(String);
+ method public void setListener(android.telephony.ims.ImsCallSessionListener);
+ method public void setMute(boolean);
+ method public void start(String, android.telephony.ims.ImsCallProfile);
+ method public void startConference(String[], android.telephony.ims.ImsCallProfile);
+ method public void startDtmf(char);
+ method public void stopDtmf();
+ method public void terminate(int);
+ method public void update(int, android.telephony.ims.ImsStreamMediaProfile);
+ field public static final int USSD_MODE_NOTIFY = 0; // 0x0
+ field public static final int USSD_MODE_REQUEST = 1; // 0x1
+ }
+
+ public static class ImsCallSessionImplBase.State {
+ method public static String toString(int);
+ field public static final int ESTABLISHED = 4; // 0x4
+ field public static final int ESTABLISHING = 3; // 0x3
+ field public static final int IDLE = 0; // 0x0
+ field public static final int INITIATED = 1; // 0x1
+ field public static final int INVALID = -1; // 0xffffffff
+ field public static final int NEGOTIATING = 2; // 0x2
+ field public static final int REESTABLISHING = 6; // 0x6
+ field public static final int RENEGOTIATING = 5; // 0x5
+ field public static final int TERMINATED = 8; // 0x8
+ field public static final int TERMINATING = 7; // 0x7
+ }
+
+ public class ImsConfigImplBase {
+ ctor public ImsConfigImplBase();
+ method public int getConfigInt(int);
+ method public String getConfigString(int);
+ method public final void notifyProvisionedValueChanged(int, int);
+ method public final void notifyProvisionedValueChanged(int, String);
+ method public int setConfig(int, int);
+ method public int setConfig(int, String);
+ field public static final int CONFIG_RESULT_FAILED = 1; // 0x1
+ field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0
+ field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff
+ }
+
+ public class ImsEcbmImplBase {
+ ctor public ImsEcbmImplBase();
+ method public final void enteredEcbm();
+ method public void exitEmergencyCallbackMode();
+ method public final void exitedEcbm();
+ }
+
+ public final class ImsFeatureConfiguration implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR;
+ }
+
+ public static class ImsFeatureConfiguration.Builder {
+ ctor public ImsFeatureConfiguration.Builder();
+ method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int);
+ method public android.telephony.ims.stub.ImsFeatureConfiguration build();
+ }
+
+ public static final class ImsFeatureConfiguration.FeatureSlotPair {
+ ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int);
+ field public final int featureType;
+ field public final int slotId;
+ }
+
+ public class ImsMultiEndpointImplBase {
+ ctor public ImsMultiEndpointImplBase();
+ method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>);
+ method public void requestImsExternalCallStateInfo();
+ }
+
+ public class ImsRegistrationImplBase {
+ ctor public ImsRegistrationImplBase();
+ method public final void onDeregistered(android.telephony.ims.ImsReasonInfo);
+ method public final void onRegistered(int);
+ method public final void onRegistering(int);
+ method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]);
+ method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
+ field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1
+ field public static final int REGISTRATION_TECH_LTE = 0; // 0x0
+ field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff
+ }
+
+ public class ImsSmsImplBase {
+ ctor public ImsSmsImplBase();
+ method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int);
+ method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int);
+ method public String getSmsFormat();
+ method public void onReady();
+ method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException;
+ method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException;
+ method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException;
+ method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException;
+ method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException;
+ method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException;
+ method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]);
+ field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2
+ field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3
+ field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4
+ field public static final int DELIVER_STATUS_OK = 1; // 0x1
+ field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff
+ field public static final int SEND_STATUS_ERROR = 2; // 0x2
+ field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
+ field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3
+ field public static final int SEND_STATUS_OK = 1; // 0x1
+ field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2
+ field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1
+ }
+
+ public class ImsUtImplBase {
+ ctor public ImsUtImplBase();
+ method public void close();
+ method public int queryCallBarring(int);
+ method public int queryCallBarringForServiceClass(int, int);
+ method public int queryCallForward(int, String);
+ method public int queryCallWaiting();
+ method public int queryClip();
+ method public int queryClir();
+ method public int queryColp();
+ method public int queryColr();
+ method public void setListener(android.telephony.ims.ImsUtListener);
+ method public int transact(android.os.Bundle);
+ method public int updateCallBarring(int, int, String[]);
+ method public int updateCallBarringForServiceClass(int, int, String[], int);
+ method public int updateCallForward(int, int, String, int, int);
+ method public int updateCallWaiting(boolean, int);
+ method public int updateClip(boolean);
+ method public int updateClir(int);
+ method public int updateColp(boolean);
+ method public int updateColr(int);
+ }
+
+}
+
package android.telephony.mbms {
public static class DownloadRequest.Builder {
diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt
index 1f85f3f..bf21ce7 100644
--- a/api/test-lint-baseline.txt
+++ b/api/test-lint-baseline.txt
@@ -5,6 +5,36 @@
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_ADDITIONAL_CALL_INFO:
+ Inconsistent extra value; expected `android.telephony.ims.extra.ADDITIONAL_CALL_INFO`, was `AdditionalCallInfo`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CALL_RAT_TYPE:
+ Inconsistent extra value; expected `android.telephony.ims.extra.CALL_RAT_TYPE`, was `CallRadioTech`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CHILD_NUMBER:
+ Inconsistent extra value; expected `android.telephony.ims.extra.CHILD_NUMBER`, was `ChildNum`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNA:
+ Inconsistent extra value; expected `android.telephony.ims.extra.CNA`, was `cna`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNAP:
+ Inconsistent extra value; expected `android.telephony.ims.extra.CNAP`, was `cnap`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CODEC:
+ Inconsistent extra value; expected `android.telephony.ims.extra.CODEC`, was `Codec`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DIALSTRING:
+ Inconsistent extra value; expected `android.telephony.ims.extra.DIALSTRING`, was `dialstring`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DISPLAY_TEXT:
+ Inconsistent extra value; expected `android.telephony.ims.extra.DISPLAY_TEXT`, was `DisplayText`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_EMERGENCY_CALL:
+ Inconsistent extra value; expected `android.telephony.ims.extra.EMERGENCY_CALL`, was `e_call`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_IS_CALL_PULL:
+ Inconsistent extra value; expected `android.telephony.ims.extra.IS_CALL_PULL`, was `CallPull`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OI:
+ Inconsistent extra value; expected `android.telephony.ims.extra.OI`, was `oi`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OIR:
+ Inconsistent extra value; expected `android.telephony.ims.extra.OIR`, was `oir`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_REMOTE_URI:
+ Inconsistent extra value; expected `android.telephony.ims.extra.REMOTE_URI`, was `remote_uri`
+ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_USSD:
+ Inconsistent extra value; expected `android.telephony.ims.extra.USSD`, was `ussd`
+ActionValue: android.telephony.ims.ImsReasonInfo#EXTRA_MSG_SERVICE_NOT_AUTHORIZED:
+ Inconsistent extra value; expected `android.telephony.ims.extra.MSG_SERVICE_NOT_AUTHORIZED`, was `Forbidden. Not Authorized for Service`
ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_CLEANUP:
ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_DOWNLOAD_RESULT_INTERNAL:
@@ -67,6 +97,14 @@
ArrayReturn: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]):
+ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
+ Method parameter should be Collection<ImsSsInfo> (or subclass) instead of raw array; was `android.telephony.ims.ImsSsInfo[]`
+ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
+ Method parameter should be Collection<ImsCallForwardInfo> (or subclass) instead of raw array; was `android.telephony.ims.ImsCallForwardInfo[]`
+ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
+ Method parameter should be Collection<ImsSsInfo> (or subclass) instead of raw array; was `android.telephony.ims.ImsSsInfo[]`
+ArrayReturn: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
+ Method parameter should be Collection<Uri> (or subclass) instead of raw array; was `android.net.Uri[]`
ArrayReturn: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
@@ -231,6 +269,8 @@
ConcreteCollection: android.service.autofill.UserData#getFieldClassificationAlgorithms():
+ConcreteCollection: android.telephony.ims.ImsConferenceState#mParticipants:
+ Field type is concrete collection (`java.util.HashMap`); must be higher-level interface
ContextFirst: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
@@ -303,6 +343,10 @@
ExecutorRegistration: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
+ExecutorRegistration: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener):
+ Registration methods should have overload that accepts delivery Executor: `setListener`
+ExecutorRegistration: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener):
+ Registration methods should have overload that accepts delivery Executor: `setListener`
ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
@@ -415,6 +459,10 @@
+InternalField: android.telephony.ims.ImsConferenceState#mParticipants:
+ Internal field mParticipants must not be exposed
+
+
KotlinOperator: android.os.WorkSource#get(int):
@@ -425,6 +473,10 @@
ListenerInterface: android.os.IncidentManager.AuthListener:
+ListenerInterface: android.telephony.ims.ImsCallSessionListener:
+ Listeners should be an interface, or otherwise renamed Callback: ImsCallSessionListener
+ListenerInterface: android.telephony.ims.ImsUtListener:
+ Listeners should be an interface, or otherwise renamed Callback: ImsUtListener
ListenerLast: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #4:
@@ -443,6 +495,20 @@
+ManagerLookup: android.telephony.ims.ImsMmTelManager#createForSubscriptionId(int):
+ Managers must always be obtained from Context (`createForSubscriptionId`)
+ManagerLookup: android.telephony.ims.ProvisioningManager#createForSubscriptionId(int):
+ Managers must always be obtained from Context (`createForSubscriptionId`)
+
+
+MethodNameTense: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
+ Unexpected tense; probably meant `enabled`, was `getCapabilitiesToEnable`
+
+
+MethodNameUnits: android.telephony.ims.ImsCallForwardInfo#getTimeSeconds():
+ Returned time values must be in milliseconds, was `getTimeSeconds`
+
+
MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS:
@@ -1399,6 +1465,8 @@
MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent) parameter #0:
+MissingNullability: android.telephony.CallQuality#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `dest` in method `writeToParcel`
MissingNullability: android.telephony.DataSpecificRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
MissingNullability: android.telephony.LteVopsSupportInfo#writeToParcel(android.os.Parcel, int) parameter #0:
@@ -1415,6 +1483,10 @@
MissingNullability: android.telephony.TelephonyManager#checkCarrierPrivilegesForPackage(String) parameter #0:
+MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent):
+ Missing nullability on method `getCarrierPackageNamesForIntent` return
+MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent) parameter #0:
+ Missing nullability on parameter `intent` in method `getCarrierPackageNamesForIntent`
MissingNullability: android.telephony.TelephonyManager#getLine1AlphaTag():
MissingNullability: android.telephony.TelephonyManager#getRadioHalVersion():
@@ -1451,6 +1523,316 @@
MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #8:
+MissingNullability: android.telephony.ims.ImsCallForwardInfo#getNumber():
+ Missing nullability on method `getNumber` return
+MissingNullability: android.telephony.ims.ImsCallForwardInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #2:
+ Missing nullability on parameter `callExtras` in method `ImsCallProfile`
+MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #3:
+ Missing nullability on parameter `mediaProfile` in method `ImsCallProfile`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String):
+ Missing nullability on method `getCallExtra` return
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String) parameter #0:
+ Missing nullability on parameter `name` in method `getCallExtra`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String):
+ Missing nullability on method `getCallExtra` return
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #0:
+ Missing nullability on parameter `name` in method `getCallExtra`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #1:
+ Missing nullability on parameter `defaultValue` in method `getCallExtra`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String) parameter #0:
+ Missing nullability on parameter `name` in method `getCallExtraBoolean`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String, boolean) parameter #0:
+ Missing nullability on parameter `name` in method `getCallExtraBoolean`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String) parameter #0:
+ Missing nullability on parameter `name` in method `getCallExtraInt`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String, int) parameter #0:
+ Missing nullability on parameter `name` in method `getCallExtraInt`
+MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtras():
+ Missing nullability on method `getCallExtras` return
+MissingNullability: android.telephony.ims.ImsCallProfile#getMediaProfile():
+ Missing nullability on method `getMediaProfile` return
+MissingNullability: android.telephony.ims.ImsCallProfile#getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `callProfile` in method `getVideoStateFromImsCallProfile`
+MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #0:
+ Missing nullability on parameter `name` in method `setCallExtra`
+MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #1:
+ Missing nullability on parameter `value` in method `setCallExtra`
+MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraBoolean(String, boolean) parameter #0:
+ Missing nullability on parameter `name` in method `setCallExtraBoolean`
+MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraInt(String, int) parameter #0:
+ Missing nullability on parameter `name` in method `setCallExtraInt`
+MissingNullability: android.telephony.ims.ImsCallProfile#updateCallExtras(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `updateCallExtras`
+MissingNullability: android.telephony.ims.ImsCallProfile#updateCallType(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `updateCallType`
+MissingNullability: android.telephony.ims.ImsCallProfile#updateMediaProfile(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `updateMediaProfile`
+MissingNullability: android.telephony.ims.ImsCallProfile#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionConferenceExtendFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `newSession` in method `callSessionConferenceExtendReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `callSessionConferenceExtendReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `newSession` in method `callSessionConferenceExtended`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `callSessionConferenceExtended`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState) parameter #0:
+ Missing nullability on parameter `state` in method `callSessionConferenceStateUpdated`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
+ Missing nullability on parameter `reasonInfo` in method `callSessionHandover`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
+ Missing nullability on parameter `reasonInfo` in method `callSessionHandoverFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHeld(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionHeld`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionHoldFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldReceived(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionHoldReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiated(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionInitiated`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionInitiatedFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionInviteParticipantsRequestFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase) parameter #0:
+ Missing nullability on parameter `newSession` in method `callSessionMergeComplete`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionMergeFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `newSession` in method `callSessionMergeStarted`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `callSessionMergeStarted`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionProgressing`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionRemoveParticipantsRequestFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionResumeFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeReceived(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionResumeReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumed(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionResumed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttMessageReceived(String) parameter #0:
+ Missing nullability on parameter `rttMessage` in method `callSessionRttMessageReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `callProfile` in method `callSessionRttModifyRequestReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification) parameter #0:
+ Missing nullability on parameter `suppSrvNotification` in method `callSessionSuppServiceReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionTerminated(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionTerminated`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `reasonInfo` in method `callSessionUpdateFailed`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateReceived(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionUpdateReceived`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdated(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `callSessionUpdated`
+MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUssdMessageReceived(int, String) parameter #1:
+ Missing nullability on parameter `ussdMessage` in method `callSessionUssdMessageReceived`
+MissingNullability: android.telephony.ims.ImsConferenceState#getConnectionStateForStatus(String) parameter #0:
+ Missing nullability on parameter `status` in method `getConnectionStateForStatus`
+MissingNullability: android.telephony.ims.ImsConferenceState#mParticipants:
+ Missing nullability on field `mParticipants` in class `class android.telephony.ims.ImsConferenceState`
+MissingNullability: android.telephony.ims.ImsConferenceState#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsExternalCallState#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsReasonInfo#ImsReasonInfo(int, int, String) parameter #2:
+ Missing nullability on parameter `extraMessage` in method `ImsReasonInfo`
+MissingNullability: android.telephony.ims.ImsReasonInfo#getExtraMessage():
+ Missing nullability on method `getExtraMessage` return
+MissingNullability: android.telephony.ims.ImsReasonInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsService#createMmTelFeature(int):
+ Missing nullability on method `createMmTelFeature` return
+MissingNullability: android.telephony.ims.ImsService#createRcsFeature(int):
+ Missing nullability on method `createRcsFeature` return
+MissingNullability: android.telephony.ims.ImsService#getConfig(int):
+ Missing nullability on method `getConfig` return
+MissingNullability: android.telephony.ims.ImsService#getRegistration(int):
+ Missing nullability on method `getRegistration` return
+MissingNullability: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) parameter #0:
+ Missing nullability on parameter `c` in method `onUpdateSupportedImsFeatures`
+MissingNullability: android.telephony.ims.ImsService#querySupportedImsFeatures():
+ Missing nullability on method `querySupportedImsFeatures` return
+MissingNullability: android.telephony.ims.ImsSsData#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsSsInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsStreamMediaProfile#copyFrom(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `copyFrom`
+MissingNullability: android.telephony.ims.ImsStreamMediaProfile#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #4:
+ Missing nullability on parameter `number` in method `ImsSuppServiceNotification`
+MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #5:
+ Missing nullability on parameter `history` in method `ImsSuppServiceNotification`
+MissingNullability: android.telephony.ims.ImsSuppServiceNotification#history:
+ Missing nullability on field `history` in class `class android.telephony.ims.ImsSuppServiceNotification`
+MissingNullability: android.telephony.ims.ImsSuppServiceNotification#number:
+ Missing nullability on field `number` in class `class android.telephony.ims.ImsSuppServiceNotification`
+MissingNullability: android.telephony.ims.ImsSuppServiceNotification#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.telephony.ims.ImsUtListener#onSupplementaryServiceIndication(android.telephony.ims.ImsSsData) parameter #0:
+ Missing nullability on parameter `ssData` in method `onSupplementaryServiceIndication`
+MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
+ Missing nullability on parameter `cbInfo` in method `onUtConfigurationCallBarringQueried`
+MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
+ Missing nullability on parameter `cfInfo` in method `onUtConfigurationCallForwardQueried`
+MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
+ Missing nullability on parameter `cwInfo` in method `onUtConfigurationCallWaitingQueried`
+MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueried(int, android.os.Bundle) parameter #1:
+ Missing nullability on parameter `configuration` in method `onUtConfigurationQueried`
+MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
+ Missing nullability on parameter `error` in method `onUtConfigurationQueryFailed`
+MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
+ Missing nullability on parameter `error` in method `onUtConfigurationUpdateFailed`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities) parameter #0:
+ Missing nullability on parameter `CameraCapabilities` in method `changeCameraCapabilities`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #0:
+ Missing nullability on parameter `fromProfile` in method `onSendSessionModifyRequest`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
+ Missing nullability on parameter `toProfile` in method `onSendSessionModifyRequest`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyResponse(android.telecom.VideoProfile) parameter #0:
+ Missing nullability on parameter `responseProfile` in method `onSendSessionModifyResponse`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String) parameter #0:
+ Missing nullability on parameter `cameraId` in method `onSetCamera`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String, int) parameter #0:
+ Missing nullability on parameter `cameraId` in method `onSetCamera`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetDisplaySurface(android.view.Surface) parameter #0:
+ Missing nullability on parameter `surface` in method `onSetDisplaySurface`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPauseImage(android.net.Uri) parameter #0:
+ Missing nullability on parameter `uri` in method `onSetPauseImage`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPreviewSurface(android.view.Surface) parameter #0:
+ Missing nullability on parameter `surface` in method `onSetPreviewSurface`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyRequest(android.telecom.VideoProfile) parameter #0:
+ Missing nullability on parameter `VideoProfile` in method `receiveSessionModifyRequest`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
+ Missing nullability on parameter `requestedProfile` in method `receiveSessionModifyResponse`
+MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #2:
+ Missing nullability on parameter `responseProfile` in method `receiveSessionModifyResponse`
+MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToDisable():
+ Missing nullability on method `getCapabilitiesToDisable` return
+MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
+ Missing nullability on method `getCapabilitiesToEnable` return
+MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #0:
+ Missing nullability on parameter `request` in method `changeEnabledCapabilities`
+MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #1:
+ Missing nullability on parameter `c` in method `changeEnabledCapabilities`
+MissingNullability: android.telephony.ims.feature.MmTelFeature#queryCapabilityStatus():
+ Missing nullability on method `queryCapabilityStatus` return
+MissingNullability: android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities) parameter #0:
+ Missing nullability on parameter `c` in method `MmTelCapabilities`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#accept(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `accept`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#deflect(String) parameter #0:
+ Missing nullability on parameter `deflectNumber` in method `deflect`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#extendToConference(String[]) parameter #0:
+ Missing nullability on parameter `participants` in method `extendToConference`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallId():
+ Missing nullability on method `getCallId` return
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallProfile():
+ Missing nullability on method `getCallProfile` return
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getImsVideoCallProvider():
+ Missing nullability on method `getImsVideoCallProvider` return
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getLocalCallProfile():
+ Missing nullability on method `getLocalCallProfile` return
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String):
+ Missing nullability on method `getProperty` return
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String) parameter #0:
+ Missing nullability on parameter `name` in method `getProperty`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getRemoteCallProfile():
+ Missing nullability on method `getRemoteCallProfile` return
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#hold(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `hold`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#inviteParticipants(String[]) parameter #0:
+ Missing nullability on parameter `participants` in method `inviteParticipants`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#removeParticipants(String[]) parameter #0:
+ Missing nullability on parameter `participants` in method `removeParticipants`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#resume(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
+ Missing nullability on parameter `profile` in method `resume`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendDtmf(char, android.os.Message) parameter #1:
+ Missing nullability on parameter `result` in method `sendDtmf`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttMessage(String) parameter #0:
+ Missing nullability on parameter `rttMessage` in method `sendRttMessage`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttModifyRequest(android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `toProfile` in method `sendRttModifyRequest`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendUssd(String) parameter #0:
+ Missing nullability on parameter `ussdMessage` in method `sendUssd`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener) parameter #0:
+ Missing nullability on parameter `listener` in method `setListener`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `callee` in method `start`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `start`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #0:
+ Missing nullability on parameter `participants` in method `startConference`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `startConference`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#update(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
+ Missing nullability on parameter `profile` in method `update`
+MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase.State#toString(int):
+ Missing nullability on method `toString` return
+MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#getConfigString(int):
+ Missing nullability on method `getConfigString` return
+MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#notifyProvisionedValueChanged(int, String) parameter #1:
+ Missing nullability on parameter `value` in method `notifyProvisionedValueChanged`
+MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#setConfig(int, String) parameter #1:
+ Missing nullability on parameter `value` in method `setConfig`
+MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#getServiceFeatures():
+ Missing nullability on method `getServiceFeatures` return
+MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `dest` in method `writeToParcel`
+MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int):
+ Missing nullability on method `addFeature` return
+MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#build():
+ Missing nullability on method `build` return
+MissingNullability: android.telephony.ims.stub.ImsMultiEndpointImplBase#onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>) parameter #0:
+ Missing nullability on parameter `externalCallDialogs` in method `onImsExternalCallStateUpdate`
+MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onDeregistered(android.telephony.ims.ImsReasonInfo) parameter #0:
+ Missing nullability on parameter `info` in method `onDeregistered`
+MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
+ Missing nullability on parameter `uris` in method `onSubscriberAssociatedUriChanged`
+MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
+ Missing nullability on parameter `info` in method `onTechnologyChangeFailed`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#getSmsFormat():
+ Missing nullability on method `getSmsFormat` return
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #1:
+ Missing nullability on parameter `format` in method `onSmsReceived`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #2:
+ Missing nullability on parameter `pdu` in method `onSmsReceived`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #1:
+ Missing nullability on parameter `format` in method `onSmsStatusReportReceived`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #2:
+ Missing nullability on parameter `pdu` in method `onSmsStatusReportReceived`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #2:
+ Missing nullability on parameter `format` in method `onSmsStatusReportReceived`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #3:
+ Missing nullability on parameter `pdu` in method `onSmsStatusReportReceived`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #2:
+ Missing nullability on parameter `format` in method `sendSms`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #3:
+ Missing nullability on parameter `smsc` in method `sendSms`
+MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #5:
+ Missing nullability on parameter `pdu` in method `sendSms`
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCallForward(int, String) parameter #1:
+ Missing nullability on parameter `number` in method `queryCallForward`
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener) parameter #0:
+ Missing nullability on parameter `listener` in method `setListener`
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#transact(android.os.Bundle) parameter #0:
+ Missing nullability on parameter `ssInfo` in method `transact`
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarring(int, int, String[]) parameter #2:
+ Missing nullability on parameter `barrList` in method `updateCallBarring`
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarringForServiceClass(int, int, String[], int) parameter #2:
+ Missing nullability on parameter `barrList` in method `updateCallBarringForServiceClass`
+MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallForward(int, int, String, int, int) parameter #2:
+ Missing nullability on parameter `number` in method `updateCallForward`
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
@@ -1915,6 +2297,8 @@
NotCloseable: android.os.HwParcel:
+NotCloseable: android.telephony.ims.stub.ImsUtImplBase:
+ Classes that release resources (close()) should implement AutoClosable and CloseGuard: class android.telephony.ims.stub.ImsUtImplBase
OnNameExpected: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
@@ -1927,6 +2311,22 @@
OnNameExpected: android.service.quicksettings.TileService#isQuickSettingsSupported():
+OnNameExpected: android.telephony.ims.ImsService#createMmTelFeature(int):
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#createRcsFeature(int):
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#disableIms(int):
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#enableIms(int):
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#getConfig(int):
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#getRegistration(int):
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#querySupportedImsFeatures():
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.telephony.ims.ImsService#readyForFeatureCreation():
+ If implemented by developer, should follow the on<Something> style; otherwise consider marking final
OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
@@ -2065,6 +2465,8 @@
RethrowRemoteException: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
+RethrowRemoteException: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration):
+ Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
@@ -2143,6 +2545,8 @@
SamShouldBeLast: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>):
+SamShouldBeLast: android.telephony.ims.ImsMmTelManager#getFeatureState(java.util.function.Consumer<java.lang.Integer>, java.util.concurrent.Executor):
+ SAM-compatible parameters (such as parameter 1, "callback", in android.telephony.ims.ImsMmTelManager.getFeatureState) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.view.Choreographer#postCallback(int, Runnable, Object):
SamShouldBeLast: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long):
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 41d546f..22e1d01 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -174,6 +174,8 @@
instrument.noWindowAnimation = true;
} else if (opt.equals("--no-hidden-api-checks")) {
instrument.disableHiddenApiChecks = true;
+ } else if (opt.equals("--no-test-api-checks")) {
+ instrument.disableTestApiChecks = true;
} else if (opt.equals("--no-isolated-storage")) {
instrument.disableIsolatedStorage = true;
} else if (opt.equals("--user")) {
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 4d7b5a7..6afd7c4 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -17,6 +17,7 @@
package com.android.commands.am;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS;
import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
import android.app.IActivityManager;
@@ -85,6 +86,7 @@
String logPath = null;
public boolean noWindowAnimation = false;
public boolean disableHiddenApiChecks = false;
+ public boolean disableTestApiChecks = false;
public boolean disableIsolatedStorage = false;
public String abi = null;
public int userId = UserHandle.USER_CURRENT;
@@ -506,6 +508,9 @@
if (disableHiddenApiChecks) {
flags |= INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
}
+ if (disableTestApiChecks) {
+ flags |= INSTR_FLAG_DISABLE_TEST_API_CHECKS;
+ }
if (disableIsolatedStorage) {
flags |= INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 847c298..8a8df38 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -324,6 +324,8 @@
AppCompatibilityChangeReported app_compatibility_change_reported =
228 [(allow_from_any_uid) = true];
+ PerfettoUploaded perfetto_uploaded =
+ 229 [(log_from_module) = "perfetto"];
}
// Pulled events will start at field 10000.
@@ -6857,3 +6859,37 @@
optional Source source = 4;
}
+
+/**
+ * Logged from
+ * external/perfetto/src/perfetto_cmd/perfetto_cmd.cc
+ */
+message PerfettoUploaded {
+ enum Event {
+ PERFETTO_UNDEFINED = 0;
+ PERFETTO_TRACE_BEGIN = 1;
+ PERFETTO_BACKGROUND_TRACE_BEGIN = 2;
+ PERFETTO_ON_CONNECT = 3;
+ PERFETTO_ON_TRACING_DISABLED = 4;
+ PERFETTO_UPLOAD_DROPBOX_BEGIN = 5;
+ PERFETTO_UPLOAD_DROPBOX_SUCCESS = 6;
+ PERFETTO_UPLOAD_DROPBOX_FAILURE = 7;
+ PERFETTO_UPLOAD_INCIDENT_BEGIN = 8;
+ PERFETTO_UPLOAD_INCIDENT_SUCCESS = 9;
+ PERFETTO_UPLOAD_INCIDENT_FAILURE = 10;
+ PERFETTO_FINALIZE_TRACE_AND_EXIT = 11;
+ PERFETTO_TRIGGER_BEGIN = 12;
+ PERFETTO_TRIGGER_SUCCESS = 13;
+ PERFETTO_TRIGGER_FAILURE = 14;
+ PERFETTO_HIT_GUARDRAILS = 15;
+ PERFETTO_ON_TIMEOUT = 16;
+ PERFETTO_NOT_UPLOADING_EMPTY_TRACE = 17;
+ }
+
+ // Which stage of the pipeline we are reporting from.
+ optional Event event = 1;
+
+ // UUID matching the one set inside the SystemInfo trace packet.
+ optional int64 trace_uuid_lsb = 2;
+ optional int64 trace_uuid_msb = 3;
+}
diff --git a/config/OWNERS b/config/OWNERS
new file mode 100644
index 0000000..53f80e6
--- /dev/null
+++ b/config/OWNERS
@@ -0,0 +1,5 @@
+# compat-team@ for changes to hiddenapi files
+per-file hiddenapi-* = andreionea@google.com, atrost@google.com, mathewi@google.com, satayev@google.com
+
+# Escalations:
+per-file hiddenapi-* = bdc@google.com, narayan@google.com
\ No newline at end of file
diff --git a/config/hiddenapi-greylist-max-q.txt b/config/hiddenapi-greylist-max-q.txt
new file mode 100644
index 0000000..f465604
--- /dev/null
+++ b/config/hiddenapi-greylist-max-q.txt
@@ -0,0 +1,704 @@
+Landroid/R$styleable;->ActionBar:[I
+Landroid/R$styleable;->ActionBar_background:I
+Landroid/R$styleable;->ActionBar_backgroundSplit:I
+Landroid/R$styleable;->ActionBar_backgroundStacked:I
+Landroid/R$styleable;->ActionBar_divider:I
+Landroid/R$styleable;->ActionBar_itemPadding:I
+Landroid/R$styleable;->CalendarView:[I
+Landroid/R$styleable;->CalendarView_dateTextAppearance:I
+Landroid/R$styleable;->CalendarView_firstDayOfWeek:I
+Landroid/R$styleable;->CalendarView_focusedMonthDateColor:I
+Landroid/R$styleable;->CalendarView_selectedDateVerticalBar:I
+Landroid/R$styleable;->CalendarView_selectedWeekBackgroundColor:I
+Landroid/R$styleable;->CalendarView_shownWeekCount:I
+Landroid/R$styleable;->CalendarView_showWeekNumber:I
+Landroid/R$styleable;->CalendarView_unfocusedMonthDateColor:I
+Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I
+Landroid/R$styleable;->CalendarView_weekNumberColor:I
+Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I
+Landroid/R$styleable;->CheckBoxPreference:[I
+Landroid/R$styleable;->CheckedTextView:[I
+Landroid/R$styleable;->CheckedTextView_checkMark:I
+Landroid/R$styleable;->CompoundButton:[I
+Landroid/R$styleable;->CompoundButton_button:I
+Landroid/R$styleable;->ContactsDataKind:[I
+Landroid/R$styleable;->DatePicker:[I
+Landroid/R$styleable;->DialogPreference:[I
+Landroid/R$styleable;->DrawableStates:[I
+Landroid/R$styleable;->ExpandableListView:[I
+Landroid/R$styleable;->FrameLayout_Layout:[I
+Landroid/R$styleable;->HorizontalScrollView:[I
+Landroid/R$styleable;->ImageView:[I
+Landroid/R$styleable;->ImageView_adjustViewBounds:I
+Landroid/R$styleable;->ImageView_baselineAlignBottom:I
+Landroid/R$styleable;->ImageView_cropToPadding:I
+Landroid/R$styleable;->ImageView_maxHeight:I
+Landroid/R$styleable;->ImageView_maxWidth:I
+Landroid/R$styleable;->ImageView_scaleType:I
+Landroid/R$styleable;->ImageView_src:I
+Landroid/R$styleable;->ImageView_tint:I
+Landroid/R$styleable;->Keyboard:[I
+Landroid/R$styleable;->Keyboard_horizontalGap:I
+Landroid/R$styleable;->Keyboard_Key:[I
+Landroid/R$styleable;->Keyboard_keyHeight:I
+Landroid/R$styleable;->Keyboard_keyWidth:I
+Landroid/R$styleable;->Keyboard_Key_codes:I
+Landroid/R$styleable;->Keyboard_Key_iconPreview:I
+Landroid/R$styleable;->Keyboard_Key_isModifier:I
+Landroid/R$styleable;->Keyboard_Key_isRepeatable:I
+Landroid/R$styleable;->Keyboard_Key_isSticky:I
+Landroid/R$styleable;->Keyboard_Key_keyEdgeFlags:I
+Landroid/R$styleable;->Keyboard_Key_keyIcon:I
+Landroid/R$styleable;->Keyboard_Key_keyLabel:I
+Landroid/R$styleable;->Keyboard_Key_keyOutputText:I
+Landroid/R$styleable;->Keyboard_Key_popupCharacters:I
+Landroid/R$styleable;->Keyboard_Key_popupKeyboard:I
+Landroid/R$styleable;->Keyboard_Row:[I
+Landroid/R$styleable;->Keyboard_Row_keyboardMode:I
+Landroid/R$styleable;->Keyboard_Row_rowEdgeFlags:I
+Landroid/R$styleable;->Keyboard_verticalGap:I
+Landroid/R$styleable;->LinearLayout:[I
+Landroid/R$styleable;->LinearLayout_baselineAligned:I
+Landroid/R$styleable;->LinearLayout_baselineAlignedChildIndex:I
+Landroid/R$styleable;->LinearLayout_divider:I
+Landroid/R$styleable;->LinearLayout_dividerPadding:I
+Landroid/R$styleable;->LinearLayout_gravity:I
+Landroid/R$styleable;->LinearLayout_Layout:[I
+Landroid/R$styleable;->LinearLayout_Layout_layout_gravity:I
+Landroid/R$styleable;->LinearLayout_Layout_layout_height:I
+Landroid/R$styleable;->LinearLayout_Layout_layout_weight:I
+Landroid/R$styleable;->LinearLayout_Layout_layout_width:I
+Landroid/R$styleable;->LinearLayout_measureWithLargestChild:I
+Landroid/R$styleable;->LinearLayout_orientation:I
+Landroid/R$styleable;->LinearLayout_showDividers:I
+Landroid/R$styleable;->ListView:[I
+Landroid/R$styleable;->ListView_divider:I
+Landroid/R$styleable;->ListView_dividerHeight:I
+Landroid/R$styleable;->LockPatternView:[I
+Landroid/R$styleable;->NumberPicker:[I
+Landroid/R$styleable;->NumberPicker_solidColor:I
+Landroid/R$styleable;->PopupWindow:[I
+Landroid/R$styleable;->ProgressBar:[I
+Landroid/R$styleable;->ProgressBar_indeterminateDrawable:I
+Landroid/R$styleable;->ProgressBar_indeterminateDuration:I
+Landroid/R$styleable;->ProgressBar_maxHeight:I
+Landroid/R$styleable;->ProgressBar_maxWidth:I
+Landroid/R$styleable;->ProgressBar_minHeight:I
+Landroid/R$styleable;->ProgressBar_minWidth:I
+Landroid/R$styleable;->ProgressBar_progressDrawable:I
+Landroid/R$styleable;->RingtonePreference:[I
+Landroid/R$styleable;->ScrollView:[I
+Landroid/R$styleable;->SearchView:[I
+Landroid/R$styleable;->SeekBar:[I
+Landroid/R$styleable;->SeekBar_thumb:I
+Landroid/R$styleable;->SeekBar_thumbOffset:I
+Landroid/R$styleable;->SlidingDrawer:[I
+Landroid/R$styleable;->SlidingDrawer_allowSingleTap:I
+Landroid/R$styleable;->SlidingDrawer_animateOnClick:I
+Landroid/R$styleable;->SlidingDrawer_bottomOffset:I
+Landroid/R$styleable;->SlidingDrawer_content:I
+Landroid/R$styleable;->SlidingDrawer_handle:I
+Landroid/R$styleable;->SlidingDrawer_orientation:I
+Landroid/R$styleable;->SlidingDrawer_topOffset:I
+Landroid/R$styleable;->Switch:[I
+Landroid/R$styleable;->Switch_showText:I
+Landroid/R$styleable;->Switch_splitTrack:I
+Landroid/R$styleable;->Switch_switchMinWidth:I
+Landroid/R$styleable;->Switch_switchPadding:I
+Landroid/R$styleable;->Switch_switchTextAppearance:I
+Landroid/R$styleable;->Switch_textOff:I
+Landroid/R$styleable;->Switch_textOn:I
+Landroid/R$styleable;->Switch_thumb:I
+Landroid/R$styleable;->Switch_thumbTextPadding:I
+Landroid/R$styleable;->Switch_track:I
+Landroid/R$styleable;->TextAppearance:[I
+Landroid/R$styleable;->TextAppearance_textAllCaps:I
+Landroid/R$styleable;->TextAppearance_textColor:I
+Landroid/R$styleable;->TextAppearance_textColorHighlight:I
+Landroid/R$styleable;->TextAppearance_textColorHint:I
+Landroid/R$styleable;->TextAppearance_textColorLink:I
+Landroid/R$styleable;->TextAppearance_textSize:I
+Landroid/R$styleable;->TextAppearance_textStyle:I
+Landroid/R$styleable;->TextAppearance_typeface:I
+Landroid/R$styleable;->TextView:[I
+Landroid/R$styleable;->TextView_autoLink:I
+Landroid/R$styleable;->TextView_autoText:I
+Landroid/R$styleable;->TextView_bufferType:I
+Landroid/R$styleable;->TextView_capitalize:I
+Landroid/R$styleable;->TextView_cursorVisible:I
+Landroid/R$styleable;->TextView_digits:I
+Landroid/R$styleable;->TextView_drawableBottom:I
+Landroid/R$styleable;->TextView_drawableEnd:I
+Landroid/R$styleable;->TextView_drawableLeft:I
+Landroid/R$styleable;->TextView_drawablePadding:I
+Landroid/R$styleable;->TextView_drawableRight:I
+Landroid/R$styleable;->TextView_drawableStart:I
+Landroid/R$styleable;->TextView_drawableTop:I
+Landroid/R$styleable;->TextView_editable:I
+Landroid/R$styleable;->TextView_ellipsize:I
+Landroid/R$styleable;->TextView_ems:I
+Landroid/R$styleable;->TextView_enabled:I
+Landroid/R$styleable;->TextView_freezesText:I
+Landroid/R$styleable;->TextView_gravity:I
+Landroid/R$styleable;->TextView_height:I
+Landroid/R$styleable;->TextView_hint:I
+Landroid/R$styleable;->TextView_imeActionId:I
+Landroid/R$styleable;->TextView_imeActionLabel:I
+Landroid/R$styleable;->TextView_imeOptions:I
+Landroid/R$styleable;->TextView_includeFontPadding:I
+Landroid/R$styleable;->TextView_inputMethod:I
+Landroid/R$styleable;->TextView_inputType:I
+Landroid/R$styleable;->TextView_lines:I
+Landroid/R$styleable;->TextView_lineSpacingExtra:I
+Landroid/R$styleable;->TextView_lineSpacingMultiplier:I
+Landroid/R$styleable;->TextView_linksClickable:I
+Landroid/R$styleable;->TextView_marqueeRepeatLimit:I
+Landroid/R$styleable;->TextView_maxEms:I
+Landroid/R$styleable;->TextView_maxHeight:I
+Landroid/R$styleable;->TextView_maxLength:I
+Landroid/R$styleable;->TextView_maxLines:I
+Landroid/R$styleable;->TextView_maxWidth:I
+Landroid/R$styleable;->TextView_minEms:I
+Landroid/R$styleable;->TextView_minHeight:I
+Landroid/R$styleable;->TextView_minLines:I
+Landroid/R$styleable;->TextView_minWidth:I
+Landroid/R$styleable;->TextView_numeric:I
+Landroid/R$styleable;->TextView_password:I
+Landroid/R$styleable;->TextView_phoneNumber:I
+Landroid/R$styleable;->TextView_privateImeOptions:I
+Landroid/R$styleable;->TextView_scrollHorizontally:I
+Landroid/R$styleable;->TextView_selectAllOnFocus:I
+Landroid/R$styleable;->TextView_shadowColor:I
+Landroid/R$styleable;->TextView_shadowDx:I
+Landroid/R$styleable;->TextView_shadowDy:I
+Landroid/R$styleable;->TextView_shadowRadius:I
+Landroid/R$styleable;->TextView_singleLine:I
+Landroid/R$styleable;->TextView_text:I
+Landroid/R$styleable;->TextView_textAllCaps:I
+Landroid/R$styleable;->TextView_textAppearance:I
+Landroid/R$styleable;->TextView_textColor:I
+Landroid/R$styleable;->TextView_textColorHighlight:I
+Landroid/R$styleable;->TextView_textColorHint:I
+Landroid/R$styleable;->TextView_textColorLink:I
+Landroid/R$styleable;->TextView_textCursorDrawable:I
+Landroid/R$styleable;->TextView_textIsSelectable:I
+Landroid/R$styleable;->TextView_textScaleX:I
+Landroid/R$styleable;->TextView_textSelectHandle:I
+Landroid/R$styleable;->TextView_textSelectHandleLeft:I
+Landroid/R$styleable;->TextView_textSelectHandleRight:I
+Landroid/R$styleable;->TextView_textSize:I
+Landroid/R$styleable;->TextView_textStyle:I
+Landroid/R$styleable;->TextView_typeface:I
+Landroid/R$styleable;->TextView_width:I
+Landroid/R$styleable;->Theme:[I
+Landroid/R$styleable;->View:[I
+Landroid/R$styleable;->ViewDrawableStates:[I
+Landroid/R$styleable;->ViewGroup_Layout:[I
+Landroid/R$styleable;->ViewGroup_Layout_layout_height:I
+Landroid/R$styleable;->ViewGroup_Layout_layout_width:I
+Landroid/R$styleable;->ViewGroup_MarginLayout:[I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_height:I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_margin:I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginBottom:I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginLeft:I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginRight:I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginTop:I
+Landroid/R$styleable;->ViewGroup_MarginLayout_layout_width:I
+Landroid/R$styleable;->View_alpha:I
+Landroid/R$styleable;->View_background:I
+Landroid/R$styleable;->View_clickable:I
+Landroid/R$styleable;->View_contentDescription:I
+Landroid/R$styleable;->View_drawingCacheQuality:I
+Landroid/R$styleable;->View_duplicateParentState:I
+Landroid/R$styleable;->View_fadingEdge:I
+Landroid/R$styleable;->View_filterTouchesWhenObscured:I
+Landroid/R$styleable;->View_fitsSystemWindows:I
+Landroid/R$styleable;->View_focusable:I
+Landroid/R$styleable;->View_focusableInTouchMode:I
+Landroid/R$styleable;->View_hapticFeedbackEnabled:I
+Landroid/R$styleable;->View_id:I
+Landroid/R$styleable;->View_isScrollContainer:I
+Landroid/R$styleable;->View_keepScreenOn:I
+Landroid/R$styleable;->View_longClickable:I
+Landroid/R$styleable;->View_minHeight:I
+Landroid/R$styleable;->View_minWidth:I
+Landroid/R$styleable;->View_nextFocusDown:I
+Landroid/R$styleable;->View_nextFocusLeft:I
+Landroid/R$styleable;->View_nextFocusRight:I
+Landroid/R$styleable;->View_nextFocusUp:I
+Landroid/R$styleable;->View_onClick:I
+Landroid/R$styleable;->View_overScrollMode:I
+Landroid/R$styleable;->View_padding:I
+Landroid/R$styleable;->View_paddingBottom:I
+Landroid/R$styleable;->View_paddingEnd:I
+Landroid/R$styleable;->View_paddingLeft:I
+Landroid/R$styleable;->View_paddingRight:I
+Landroid/R$styleable;->View_paddingStart:I
+Landroid/R$styleable;->View_paddingTop:I
+Landroid/R$styleable;->View_rotation:I
+Landroid/R$styleable;->View_rotationX:I
+Landroid/R$styleable;->View_rotationY:I
+Landroid/R$styleable;->View_saveEnabled:I
+Landroid/R$styleable;->View_scaleX:I
+Landroid/R$styleable;->View_scaleY:I
+Landroid/R$styleable;->View_scrollbarDefaultDelayBeforeFade:I
+Landroid/R$styleable;->View_scrollbarFadeDuration:I
+Landroid/R$styleable;->View_scrollbars:I
+Landroid/R$styleable;->View_scrollbarSize:I
+Landroid/R$styleable;->View_scrollbarStyle:I
+Landroid/R$styleable;->View_scrollbarThumbHorizontal:I
+Landroid/R$styleable;->View_scrollbarThumbVertical:I
+Landroid/R$styleable;->View_scrollbarTrackHorizontal:I
+Landroid/R$styleable;->View_scrollbarTrackVertical:I
+Landroid/R$styleable;->View_scrollX:I
+Landroid/R$styleable;->View_scrollY:I
+Landroid/R$styleable;->View_soundEffectsEnabled:I
+Landroid/R$styleable;->View_tag:I
+Landroid/R$styleable;->View_transformPivotX:I
+Landroid/R$styleable;->View_transformPivotY:I
+Landroid/R$styleable;->View_translationX:I
+Landroid/R$styleable;->View_translationY:I
+Landroid/R$styleable;->View_visibility:I
+Landroid/R$styleable;->Window:[I
+Landroid/R$styleable;->Window_windowBackground:I
+Landroid/R$styleable;->Window_windowFrame:I
+Lcom/android/internal/R$anim;->fade_in:I
+Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I
+Lcom/android/internal/R$array;->config_autoBrightnessLevels:I
+Lcom/android/internal/R$array;->config_mobile_hotspot_provision_app:I
+Lcom/android/internal/R$array;->config_sms_enabled_locking_shift_tables:I
+Lcom/android/internal/R$array;->config_sms_enabled_single_shift_tables:I
+Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I
+Lcom/android/internal/R$array;->config_tether_upstream_types:I
+Lcom/android/internal/R$array;->config_tether_usb_regexs:I
+Lcom/android/internal/R$array;->config_tether_wifi_regexs:I
+Lcom/android/internal/R$array;->maps_starting_lat_lng:I
+Lcom/android/internal/R$array;->maps_starting_zoom:I
+Lcom/android/internal/R$attr;->actionBarStyle:I
+Lcom/android/internal/R$attr;->buttonStyle:I
+Lcom/android/internal/R$attr;->description:I
+Lcom/android/internal/R$attr;->editTextStyle:I
+Lcom/android/internal/R$attr;->mapViewStyle:I
+Lcom/android/internal/R$attr;->popupWindowStyle:I
+Lcom/android/internal/R$attr;->state_above_anchor:I
+Lcom/android/internal/R$attr;->state_focused:I
+Lcom/android/internal/R$attr;->state_pressed:I
+Lcom/android/internal/R$attr;->state_selected:I
+Lcom/android/internal/R$attr;->switchStyle:I
+Lcom/android/internal/R$attr;->text:I
+Lcom/android/internal/R$attr;->title:I
+Lcom/android/internal/R$attr;->webViewStyle:I
+Lcom/android/internal/R$bool;-><init>()V
+Lcom/android/internal/R$bool;->config_automatic_brightness_available:I
+Lcom/android/internal/R$bool;->config_intrusiveNotificationLed:I
+Lcom/android/internal/R$bool;->config_mms_content_disposition_support:I
+Lcom/android/internal/R$bool;->config_showNavigationBar:I
+Lcom/android/internal/R$dimen;-><init>()V
+Lcom/android/internal/R$dimen;->item_touch_helper_max_drag_scroll_per_frame:I
+Lcom/android/internal/R$dimen;->navigation_bar_height:I
+Lcom/android/internal/R$dimen;->navigation_bar_height_landscape:I
+Lcom/android/internal/R$dimen;->navigation_bar_width:I
+Lcom/android/internal/R$dimen;->status_bar_height:I
+Lcom/android/internal/R$dimen;->toast_y_offset:I
+Lcom/android/internal/R$drawable;->btn_check_off:I
+Lcom/android/internal/R$drawable;->compass_arrow:I
+Lcom/android/internal/R$drawable;->compass_base:I
+Lcom/android/internal/R$drawable;->ic_maps_indicator_current_position_anim:I
+Lcom/android/internal/R$drawable;->ic_menu_close_clear_cancel:I
+Lcom/android/internal/R$drawable;->loading_tile_android:I
+Lcom/android/internal/R$drawable;->maps_google_logo:I
+Lcom/android/internal/R$drawable;->no_tile_256:I
+Lcom/android/internal/R$drawable;->reticle:I
+Lcom/android/internal/R$drawable;->stat_sys_download:I
+Lcom/android/internal/R$fraction;->config_autoBrightnessAdjustmentMaxGamma:I
+Lcom/android/internal/R$id;->account_name:I
+Lcom/android/internal/R$id;->account_type:I
+Lcom/android/internal/R$id;->alertTitle:I
+Lcom/android/internal/R$id;->allow_button:I
+Lcom/android/internal/R$id;->amPm:I
+Lcom/android/internal/R$id;->authtoken_type:I
+Lcom/android/internal/R$id;->background:I
+Lcom/android/internal/R$id;->back_button:I
+Lcom/android/internal/R$id;->body:I
+Lcom/android/internal/R$id;->buttonPanel:I
+Lcom/android/internal/R$id;->camera:I
+Lcom/android/internal/R$id;->cancel:I
+Lcom/android/internal/R$id;->clip_children_set_tag:I
+Lcom/android/internal/R$id;->clip_children_tag:I
+Lcom/android/internal/R$id;->clip_to_padding_tag:I
+Lcom/android/internal/R$id;->closeButton:I
+Lcom/android/internal/R$id;->content:I
+Lcom/android/internal/R$id;->contentPanel:I
+Lcom/android/internal/R$id;->custom:I
+Lcom/android/internal/R$id;->customPanel:I
+Lcom/android/internal/R$id;->datePicker:I
+Lcom/android/internal/R$id;->day:I
+Lcom/android/internal/R$id;->deny_button:I
+Lcom/android/internal/R$id;->description:I
+Lcom/android/internal/R$id;->edit:I
+Lcom/android/internal/R$id;->edittext_container:I
+Lcom/android/internal/R$id;->find_next:I
+Lcom/android/internal/R$id;->find_prev:I
+Lcom/android/internal/R$id;->icon:I
+Lcom/android/internal/R$id;->keyboard:I
+Lcom/android/internal/R$id;->keyboardView:I
+Lcom/android/internal/R$id;->line1:I
+Lcom/android/internal/R$id;->list_item:I
+Lcom/android/internal/R$id;->matches:I
+Lcom/android/internal/R$id;->mediacontroller_progress:I
+Lcom/android/internal/R$id;->media_actions:I
+Lcom/android/internal/R$id;->message:I
+Lcom/android/internal/R$id;->minute:I
+Lcom/android/internal/R$id;->month:I
+Lcom/android/internal/R$id;->name:I
+Lcom/android/internal/R$id;->notification_header:I
+Lcom/android/internal/R$id;->ok:I
+Lcom/android/internal/R$id;->overlay:I
+Lcom/android/internal/R$id;->packages_list:I
+Lcom/android/internal/R$id;->package_label:I
+Lcom/android/internal/R$id;->parentPanel:I
+Lcom/android/internal/R$id;->pause:I
+Lcom/android/internal/R$id;->pending_intent_tag:I
+Lcom/android/internal/R$id;->progress:I
+Lcom/android/internal/R$id;->redo:I
+Lcom/android/internal/R$id;->remote_input_tag:I
+Lcom/android/internal/R$id;->right_icon:I
+Lcom/android/internal/R$id;->search_src_text:I
+Lcom/android/internal/R$id;->share:I
+Lcom/android/internal/R$id;->shortcut:I
+Lcom/android/internal/R$id;->status_bar_latest_event_content:I
+Lcom/android/internal/R$id;->tabcontent:I
+Lcom/android/internal/R$id;->tabs:I
+Lcom/android/internal/R$id;->text1:I
+Lcom/android/internal/R$id;->text2:I
+Lcom/android/internal/R$id;->text:I
+Lcom/android/internal/R$id;->time:I
+Lcom/android/internal/R$id;->timePicker:I
+Lcom/android/internal/R$id;->time_current:I
+Lcom/android/internal/R$id;->title:I
+Lcom/android/internal/R$id;->titleDivider:I
+Lcom/android/internal/R$id;->titleDividerTop:I
+Lcom/android/internal/R$id;->title_container:I
+Lcom/android/internal/R$id;->title_template:I
+Lcom/android/internal/R$id;->topPanel:I
+Lcom/android/internal/R$id;->up:I
+Lcom/android/internal/R$id;->year:I
+Lcom/android/internal/R$id;->zoomControls:I
+Lcom/android/internal/R$id;->zoomMagnify:I
+Lcom/android/internal/R$integer;->config_screenBrightnessDim:I
+Lcom/android/internal/R$integer;->config_screenBrightnessSettingMaximum:I
+Lcom/android/internal/R$integer;->config_screenBrightnessSettingMinimum:I
+Lcom/android/internal/R$integer;->config_toastDefaultGravity:I
+Lcom/android/internal/R$interpolator;->accelerate_cubic:I
+Lcom/android/internal/R$interpolator;->decelerate_cubic:I
+Lcom/android/internal/R$layout;->notification_template_material_base:I
+Lcom/android/internal/R$layout;->preference_header_item:I
+Lcom/android/internal/R$layout;->screen_title:I
+Lcom/android/internal/R$layout;->select_dialog:I
+Lcom/android/internal/R$layout;->select_dialog_multichoice:I
+Lcom/android/internal/R$layout;->select_dialog_singlechoice:I
+Lcom/android/internal/R$layout;->webview_find:I
+Lcom/android/internal/R$layout;->zoom_magnify:I
+Lcom/android/internal/R$plurals;->matches_found:I
+Lcom/android/internal/R$raw;->loaderror:I
+Lcom/android/internal/R$raw;->nodomain:I
+Lcom/android/internal/R$string;->byteShort:I
+Lcom/android/internal/R$string;->cancel:I
+Lcom/android/internal/R$string;->enable_explore_by_touch_warning_title:I
+Lcom/android/internal/R$string;->gigabyteShort:I
+Lcom/android/internal/R$string;->kilobyteShort:I
+Lcom/android/internal/R$string;->map:I
+Lcom/android/internal/R$string;->megabyteShort:I
+Lcom/android/internal/R$string;->notification_title:I
+Lcom/android/internal/R$string;->no_matches:I
+Lcom/android/internal/R$string;->ok:I
+Lcom/android/internal/R$string;->petabyteShort:I
+Lcom/android/internal/R$string;->redo:I
+Lcom/android/internal/R$string;->share:I
+Lcom/android/internal/R$string;->terabyteShort:I
+Lcom/android/internal/R$string;->whichApplication:I
+Lcom/android/internal/R$style;->Animation_DropDownDown:I
+Lcom/android/internal/R$style;->Animation_DropDownUp:I
+Lcom/android/internal/R$style;->Animation_PopupWindow:I
+Lcom/android/internal/R$style;->Theme:I
+Lcom/android/internal/R$style;->Theme_Dialog_Alert:I
+Lcom/android/internal/R$style;->Theme_Holo_Light:I
+Lcom/android/internal/R$style;->Theme_Light:I
+Lcom/android/internal/R$styleable;-><init>()V
+Lcom/android/internal/R$styleable;->AbsListView:[I
+Lcom/android/internal/R$styleable;->AbsListView_cacheColorHint:I
+Lcom/android/internal/R$styleable;->AbsListView_choiceMode:I
+Lcom/android/internal/R$styleable;->AbsListView_drawSelectorOnTop:I
+Lcom/android/internal/R$styleable;->AbsListView_fastScrollAlwaysVisible:I
+Lcom/android/internal/R$styleable;->AbsListView_fastScrollEnabled:I
+Lcom/android/internal/R$styleable;->AbsListView_listSelector:I
+Lcom/android/internal/R$styleable;->AbsListView_scrollingCache:I
+Lcom/android/internal/R$styleable;->AbsListView_smoothScrollbar:I
+Lcom/android/internal/R$styleable;->AbsListView_stackFromBottom:I
+Lcom/android/internal/R$styleable;->AbsListView_textFilterEnabled:I
+Lcom/android/internal/R$styleable;->AbsListView_transcriptMode:I
+Lcom/android/internal/R$styleable;->AbsSpinner:[I
+Lcom/android/internal/R$styleable;->AccountAuthenticator:[I
+Lcom/android/internal/R$styleable;->AccountAuthenticator_accountPreferences:I
+Lcom/android/internal/R$styleable;->AccountAuthenticator_accountType:I
+Lcom/android/internal/R$styleable;->AccountAuthenticator_customTokens:I
+Lcom/android/internal/R$styleable;->AccountAuthenticator_icon:I
+Lcom/android/internal/R$styleable;->AccountAuthenticator_label:I
+Lcom/android/internal/R$styleable;->AccountAuthenticator_smallIcon:I
+Lcom/android/internal/R$styleable;->ActionMode:[I
+Lcom/android/internal/R$styleable;->AdapterViewAnimator:[I
+Lcom/android/internal/R$styleable;->AdapterViewFlipper:[I
+Lcom/android/internal/R$styleable;->AlertDialog:[I
+Lcom/android/internal/R$styleable;->AnalogClock:[I
+Lcom/android/internal/R$styleable;->AndroidManifest:[I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_allowTaskReparenting:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_configChanges:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_description:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_enabled:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_excludeFromRecents:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_exported:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_hardwareAccelerated:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_icon:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_immersive:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_label:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_launchMode:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_logo:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_noHistory:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_permission:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_process:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_screenOrientation:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_taskAffinity:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_theme:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_uiOptions:I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity_windowSoftInputMode:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_enabled:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_hardwareAccelerated:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_label:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_largeHeap:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_permission:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_process:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_supportsRtl:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I
+Lcom/android/internal/R$styleable;->AndroidManifestData:[I
+Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter:[I
+Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter_priority:I
+Lcom/android/internal/R$styleable;->AndroidManifestMetaData:[I
+Lcom/android/internal/R$styleable;->AndroidManifestMetaData_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestMetaData_resource:I
+Lcom/android/internal/R$styleable;->AndroidManifestMetaData_value:I
+Lcom/android/internal/R$styleable;->AndroidManifestPackageVerifier:[I
+Lcom/android/internal/R$styleable;->AndroidManifestProvider:[I
+Lcom/android/internal/R$styleable;->AndroidManifestService:[I
+Lcom/android/internal/R$styleable;->AndroidManifestService_enabled:I
+Lcom/android/internal/R$styleable;->AndroidManifestService_exported:I
+Lcom/android/internal/R$styleable;->AndroidManifestService_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestService_permission:I
+Lcom/android/internal/R$styleable;->AndroidManifestService_process:I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesLibrary:[I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk:[I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_minSdkVersion:I
+Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_targetSdkVersion:I
+Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I
+Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I
+Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I
+Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I
+Lcom/android/internal/R$styleable;->AutoCompleteTextView:[I
+Lcom/android/internal/R$styleable;->CheckBoxPreference:[I
+Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I
+Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOff:I
+Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOn:I
+Lcom/android/internal/R$styleable;->CheckedTextView:[I
+Lcom/android/internal/R$styleable;->CheckedTextView_checked:I
+Lcom/android/internal/R$styleable;->CheckedTextView_checkMark:I
+Lcom/android/internal/R$styleable;->CompoundButton:[I
+Lcom/android/internal/R$styleable;->CompoundButton_button:I
+Lcom/android/internal/R$styleable;->CompoundButton_checked:I
+Lcom/android/internal/R$styleable;->ContactsDataKind:[I
+Lcom/android/internal/R$styleable;->DatePicker:[I
+Lcom/android/internal/R$styleable;->DialogPreference:[I
+Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I
+Lcom/android/internal/R$styleable;->Dream:[I
+Lcom/android/internal/R$styleable;->EdgeEffect:[I
+Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I
+Lcom/android/internal/R$styleable;->FastScroll:[I
+Lcom/android/internal/R$styleable;->FrameLayout:[I
+Lcom/android/internal/R$styleable;->FrameLayout_Layout:[I
+Lcom/android/internal/R$styleable;->Gallery:[I
+Lcom/android/internal/R$styleable;->GridView:[I
+Lcom/android/internal/R$styleable;->IconMenuView:[I
+Lcom/android/internal/R$styleable;->ImageView:[I
+Lcom/android/internal/R$styleable;->ImageView_scaleType:I
+Lcom/android/internal/R$styleable;->ImageView_src:I
+Lcom/android/internal/R$styleable;->Keyboard:[I
+Lcom/android/internal/R$styleable;->KeyboardView:[I
+Lcom/android/internal/R$styleable;->Keyboard_Key:[I
+Lcom/android/internal/R$styleable;->Keyboard_Row:[I
+Lcom/android/internal/R$styleable;->ListPreference:[I
+Lcom/android/internal/R$styleable;->ListPreference_entries:I
+Lcom/android/internal/R$styleable;->ListView:[I
+Lcom/android/internal/R$styleable;->ListView_divider:I
+Lcom/android/internal/R$styleable;->ListView_dividerHeight:I
+Lcom/android/internal/R$styleable;->ListView_entries:I
+Lcom/android/internal/R$styleable;->ListView_footerDividersEnabled:I
+Lcom/android/internal/R$styleable;->ListView_headerDividersEnabled:I
+Lcom/android/internal/R$styleable;->ListView_overScrollFooter:I
+Lcom/android/internal/R$styleable;->ListView_overScrollHeader:I
+Lcom/android/internal/R$styleable;->MapView:[I
+Lcom/android/internal/R$styleable;->MapView_apiKey:I
+Lcom/android/internal/R$styleable;->MenuGroup:[I
+Lcom/android/internal/R$styleable;->MenuItem:[I
+Lcom/android/internal/R$styleable;->NumberPicker:[I
+Lcom/android/internal/R$styleable;->PopupWindow:[I
+Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I
+Lcom/android/internal/R$styleable;->PopupWindow_popupBackground:I
+Lcom/android/internal/R$styleable;->Preference:[I
+Lcom/android/internal/R$styleable;->PreferenceGroup:[I
+Lcom/android/internal/R$styleable;->PreferenceGroup_orderingFromXml:I
+Lcom/android/internal/R$styleable;->Preference_defaultValue:I
+Lcom/android/internal/R$styleable;->Preference_dependency:I
+Lcom/android/internal/R$styleable;->Preference_enabled:I
+Lcom/android/internal/R$styleable;->Preference_fragment:I
+Lcom/android/internal/R$styleable;->Preference_icon:I
+Lcom/android/internal/R$styleable;->Preference_key:I
+Lcom/android/internal/R$styleable;->Preference_layout:I
+Lcom/android/internal/R$styleable;->Preference_order:I
+Lcom/android/internal/R$styleable;->Preference_persistent:I
+Lcom/android/internal/R$styleable;->Preference_selectable:I
+Lcom/android/internal/R$styleable;->Preference_shouldDisableView:I
+Lcom/android/internal/R$styleable;->Preference_summary:I
+Lcom/android/internal/R$styleable;->Preference_title:I
+Lcom/android/internal/R$styleable;->Preference_widgetLayout:I
+Lcom/android/internal/R$styleable;->ProgressBar:[I
+Lcom/android/internal/R$styleable;->QuickContactBadge:[I
+Lcom/android/internal/R$styleable;->RingtonePreference:[I
+Lcom/android/internal/R$styleable;->ScrollView:[I
+Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I
+Lcom/android/internal/R$styleable;->SelectionModeDrawables:[I
+Lcom/android/internal/R$styleable;->Switch:[I
+Lcom/android/internal/R$styleable;->SwitchPreference:[I
+Lcom/android/internal/R$styleable;->SyncAdapter:[I
+Lcom/android/internal/R$styleable;->SyncAdapter_accountType:I
+Lcom/android/internal/R$styleable;->SyncAdapter_allowParallelSyncs:I
+Lcom/android/internal/R$styleable;->SyncAdapter_contentAuthority:I
+Lcom/android/internal/R$styleable;->SyncAdapter_isAlwaysSyncable:I
+Lcom/android/internal/R$styleable;->SyncAdapter_settingsActivity:I
+Lcom/android/internal/R$styleable;->SyncAdapter_supportsUploading:I
+Lcom/android/internal/R$styleable;->SyncAdapter_userVisible:I
+Lcom/android/internal/R$styleable;->TabWidget:[I
+Lcom/android/internal/R$styleable;->TextAppearance:[I
+Lcom/android/internal/R$styleable;->TextAppearance_fontFamily:I
+Lcom/android/internal/R$styleable;->TextAppearance_textAllCaps:I
+Lcom/android/internal/R$styleable;->TextAppearance_textColor:I
+Lcom/android/internal/R$styleable;->TextAppearance_textColorHighlight:I
+Lcom/android/internal/R$styleable;->TextAppearance_textColorHint:I
+Lcom/android/internal/R$styleable;->TextAppearance_textColorLink:I
+Lcom/android/internal/R$styleable;->TextAppearance_textSize:I
+Lcom/android/internal/R$styleable;->TextAppearance_textStyle:I
+Lcom/android/internal/R$styleable;->TextAppearance_typeface:I
+Lcom/android/internal/R$styleable;->TextClock:[I
+Lcom/android/internal/R$styleable;->TextView:[I
+Lcom/android/internal/R$styleable;->TextViewAppearance:[I
+Lcom/android/internal/R$styleable;->TextViewAppearance_textAppearance:I
+Lcom/android/internal/R$styleable;->TextView_autoLink:I
+Lcom/android/internal/R$styleable;->TextView_autoText:I
+Lcom/android/internal/R$styleable;->TextView_bufferType:I
+Lcom/android/internal/R$styleable;->TextView_capitalize:I
+Lcom/android/internal/R$styleable;->TextView_cursorVisible:I
+Lcom/android/internal/R$styleable;->TextView_digits:I
+Lcom/android/internal/R$styleable;->TextView_drawableBottom:I
+Lcom/android/internal/R$styleable;->TextView_drawableEnd:I
+Lcom/android/internal/R$styleable;->TextView_drawableLeft:I
+Lcom/android/internal/R$styleable;->TextView_drawablePadding:I
+Lcom/android/internal/R$styleable;->TextView_drawableRight:I
+Lcom/android/internal/R$styleable;->TextView_drawableStart:I
+Lcom/android/internal/R$styleable;->TextView_drawableTop:I
+Lcom/android/internal/R$styleable;->TextView_editable:I
+Lcom/android/internal/R$styleable;->TextView_editorExtras:I
+Lcom/android/internal/R$styleable;->TextView_ellipsize:I
+Lcom/android/internal/R$styleable;->TextView_ems:I
+Lcom/android/internal/R$styleable;->TextView_enabled:I
+Lcom/android/internal/R$styleable;->TextView_freezesText:I
+Lcom/android/internal/R$styleable;->TextView_gravity:I
+Lcom/android/internal/R$styleable;->TextView_height:I
+Lcom/android/internal/R$styleable;->TextView_hint:I
+Lcom/android/internal/R$styleable;->TextView_imeActionId:I
+Lcom/android/internal/R$styleable;->TextView_imeActionLabel:I
+Lcom/android/internal/R$styleable;->TextView_imeOptions:I
+Lcom/android/internal/R$styleable;->TextView_includeFontPadding:I
+Lcom/android/internal/R$styleable;->TextView_inputMethod:I
+Lcom/android/internal/R$styleable;->TextView_inputType:I
+Lcom/android/internal/R$styleable;->TextView_lines:I
+Lcom/android/internal/R$styleable;->TextView_lineSpacingExtra:I
+Lcom/android/internal/R$styleable;->TextView_lineSpacingMultiplier:I
+Lcom/android/internal/R$styleable;->TextView_linksClickable:I
+Lcom/android/internal/R$styleable;->TextView_marqueeRepeatLimit:I
+Lcom/android/internal/R$styleable;->TextView_maxEms:I
+Lcom/android/internal/R$styleable;->TextView_maxHeight:I
+Lcom/android/internal/R$styleable;->TextView_maxLength:I
+Lcom/android/internal/R$styleable;->TextView_maxLines:I
+Lcom/android/internal/R$styleable;->TextView_maxWidth:I
+Lcom/android/internal/R$styleable;->TextView_minEms:I
+Lcom/android/internal/R$styleable;->TextView_minHeight:I
+Lcom/android/internal/R$styleable;->TextView_minLines:I
+Lcom/android/internal/R$styleable;->TextView_minWidth:I
+Lcom/android/internal/R$styleable;->TextView_numeric:I
+Lcom/android/internal/R$styleable;->TextView_password:I
+Lcom/android/internal/R$styleable;->TextView_phoneNumber:I
+Lcom/android/internal/R$styleable;->TextView_privateImeOptions:I
+Lcom/android/internal/R$styleable;->TextView_scrollHorizontally:I
+Lcom/android/internal/R$styleable;->TextView_selectAllOnFocus:I
+Lcom/android/internal/R$styleable;->TextView_shadowColor:I
+Lcom/android/internal/R$styleable;->TextView_shadowDx:I
+Lcom/android/internal/R$styleable;->TextView_shadowDy:I
+Lcom/android/internal/R$styleable;->TextView_shadowRadius:I
+Lcom/android/internal/R$styleable;->TextView_singleLine:I
+Lcom/android/internal/R$styleable;->TextView_text:I
+Lcom/android/internal/R$styleable;->TextView_textAllCaps:I
+Lcom/android/internal/R$styleable;->TextView_textAppearance:I
+Lcom/android/internal/R$styleable;->TextView_textColor:I
+Lcom/android/internal/R$styleable;->TextView_textColorHighlight:I
+Lcom/android/internal/R$styleable;->TextView_textColorHint:I
+Lcom/android/internal/R$styleable;->TextView_textColorLink:I
+Lcom/android/internal/R$styleable;->TextView_textCursorDrawable:I
+Lcom/android/internal/R$styleable;->TextView_textEditSuggestionItemLayout:I
+Lcom/android/internal/R$styleable;->TextView_textIsSelectable:I
+Lcom/android/internal/R$styleable;->TextView_textScaleX:I
+Lcom/android/internal/R$styleable;->TextView_textSelectHandle:I
+Lcom/android/internal/R$styleable;->TextView_textSelectHandleLeft:I
+Lcom/android/internal/R$styleable;->TextView_textSelectHandleRight:I
+Lcom/android/internal/R$styleable;->TextView_textSize:I
+Lcom/android/internal/R$styleable;->TextView_textStyle:I
+Lcom/android/internal/R$styleable;->TextView_typeface:I
+Lcom/android/internal/R$styleable;->TextView_width:I
+Lcom/android/internal/R$styleable;->Theme:[I
+Lcom/android/internal/R$styleable;->TwoLineListItem:[I
+Lcom/android/internal/R$styleable;->View:[I
+Lcom/android/internal/R$styleable;->ViewAnimator:[I
+Lcom/android/internal/R$styleable;->ViewFlipper:[I
+Lcom/android/internal/R$styleable;->ViewGroup_Layout:[I
+Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_height:I
+Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_width:I
+Lcom/android/internal/R$styleable;->ViewStub:[I
+Lcom/android/internal/R$styleable;->ViewStub_inflatedId:I
+Lcom/android/internal/R$styleable;->ViewStub_layout:I
+Lcom/android/internal/R$styleable;->View_background:I
+Lcom/android/internal/R$styleable;->View_clickable:I
+Lcom/android/internal/R$styleable;->View_focusable:I
+Lcom/android/internal/R$styleable;->View_id:I
+Lcom/android/internal/R$styleable;->View_longClickable:I
+Lcom/android/internal/R$styleable;->WallpaperPreviewInfo:[I
+Lcom/android/internal/R$styleable;->Window:[I
+Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I
+Lcom/android/internal/R$styleable;->Window_windowBackground:I
+Lcom/android/internal/R$styleable;->Window_windowFullscreen:I
+Lcom/android/internal/R$styleable;->Window_windowIsFloating:I
+Lcom/android/internal/R$styleable;->Window_windowIsTranslucent:I
+Lcom/android/internal/R$styleable;->Window_windowShowWallpaper:I
+Lcom/android/internal/R$xml;->power_profile:I
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 2d3394b..52caa42 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -238,270 +238,6 @@
Landroid/os/storage/IObbActionListener$Stub;-><init>()V
Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
-Landroid/R$styleable;->ActionBar:[I
-Landroid/R$styleable;->ActionBar_background:I
-Landroid/R$styleable;->ActionBar_backgroundSplit:I
-Landroid/R$styleable;->ActionBar_backgroundStacked:I
-Landroid/R$styleable;->ActionBar_divider:I
-Landroid/R$styleable;->ActionBar_itemPadding:I
-Landroid/R$styleable;->CalendarView:[I
-Landroid/R$styleable;->CalendarView_dateTextAppearance:I
-Landroid/R$styleable;->CalendarView_firstDayOfWeek:I
-Landroid/R$styleable;->CalendarView_focusedMonthDateColor:I
-Landroid/R$styleable;->CalendarView_selectedDateVerticalBar:I
-Landroid/R$styleable;->CalendarView_selectedWeekBackgroundColor:I
-Landroid/R$styleable;->CalendarView_shownWeekCount:I
-Landroid/R$styleable;->CalendarView_showWeekNumber:I
-Landroid/R$styleable;->CalendarView_unfocusedMonthDateColor:I
-Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I
-Landroid/R$styleable;->CalendarView_weekNumberColor:I
-Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I
-Landroid/R$styleable;->CheckBoxPreference:[I
-Landroid/R$styleable;->CheckedTextView:[I
-Landroid/R$styleable;->CheckedTextView_checkMark:I
-Landroid/R$styleable;->CompoundButton:[I
-Landroid/R$styleable;->CompoundButton_button:I
-Landroid/R$styleable;->ContactsDataKind:[I
-Landroid/R$styleable;->DatePicker:[I
-Landroid/R$styleable;->DialogPreference:[I
-Landroid/R$styleable;->DrawableStates:[I
-Landroid/R$styleable;->ExpandableListView:[I
-Landroid/R$styleable;->FrameLayout_Layout:[I
-Landroid/R$styleable;->HorizontalScrollView:[I
-Landroid/R$styleable;->ImageView:[I
-Landroid/R$styleable;->ImageView_adjustViewBounds:I
-Landroid/R$styleable;->ImageView_baselineAlignBottom:I
-Landroid/R$styleable;->ImageView_cropToPadding:I
-Landroid/R$styleable;->ImageView_maxHeight:I
-Landroid/R$styleable;->ImageView_maxWidth:I
-Landroid/R$styleable;->ImageView_scaleType:I
-Landroid/R$styleable;->ImageView_src:I
-Landroid/R$styleable;->ImageView_tint:I
-Landroid/R$styleable;->Keyboard:[I
-Landroid/R$styleable;->Keyboard_horizontalGap:I
-Landroid/R$styleable;->Keyboard_Key:[I
-Landroid/R$styleable;->Keyboard_keyHeight:I
-Landroid/R$styleable;->Keyboard_keyWidth:I
-Landroid/R$styleable;->Keyboard_Key_codes:I
-Landroid/R$styleable;->Keyboard_Key_iconPreview:I
-Landroid/R$styleable;->Keyboard_Key_isModifier:I
-Landroid/R$styleable;->Keyboard_Key_isRepeatable:I
-Landroid/R$styleable;->Keyboard_Key_isSticky:I
-Landroid/R$styleable;->Keyboard_Key_keyEdgeFlags:I
-Landroid/R$styleable;->Keyboard_Key_keyIcon:I
-Landroid/R$styleable;->Keyboard_Key_keyLabel:I
-Landroid/R$styleable;->Keyboard_Key_keyOutputText:I
-Landroid/R$styleable;->Keyboard_Key_popupCharacters:I
-Landroid/R$styleable;->Keyboard_Key_popupKeyboard:I
-Landroid/R$styleable;->Keyboard_Row:[I
-Landroid/R$styleable;->Keyboard_Row_keyboardMode:I
-Landroid/R$styleable;->Keyboard_Row_rowEdgeFlags:I
-Landroid/R$styleable;->Keyboard_verticalGap:I
-Landroid/R$styleable;->LinearLayout:[I
-Landroid/R$styleable;->LinearLayout_baselineAligned:I
-Landroid/R$styleable;->LinearLayout_baselineAlignedChildIndex:I
-Landroid/R$styleable;->LinearLayout_divider:I
-Landroid/R$styleable;->LinearLayout_dividerPadding:I
-Landroid/R$styleable;->LinearLayout_gravity:I
-Landroid/R$styleable;->LinearLayout_Layout:[I
-Landroid/R$styleable;->LinearLayout_Layout_layout_gravity:I
-Landroid/R$styleable;->LinearLayout_Layout_layout_height:I
-Landroid/R$styleable;->LinearLayout_Layout_layout_weight:I
-Landroid/R$styleable;->LinearLayout_Layout_layout_width:I
-Landroid/R$styleable;->LinearLayout_measureWithLargestChild:I
-Landroid/R$styleable;->LinearLayout_orientation:I
-Landroid/R$styleable;->LinearLayout_showDividers:I
-Landroid/R$styleable;->ListView:[I
-Landroid/R$styleable;->ListView_divider:I
-Landroid/R$styleable;->ListView_dividerHeight:I
-Landroid/R$styleable;->LockPatternView:[I
-Landroid/R$styleable;->NumberPicker:[I
-Landroid/R$styleable;->NumberPicker_solidColor:I
-Landroid/R$styleable;->PopupWindow:[I
-Landroid/R$styleable;->ProgressBar:[I
-Landroid/R$styleable;->ProgressBar_indeterminateDrawable:I
-Landroid/R$styleable;->ProgressBar_indeterminateDuration:I
-Landroid/R$styleable;->ProgressBar_maxHeight:I
-Landroid/R$styleable;->ProgressBar_maxWidth:I
-Landroid/R$styleable;->ProgressBar_minHeight:I
-Landroid/R$styleable;->ProgressBar_minWidth:I
-Landroid/R$styleable;->ProgressBar_progressDrawable:I
-Landroid/R$styleable;->RingtonePreference:[I
-Landroid/R$styleable;->ScrollView:[I
-Landroid/R$styleable;->SearchView:[I
-Landroid/R$styleable;->SeekBar:[I
-Landroid/R$styleable;->SeekBar_thumb:I
-Landroid/R$styleable;->SeekBar_thumbOffset:I
-Landroid/R$styleable;->SlidingDrawer:[I
-Landroid/R$styleable;->SlidingDrawer_allowSingleTap:I
-Landroid/R$styleable;->SlidingDrawer_animateOnClick:I
-Landroid/R$styleable;->SlidingDrawer_bottomOffset:I
-Landroid/R$styleable;->SlidingDrawer_content:I
-Landroid/R$styleable;->SlidingDrawer_handle:I
-Landroid/R$styleable;->SlidingDrawer_orientation:I
-Landroid/R$styleable;->SlidingDrawer_topOffset:I
-Landroid/R$styleable;->Switch:[I
-Landroid/R$styleable;->Switch_showText:I
-Landroid/R$styleable;->Switch_splitTrack:I
-Landroid/R$styleable;->Switch_switchMinWidth:I
-Landroid/R$styleable;->Switch_switchPadding:I
-Landroid/R$styleable;->Switch_switchTextAppearance:I
-Landroid/R$styleable;->Switch_textOff:I
-Landroid/R$styleable;->Switch_textOn:I
-Landroid/R$styleable;->Switch_thumb:I
-Landroid/R$styleable;->Switch_thumbTextPadding:I
-Landroid/R$styleable;->Switch_track:I
-Landroid/R$styleable;->TextAppearance:[I
-Landroid/R$styleable;->TextAppearance_textAllCaps:I
-Landroid/R$styleable;->TextAppearance_textColor:I
-Landroid/R$styleable;->TextAppearance_textColorHighlight:I
-Landroid/R$styleable;->TextAppearance_textColorHint:I
-Landroid/R$styleable;->TextAppearance_textColorLink:I
-Landroid/R$styleable;->TextAppearance_textSize:I
-Landroid/R$styleable;->TextAppearance_textStyle:I
-Landroid/R$styleable;->TextAppearance_typeface:I
-Landroid/R$styleable;->TextView:[I
-Landroid/R$styleable;->TextView_autoLink:I
-Landroid/R$styleable;->TextView_autoText:I
-Landroid/R$styleable;->TextView_bufferType:I
-Landroid/R$styleable;->TextView_capitalize:I
-Landroid/R$styleable;->TextView_cursorVisible:I
-Landroid/R$styleable;->TextView_digits:I
-Landroid/R$styleable;->TextView_drawableBottom:I
-Landroid/R$styleable;->TextView_drawableEnd:I
-Landroid/R$styleable;->TextView_drawableLeft:I
-Landroid/R$styleable;->TextView_drawablePadding:I
-Landroid/R$styleable;->TextView_drawableRight:I
-Landroid/R$styleable;->TextView_drawableStart:I
-Landroid/R$styleable;->TextView_drawableTop:I
-Landroid/R$styleable;->TextView_editable:I
-Landroid/R$styleable;->TextView_ellipsize:I
-Landroid/R$styleable;->TextView_ems:I
-Landroid/R$styleable;->TextView_enabled:I
-Landroid/R$styleable;->TextView_freezesText:I
-Landroid/R$styleable;->TextView_gravity:I
-Landroid/R$styleable;->TextView_height:I
-Landroid/R$styleable;->TextView_hint:I
-Landroid/R$styleable;->TextView_imeActionId:I
-Landroid/R$styleable;->TextView_imeActionLabel:I
-Landroid/R$styleable;->TextView_imeOptions:I
-Landroid/R$styleable;->TextView_includeFontPadding:I
-Landroid/R$styleable;->TextView_inputMethod:I
-Landroid/R$styleable;->TextView_inputType:I
-Landroid/R$styleable;->TextView_lines:I
-Landroid/R$styleable;->TextView_lineSpacingExtra:I
-Landroid/R$styleable;->TextView_lineSpacingMultiplier:I
-Landroid/R$styleable;->TextView_linksClickable:I
-Landroid/R$styleable;->TextView_marqueeRepeatLimit:I
-Landroid/R$styleable;->TextView_maxEms:I
-Landroid/R$styleable;->TextView_maxHeight:I
-Landroid/R$styleable;->TextView_maxLength:I
-Landroid/R$styleable;->TextView_maxLines:I
-Landroid/R$styleable;->TextView_maxWidth:I
-Landroid/R$styleable;->TextView_minEms:I
-Landroid/R$styleable;->TextView_minHeight:I
-Landroid/R$styleable;->TextView_minLines:I
-Landroid/R$styleable;->TextView_minWidth:I
-Landroid/R$styleable;->TextView_numeric:I
-Landroid/R$styleable;->TextView_password:I
-Landroid/R$styleable;->TextView_phoneNumber:I
-Landroid/R$styleable;->TextView_privateImeOptions:I
-Landroid/R$styleable;->TextView_scrollHorizontally:I
-Landroid/R$styleable;->TextView_selectAllOnFocus:I
-Landroid/R$styleable;->TextView_shadowColor:I
-Landroid/R$styleable;->TextView_shadowDx:I
-Landroid/R$styleable;->TextView_shadowDy:I
-Landroid/R$styleable;->TextView_shadowRadius:I
-Landroid/R$styleable;->TextView_singleLine:I
-Landroid/R$styleable;->TextView_text:I
-Landroid/R$styleable;->TextView_textAllCaps:I
-Landroid/R$styleable;->TextView_textAppearance:I
-Landroid/R$styleable;->TextView_textColor:I
-Landroid/R$styleable;->TextView_textColorHighlight:I
-Landroid/R$styleable;->TextView_textColorHint:I
-Landroid/R$styleable;->TextView_textColorLink:I
-Landroid/R$styleable;->TextView_textCursorDrawable:I
-Landroid/R$styleable;->TextView_textIsSelectable:I
-Landroid/R$styleable;->TextView_textScaleX:I
-Landroid/R$styleable;->TextView_textSelectHandle:I
-Landroid/R$styleable;->TextView_textSelectHandleLeft:I
-Landroid/R$styleable;->TextView_textSelectHandleRight:I
-Landroid/R$styleable;->TextView_textSize:I
-Landroid/R$styleable;->TextView_textStyle:I
-Landroid/R$styleable;->TextView_typeface:I
-Landroid/R$styleable;->TextView_width:I
-Landroid/R$styleable;->Theme:[I
-Landroid/R$styleable;->View:[I
-Landroid/R$styleable;->ViewDrawableStates:[I
-Landroid/R$styleable;->ViewGroup_Layout:[I
-Landroid/R$styleable;->ViewGroup_Layout_layout_height:I
-Landroid/R$styleable;->ViewGroup_Layout_layout_width:I
-Landroid/R$styleable;->ViewGroup_MarginLayout:[I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_height:I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_margin:I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginBottom:I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginLeft:I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginRight:I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginTop:I
-Landroid/R$styleable;->ViewGroup_MarginLayout_layout_width:I
-Landroid/R$styleable;->View_alpha:I
-Landroid/R$styleable;->View_background:I
-Landroid/R$styleable;->View_clickable:I
-Landroid/R$styleable;->View_contentDescription:I
-Landroid/R$styleable;->View_drawingCacheQuality:I
-Landroid/R$styleable;->View_duplicateParentState:I
-Landroid/R$styleable;->View_fadingEdge:I
-Landroid/R$styleable;->View_filterTouchesWhenObscured:I
-Landroid/R$styleable;->View_fitsSystemWindows:I
-Landroid/R$styleable;->View_focusable:I
-Landroid/R$styleable;->View_focusableInTouchMode:I
-Landroid/R$styleable;->View_hapticFeedbackEnabled:I
-Landroid/R$styleable;->View_id:I
-Landroid/R$styleable;->View_isScrollContainer:I
-Landroid/R$styleable;->View_keepScreenOn:I
-Landroid/R$styleable;->View_longClickable:I
-Landroid/R$styleable;->View_minHeight:I
-Landroid/R$styleable;->View_minWidth:I
-Landroid/R$styleable;->View_nextFocusDown:I
-Landroid/R$styleable;->View_nextFocusLeft:I
-Landroid/R$styleable;->View_nextFocusRight:I
-Landroid/R$styleable;->View_nextFocusUp:I
-Landroid/R$styleable;->View_onClick:I
-Landroid/R$styleable;->View_overScrollMode:I
-Landroid/R$styleable;->View_padding:I
-Landroid/R$styleable;->View_paddingBottom:I
-Landroid/R$styleable;->View_paddingEnd:I
-Landroid/R$styleable;->View_paddingLeft:I
-Landroid/R$styleable;->View_paddingRight:I
-Landroid/R$styleable;->View_paddingStart:I
-Landroid/R$styleable;->View_paddingTop:I
-Landroid/R$styleable;->View_rotation:I
-Landroid/R$styleable;->View_rotationX:I
-Landroid/R$styleable;->View_rotationY:I
-Landroid/R$styleable;->View_saveEnabled:I
-Landroid/R$styleable;->View_scaleX:I
-Landroid/R$styleable;->View_scaleY:I
-Landroid/R$styleable;->View_scrollbarDefaultDelayBeforeFade:I
-Landroid/R$styleable;->View_scrollbarFadeDuration:I
-Landroid/R$styleable;->View_scrollbars:I
-Landroid/R$styleable;->View_scrollbarSize:I
-Landroid/R$styleable;->View_scrollbarStyle:I
-Landroid/R$styleable;->View_scrollbarThumbHorizontal:I
-Landroid/R$styleable;->View_scrollbarThumbVertical:I
-Landroid/R$styleable;->View_scrollbarTrackHorizontal:I
-Landroid/R$styleable;->View_scrollbarTrackVertical:I
-Landroid/R$styleable;->View_scrollX:I
-Landroid/R$styleable;->View_scrollY:I
-Landroid/R$styleable;->View_soundEffectsEnabled:I
-Landroid/R$styleable;->View_tag:I
-Landroid/R$styleable;->View_transformPivotX:I
-Landroid/R$styleable;->View_transformPivotY:I
-Landroid/R$styleable;->View_translationX:I
-Landroid/R$styleable;->View_translationY:I
-Landroid/R$styleable;->View_visibility:I
-Landroid/R$styleable;->Window:[I
-Landroid/R$styleable;->Window_windowBackground:I
-Landroid/R$styleable;->Window_windowFrame:I
Landroid/security/IKeyChainService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeyChainService;
Landroid/security/keystore/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/keystore/IKeystoreService;
Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
@@ -589,446 +325,6 @@
Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService;
Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
-Lcom/android/internal/R$anim;->fade_in:I
-Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I
-Lcom/android/internal/R$array;->config_autoBrightnessLevels:I
-Lcom/android/internal/R$array;->config_mobile_hotspot_provision_app:I
-Lcom/android/internal/R$array;->config_sms_enabled_locking_shift_tables:I
-Lcom/android/internal/R$array;->config_sms_enabled_single_shift_tables:I
-Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I
-Lcom/android/internal/R$array;->config_tether_upstream_types:I
-Lcom/android/internal/R$array;->config_tether_usb_regexs:I
-Lcom/android/internal/R$array;->config_tether_wifi_regexs:I
-Lcom/android/internal/R$array;->maps_starting_lat_lng:I
-Lcom/android/internal/R$array;->maps_starting_zoom:I
-Lcom/android/internal/R$attr;->actionBarStyle:I
-Lcom/android/internal/R$attr;->buttonStyle:I
-Lcom/android/internal/R$attr;->description:I
-Lcom/android/internal/R$attr;->editTextStyle:I
-Lcom/android/internal/R$attr;->mapViewStyle:I
-Lcom/android/internal/R$attr;->popupWindowStyle:I
-Lcom/android/internal/R$attr;->state_above_anchor:I
-Lcom/android/internal/R$attr;->state_focused:I
-Lcom/android/internal/R$attr;->state_pressed:I
-Lcom/android/internal/R$attr;->state_selected:I
-Lcom/android/internal/R$attr;->switchStyle:I
-Lcom/android/internal/R$attr;->text:I
-Lcom/android/internal/R$attr;->title:I
-Lcom/android/internal/R$attr;->webViewStyle:I
-Lcom/android/internal/R$bool;-><init>()V
-Lcom/android/internal/R$bool;->config_automatic_brightness_available:I
-Lcom/android/internal/R$bool;->config_intrusiveNotificationLed:I
-Lcom/android/internal/R$bool;->config_mms_content_disposition_support:I
-Lcom/android/internal/R$bool;->config_showNavigationBar:I
-Lcom/android/internal/R$dimen;-><init>()V
-Lcom/android/internal/R$dimen;->item_touch_helper_max_drag_scroll_per_frame:I
-Lcom/android/internal/R$dimen;->navigation_bar_height:I
-Lcom/android/internal/R$dimen;->navigation_bar_height_landscape:I
-Lcom/android/internal/R$dimen;->navigation_bar_width:I
-Lcom/android/internal/R$dimen;->status_bar_height:I
-Lcom/android/internal/R$dimen;->toast_y_offset:I
-Lcom/android/internal/R$drawable;->btn_check_off:I
-Lcom/android/internal/R$drawable;->compass_arrow:I
-Lcom/android/internal/R$drawable;->compass_base:I
-Lcom/android/internal/R$drawable;->ic_maps_indicator_current_position_anim:I
-Lcom/android/internal/R$drawable;->ic_menu_close_clear_cancel:I
-Lcom/android/internal/R$drawable;->loading_tile_android:I
-Lcom/android/internal/R$drawable;->maps_google_logo:I
-Lcom/android/internal/R$drawable;->no_tile_256:I
-Lcom/android/internal/R$drawable;->reticle:I
-Lcom/android/internal/R$drawable;->stat_sys_download:I
-Lcom/android/internal/R$fraction;->config_autoBrightnessAdjustmentMaxGamma:I
-Lcom/android/internal/R$id;->account_name:I
-Lcom/android/internal/R$id;->account_type:I
-Lcom/android/internal/R$id;->alertTitle:I
-Lcom/android/internal/R$id;->allow_button:I
-Lcom/android/internal/R$id;->amPm:I
-Lcom/android/internal/R$id;->authtoken_type:I
-Lcom/android/internal/R$id;->background:I
-Lcom/android/internal/R$id;->back_button:I
-Lcom/android/internal/R$id;->body:I
-Lcom/android/internal/R$id;->buttonPanel:I
-Lcom/android/internal/R$id;->camera:I
-Lcom/android/internal/R$id;->cancel:I
-Lcom/android/internal/R$id;->clip_children_set_tag:I
-Lcom/android/internal/R$id;->clip_children_tag:I
-Lcom/android/internal/R$id;->clip_to_padding_tag:I
-Lcom/android/internal/R$id;->closeButton:I
-Lcom/android/internal/R$id;->content:I
-Lcom/android/internal/R$id;->contentPanel:I
-Lcom/android/internal/R$id;->custom:I
-Lcom/android/internal/R$id;->customPanel:I
-Lcom/android/internal/R$id;->datePicker:I
-Lcom/android/internal/R$id;->day:I
-Lcom/android/internal/R$id;->deny_button:I
-Lcom/android/internal/R$id;->description:I
-Lcom/android/internal/R$id;->edit:I
-Lcom/android/internal/R$id;->edittext_container:I
-Lcom/android/internal/R$id;->find_next:I
-Lcom/android/internal/R$id;->find_prev:I
-Lcom/android/internal/R$id;->icon:I
-Lcom/android/internal/R$id;->keyboard:I
-Lcom/android/internal/R$id;->keyboardView:I
-Lcom/android/internal/R$id;->line1:I
-Lcom/android/internal/R$id;->list_item:I
-Lcom/android/internal/R$id;->matches:I
-Lcom/android/internal/R$id;->mediacontroller_progress:I
-Lcom/android/internal/R$id;->media_actions:I
-Lcom/android/internal/R$id;->message:I
-Lcom/android/internal/R$id;->minute:I
-Lcom/android/internal/R$id;->month:I
-Lcom/android/internal/R$id;->name:I
-Lcom/android/internal/R$id;->notification_header:I
-Lcom/android/internal/R$id;->ok:I
-Lcom/android/internal/R$id;->overlay:I
-Lcom/android/internal/R$id;->packages_list:I
-Lcom/android/internal/R$id;->package_label:I
-Lcom/android/internal/R$id;->parentPanel:I
-Lcom/android/internal/R$id;->pause:I
-Lcom/android/internal/R$id;->pending_intent_tag:I
-Lcom/android/internal/R$id;->progress:I
-Lcom/android/internal/R$id;->redo:I
-Lcom/android/internal/R$id;->remote_input_tag:I
-Lcom/android/internal/R$id;->right_icon:I
-Lcom/android/internal/R$id;->search_src_text:I
-Lcom/android/internal/R$id;->share:I
-Lcom/android/internal/R$id;->shortcut:I
-Lcom/android/internal/R$id;->status_bar_latest_event_content:I
-Lcom/android/internal/R$id;->tabcontent:I
-Lcom/android/internal/R$id;->tabs:I
-Lcom/android/internal/R$id;->text1:I
-Lcom/android/internal/R$id;->text2:I
-Lcom/android/internal/R$id;->text:I
-Lcom/android/internal/R$id;->time:I
-Lcom/android/internal/R$id;->timePicker:I
-Lcom/android/internal/R$id;->time_current:I
-Lcom/android/internal/R$id;->title:I
-Lcom/android/internal/R$id;->titleDivider:I
-Lcom/android/internal/R$id;->titleDividerTop:I
-Lcom/android/internal/R$id;->title_container:I
-Lcom/android/internal/R$id;->title_template:I
-Lcom/android/internal/R$id;->topPanel:I
-Lcom/android/internal/R$id;->up:I
-Lcom/android/internal/R$id;->year:I
-Lcom/android/internal/R$id;->zoomControls:I
-Lcom/android/internal/R$id;->zoomMagnify:I
-Lcom/android/internal/R$integer;->config_screenBrightnessDim:I
-Lcom/android/internal/R$integer;->config_screenBrightnessSettingMaximum:I
-Lcom/android/internal/R$integer;->config_screenBrightnessSettingMinimum:I
-Lcom/android/internal/R$integer;->config_toastDefaultGravity:I
-Lcom/android/internal/R$interpolator;->accelerate_cubic:I
-Lcom/android/internal/R$interpolator;->decelerate_cubic:I
-Lcom/android/internal/R$layout;->notification_template_material_base:I
-Lcom/android/internal/R$layout;->preference_header_item:I
-Lcom/android/internal/R$layout;->screen_title:I
-Lcom/android/internal/R$layout;->select_dialog:I
-Lcom/android/internal/R$layout;->select_dialog_multichoice:I
-Lcom/android/internal/R$layout;->select_dialog_singlechoice:I
-Lcom/android/internal/R$layout;->webview_find:I
-Lcom/android/internal/R$layout;->zoom_magnify:I
-Lcom/android/internal/R$plurals;->matches_found:I
-Lcom/android/internal/R$raw;->loaderror:I
-Lcom/android/internal/R$raw;->nodomain:I
-Lcom/android/internal/R$string;->byteShort:I
-Lcom/android/internal/R$string;->cancel:I
-Lcom/android/internal/R$string;->enable_explore_by_touch_warning_title:I
-Lcom/android/internal/R$string;->gigabyteShort:I
-Lcom/android/internal/R$string;->kilobyteShort:I
-Lcom/android/internal/R$string;->map:I
-Lcom/android/internal/R$string;->megabyteShort:I
-Lcom/android/internal/R$string;->notification_title:I
-Lcom/android/internal/R$string;->no_matches:I
-Lcom/android/internal/R$string;->ok:I
-Lcom/android/internal/R$string;->petabyteShort:I
-Lcom/android/internal/R$string;->redo:I
-Lcom/android/internal/R$string;->share:I
-Lcom/android/internal/R$string;->terabyteShort:I
-Lcom/android/internal/R$string;->whichApplication:I
-Lcom/android/internal/R$style;->Animation_DropDownDown:I
-Lcom/android/internal/R$style;->Animation_DropDownUp:I
-Lcom/android/internal/R$style;->Animation_PopupWindow:I
-Lcom/android/internal/R$style;->Theme:I
-Lcom/android/internal/R$style;->Theme_Dialog_Alert:I
-Lcom/android/internal/R$style;->Theme_Holo_Light:I
-Lcom/android/internal/R$style;->Theme_Light:I
-Lcom/android/internal/R$styleable;-><init>()V
-Lcom/android/internal/R$styleable;->AbsListView:[I
-Lcom/android/internal/R$styleable;->AbsListView_cacheColorHint:I
-Lcom/android/internal/R$styleable;->AbsListView_choiceMode:I
-Lcom/android/internal/R$styleable;->AbsListView_drawSelectorOnTop:I
-Lcom/android/internal/R$styleable;->AbsListView_fastScrollAlwaysVisible:I
-Lcom/android/internal/R$styleable;->AbsListView_fastScrollEnabled:I
-Lcom/android/internal/R$styleable;->AbsListView_listSelector:I
-Lcom/android/internal/R$styleable;->AbsListView_scrollingCache:I
-Lcom/android/internal/R$styleable;->AbsListView_smoothScrollbar:I
-Lcom/android/internal/R$styleable;->AbsListView_stackFromBottom:I
-Lcom/android/internal/R$styleable;->AbsListView_textFilterEnabled:I
-Lcom/android/internal/R$styleable;->AbsListView_transcriptMode:I
-Lcom/android/internal/R$styleable;->AbsSpinner:[I
-Lcom/android/internal/R$styleable;->AccountAuthenticator:[I
-Lcom/android/internal/R$styleable;->AccountAuthenticator_accountPreferences:I
-Lcom/android/internal/R$styleable;->AccountAuthenticator_accountType:I
-Lcom/android/internal/R$styleable;->AccountAuthenticator_customTokens:I
-Lcom/android/internal/R$styleable;->AccountAuthenticator_icon:I
-Lcom/android/internal/R$styleable;->AccountAuthenticator_label:I
-Lcom/android/internal/R$styleable;->AccountAuthenticator_smallIcon:I
-Lcom/android/internal/R$styleable;->ActionMode:[I
-Lcom/android/internal/R$styleable;->AdapterViewAnimator:[I
-Lcom/android/internal/R$styleable;->AdapterViewFlipper:[I
-Lcom/android/internal/R$styleable;->AlertDialog:[I
-Lcom/android/internal/R$styleable;->AnalogClock:[I
-Lcom/android/internal/R$styleable;->AndroidManifest:[I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_allowTaskReparenting:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_configChanges:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_description:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_enabled:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_excludeFromRecents:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_exported:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_hardwareAccelerated:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_icon:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_immersive:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_label:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_launchMode:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_logo:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_name:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_noHistory:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_permission:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_process:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_screenOrientation:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_taskAffinity:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_theme:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_uiOptions:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity_windowSoftInputMode:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_enabled:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_hardwareAccelerated:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_label:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_largeHeap:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_name:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_permission:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_process:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_supportsRtl:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I
-Lcom/android/internal/R$styleable;->AndroidManifestData:[I
-Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter:[I
-Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter_priority:I
-Lcom/android/internal/R$styleable;->AndroidManifestMetaData:[I
-Lcom/android/internal/R$styleable;->AndroidManifestMetaData_name:I
-Lcom/android/internal/R$styleable;->AndroidManifestMetaData_resource:I
-Lcom/android/internal/R$styleable;->AndroidManifestMetaData_value:I
-Lcom/android/internal/R$styleable;->AndroidManifestPackageVerifier:[I
-Lcom/android/internal/R$styleable;->AndroidManifestProvider:[I
-Lcom/android/internal/R$styleable;->AndroidManifestService:[I
-Lcom/android/internal/R$styleable;->AndroidManifestService_enabled:I
-Lcom/android/internal/R$styleable;->AndroidManifestService_exported:I
-Lcom/android/internal/R$styleable;->AndroidManifestService_name:I
-Lcom/android/internal/R$styleable;->AndroidManifestService_permission:I
-Lcom/android/internal/R$styleable;->AndroidManifestService_process:I
-Lcom/android/internal/R$styleable;->AndroidManifestUsesLibrary:[I
-Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I
-Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I
-Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk:[I
-Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_minSdkVersion:I
-Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_targetSdkVersion:I
-Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I
-Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I
-Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I
-Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I
-Lcom/android/internal/R$styleable;->AutoCompleteTextView:[I
-Lcom/android/internal/R$styleable;->CheckBoxPreference:[I
-Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I
-Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOff:I
-Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOn:I
-Lcom/android/internal/R$styleable;->CheckedTextView:[I
-Lcom/android/internal/R$styleable;->CheckedTextView_checked:I
-Lcom/android/internal/R$styleable;->CheckedTextView_checkMark:I
-Lcom/android/internal/R$styleable;->CompoundButton:[I
-Lcom/android/internal/R$styleable;->CompoundButton_button:I
-Lcom/android/internal/R$styleable;->CompoundButton_checked:I
-Lcom/android/internal/R$styleable;->ContactsDataKind:[I
-Lcom/android/internal/R$styleable;->DatePicker:[I
-Lcom/android/internal/R$styleable;->DialogPreference:[I
-Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I
-Lcom/android/internal/R$styleable;->Dream:[I
-Lcom/android/internal/R$styleable;->EdgeEffect:[I
-Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I
-Lcom/android/internal/R$styleable;->FastScroll:[I
-Lcom/android/internal/R$styleable;->FrameLayout:[I
-Lcom/android/internal/R$styleable;->FrameLayout_Layout:[I
-Lcom/android/internal/R$styleable;->Gallery:[I
-Lcom/android/internal/R$styleable;->GridView:[I
-Lcom/android/internal/R$styleable;->IconMenuView:[I
-Lcom/android/internal/R$styleable;->ImageView:[I
-Lcom/android/internal/R$styleable;->ImageView_scaleType:I
-Lcom/android/internal/R$styleable;->ImageView_src:I
-Lcom/android/internal/R$styleable;->Keyboard:[I
-Lcom/android/internal/R$styleable;->KeyboardView:[I
-Lcom/android/internal/R$styleable;->Keyboard_Key:[I
-Lcom/android/internal/R$styleable;->Keyboard_Row:[I
-Lcom/android/internal/R$styleable;->ListPreference:[I
-Lcom/android/internal/R$styleable;->ListPreference_entries:I
-Lcom/android/internal/R$styleable;->ListView:[I
-Lcom/android/internal/R$styleable;->ListView_divider:I
-Lcom/android/internal/R$styleable;->ListView_dividerHeight:I
-Lcom/android/internal/R$styleable;->ListView_entries:I
-Lcom/android/internal/R$styleable;->ListView_footerDividersEnabled:I
-Lcom/android/internal/R$styleable;->ListView_headerDividersEnabled:I
-Lcom/android/internal/R$styleable;->ListView_overScrollFooter:I
-Lcom/android/internal/R$styleable;->ListView_overScrollHeader:I
-Lcom/android/internal/R$styleable;->MapView:[I
-Lcom/android/internal/R$styleable;->MapView_apiKey:I
-Lcom/android/internal/R$styleable;->MenuGroup:[I
-Lcom/android/internal/R$styleable;->MenuItem:[I
-Lcom/android/internal/R$styleable;->NumberPicker:[I
-Lcom/android/internal/R$styleable;->PopupWindow:[I
-Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I
-Lcom/android/internal/R$styleable;->PopupWindow_popupBackground:I
-Lcom/android/internal/R$styleable;->Preference:[I
-Lcom/android/internal/R$styleable;->PreferenceGroup:[I
-Lcom/android/internal/R$styleable;->PreferenceGroup_orderingFromXml:I
-Lcom/android/internal/R$styleable;->Preference_defaultValue:I
-Lcom/android/internal/R$styleable;->Preference_dependency:I
-Lcom/android/internal/R$styleable;->Preference_enabled:I
-Lcom/android/internal/R$styleable;->Preference_fragment:I
-Lcom/android/internal/R$styleable;->Preference_icon:I
-Lcom/android/internal/R$styleable;->Preference_key:I
-Lcom/android/internal/R$styleable;->Preference_layout:I
-Lcom/android/internal/R$styleable;->Preference_order:I
-Lcom/android/internal/R$styleable;->Preference_persistent:I
-Lcom/android/internal/R$styleable;->Preference_selectable:I
-Lcom/android/internal/R$styleable;->Preference_shouldDisableView:I
-Lcom/android/internal/R$styleable;->Preference_summary:I
-Lcom/android/internal/R$styleable;->Preference_title:I
-Lcom/android/internal/R$styleable;->Preference_widgetLayout:I
-Lcom/android/internal/R$styleable;->ProgressBar:[I
-Lcom/android/internal/R$styleable;->QuickContactBadge:[I
-Lcom/android/internal/R$styleable;->RingtonePreference:[I
-Lcom/android/internal/R$styleable;->ScrollView:[I
-Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I
-Lcom/android/internal/R$styleable;->SelectionModeDrawables:[I
-Lcom/android/internal/R$styleable;->Switch:[I
-Lcom/android/internal/R$styleable;->SwitchPreference:[I
-Lcom/android/internal/R$styleable;->SyncAdapter:[I
-Lcom/android/internal/R$styleable;->SyncAdapter_accountType:I
-Lcom/android/internal/R$styleable;->SyncAdapter_allowParallelSyncs:I
-Lcom/android/internal/R$styleable;->SyncAdapter_contentAuthority:I
-Lcom/android/internal/R$styleable;->SyncAdapter_isAlwaysSyncable:I
-Lcom/android/internal/R$styleable;->SyncAdapter_settingsActivity:I
-Lcom/android/internal/R$styleable;->SyncAdapter_supportsUploading:I
-Lcom/android/internal/R$styleable;->SyncAdapter_userVisible:I
-Lcom/android/internal/R$styleable;->TabWidget:[I
-Lcom/android/internal/R$styleable;->TextAppearance:[I
-Lcom/android/internal/R$styleable;->TextAppearance_fontFamily:I
-Lcom/android/internal/R$styleable;->TextAppearance_textAllCaps:I
-Lcom/android/internal/R$styleable;->TextAppearance_textColor:I
-Lcom/android/internal/R$styleable;->TextAppearance_textColorHighlight:I
-Lcom/android/internal/R$styleable;->TextAppearance_textColorHint:I
-Lcom/android/internal/R$styleable;->TextAppearance_textColorLink:I
-Lcom/android/internal/R$styleable;->TextAppearance_textSize:I
-Lcom/android/internal/R$styleable;->TextAppearance_textStyle:I
-Lcom/android/internal/R$styleable;->TextAppearance_typeface:I
-Lcom/android/internal/R$styleable;->TextClock:[I
-Lcom/android/internal/R$styleable;->TextView:[I
-Lcom/android/internal/R$styleable;->TextViewAppearance:[I
-Lcom/android/internal/R$styleable;->TextViewAppearance_textAppearance:I
-Lcom/android/internal/R$styleable;->TextView_autoLink:I
-Lcom/android/internal/R$styleable;->TextView_autoText:I
-Lcom/android/internal/R$styleable;->TextView_bufferType:I
-Lcom/android/internal/R$styleable;->TextView_capitalize:I
-Lcom/android/internal/R$styleable;->TextView_cursorVisible:I
-Lcom/android/internal/R$styleable;->TextView_digits:I
-Lcom/android/internal/R$styleable;->TextView_drawableBottom:I
-Lcom/android/internal/R$styleable;->TextView_drawableEnd:I
-Lcom/android/internal/R$styleable;->TextView_drawableLeft:I
-Lcom/android/internal/R$styleable;->TextView_drawablePadding:I
-Lcom/android/internal/R$styleable;->TextView_drawableRight:I
-Lcom/android/internal/R$styleable;->TextView_drawableStart:I
-Lcom/android/internal/R$styleable;->TextView_drawableTop:I
-Lcom/android/internal/R$styleable;->TextView_editable:I
-Lcom/android/internal/R$styleable;->TextView_editorExtras:I
-Lcom/android/internal/R$styleable;->TextView_ellipsize:I
-Lcom/android/internal/R$styleable;->TextView_ems:I
-Lcom/android/internal/R$styleable;->TextView_enabled:I
-Lcom/android/internal/R$styleable;->TextView_freezesText:I
-Lcom/android/internal/R$styleable;->TextView_gravity:I
-Lcom/android/internal/R$styleable;->TextView_height:I
-Lcom/android/internal/R$styleable;->TextView_hint:I
-Lcom/android/internal/R$styleable;->TextView_imeActionId:I
-Lcom/android/internal/R$styleable;->TextView_imeActionLabel:I
-Lcom/android/internal/R$styleable;->TextView_imeOptions:I
-Lcom/android/internal/R$styleable;->TextView_includeFontPadding:I
-Lcom/android/internal/R$styleable;->TextView_inputMethod:I
-Lcom/android/internal/R$styleable;->TextView_inputType:I
-Lcom/android/internal/R$styleable;->TextView_lines:I
-Lcom/android/internal/R$styleable;->TextView_lineSpacingExtra:I
-Lcom/android/internal/R$styleable;->TextView_lineSpacingMultiplier:I
-Lcom/android/internal/R$styleable;->TextView_linksClickable:I
-Lcom/android/internal/R$styleable;->TextView_marqueeRepeatLimit:I
-Lcom/android/internal/R$styleable;->TextView_maxEms:I
-Lcom/android/internal/R$styleable;->TextView_maxHeight:I
-Lcom/android/internal/R$styleable;->TextView_maxLength:I
-Lcom/android/internal/R$styleable;->TextView_maxLines:I
-Lcom/android/internal/R$styleable;->TextView_maxWidth:I
-Lcom/android/internal/R$styleable;->TextView_minEms:I
-Lcom/android/internal/R$styleable;->TextView_minHeight:I
-Lcom/android/internal/R$styleable;->TextView_minLines:I
-Lcom/android/internal/R$styleable;->TextView_minWidth:I
-Lcom/android/internal/R$styleable;->TextView_numeric:I
-Lcom/android/internal/R$styleable;->TextView_password:I
-Lcom/android/internal/R$styleable;->TextView_phoneNumber:I
-Lcom/android/internal/R$styleable;->TextView_privateImeOptions:I
-Lcom/android/internal/R$styleable;->TextView_scrollHorizontally:I
-Lcom/android/internal/R$styleable;->TextView_selectAllOnFocus:I
-Lcom/android/internal/R$styleable;->TextView_shadowColor:I
-Lcom/android/internal/R$styleable;->TextView_shadowDx:I
-Lcom/android/internal/R$styleable;->TextView_shadowDy:I
-Lcom/android/internal/R$styleable;->TextView_shadowRadius:I
-Lcom/android/internal/R$styleable;->TextView_singleLine:I
-Lcom/android/internal/R$styleable;->TextView_text:I
-Lcom/android/internal/R$styleable;->TextView_textAllCaps:I
-Lcom/android/internal/R$styleable;->TextView_textAppearance:I
-Lcom/android/internal/R$styleable;->TextView_textColor:I
-Lcom/android/internal/R$styleable;->TextView_textColorHighlight:I
-Lcom/android/internal/R$styleable;->TextView_textColorHint:I
-Lcom/android/internal/R$styleable;->TextView_textColorLink:I
-Lcom/android/internal/R$styleable;->TextView_textCursorDrawable:I
-Lcom/android/internal/R$styleable;->TextView_textEditSuggestionItemLayout:I
-Lcom/android/internal/R$styleable;->TextView_textIsSelectable:I
-Lcom/android/internal/R$styleable;->TextView_textScaleX:I
-Lcom/android/internal/R$styleable;->TextView_textSelectHandle:I
-Lcom/android/internal/R$styleable;->TextView_textSelectHandleLeft:I
-Lcom/android/internal/R$styleable;->TextView_textSelectHandleRight:I
-Lcom/android/internal/R$styleable;->TextView_textSize:I
-Lcom/android/internal/R$styleable;->TextView_textStyle:I
-Lcom/android/internal/R$styleable;->TextView_typeface:I
-Lcom/android/internal/R$styleable;->TextView_width:I
-Lcom/android/internal/R$styleable;->Theme:[I
-Lcom/android/internal/R$styleable;->TwoLineListItem:[I
-Lcom/android/internal/R$styleable;->View:[I
-Lcom/android/internal/R$styleable;->ViewAnimator:[I
-Lcom/android/internal/R$styleable;->ViewFlipper:[I
-Lcom/android/internal/R$styleable;->ViewGroup_Layout:[I
-Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_height:I
-Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_width:I
-Lcom/android/internal/R$styleable;->ViewStub:[I
-Lcom/android/internal/R$styleable;->ViewStub_inflatedId:I
-Lcom/android/internal/R$styleable;->ViewStub_layout:I
-Lcom/android/internal/R$styleable;->View_background:I
-Lcom/android/internal/R$styleable;->View_clickable:I
-Lcom/android/internal/R$styleable;->View_focusable:I
-Lcom/android/internal/R$styleable;->View_id:I
-Lcom/android/internal/R$styleable;->View_longClickable:I
-Lcom/android/internal/R$styleable;->WallpaperPreviewInfo:[I
-Lcom/android/internal/R$styleable;->Window:[I
-Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I
-Lcom/android/internal/R$styleable;->Window_windowBackground:I
-Lcom/android/internal/R$styleable;->Window_windowFullscreen:I
-Lcom/android/internal/R$styleable;->Window_windowIsFloating:I
-Lcom/android/internal/R$styleable;->Window_windowIsTranslucent:I
-Lcom/android/internal/R$styleable;->Window_windowShowWallpaper:I
-Lcom/android/internal/R$xml;->power_profile:I
Lcom/android/internal/statusbar/IStatusBar$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/statusbar/IStatusBar;
Lcom/android/internal/statusbar/IStatusBarService$Stub;-><init>()V
Lcom/android/internal/statusbar/IStatusBarService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/statusbar/IStatusBarService;
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 25cd342..6470a04 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -103,8 +103,6 @@
* When writing an activity to satisfy these requests one must pass in the AccountManagerResponse
* and return the result via that response when the activity finishes (or whenever else the
* activity author deems it is the correct time to respond).
- * The {@link AccountAuthenticatorActivity} handles this, so one may wish to extend that when
- * writing activities to handle these requests.
*/
public abstract class AbstractAccountAuthenticator {
private static final String TAG = "AccountAuthenticator";
diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java
index 967aa04..65ba35f 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -32,7 +32,11 @@
* This result will be sent as the result of the request when the activity finishes. If this
* is never set or if it is set to null then error {@link AccountManager#ERROR_CODE_CANCELED}
* will be called on the response.
+ *
+ * @deprecated Applications should extend Activity themselves. This class is not compatible with
+ * AppCompat, and the functionality it provides is not complex.
*/
+@Deprecated
public class AccountAuthenticatorActivity extends Activity {
private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null;
private Bundle mResultBundle = null;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index ebb03e7..764e599 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -296,6 +296,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static void setDurationScale(float durationScale) {
sDurationScale = durationScale;
@@ -304,6 +305,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static float getDurationScale() {
return sDurationScale;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4828c74..151c03f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2797,6 +2797,7 @@
* @see View#onMovedToDisplay(int, Configuration)
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public void onMovedToDisplay(int displayId, Configuration config) {
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 91b98c7..e8e4085 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -153,6 +153,12 @@
*/
public static final int INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL = 1 << 1;
+ /**
+ * Disable test API access for the newly started instrumentation.
+ * @hide
+ */
+ public static final int INSTR_FLAG_DISABLE_TEST_API_CHECKS = 1 << 2;
+
static final class UidObserver extends IUidObserver.Stub {
final OnUidImportanceListener mListener;
final Context mContext;
@@ -2893,6 +2899,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
diff --git a/core/java/android/app/AliasActivity.java b/core/java/android/app/AliasActivity.java
index 3756529..37be901 100644
--- a/core/java/android/app/AliasActivity.java
+++ b/core/java/android/app/AliasActivity.java
@@ -39,7 +39,10 @@
* To use this activity, you should include in the manifest for the associated
* component an entry named "android.app.alias". It is a reference to an XML
* resource describing an intent that launches the real application.
+ *
+ * @deprecated Use {@code <activity-alias>} or subclass Activity directly.
*/
+@Deprecated
public class AliasActivity extends Activity {
/**
* This is the name under which you should store in your component the
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index da4c038..aedf4b5 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -570,6 +570,7 @@
@UnsupportedAppUsage
public static final int OP_NONE = -1;
/** @hide Access to coarse location information. */
+ @UnsupportedAppUsage
@TestApi
public static final int OP_COARSE_LOCATION = 0;
/** @hide Access to fine location information. */
@@ -642,6 +643,7 @@
@UnsupportedAppUsage
public static final int OP_WRITE_SETTINGS = 23;
/** @hide Required to draw on top of other apps. */
+ @UnsupportedAppUsage
@TestApi
public static final int OP_SYSTEM_ALERT_WINDOW = 24;
/** @hide */
@@ -651,6 +653,7 @@
@UnsupportedAppUsage
public static final int OP_CAMERA = 26;
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public static final int OP_RECORD_AUDIO = 27;
/** @hide */
@@ -798,6 +801,7 @@
@UnsupportedAppUsage
public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
/** @hide Any app start foreground service. */
+ @UnsupportedAppUsage
@TestApi
public static final int OP_START_FOREGROUND = 76;
/** @hide */
@@ -2058,6 +2062,7 @@
* Retrieve the permission associated with an operation, or null if there is not one.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static String opToPermission(int op) {
return sOpPerms[op];
@@ -2090,6 +2095,7 @@
* to the corresponding app op.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static int permissionToOpCode(String permission) {
Integer boxedOpCode = sPermToOp.get(permission);
@@ -4578,6 +4584,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setMode(int code, int uid, String packageName, @Mode int mode) {
@@ -4905,6 +4912,7 @@
/**
* {@hide}
*/
+ @UnsupportedAppUsage
@TestApi
public static int strOpToOp(@NonNull String op) {
Integer val = sOpStrToOp.get(op);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 360be35..835769f 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3121,6 +3121,15 @@
}
@Override
+ public String[] getTelephonyPackageNames() {
+ try {
+ return mPM.getTelephonyPackageNames();
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ @Override
public String getSystemCaptionsServicePackageName() {
try {
return mPM.getSystemCaptionsServicePackageName();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 69be171..794ffcb 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2224,6 +2224,15 @@
}
@Override
+ public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+ try {
+ return createPackageContextAsUser(getPackageName(), flags, user);
+ } catch (NameNotFoundException e) {
+ throw new IllegalStateException("Own package not found: package=" + getPackageName());
+ }
+ }
+
+ @Override
public Context createContextForSplit(String splitName) throws NameNotFoundException {
if (!mPackageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
// All Splits are always loaded.
@@ -2321,6 +2330,7 @@
return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0;
}
+ @UnsupportedAppUsage
@TestApi
@Override
public Display getDisplay() {
diff --git a/core/java/android/app/ExpandableListActivity.java b/core/java/android/app/ExpandableListActivity.java
index e08f25a..22de878 100644
--- a/core/java/android/app/ExpandableListActivity.java
+++ b/core/java/android/app/ExpandableListActivity.java
@@ -150,7 +150,11 @@
*
* @see #setListAdapter
* @see android.widget.ExpandableListView
+ *
+ * @deprecated Use {@link androidx.recyclerview.widget.RecyclerView} or use
+ * {@link android.widget.ExpandableListView} directly
*/
+@Deprecated
public class ExpandableListActivity extends Activity implements
OnCreateContextMenuListener,
ExpandableListView.OnChildClickListener, ExpandableListView.OnGroupCollapseListener,
diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl
index f2c9f61..a3e0845 100644
--- a/core/java/android/app/IUiModeManager.aidl
+++ b/core/java/android/app/IUiModeManager.aidl
@@ -25,7 +25,7 @@
* Enables the car mode. Only the system can do this.
* @hide
*/
- void enableCarMode(int flags);
+ void enableCarMode(int flags, int priority, String callingPackage);
/**
* Disables the car mode.
@@ -34,6 +34,12 @@
void disableCarMode(int flags);
/**
+ * Disables car mode (the original version is marked unsupported app usage so cannot be changed
+ * for the time being).
+ */
+ void disableCarModeByCallingPackage(int flags, String callingPackage);
+
+ /**
* Return the current running mode.
*/
int getCurrentModeType();
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index 88e2356..b495b3c 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -53,7 +53,11 @@
* Displays a list of all activities which can be performed
* for a given intent. Launches when clicked.
*
+ * @deprecated Applications can implement this UI themselves using
+ * {@link androidx.recyclerview.widget.RecyclerView} and
+ * {@link android.content.pm.PackageManager#queryIntentActivities(Intent, int)}
*/
+@Deprecated
public abstract class LauncherActivity extends ListActivity {
Intent mIntent;
PackageManager mPackageManager;
diff --git a/core/java/android/app/ListActivity.java b/core/java/android/app/ListActivity.java
index 2162521..810cca2 100644
--- a/core/java/android/app/ListActivity.java
+++ b/core/java/android/app/ListActivity.java
@@ -171,7 +171,11 @@
*
* @see #setListAdapter
* @see android.widget.ListView
+ *
+ * @deprecated Use {@link androidx.fragment.app.ListFragment} or
+ * {@link androidx.recyclerview.widget.RecyclerView} to implement your Activity instead.
*/
+@Deprecated
public class ListActivity extends Activity {
/**
* This field should be made private, so it is hidden from the SDK.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ceadd85..47f0cf8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -628,6 +628,13 @@
*/
public static final int FLAG_BUBBLE = 0x00001000;
+ /** @hide */
+ @IntDef({FLAG_SHOW_LIGHTS, FLAG_ONGOING_EVENT, FLAG_INSISTENT, FLAG_ONLY_ALERT_ONCE,
+ FLAG_AUTO_CANCEL, FLAG_NO_CLEAR, FLAG_FOREGROUND_SERVICE, FLAG_HIGH_PRIORITY,
+ FLAG_LOCAL_ONLY, FLAG_GROUP_SUMMARY, FLAG_AUTOGROUP_SUMMARY, FLAG_BUBBLE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NotificationFlags{};
+
public int flags;
/** @hide */
@@ -4537,10 +4544,15 @@
}
/**
- * @hide
+ * Set the value for a notification flag
+ *
+ * @param mask Bit mask of the flag
+ * @param value Status (on/off) of the flag
+ *
+ * @return The same Builder.
*/
@NonNull
- public Builder setFlag(int mask, boolean value) {
+ public Builder setFlag(@NotificationFlags int mask, boolean value) {
if (value) {
mN.flags |= mask;
} else {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index dd39376..903dd49 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1638,7 +1638,7 @@
@Override
public int hashCode() {
return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
- suppressedVisualEffects);
+ suppressedVisualEffects, state);
}
@Override
@@ -1650,10 +1650,10 @@
&& other.priorityCallSenders == priorityCallSenders
&& other.priorityMessageSenders == priorityMessageSenders
&& suppressedVisualEffectsEqual(suppressedVisualEffects,
- other.suppressedVisualEffects);
+ other.suppressedVisualEffects)
+ && other.state == this.state;
}
-
private boolean suppressedVisualEffectsEqual(int suppressedEffects,
int otherSuppressedVisualEffects) {
if (suppressedEffects == otherSuppressedVisualEffects) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 646f0dc..29cb3c1 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -157,7 +157,7 @@
import android.os.image.DynamicSystemManager;
import android.os.image.IDynamicSystemService;
import android.os.storage.StorageManager;
-import android.os.telephony.TelephonyRegistryManager;
+import android.telephony.TelephonyRegistryManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.print.IPrintManager;
@@ -173,8 +173,6 @@
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.RcsMessageManager;
import android.util.ArrayMap;
import android.util.Log;
import android.view.ContextThemeWrapper;
@@ -613,7 +611,7 @@
new CachedServiceFetcher<TelephonyRegistryManager>() {
@Override
public TelephonyRegistryManager createService(ContextImpl ctx) {
- return new TelephonyRegistryManager();
+ return new TelephonyRegistryManager(ctx);
}});
registerService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class,
@@ -623,22 +621,6 @@
return new SubscriptionManager(ctx.getOuterContext());
}});
- registerService(Context.TELEPHONY_RCS_MESSAGE_SERVICE, RcsMessageManager.class,
- new CachedServiceFetcher<RcsMessageManager>() {
- @Override
- public RcsMessageManager createService(ContextImpl ctx) {
- return new RcsMessageManager(ctx.getOuterContext());
- }
- });
-
- registerService(Context.TELEPHONY_IMS_SERVICE, ImsManager.class,
- new CachedServiceFetcher<ImsManager>() {
- @Override
- public ImsManager createService(ContextImpl ctx) {
- return new ImsManager(ctx.getOuterContext());
- }
- });
-
registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
new CachedServiceFetcher<CarrierConfigManager>() {
@Override
@@ -671,7 +653,7 @@
new CachedServiceFetcher<UiModeManager>() {
@Override
public UiModeManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- return new UiModeManager();
+ return new UiModeManager(ctx.getOuterContext());
}});
registerService(Context.USB_SERVICE, UsbManager.class,
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 46316e1..8324787 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -17,6 +17,10 @@
package android.app;
import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
@@ -68,6 +72,25 @@
* of the broadcast to {@link Activity#RESULT_CANCELED}.
*/
public static String ACTION_ENTER_CAR_MODE = "android.app.action.ENTER_CAR_MODE";
+
+ /**
+ * Broadcast sent when the device's UI has switched to car mode, either by being placed in a car
+ * dock or explicit action of the user.
+ * <p>
+ * In addition to the behavior for {@link #ACTION_ENTER_CAR_MODE}, this broadcast includes the
+ * package name of the app which requested to enter car mode in the
+ * {@link #EXTRA_CALLING_PACKAGE}. If an app requested to enter car mode using
+ * {@link #enableCarMode(int, int)} and specified a priority this will be specified in the
+ * {@link #EXTRA_PRIORITY}.
+ *
+ * This is primarily intended to be received by other components of the Android OS.
+ * <p>
+ * Receiver requires permission: {@link android.Manifest.permission.HANDLE_CAR_MODE_CHANGES}
+ * @hide
+ */
+ @SystemApi
+ public static final String ACTION_ENTER_CAR_MODE_PRIORITIZED =
+ "android.app.action.ENTER_CAR_MODE_PRIORITIZED";
/**
* Broadcast sent when the device's UI has switch away from car mode back
@@ -75,6 +98,28 @@
* when the user exits car mode.
*/
public static String ACTION_EXIT_CAR_MODE = "android.app.action.EXIT_CAR_MODE";
+
+ /**
+ * Broadcast sent when the device's UI has switched away from car mode back to normal mode.
+ * Typically used by a car mode app, to dismiss itself when the user exits car mode.
+ * <p>
+ * In addition to the behavior for {@link #ACTION_EXIT_CAR_MODE}, this broadcast includes the
+ * package name of the app which requested to exit car mode in {@link #EXTRA_CALLING_PACKAGE}.
+ * If an app requested to enter car mode using {@link #enableCarMode(int, int)} and specified a
+ * priority this will be specified in the {@link #EXTRA_PRIORITY} when exiting car mode.
+ * <p>
+ * If {@link #DISABLE_CAR_MODE_ALL_PRIORITIES} is used when disabling car mode (i.e. this is
+ * initiated by the user via the persistent car mode notification), this broadcast is sent once
+ * for each priority level for which car mode is being disabled.
+ * <p>
+ * This is primarily intended to be received by other components of the Android OS.
+ * <p>
+ * Receiver requires permission: {@link android.Manifest.permission.HANDLE_CAR_MODE_CHANGES}
+ * @hide
+ */
+ @SystemApi
+ public static final String ACTION_EXIT_CAR_MODE_PRIORITIZED =
+ "android.app.action.EXIT_CAR_MODE_PRIORITIZED";
/**
* Broadcast sent when the device's UI has switched to desk mode,
@@ -97,6 +142,24 @@
*/
public static String ACTION_EXIT_DESK_MODE = "android.app.action.EXIT_DESK_MODE";
+ /**
+ * String extra used with {@link #ACTION_ENTER_CAR_MODE_PRIORITIZED} and
+ * {@link #ACTION_EXIT_CAR_MODE_PRIORITIZED} to indicate the package name of the app which
+ * requested to enter or exit car mode.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_CALLING_PACKAGE = "android.app.extra.CALLING_PACKAGE";
+
+ /**
+ * Integer extra used with {@link #ACTION_ENTER_CAR_MODE_PRIORITIZED} and
+ * {@link #ACTION_EXIT_CAR_MODE_PRIORITIZED} to indicate the priority level at which car mode
+ * is being disabled.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PRIORITY = "android.app.extra.PRIORITY";
+
/** @hide */
@IntDef(prefix = { "MODE_" }, value = {
MODE_NIGHT_AUTO,
@@ -126,10 +189,21 @@
private IUiModeManager mService;
+ /**
+ * Context required for getting the opPackageName of API caller; maybe be {@code null} if the
+ * old constructor marked with UnSupportedAppUsage is used.
+ */
+ private @Nullable Context mContext;
+
@UnsupportedAppUsage
/*package*/ UiModeManager() throws ServiceNotFoundException {
+ this(null /* context */);
+ }
+
+ /*package*/ UiModeManager(Context context) throws ServiceNotFoundException {
mService = IUiModeManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.UI_MODE_SERVICE));
+ mContext = context;
}
/**
@@ -152,6 +226,14 @@
*/
public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 0x0002;
+ /** @hide */
+ @IntDef(prefix = { "ENABLE_CAR_MODE_" }, value = {
+ ENABLE_CAR_MODE_GO_CAR_HOME,
+ ENABLE_CAR_MODE_ALLOW_SLEEP
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EnableCarMode {}
+
/**
* Force device into car mode, like it had been placed in the car dock.
* This will cause the device to switch to the car home UI as part of
@@ -159,9 +241,54 @@
* @param flags Must be 0.
*/
public void enableCarMode(int flags) {
+ enableCarMode(DEFAULT_PRIORITY, flags);
+ }
+
+ /**
+ * Force device into car mode, like it had been placed in the car dock. This will cause the
+ * device to switch to the car home UI as part of the mode switch.
+ * <p>
+ * An app may request to enter car mode when the system is already in car mode. The app may
+ * specify a "priority" when entering car mode. The device will remain in car mode
+ * (i.e. {@link #getCurrentModeType()} is {@link Configuration#UI_MODE_TYPE_CAR}) as long as
+ * there is a priority level at which car mode have been enabled. For example assume app A
+ * enters car mode at priority level 100, and then app B enters car mode at the default priority
+ * (0). If app A exits car mode, the device will remain in car mode until app B exits car mode.
+ * <p>
+ * Specifying a priority level when entering car mode is important in cases where multiple apps
+ * on a device implement a car-mode {@link android.telecom.InCallService} (see
+ * {@link android.telecom.TelecomManager#METADATA_IN_CALL_SERVICE_CAR_MODE_UI}). The
+ * {@link android.telecom.InCallService} associated with the highest priority app which entered
+ * car mode will be bound to by Telecom and provided with information about ongoing calls on
+ * the device.
+ * <p>
+ * System apps holding the required permission can enable car mode when the app determines the
+ * correct conditions exist for that app to be in car mode. The device maker should ensure that
+ * where multiple apps exist on the device which can potentially enter car mode, appropriate
+ * priorities are used to ensure that calls delivered by the
+ * {@link android.telecom.InCallService} API are delivered to the highest priority app.
+ * If app A and app B can both potentially enable car mode, and it is desired that app B is the
+ * one which should receive call information, the priority for app B should be higher than the
+ * one for app A.
+ * <p>
+ * When an app uses a priority to enable car mode, they can disable car mode at the specified
+ * priority level using {@link #disableCarMode(int)}. An app may only enable car mode at a
+ * single priority.
+ * <p>
+ * Public apps are assumed to enter/exit car mode at {@link #DEFAULT_PRIORITY}.
+ *
+ * @param priority The declared priority for the caller.
+ * @param flags Car mode flags.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED)
+ public void enableCarMode(@IntRange(from = 0) int priority, @EnableCarMode int flags) {
if (mService != null) {
try {
- mService.enableCarMode(flags);
+ mService.enableCarMode(flags, priority,
+ mContext == null ? null : mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -176,15 +303,44 @@
* being in car mode).
*/
public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001;
+
+ /**
+ * Flag for use with {@link #disableCarMode(int)}: Disables car mode at ALL priority levels.
+ * Primarily intended for use from {@link com.android.internal.app.DisableCarModeActivity} to
+ * provide the user with a means to exit car mode at all priority levels.
+ * @hide
+ */
+ public static final int DISABLE_CAR_MODE_ALL_PRIORITIES = 0x0002;
+
+ /** @hide */
+ @IntDef(prefix = { "DISABLE_CAR_MODE_" }, value = {
+ DISABLE_CAR_MODE_GO_HOME
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DisableCarMode {}
+
+ /**
+ * The default priority used for entering car mode.
+ * <p>
+ * Callers of the {@link UiModeManager#enableCarMode(int)} priority will be assigned the
+ * default priority.
+ * <p>
+ * System apps can specify a priority other than the default priority when using
+ * {@link UiModeManager#enableCarMode(int, int)} to enable car mode.
+ * @hide
+ */
+ @SystemApi
+ public static final int DEFAULT_PRIORITY = 0;
/**
* Turn off special mode if currently in car mode.
- * @param flags May be 0 or {@link #DISABLE_CAR_MODE_GO_HOME}.
+ * @param flags One of the disable car mode flags.
*/
- public void disableCarMode(int flags) {
+ public void disableCarMode(@DisableCarMode int flags) {
if (mService != null) {
try {
- mService.disableCarMode(flags);
+ mService.disableCarModeByCallingPackage(flags,
+ mContext == null ? null : mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index affc8b9..74237b4 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -35,6 +35,8 @@
import android.util.proto.WireTypeMismatchException;
import android.view.DisplayInfo;
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
import java.io.IOException;
/**
@@ -199,6 +201,7 @@
/** @hide */
public static final int PINNED_WINDOWING_MODE_ELEVATION_IN_DIP = 5;
+ @UnsupportedAppUsage
public WindowConfiguration() {
unset();
}
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 8e40449..6bade90 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -146,6 +146,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public void setPollForce(boolean pollForce) {
if (pollForce) {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 566b387..9d152a7 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1734,6 +1734,56 @@
}
/**
+ * Connects all enabled and supported bluetooth profiles between the local and remote device
+ *
+ * @param device is the remote device with which to connect these profiles
+ * @return true if all profiles successfully connected, false if an error occurred
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) {
+ return mService.connectAllEnabledProfiles(device);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+
+ return false;
+ }
+
+ /**
+ * Disconnects all enabled and supported bluetooth profiles between the local and remote device
+ *
+ * @param device is the remote device with which to disconnect these profiles
+ * @return true if all profiles successfully disconnected, false if an error occurred
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) {
+ return mService.disconnectAllEnabledProfiles(device);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+
+ return false;
+ }
+
+ /**
* Return true if the multi advertisement is supported by the chipset
*
* @return true if Multiple Advertisement feature is supported
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index c616044..0be3eca 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -173,13 +173,10 @@
* changed.
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
- *
- * @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @UnsupportedAppUsage
public static final String ACTION_ALIAS_CHANGED =
- "android.bluetooth.device.action.ALIAS_CHANGED";
+ "android.bluetooth.action.ALIAS_CHANGED";
/**
* Broadcast Action: Indicates a change in the bond state of a remote
@@ -1048,10 +1045,11 @@
* Get the Bluetooth alias of the remote device.
* <p>Alias is the locally modified name of a remote device.
*
- * @return the Bluetooth alias, or null if no alias or there was a problem
- * @hide
+ * @return the Bluetooth alias, the friendly device name if no alias, or
+ * null if there was a problem
*/
- @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
+ @Nullable
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public String getAlias() {
final IBluetooth service = sService;
if (service == null) {
@@ -1059,7 +1057,11 @@
return null;
}
try {
- return service.getRemoteAlias(this);
+ String alias = service.getRemoteAlias(this);
+ if (alias == null) {
+ return getName();
+ }
+ return alias;
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1076,8 +1078,9 @@
* @return true on success, false on error
* @hide
*/
- @UnsupportedAppUsage
- public boolean setAlias(String alias) {
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public boolean setAlias(@NonNull String alias) {
final IBluetooth service = sService;
if (service == null) {
Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
@@ -1092,24 +1095,6 @@
}
/**
- * Get the Bluetooth alias of the remote device.
- * If Alias is null, get the Bluetooth name instead.
- *
- * @return the Bluetooth alias, or null if no alias or there was a problem
- * @hide
- * @see #getAlias()
- * @see #getName()
- */
- @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
- public String getAliasName() {
- String name = getAlias();
- if (name == null) {
- name = getName();
- }
- return name;
- }
-
- /**
* Get the most recent identified battery level of this Bluetooth device
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index cfb363a08..4e97627 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -16,8 +16,13 @@
package android.bluetooth;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -25,6 +30,8 @@
import android.os.RemoteException;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
@@ -40,6 +47,7 @@
*
* @hide
*/
+@SystemApi
public final class BluetoothPan implements BluetoothProfile {
private static final String TAG = "BluetoothPan";
private static final boolean DBG = true;
@@ -67,6 +75,7 @@
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
* receive.
*/
+ @SuppressLint("ActionValue")
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
@@ -76,19 +85,32 @@
* The local role of the PAN profile that the remote device is bound to.
* It can be one of {@link #LOCAL_NAP_ROLE} or {@link #LOCAL_PANU_ROLE}.
*/
+ @SuppressLint("ActionValue")
public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
+ /** @hide */
+ @IntDef({PAN_ROLE_NONE, LOCAL_NAP_ROLE, LOCAL_PANU_ROLE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LocalPanRole {}
+
public static final int PAN_ROLE_NONE = 0;
/**
* The local device is acting as a Network Access Point.
*/
public static final int LOCAL_NAP_ROLE = 1;
- public static final int REMOTE_NAP_ROLE = 1;
/**
* The local device is acting as a PAN User.
*/
public static final int LOCAL_PANU_ROLE = 2;
+
+ /** @hide */
+ @IntDef({PAN_ROLE_NONE, REMOTE_NAP_ROLE, REMOTE_PANU_ROLE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RemotePanRole {}
+
+ public static final int REMOTE_NAP_ROLE = 1;
+
public static final int REMOTE_PANU_ROLE = 2;
/**
@@ -134,6 +156,8 @@
/**
* Create a BluetoothPan proxy object for interacting with the local
* Bluetooth Service which handles the Pan profile
+ *
+ * @hide
*/
@UnsupportedAppUsage
/*package*/ BluetoothPan(Context context, ServiceListener listener) {
@@ -235,7 +259,7 @@
* {@inheritDoc}
*/
@Override
- public List<BluetoothDevice> getConnectedDevices() {
+ public @NonNull List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
@@ -252,6 +276,7 @@
/**
* {@inheritDoc}
+ * @hide
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
@@ -273,7 +298,7 @@
* {@inheritDoc}
*/
@Override
- public int getConnectionState(BluetoothDevice device) {
+ public int getConnectionState(@Nullable BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
final IBluetoothPan service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
@@ -288,7 +313,11 @@
return BluetoothProfile.STATE_DISCONNECTED;
}
- @UnsupportedAppUsage
+ /**
+ * Turns on/off bluetooth tethering
+ *
+ * @param value is whether to enable or disable bluetooth tethering
+ */
public void setBluetoothTethering(boolean value) {
String pkgName = mContext.getOpPackageName();
if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
@@ -302,7 +331,11 @@
}
}
- @UnsupportedAppUsage
+ /**
+ * Determines whether tethering is enabled
+ *
+ * @return true if tethering is on, false if not or some error occurred
+ */
public boolean isTetheringOn() {
if (VDBG) log("isTetheringOn()");
final IBluetoothPan service = getService();
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index dabe0fd..f1ac765 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -20,9 +20,9 @@
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -43,6 +43,7 @@
* This extra represents the current connection state of the profile of the
* Bluetooth device.
*/
+ @SuppressLint("ActionValue")
String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
/**
@@ -51,6 +52,7 @@
* This extra represents the previous connection state of the profile of the
* Bluetooth device.
*/
+ @SuppressLint("ActionValue")
String EXTRA_PREVIOUS_STATE =
"android.bluetooth.profile.extra.PREVIOUS_STATE";
@@ -106,7 +108,7 @@
*
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @SystemApi
int PAN = 5;
/**
@@ -324,4 +326,54 @@
return "STATE_UNKNOWN";
}
}
+
+ /**
+ * Convert an integer value of profile ID into human readable string
+ *
+ * @param profile profile ID
+ * @return profile name as String, UNKOWN_PROFILE if the profile ID is not defined.
+ * @hide
+ */
+ static String getProfileName(int profile) {
+ switch(profile) {
+ case HEADSET:
+ return "HEADSET";
+ case A2DP:
+ return "A2DP";
+ case HID_HOST:
+ return "HID_HOST";
+ case PAN:
+ return "PAN";
+ case PBAP:
+ return "PBAP";
+ case GATT:
+ return "GATT";
+ case GATT_SERVER:
+ return "GATT_SERVER";
+ case MAP:
+ return "MAP";
+ case SAP:
+ return "SAP";
+ case A2DP_SINK:
+ return "A2DP_SINK";
+ case AVRCP_CONTROLLER:
+ return "AVRCP_CONTROLLER";
+ case AVRCP:
+ return "AVRCP";
+ case HEADSET_CLIENT:
+ return "HEADSET_CLIENT";
+ case PBAP_CLIENT:
+ return "PBAP_CLIENT";
+ case MAP_CLIENT:
+ return "MAP_CLIENT";
+ case HID_DEVICE:
+ return "HID_DEVICE";
+ case OPP:
+ return "OPP";
+ case HEARING_AID:
+ return "HEARING_AID";
+ default:
+ return "UNKNOWN_PROFILE";
+ }
+ }
}
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 75e726b..0f67f6b 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -129,7 +129,7 @@
@UnsupportedAppUsage
public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) {
- return firstNotEmpty(device.getAliasName(), device.getAddress());
+ return firstNotEmpty(device.getAlias(), device.getAddress());
}
@UnsupportedAppUsage
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a8c1216..4b22166 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -63,6 +63,7 @@
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.MediaStore;
+import android.telephony.TelephonyRegistryManager;
import android.util.AttributeSet;
import android.view.Display;
import android.view.DisplayAdjustments;
@@ -2423,10 +2424,10 @@
*
* @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
*/
- public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent,
- @Nullable String receiverPermission, @Nullable String receiverAppOp,
- @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
- int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
+ public void sendOrderedBroadcast(@NonNull Intent intent, @Nullable String receiverPermission,
+ @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+ @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+ @Nullable Bundle initialExtras) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
@@ -4747,7 +4748,7 @@
/**
* Use with {@link #getSystemService(String)} to retrieve an
- * {@link android.os.telephony.TelephonyRegistryManager}.
+ * {@link TelephonyRegistryManager}.
* @hide
*/
@SystemApi
@@ -5255,8 +5256,9 @@
*/
@SystemApi
@TestApi
+ @NonNull
public Context createPackageContextAsUser(
- String packageName, @CreatePackageOptions int flags, UserHandle user)
+ @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user)
throws PackageManager.NameNotFoundException {
if (Build.IS_ENG) {
throw new IllegalStateException("createPackageContextAsUser not overridden!");
@@ -5265,6 +5267,23 @@
}
/**
+ * Similar to {@link #createPackageContext(String, int)}, but for the own package with a
+ * different {@link UserHandle}. For example, {@link #getContentResolver()}
+ * will open any {@link Uri} as the given user.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @NonNull
+ public Context createContextAsUser(@NonNull UserHandle user, @CreatePackageOptions int flags) {
+ if (Build.IS_ENG) {
+ throw new IllegalStateException("createContextAsUser not overridden!");
+ }
+ return this;
+ }
+
+ /**
* Creates a context given an {@link android.content.pm.ApplicationInfo}.
*
* @hide
@@ -5300,6 +5319,7 @@
* Get the user associated with this context
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public @UserIdInt int getUserId() {
return android.os.UserHandle.myUserId();
@@ -5416,6 +5436,7 @@
* @return Returns the {@link Display} object this context is associated with.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public abstract Display getDisplay();
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6c33f6d..428aadb 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -898,6 +898,12 @@
/** @hide */
@Override
+ public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+ return mBase.createContextAsUser(user, flags);
+ }
+
+ /** @hide */
+ @Override
@UnsupportedAppUsage
public Context createApplicationContext(ApplicationInfo application,
int flags) throws PackageManager.NameNotFoundException {
@@ -939,6 +945,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
@Override
public Display getDisplay() {
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 415c242..95e5f6b 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1237,6 +1237,7 @@
* Determines whether the {@link Activity} is considered translucent or floating.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static boolean isTranslucentOrFloating(TypedArray attributes) {
final boolean isTranslucent =
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index d6b70e0..0ea1845 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -470,6 +470,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
@TestApi
public static final int PRIVATE_FLAG_PRIVILEGED = 1<<3;
@@ -733,6 +734,7 @@
* Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public @ApplicationInfoPrivateFlags int privateFlags;
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a7eecd7..7538dca 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -753,6 +753,8 @@
String getWellbeingPackageName();
+ String[] getTelephonyPackageNames();
+
String getAppPredictionServicePackageName();
String getSystemCaptionsServicePackageName();
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3cecd7f..1099d8b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1565,7 +1565,7 @@
}
/** {@hide} */
- @SystemApi
+ @SystemApi @TestApi
public void setRequestDowngrade(boolean requestDowngrade) {
if (requestDowngrade) {
installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 1a44aa1..81670cd 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3285,6 +3285,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
@@ -3297,6 +3298,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
@@ -3919,6 +3921,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@NonNull
@TestApi
public abstract String getPermissionControllerPackageName();
@@ -4625,6 +4628,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public abstract @NonNull String getServicesSystemSharedLibraryPackageName();
@@ -4635,6 +4639,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public abstract @NonNull String getSharedSystemSharedLibraryPackageName();
@@ -7363,6 +7368,18 @@
}
/**
+ * @return the system defined telephony package names, or null if there's none.
+ *
+ * @hide
+ */
+ @Nullable
+ @TestApi
+ public String[] getTelephonyPackageNames() {
+ throw new UnsupportedOperationException(
+ "getTelephonyPackageNames not implemented in subclass");
+ }
+
+ /**
* @return the system defined content capture service package name, or null if there's none.
*
* @hide
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 672994e..ce5fc3b 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -59,6 +59,7 @@
public static final int PACKAGE_CONFIGURATOR = 9;
public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10;
public static final int PACKAGE_APP_PREDICTOR = 11;
+ public static final int PACKAGE_TELEPHONY = 12;
@IntDef(value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
@@ -72,6 +73,7 @@
PACKAGE_CONFIGURATOR,
PACKAGE_INCIDENT_REPORT_APPROVER,
PACKAGE_APP_PREDICTOR,
+ PACKAGE_TELEPHONY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KnownPackage {}
@@ -413,6 +415,17 @@
@ResolveInfoFlags int flags, int filterCallingUid, int userId);
/**
+ * Retrieve all activities that can be performed for the given intent.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#queryIntentActivities(Intent, int)
+ */
+ public abstract List<ResolveInfo> queryIntentActivities(
+ Intent intent, @Nullable String resolvedType, @ResolveInfoFlags int flags,
+ int filterCallingUid, int userId);
+
+
+ /**
* Retrieve all services that can be performed for the given intent.
* @see PackageManager#queryIntentServices(Intent, int)
*/
@@ -715,10 +728,11 @@
*/
public abstract boolean isResolveActivityComponent(@NonNull ComponentInfo component);
+
/**
- * Returns the package name for a known package.
+ * Returns a list of package names for a known package
*/
- public abstract @Nullable String getKnownPackageName(
+ public abstract @NonNull String[] getKnownPackageNames(
@KnownPackage int knownPackage, int userId);
/**
@@ -876,12 +890,6 @@
"android.content.pm.extra.ENABLE_ROLLBACK_INSTALL_FLAGS";
/**
- * Extra field name for the set of installed users for a given rollback package.
- */
- public static final String EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS =
- "android.content.pm.extra.ENABLE_ROLLBACK_INSTALLED_USERS";
-
- /**
* Extra field name for the user id an install is associated with when
* enabling rollback.
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 5c5c13d..c53b644 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -254,6 +254,8 @@
/** @hide */
public static final String APK_FILE_EXTENSION = ".apk";
+ /** @hide */
+ public static final String APEX_FILE_EXTENSION = ".apex";
/** @hide */
public static class NewPermissionInfo {
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index dd5c6a5..c77c53f 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -237,6 +237,17 @@
@TestApi
public static final int PROTECTION_FLAG_APP_PREDICTOR = 0x200000;
+ /**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the <code>telephony</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static final int PROTECTION_FLAG_TELEPHONY = 0x400000;
+
/** @hide */
@IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
PROTECTION_FLAG_PRIVILEGED,
@@ -258,6 +269,7 @@
PROTECTION_FLAG_CONFIGURATOR,
PROTECTION_FLAG_INCIDENT_REPORT_APPROVER,
PROTECTION_FLAG_APP_PREDICTOR,
+ PROTECTION_FLAG_TELEPHONY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ProtectionFlags {}
@@ -501,6 +513,9 @@
if ((level & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0) {
protLevel += "|appPredictor";
}
+ if ((level & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0) {
+ protLevel += "|telephony";
+ }
return protLevel;
}
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 1abfe70..4604424 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -799,6 +799,7 @@
* {@link ActivityInfo#CONFIG_ASSETS_PATHS}.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public int assetsSeq;
diff --git a/core/java/android/content/rollback/IRollbackManager.aidl b/core/java/android/content/rollback/IRollbackManager.aidl
index 1b84f29..8c2a65f 100644
--- a/core/java/android/content/rollback/IRollbackManager.aidl
+++ b/core/java/android/content/rollback/IRollbackManager.aidl
@@ -24,7 +24,7 @@
interface IRollbackManager {
ParceledListSlice getAvailableRollbacks();
- ParceledListSlice getRecentlyExecutedRollbacks();
+ ParceledListSlice getRecentlyCommittedRollbacks();
void commitRollback(int rollbackId, in ParceledListSlice causePackages,
String callerPackageName, in IntentSender statusReceiver);
@@ -51,4 +51,7 @@
// Used by the staging manager to notify the RollbackManager of the apk
// session for a staged session.
void notifyStagedApkSession(int originalSessionId, int apkSessionId);
+
+ // For test purposes only.
+ void blockRollbackManager(long millis);
}
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
index 2014751..c89796d 100644
--- a/core/java/android/content/rollback/PackageRollbackInfo.java
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -76,10 +76,10 @@
private final boolean mIsApex;
/*
- * The list of users the package is installed for.
+ * The list of users for which snapshots have been saved.
*/
// NOTE: Not a part of the Parcelable representation of this object.
- private final IntArray mInstalledUsers;
+ private final IntArray mSnapshottedUsers;
/**
* A mapping between user and an inode of theirs CE data snapshot.
@@ -148,8 +148,8 @@
}
/** @hide */
- public IntArray getInstalledUsers() {
- return mInstalledUsers;
+ public IntArray getSnapshottedUsers() {
+ return mSnapshottedUsers;
}
/** @hide */
@@ -179,14 +179,14 @@
public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
VersionedPackage packageRolledBackTo,
@NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
- boolean isApex, @NonNull IntArray installedUsers,
+ boolean isApex, @NonNull IntArray snapshottedUsers,
@NonNull SparseLongArray ceSnapshotInodes) {
this.mVersionRolledBackFrom = packageRolledBackFrom;
this.mVersionRolledBackTo = packageRolledBackTo;
this.mPendingBackups = pendingBackups;
this.mPendingRestores = pendingRestores;
this.mIsApex = isApex;
- this.mInstalledUsers = installedUsers;
+ this.mSnapshottedUsers = snapshottedUsers;
this.mCeSnapshotInodes = ceSnapshotInodes;
}
@@ -196,7 +196,7 @@
this.mIsApex = in.readBoolean();
this.mPendingRestores = null;
this.mPendingBackups = null;
- this.mInstalledUsers = null;
+ this.mSnapshottedUsers = null;
this.mCeSnapshotInodes = null;
}
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java
index 9a10a0c..73b8a48 100644
--- a/core/java/android/content/rollback/RollbackManager.java
+++ b/core/java/android/content/rollback/RollbackManager.java
@@ -114,7 +114,7 @@
})
public @NonNull List<RollbackInfo> getRecentlyCommittedRollbacks() {
try {
- return mBinder.getRecentlyExecutedRollbacks().getList();
+ return mBinder.getRecentlyCommittedRollbacks().getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -250,4 +250,25 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Block the RollbackManager for a specified amount of time.
+ * This API is meant to facilitate testing of race conditions in
+ * RollbackManager. Blocks RollbackManager from processing anything for
+ * the given number of milliseconds.
+ *
+ * @param millis number of milliseconds to block the RollbackManager for
+ * @throws SecurityException if the caller does not have appropriate permissions.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS)
+ @TestApi
+ public void blockRollbackManager(long millis) {
+ try {
+ mBinder.blockRollbackManager(millis);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index a231a92..3d0ac61 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -23,6 +23,8 @@
import android.util.Log;
import android.util.Printer;
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
import java.util.ArrayList;
/**
@@ -116,9 +118,15 @@
* @see #nativeGetPagerStats(PagerStats)
*/
public static class PagerStats {
+
+ @UnsupportedAppUsage
+ public PagerStats() {
+ }
+
/** the current amount of memory checked out by sqlite using sqlite3_malloc().
* documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
*/
+ @UnsupportedAppUsage
public int memoryUsed;
/** the number of bytes of page cache allocation which could not be sattisfied by the
@@ -128,16 +136,19 @@
* that overflowed because no space was left in the page cache.
* documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
*/
+ @UnsupportedAppUsage
public int pageCacheOverflow;
/** records the largest memory allocation request handed to sqlite3.
* documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
*/
+ @UnsupportedAppUsage
public int largestMemAlloc;
/** a list of {@link DbStats} - one for each main database opened by the applications
* running on the android device
*/
+ @UnsupportedAppUsage
public ArrayList<DbStats> dbStats;
}
@@ -146,16 +157,20 @@
*/
public static class DbStats {
/** name of the database */
+ @UnsupportedAppUsage
public String dbName;
/** the page size for the database */
+ @UnsupportedAppUsage
public long pageSize;
/** the database size */
+ @UnsupportedAppUsage
public long dbSize;
/**
* Number of lookaside slots: http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
+ @UnsupportedAppUsage
public int lookaside;
/** statement cache stats: hits/misses/cachesize */
@@ -175,6 +190,7 @@
* return all pager and database stats for the current process.
* @return {@link PagerStats}
*/
+ @UnsupportedAppUsage
public static PagerStats getDatabaseInfo() {
PagerStats stats = new PagerStats();
nativeGetPagerStats(stats);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 75af41c..56bacf2 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -52,13 +52,12 @@
import android.os.ServiceSpecificException;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;
@@ -711,6 +710,12 @@
@Deprecated
public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused.
+ // Deprecated constants for return values of startUsingNetworkFeature. They used to live
+ // in com.android.internal.telephony.PhoneConstants until they were made inaccessible.
+ private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0;
+ private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED = 1;
+ private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED = 3;
+
/** {@hide} */
public static final int MAX_RADIO_TYPE = TYPE_TEST;
@@ -1407,7 +1412,7 @@
if (netCap == null) {
Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
feature);
- return PhoneConstants.APN_REQUEST_FAILED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
}
NetworkRequest request = null;
@@ -1417,9 +1422,9 @@
Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
renewRequestLocked(l);
if (l.currentNetwork != null) {
- return PhoneConstants.APN_ALREADY_ACTIVE;
+ return DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE;
} else {
- return PhoneConstants.APN_REQUEST_STARTED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
}
}
@@ -1427,10 +1432,10 @@
}
if (request != null) {
Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
- return PhoneConstants.APN_REQUEST_STARTED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
} else {
Log.d(TAG, " request Failed");
- return PhoneConstants.APN_REQUEST_FAILED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
}
}
@@ -2149,19 +2154,14 @@
@Deprecated
@UnsupportedAppUsage
public boolean getMobileDataEnabled() {
- IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
- if (b != null) {
- try {
- ITelephony it = ITelephony.Stub.asInterface(b);
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
- Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
- boolean retVal = it.isUserDataEnabled(subId);
- Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
- + " retVal=" + retVal);
- return retVal;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+ if (tm != null) {
+ int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
+ boolean retVal = tm.createForSubscriptionId(subId).isDataEnabled();
+ Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
+ + " retVal=" + retVal);
+ return retVal;
}
Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
return false;
diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java
index 2af82d7..143467b 100644
--- a/core/java/android/net/IpConfiguration.java
+++ b/core/java/android/net/IpConfiguration.java
@@ -16,6 +16,10 @@
package android.net;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.net.StaticIpConfiguration;
import android.os.Parcel;
@@ -27,13 +31,17 @@
* A class representing a configured network.
* @hide
*/
-public class IpConfiguration implements Parcelable {
+@SystemApi
+public final class IpConfiguration implements Parcelable {
private static final String TAG = "IpConfiguration";
+ // This enum has been used by apps through reflection for many releases.
+ // Therefore they can't just be removed. Duplicating these constants to
+ // give an alternate SystemApi is a worse option than exposing them.
+ @SuppressLint("Enum")
public enum IpAssignment {
/* Use statically configured IP settings. Configuration can be accessed
* with staticIpConfiguration */
- @UnsupportedAppUsage
STATIC,
/* Use dynamically configured IP settings */
DHCP,
@@ -42,14 +50,19 @@
UNASSIGNED
}
+ /** @hide */
public IpAssignment ipAssignment;
+ /** @hide */
public StaticIpConfiguration staticIpConfiguration;
+ // This enum has been used by apps through reflection for many releases.
+ // Therefore they can't just be removed. Duplicating these constants to
+ // give an alternate SystemApi is a worse option than exposing them.
+ @SuppressLint("Enum")
public enum ProxySettings {
/* No proxy is to be used. Any existing proxy settings
* should be cleared. */
- @UnsupportedAppUsage
NONE,
/* Use statically configured proxy. Configuration can be accessed
* with httpProxy. */
@@ -62,8 +75,10 @@
PAC
}
+ /** @hide */
public ProxySettings proxySettings;
+ /** @hide */
@UnsupportedAppUsage
public ProxyInfo httpProxy;
@@ -83,6 +98,7 @@
init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
}
+ /** @hide */
@UnsupportedAppUsage
public IpConfiguration(IpAssignment ipAssignment,
ProxySettings proxySettings,
@@ -91,7 +107,7 @@
init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
}
- public IpConfiguration(IpConfiguration source) {
+ public IpConfiguration(@NonNull IpConfiguration source) {
this();
if (source != null) {
init(source.ipAssignment, source.proxySettings,
@@ -99,35 +115,35 @@
}
}
- public IpAssignment getIpAssignment() {
+ public @NonNull IpAssignment getIpAssignment() {
return ipAssignment;
}
- public void setIpAssignment(IpAssignment ipAssignment) {
+ public void setIpAssignment(@NonNull IpAssignment ipAssignment) {
this.ipAssignment = ipAssignment;
}
- public StaticIpConfiguration getStaticIpConfiguration() {
+ public @Nullable StaticIpConfiguration getStaticIpConfiguration() {
return staticIpConfiguration;
}
- public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
+ public void setStaticIpConfiguration(@Nullable StaticIpConfiguration staticIpConfiguration) {
this.staticIpConfiguration = staticIpConfiguration;
}
- public ProxySettings getProxySettings() {
+ public @NonNull ProxySettings getProxySettings() {
return proxySettings;
}
- public void setProxySettings(ProxySettings proxySettings) {
+ public void setProxySettings(@NonNull ProxySettings proxySettings) {
this.proxySettings = proxySettings;
}
- public ProxyInfo getHttpProxy() {
+ public @Nullable ProxyInfo getHttpProxy() {
return httpProxy;
}
- public void setHttpProxy(ProxyInfo httpProxy) {
+ public void setHttpProxy(@Nullable ProxyInfo httpProxy) {
this.httpProxy = httpProxy;
}
@@ -175,13 +191,19 @@
83 * httpProxy.hashCode();
}
- /** Implement the Parcelable interface */
+ /**
+ * Implement the Parcelable interface
+ * @hide
+ */
public int describeContents() {
return 0;
}
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
+ /**
+ * Implement the Parcelable interface
+ * @hide
+ */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(ipAssignment.name());
dest.writeString(proxySettings.name());
dest.writeParcelable(staticIpConfiguration, flags);
@@ -189,7 +211,7 @@
}
/** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<IpConfiguration> CREATOR =
+ public static final @NonNull Creator<IpConfiguration> CREATOR =
new Creator<IpConfiguration>() {
public IpConfiguration createFromParcel(Parcel in) {
IpConfiguration config = new IpConfiguration();
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index e3259ff..88877e2 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -478,6 +478,7 @@
* @return an array of capability values for this instance.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public @NetCapability int[] getCapabilities() {
return BitUtils.unpackBits(mNetworkCapabilities);
diff --git a/core/java/android/net/NetworkKey.java b/core/java/android/net/NetworkKey.java
index a101da7..9af1407 100644
--- a/core/java/android/net/NetworkKey.java
+++ b/core/java/android/net/NetworkKey.java
@@ -16,17 +16,20 @@
package android.net;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -48,6 +51,13 @@
/** A wifi network, for which {@link #wifiKey} will be populated. */
public static final int TYPE_WIFI = 1;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"TYPE_"}, value = {
+ TYPE_WIFI
+ })
+ public @interface NetworkType {}
+
/**
* The type of this network.
* @see #TYPE_WIFI
@@ -65,26 +75,28 @@
*
* @return A new {@link NetworkKey} instance or <code>null</code> if the given
* {@link ScanResult} instance is malformed.
- * @hide
*/
@Nullable
public static NetworkKey createFromScanResult(@Nullable ScanResult result) {
- if (result != null && result.wifiSsid != null) {
- final String ssid = result.wifiSsid.toString();
- final String bssid = result.BSSID;
- if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiSsid.NONE)
- && !TextUtils.isEmpty(bssid)) {
- WifiKey wifiKey;
- try {
- wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Unable to create WifiKey.", e);
- return null;
- }
- return new NetworkKey(wifiKey);
- }
+ if (result == null) {
+ return null;
}
- return null;
+ final String ssid = result.SSID;
+ if (TextUtils.isEmpty(ssid) || ssid.equals(WifiManager.UNKNOWN_SSID)) {
+ return null;
+ }
+ final String bssid = result.BSSID;
+ if (TextUtils.isEmpty(bssid)) {
+ return null;
+ }
+
+ try {
+ final WifiKey wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid);
+ return new NetworkKey(wifiKey);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Unable to create WifiKey.", e);
+ return null;
+ }
}
/**
@@ -100,7 +112,7 @@
if (wifiInfo != null) {
final String ssid = wifiInfo.getSSID();
final String bssid = wifiInfo.getBSSID();
- if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiSsid.NONE)
+ if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiManager.UNKNOWN_SSID)
&& !TextUtils.isEmpty(bssid)) {
WifiKey wifiKey;
try {
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
index 1ab6335..13f2994 100644
--- a/core/java/android/net/NetworkScore.java
+++ b/core/java/android/net/NetworkScore.java
@@ -154,4 +154,9 @@
}
return true;
}
+
+ /** Convert to a string */
+ public String toString() {
+ return "NetworkScore[" + mExtensions.toString() + "]";
+ }
}
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 50dd468..f6dc525 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -17,7 +17,9 @@
package android.net;
import android.Manifest.permission;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
@@ -25,13 +27,16 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
+import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Class that manages communication between network subsystems and a network scorer.
@@ -50,19 +55,25 @@
@SystemApi
@SystemService(Context.NETWORK_SCORE_SERVICE)
public class NetworkScoreManager {
+ private static final String TAG = "NetworkScoreManager";
+
/**
* Activity action: ask the user to change the active network scorer. This will show a dialog
* that asks the user whether they want to replace the current active scorer with the one
* specified in {@link #EXTRA_PACKAGE_NAME}. The activity will finish with RESULT_OK if the
* active scorer was changed or RESULT_CANCELED if it failed for any reason.
+ * @deprecated No longer sent.
*/
+ @Deprecated
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CHANGE_ACTIVE = "android.net.scoring.CHANGE_ACTIVE";
/**
* Extra used with {@link #ACTION_CHANGE_ACTIVE} to specify the new scorer package. Set with
* {@link android.content.Intent#putExtra(String, String)}.
+ * @deprecated No longer sent.
*/
+ @Deprecated
public static final String EXTRA_PACKAGE_NAME = "packageName";
/**
@@ -73,7 +84,9 @@
* configured by the user as well as any open networks.
*
* <p class="note">This is a protected intent that can only be sent by the system.
+ * @deprecated Use {@link #ACTION_RECOMMEND_NETWORKS} to bind scorer app instead.
*/
+ @Deprecated
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_SCORE_NETWORKS = "android.net.scoring.SCORE_NETWORKS";
@@ -81,7 +94,9 @@
* Extra used with {@link #ACTION_SCORE_NETWORKS} to specify the networks to be scored, as an
* array of {@link NetworkKey}s. Can be obtained with
* {@link android.content.Intent#getParcelableArrayExtra(String)}}.
+ * @deprecated Use {@link #ACTION_RECOMMEND_NETWORKS} to bind scorer app instead.
*/
+ @Deprecated
public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore";
/**
@@ -285,7 +300,7 @@
* @throws SecurityException if the caller is not the active scorer.
*/
@RequiresPermission(android.Manifest.permission.SCORE_NETWORKS)
- public boolean updateScores(ScoredNetwork[] networks) throws SecurityException {
+ public boolean updateScores(@NonNull ScoredNetwork[] networks) throws SecurityException {
try {
return mService.updateScores(networks);
} catch (RemoteException e) {
@@ -359,13 +374,21 @@
/**
* Request scoring for networks.
*
- * @return true if the broadcast was sent, or false if there is no active scorer.
+ * <p>
+ * Note: The results (i.e scores) for these networks, when available will be provided via the
+ * callback registered with {@link #registerNetworkScoreCallback(int, int, Executor,
+ * NetworkScoreCallback)}. The calling module is responsible for registering a callback to
+ * receive the results before requesting new scores via this API.
+ *
+ * @return true if the request was successfully sent, or false if there is no active scorer.
* @throws SecurityException if the caller does not hold the
* {@link permission#REQUEST_NETWORK_SCORES} permission.
+ *
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.REQUEST_NETWORK_SCORES)
- public boolean requestScores(NetworkKey[] networks) throws SecurityException {
+ public boolean requestScores(@NonNull NetworkKey[] networks) throws SecurityException {
try {
return mService.requestScores(networks);
} catch (RemoteException e) {
@@ -431,6 +454,88 @@
}
/**
+ * Base class for network score cache callback. Should be extended by applications and set
+ * when calling {@link #registerNetworkScoreCallback(int, int, NetworkScoreCallback,
+ * Executor)}
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface NetworkScoreCallback {
+ /**
+ * Called when a new set of network scores are available.
+ * This is triggered in response when the client invokes
+ * {@link #requestScores(NetworkKey[])} to score a new set of networks.
+ *
+ * @param networks List of {@link ScoredNetwork} containing updated scores.
+ */
+ void updateScores(@NonNull List<ScoredNetwork> networks);
+
+ /**
+ * Invokes when all the previously provided scores are no longer valid.
+ */
+ void clearScores();
+ }
+
+ /**
+ * Callback proxy for {@link NetworkScoreCallback} objects.
+ */
+ private class NetworkScoreCallbackProxy extends INetworkScoreCache.Stub {
+ private final Executor mExecutor;
+ private final NetworkScoreCallback mCallback;
+
+ NetworkScoreCallbackProxy(Executor executor, NetworkScoreCallback callback) {
+ mExecutor = executor;
+ mCallback = callback;
+ }
+
+ @Override
+ public void updateScores(@NonNull List<ScoredNetwork> networks) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> {
+ mCallback.updateScores(networks);
+ });
+ }
+
+ @Override
+ public void clearScores() {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> {
+ mCallback.clearScores();
+ });
+ }
+ }
+
+ /**
+ * Register a network score callback.
+ *
+ * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}
+ * @param filterType the {@link CacheUpdateFilter} to apply
+ * @param callback implementation of {@link NetworkScoreCallback} that will be invoked when the
+ * scores change.
+ * @param executor The executor on which to execute the callbacks.
+ * @throws SecurityException if the caller does not hold the
+ * {@link permission#REQUEST_NETWORK_SCORES} permission.
+ * @throws IllegalArgumentException if a callback is already registered for this type.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.REQUEST_NETWORK_SCORES)
+ public void registerNetworkScoreCallback(@NetworkKey.NetworkType int networkType,
+ @CacheUpdateFilter int filterType,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull NetworkScoreCallback callback) throws SecurityException {
+ if (callback == null || executor == null) {
+ throw new IllegalArgumentException("callback / executor cannot be null");
+ }
+ Log.v(TAG, "registerNetworkScoreCallback: callback=" + callback + ", executor="
+ + executor);
+ // Use the @hide method.
+ registerNetworkScoreCache(
+ networkType, new NetworkScoreCallbackProxy(executor, callback), filterType);
+ }
+
+ /**
* Determine whether the application with the given UID is the enabled scorer.
*
* @param callingUid the UID to check
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index 807c467..9d92db4 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -16,7 +16,8 @@
package android.net;
-
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -89,6 +90,15 @@
}
/**
+ * Construct a {@link ProxyInfo} object that will download and run the PAC script at the
+ * specified URL and port.
+ */
+ @NonNull
+ public static ProxyInfo buildPacProxy(@NonNull Uri pacUrl, int port) {
+ return new ProxyInfo(pacUrl, port);
+ }
+
+ /**
* Create a ProxyProperties that points at a HTTP Proxy.
* @hide
*/
@@ -105,7 +115,7 @@
* Create a ProxyProperties that points at a PAC URL.
* @hide
*/
- public ProxyInfo(Uri pacFileUrl) {
+ public ProxyInfo(@NonNull Uri pacFileUrl) {
mHost = LOCAL_HOST;
mPort = LOCAL_PORT;
mExclusionList = LOCAL_EXCL_LIST;
@@ -132,7 +142,7 @@
* Only used in PacManager after Local Proxy is bound.
* @hide
*/
- public ProxyInfo(Uri pacFileUrl, int localProxyPort) {
+ public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) {
mHost = LOCAL_HOST;
mPort = localProxyPort;
mExclusionList = LOCAL_EXCL_LIST;
@@ -159,11 +169,10 @@
mPacFileUrl = Uri.EMPTY;
}
- // copy constructor instead of clone
/**
- * @hide
+ * A copy constructor to hold proxy properties.
*/
- public ProxyInfo(ProxyInfo source) {
+ public ProxyInfo(@Nullable ProxyInfo source) {
if (source != null) {
mHost = source.getHost();
mPort = source.getPort();
@@ -226,12 +235,13 @@
* comma separated
* @hide
*/
+ @Nullable
public String getExclusionListAsString() {
return mExclusionList;
}
/**
- * @hide
+ * Return true if the pattern of proxy is valid, otherwise return false.
*/
public boolean isValid() {
if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 95d66bb..39cb323 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -304,7 +304,8 @@
}
/**
- * Sets the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next
+ * Sets the
+ * <a class="external" href="https://tools.ietf.org/id/draft-agl-tls-nextprotoneg-03.html">Next
* Protocol Negotiation (NPN)</a> protocols that this peer is interested in.
*
* <p>For servers this is the sequence of protocols to advertise as
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 5bc9953..990c114 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -25,6 +25,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.Preconditions;
+
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
@@ -152,6 +154,7 @@
* @return The {@link Builder} for chaining.
*/
public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) {
+ Preconditions.checkNotNull(dnsServers);
mDnsServers = dnsServers;
return this;
}
@@ -175,8 +178,10 @@
final StaticIpConfiguration config = new StaticIpConfiguration();
config.ipAddress = mIpAddress;
config.gateway = mGateway;
- for (InetAddress server : mDnsServers) {
- config.dnsServers.add(server);
+ if (mDnsServers != null) {
+ for (InetAddress server : mDnsServers) {
+ config.dnsServers.add(server);
+ }
}
config.domains = mDomains;
return config;
diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java
index 4e88149..aa0f622 100644
--- a/core/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/core/java/android/net/util/MultinetworkPolicyTracker.java
@@ -94,7 +94,8 @@
}
};
- TelephonyManager.from(ctx).listen(new PhoneStateListener(handler.getLooper()) {
+ ctx.getSystemService(TelephonyManager.class).listen(
+ new PhoneStateListener(handler.getLooper()) {
@Override
public void onActiveDataSubscriptionIdChanged(int subId) {
mActiveSubId = subId;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index f5426cd..f21956b 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -108,6 +108,7 @@
* Whether this build was for an emulator device.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3462d1f..c237222 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -169,6 +169,7 @@
}
/** {@hide} */
+ @UnsupportedAppUsage
@TestApi
public static @NonNull File getStorageDirectory() {
return DIR_ANDROID_STORAGE;
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index f789b72..2ac3def 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1275,7 +1275,13 @@
/**
* Closes the given object quietly, ignoring any checked exceptions. Does
* nothing if the given object is {@code null}.
+ *
+ * @deprecated This method may suppress potentially significant exceptions, particularly when
+ * closing writable resources. With a writable resource, a failure thrown from {@code close()}
+ * should be considered as significant as a failure thrown from a write method because it may
+ * indicate a failure to flush bytes to the underlying resource.
*/
+ @Deprecated
public static void closeQuietly(@Nullable AutoCloseable closeable) {
IoUtils.closeQuietly(closeable);
}
@@ -1283,7 +1289,13 @@
/**
* Closes the given object quietly, ignoring any checked exceptions. Does
* nothing if the given object is {@code null}.
+ *
+ * @deprecated This method may suppress potentially significant exceptions, particularly when
+ * closing writable resources. With a writable resource, a failure thrown from {@code close()}
+ * should be considered as significant as a failure thrown from a write method because it may
+ * indicate a failure to flush bytes to the underlying resource.
*/
+ @Deprecated
public static void closeQuietly(@Nullable FileDescriptor fd) {
IoUtils.closeQuietly(fd);
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 9af9eda..a99bdabe 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -28,15 +28,14 @@
* A Handler allows you to send and process {@link Message} and Runnable
* objects associated with a thread's {@link MessageQueue}. Each Handler
* instance is associated with a single thread and that thread's message
- * queue. When you create a new Handler, it is bound to the thread /
- * message queue of the thread that is creating it -- from that point on,
- * it will deliver messages and runnables to that message queue and execute
- * them as they come out of the message queue.
- *
+ * queue. When you create a new Handler it is bound to a {@link Looper}.
+ * It will deliver messages and runnables to that Looper's message
+ * queue and execute them on that Looper's thread.
+ *
* <p>There are two main uses for a Handler: (1) to schedule messages and
* runnables to be executed at some point in the future; and (2) to enqueue
* an action to be performed on a different thread than your own.
- *
+ *
* <p>Scheduling messages is accomplished with the
* {@link #post}, {@link #postAtTime(Runnable, long)},
* {@link #postDelayed}, {@link #sendEmptyMessage},
@@ -114,7 +113,18 @@
*
* If this thread does not have a looper, this handler won't be able to receive messages
* so an exception is thrown.
+ *
+ * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
+ * where operations are silently lost (if the Handler is not expecting new tasks and quits),
+ * crashes (if a handler is sometimes created on a thread without a Looper active), or race
+ * conditions, where the thread a handler is associated with is not what the author
+ * anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
+ * explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
+ * similar. If the implicit thread local behavior is required for compatibility, use
+ * {@code new Handler(Looper.myLooper())} to make it clear to readers.
+ *
*/
+ @Deprecated
public Handler() {
this(null, false);
}
@@ -128,7 +138,17 @@
* so an exception is thrown.
*
* @param callback The callback interface in which to handle messages, or null.
+ *
+ * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
+ * where operations are silently lost (if the Handler is not expecting new tasks and quits),
+ * crashes (if a handler is sometimes created on a thread without a Looper active), or race
+ * conditions, where the thread a handler is associated with is not what the author
+ * anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
+ * explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
+ * similar. If the implicit thread local behavior is required for compatibility, use
+ * {@code new Handler(Looper.myLooper(), callback)} to make it clear to readers.
*/
+ @Deprecated
public Handler(@Nullable Callback callback) {
this(callback, false);
}
diff --git a/core/java/android/os/HidlMemory.java b/core/java/android/os/HidlMemory.java
new file mode 100644
index 0000000..aeb6589
--- /dev/null
+++ b/core/java/android/os/HidlMemory.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2019 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.os;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * An abstract representation of a memory block, as representing by the HIDL system.
+ *
+ * The block is defined by a {name, size, handle} tuple, where the name is used to determine how to
+ * interpret the handle. The underlying handle is assumed to be owned by this instance and will be
+ * closed as soon as {@link #close()} is called on this instance, or this instance has been
+ * finalized (the latter supports using it in a shared manner without having to worry about who owns
+ * this instance, the former is more efficient resource-wise and is recommended for most use-cases).
+ * Note, however, that ownership of the handle does not necessarily imply ownership of the
+ * underlying file descriptors - the underlying handle may or may not own them. If you want the
+ * underlying handle to outlive this instance, call {@link #releaseHandle()} to obtain the handle
+ * and detach the ownership relationship.
+ *
+ * @hide
+ */
+@SystemApi
+@TestApi
+public class HidlMemory implements Closeable {
+ private final @NonNull String mName;
+ private final long mSize;
+ private @Nullable NativeHandle mHandle;
+ private long mNativeContext; // For use of native code.
+
+ /**
+ * Constructor.
+ *
+ * @param name The name of the IMapper service used to resolve the handle (e.g. "ashmem").
+ * @param size The (non-negative) size in bytes of the memory block.
+ * @param handle The handle. May be null. This instance will own the handle and will close it
+ * as soon as {@link #close()} is called or the object is destroyed. This, this
+ * handle instance should generally not be shared with other clients.
+ */
+ public HidlMemory(@NonNull String name, @IntRange(from = 0) long size,
+ @Nullable NativeHandle handle) {
+ mName = name;
+ mSize = size;
+ mHandle = handle;
+ }
+
+ /**
+ * Create a copy of this instance, where the underlying handle (and its file descriptors) have
+ * been duplicated.
+ */
+ @NonNull
+ public HidlMemory dup() throws IOException {
+ return new HidlMemory(mName, mSize, mHandle != null ? mHandle.dup() : null);
+ }
+
+ /**
+ * Close the underlying native handle. No-op if handle is null or has been released using {@link
+ * #releaseHandle()}.
+ */
+ @Override
+ public void close() throws IOException {
+ if (mHandle != null) {
+ mHandle.close();
+ }
+ }
+
+ /**
+ * Disowns the underlying handle and returns it. This object becomes invalid.
+ *
+ * @return The underlying handle.
+ */
+ @NonNull
+ public NativeHandle releaseHandle() {
+ NativeHandle handle = mHandle;
+ mHandle = null;
+ return handle;
+ }
+
+ /**
+ * Gets the name, which represents how the handle is to be interpreted.
+ *
+ * @return The name.
+ */
+ @NonNull
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the size of the block, in bytes.
+ *
+ * @return The size.
+ */
+ public long getSize() {
+ return mSize;
+ }
+
+ /**
+ * Gets a native handle. The actual interpretation depends on the name and is implementation
+ * defined.
+ *
+ * @return The native handle.
+ */
+ @Nullable
+ public NativeHandle getHandle() {
+ return mHandle;
+ }
+
+ @Override
+ protected void finalize() {
+ try {
+ close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ nativeFinalize();
+ }
+ }
+
+ private native void nativeFinalize();
+}
diff --git a/core/java/android/os/HidlMemoryUtil.java b/core/java/android/os/HidlMemoryUtil.java
new file mode 100644
index 0000000..b08822dd
--- /dev/null
+++ b/core/java/android/os/HidlMemoryUtil.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2019 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.os;
+
+import static android.system.OsConstants.MAP_SHARED;
+import static android.system.OsConstants.PROT_READ;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+
+import java.nio.ByteBuffer;
+import java.nio.DirectByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides utilities for dealing with HidlMemory.
+ *
+ * @hide
+ */
+public final class HidlMemoryUtil {
+ static private final String TAG = "HidlMemoryUtil";
+
+ private HidlMemoryUtil() {
+ }
+
+ /**
+ * Copies a byte-array into a new Ashmem region and return it as HidlMemory.
+ * The returned instance owns the underlying file descriptors, and the client should generally
+ * call close on it when no longer in use (or otherwise, when the object gets destroyed it will
+ * be closed).
+ *
+ * @param input The input byte array.
+ * @return A HidlMemory instance, containing a copy of the input.
+ */
+ public static @NonNull
+ HidlMemory byteArrayToHidlMemory(@NonNull byte[] input) {
+ return byteArrayToHidlMemory(input, null);
+ }
+
+ /**
+ * Copies a byte-array into a new Ashmem region and return it as HidlMemory.
+ * The returned instance owns the underlying file descriptors, and the client should generally
+ * call close on it when no longer in use (or otherwise, when the object gets destroyed it will
+ * be closed).
+ *
+ * @param input The input byte array.
+ * @param name An optional name for the ashmem region.
+ * @return A HidlMemory instance, containing a copy of the input.
+ */
+ public static @NonNull
+ HidlMemory byteArrayToHidlMemory(@NonNull byte[] input, @Nullable String name) {
+ Preconditions.checkNotNull(input);
+
+ if (input.length == 0) {
+ return new HidlMemory("ashmem", 0, null);
+ }
+
+ try {
+ SharedMemory shmem = SharedMemory.create(name != null ? name : "", input.length);
+ ByteBuffer buffer = shmem.mapReadWrite();
+ buffer.put(input);
+ shmem.unmap(buffer);
+ NativeHandle handle = new NativeHandle(shmem.getFileDescriptor(), true);
+ return new HidlMemory("ashmem", input.length, handle);
+ } catch (ErrnoException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Copies a byte list into a new Ashmem region and return it as HidlMemory.
+ * The returned instance owns the underlying file descriptors, and the client should generally
+ * call close on it when no longer in use (or otherwise, when the object gets destroyed it will
+ * be closed).
+ *
+ * @param input The input byte list.
+ * @return A HidlMemory instance, containing a copy of the input.
+ */
+ public static @NonNull
+ HidlMemory byteListToHidlMemory(@NonNull List<Byte> input) {
+ return byteListToHidlMemory(input, null);
+ }
+
+ /**
+ * Copies a byte list into a new Ashmem region and return it as HidlMemory.
+ * The returned instance owns the underlying file descriptors, and the client should generally
+ * call close on it when no longer in use (or otherwise, when the object gets destroyed it will
+ * be closed).
+ *
+ * @param input The input byte list.
+ * @param name An optional name for the ashmem region.
+ * @return A HidlMemory instance, containing a copy of the input.
+ */
+ public static @NonNull
+ HidlMemory byteListToHidlMemory(@NonNull List<Byte> input, @Nullable String name) {
+ Preconditions.checkNotNull(input);
+
+ if (input.isEmpty()) {
+ return new HidlMemory("ashmem", 0, null);
+ }
+
+ try {
+ SharedMemory shmem = SharedMemory.create(name != null ? name : "", input.size());
+ ByteBuffer buffer = shmem.mapReadWrite();
+ for (Byte b : input) {
+ buffer.put(b);
+ }
+ shmem.unmap(buffer);
+ NativeHandle handle = new NativeHandle(shmem.getFileDescriptor(), true);
+ return new HidlMemory("ashmem", input.size(), handle);
+ } catch (ErrnoException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Copies all data from a HidlMemory instance into a byte array.
+ *
+ * @param mem The HidlMemory instance. Must be of name "ashmem" and of size that doesn't exceed
+ * {@link Integer#MAX_VALUE}.
+ * @return A byte array, containing a copy of the input.
+ */
+ public static @NonNull
+ byte[] hidlMemoryToByteArray(@NonNull HidlMemory mem) {
+ Preconditions.checkNotNull(mem);
+ Preconditions.checkArgumentInRange(mem.getSize(), 0L, (long) Integer.MAX_VALUE,
+ "Memory size");
+ Preconditions.checkArgument(mem.getSize() == 0 || mem.getName().equals("ashmem"),
+ "Unsupported memory type: %s", mem.getName());
+
+ if (mem.getSize() == 0) {
+ return new byte[0];
+ }
+
+ ByteBuffer buffer = getBuffer(mem);
+ byte[] result = new byte[buffer.remaining()];
+ buffer.get(result);
+ return result;
+ }
+
+ /**
+ * Copies all data from a HidlMemory instance into a byte list.
+ *
+ * @param mem The HidlMemory instance. Must be of name "ashmem" and of size that doesn't exceed
+ * {@link Integer#MAX_VALUE}.
+ * @return A byte list, containing a copy of the input.
+ */
+ @SuppressLint("ConcreteCollection")
+ public static @NonNull
+ ArrayList<Byte> hidlMemoryToByteList(@NonNull HidlMemory mem) {
+ Preconditions.checkNotNull(mem);
+ Preconditions.checkArgumentInRange(mem.getSize(), 0L, (long) Integer.MAX_VALUE,
+ "Memory size");
+ Preconditions.checkArgument(mem.getSize() == 0 || mem.getName().equals("ashmem"),
+ "Unsupported memory type: %s", mem.getName());
+
+ if (mem.getSize() == 0) {
+ return new ArrayList<>();
+ }
+
+ ByteBuffer buffer = getBuffer(mem);
+
+ ArrayList<Byte> result = new ArrayList<>(buffer.remaining());
+ while (buffer.hasRemaining()) {
+ result.add(buffer.get());
+ }
+ return result;
+ }
+
+ private static ByteBuffer getBuffer(@NonNull HidlMemory mem) {
+ try {
+ final int size = (int) mem.getSize();
+
+ if (size == 0) {
+ return ByteBuffer.wrap(new byte[0]);
+ }
+
+ NativeHandle handle = mem.getHandle();
+
+ final long address = Os.mmap(0, size, PROT_READ, MAP_SHARED, handle.getFileDescriptor(),
+ 0);
+ return new DirectByteBuffer(size, address, handle.getFileDescriptor(), () -> {
+ try {
+ Os.munmap(address, size);
+ } catch (ErrnoException e) {
+ Log.wtf(TAG, e);
+ }
+ }, true);
+ } catch (ErrnoException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/core/java/android/os/HwBlob.java b/core/java/android/os/HwBlob.java
index 2c453bf..154227b2 100644
--- a/core/java/android/os/HwBlob.java
+++ b/core/java/android/os/HwBlob.java
@@ -92,6 +92,14 @@
* @throws IndexOutOfBoundsException when offset is out of this HwBlob
*/
public native final String getString(long offset);
+ /**
+ * For embedded fields that follow a two-step approach for reading, first obtain their field
+ * handle using this method, and pass that field handle to the respective
+ * HwParcel.readEmbedded*() method.
+ * @param offset The field offset.
+ * @return The field handle.
+ */
+ public native final long getFieldHandle(long offset);
/**
* Copy the blobs data starting from the given byte offset into the range, copying
@@ -312,6 +320,20 @@
public native final void putBlob(long offset, HwBlob blob);
/**
+ * Writes a HidlMemory instance (without duplicating the underlying file descriptors) at an
+ * offset.
+ *
+ * @param offset location to write value
+ * @param mem a {@link HidlMemory} instance to write
+ * @throws IndexOutOfBoundsException when [offset, offset + sizeof(jobject)] is out of range
+ */
+ public final void putHidlMemory(long offset, @NonNull HidlMemory mem) {
+ putNativeHandle(offset + 0 /* offset of 'handle' field. */, mem.getHandle());
+ putInt64(offset + 16 /* offset of 'size' field. */, mem.getSize());
+ putString(offset + 24 /* offset of 'name' field. */, mem.getName());
+ }
+
+ /**
* @return current handle of HwBlob for reference in a parcelled binder transaction
*/
public native final long handle();
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 5e8929c..9786f16 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -324,6 +324,15 @@
public native final void writeStrongBinder(IHwBinder binder);
/**
+ * Write a HidlMemory object (without duplicating the underlying file descriptors) to the end
+ * of the parcel.
+ *
+ * @param memory value to write
+ */
+ @FastNative
+ public native final void writeHidlMemory(@NonNull HidlMemory memory);
+
+ /**
* Checks to make sure that the interface name matches the name written by the parcel
* sender by writeInterfaceToken
*
@@ -582,6 +591,38 @@
public native final IHwBinder readStrongBinder();
/**
+ * Reads a HidlMemory value (without duplicating the underlying file
+ * descriptors) from the parcel. These file descriptors will only
+ * be open for the duration that the binder window is open. If they
+ * are needed further, you must call {@link HidlMemory#dup()}, which makes you also
+ * responsible for calling {@link HidlMemory#close()}.
+ *
+ * @return HidlMemory object read from parcel.
+ * @throws IllegalArgumentException if the parcel has no more data or is otherwise corrupt.
+ */
+ @FastNative
+ @NonNull
+ public native final HidlMemory readHidlMemory();
+
+ /**
+ * Reads an embedded HidlMemory (without duplicating the underlying
+ * file descriptors) from the parcel. These file descriptors will only
+ * be open for the duration that the binder window is open. If they
+ * are needed further, you must call {@link HidlMemory#dup()}. You
+ * do not need to call close on the HidlMemory returned from this.
+ *
+ * @param fieldHandle handle of the field, obtained from the {@link HwBlob}.
+ * @param parentHandle parentHandle from which to read the embedded object
+ * @param offset offset into parent
+ * @return a {@link HidlMemory} instance parsed from the parcel
+ * @throws IllegalArgumentException if the parcel has no more data
+ */
+ @FastNative
+ @NonNull
+ public native final @Nullable
+ HidlMemory readEmbeddedHidlMemory(long fieldHandle, long parentHandle, long offset);
+
+ /**
* Read opaque segment of data as a blob.
* @return blob of size expectedSize
* @throws IllegalArgumentException if the parcel has no more data
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 3222fc4..d468972 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -112,10 +112,12 @@
/**
* Initialize the current thread as a looper, marking it as an
- * application's main looper. The main looper for your application
- * is created by the Android environment, so you should never need
- * to call this function yourself. See also: {@link #prepare()}
+ * application's main looper. See also: {@link #prepare()}
+ *
+ * @deprecated The main looper for your application is created by the Android environment,
+ * so you should never need to call this function yourself.
*/
+ @Deprecated
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index c5f1698..f98fdc3 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -468,6 +468,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public int postSyncBarrier() {
return postSyncBarrier(SystemClock.uptimeMillis());
@@ -512,6 +513,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public void removeSyncBarrier(int token) {
// Remove a sync barrier token from the queue.
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 8d74fc5..450bfae 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -229,6 +229,7 @@
* First uid used for fully isolated sandboxed processes (with no permissions of their own)
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int FIRST_ISOLATED_UID = 99000;
@@ -236,6 +237,7 @@
* Last uid used for fully isolated sandboxed processes (with no permissions of their own)
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int LAST_ISOLATED_UID = 99999;
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 48fc2a6..e3f6e12 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -888,7 +888,7 @@
}
List<SubscriptionInfo> invisibleSubs = new ArrayList<>();
for (SubscriptionInfo sub : availableSubs) {
- if (sub.isEmbedded() && !subscriptionManager.isSubscriptionVisible(sub)) {
+ if (sub.isEmbedded() && sub.getGroupUuid() != null && sub.isOpportunistic()) {
invisibleSubs.add(sub);
}
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index c707ba8..0bf634e 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1892,6 +1892,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public static void conditionallyCheckInstanceCounts() {
VmPolicy policy = getVmPolicy();
@@ -2751,6 +2752,7 @@
}
/** Create an instance of ViolationInfo initialized from a Parcel. */
+ @UnsupportedAppUsage
public ViolationInfo(Parcel in) {
this(in, false);
}
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 8b0ffe1..f08e1ff 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -26,6 +26,9 @@
import com.android.internal.annotations.GuardedBy;
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
import libcore.util.HexEncoding;
import java.nio.charset.StandardCharsets;
@@ -93,18 +96,43 @@
}
}
+ // The one-argument version of native_get used to be a regular native function. Nowadays,
+ // we use the two-argument form of native_get all the time, but we can't just delete the
+ // one-argument overload: apps use it via reflection, as the UnsupportedAppUsage annotation
+ // indicates. Let's just live with having a Java function with a very unusual name.
@UnsupportedAppUsage
- private static native String native_get(String key);
+ private static String native_get(String key) {
+ return native_get(key, "");
+ }
+
+ @FastNative
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native String native_get(String key, String def);
+ @FastNative
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native int native_get_int(String key, int def);
+ @FastNative
@UnsupportedAppUsage
private static native long native_get_long(String key, long def);
+ @FastNative
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native boolean native_get_boolean(String key, boolean def);
+
+ @FastNative
+ private static native long native_find(String name);
+ @FastNative
+ private static native String native_get(long handle);
+ @CriticalNative
+ private static native int native_get_int(long handle, int def);
+ @CriticalNative
+ private static native long native_get_long(long handle, long def);
+ @CriticalNative
+ private static native boolean native_get_boolean(long handle, boolean def);
+
+ // _NOT_ FastNative: native_set performs IPC and can block
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native void native_set(String key, String def);
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native void native_add_change_callback();
private static native void native_report_sysprop_change();
@@ -229,25 +257,27 @@
@SuppressWarnings("unused") // Called from native code.
private static void callChangeCallbacks() {
+ ArrayList<Runnable> callbacks = null;
synchronized (sChangeCallbacks) {
//Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
if (sChangeCallbacks.size() == 0) {
return;
}
- ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
- final long token = Binder.clearCallingIdentity();
- try {
- for (int i = 0; i < callbacks.size(); i++) {
- try {
- callbacks.get(i).run();
- } catch (Throwable t) {
- Log.wtf(TAG, "Exception in SystemProperties change callback", t);
- // Ignore and try to go on.
- }
+ callbacks = new ArrayList<Runnable>(sChangeCallbacks);
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ for (int i = 0; i < callbacks.size(); i++) {
+ try {
+ callbacks.get(i).run();
+ } catch (Throwable t) {
+ // Ignore and try to go on. Don't use wtf here: that
+ // will cause the process to exit on some builds and break tests.
+ Log.e(TAG, "Exception in SystemProperties change callback", t);
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -284,4 +314,60 @@
@UnsupportedAppUsage
private SystemProperties() {
}
+
+ /**
+ * Look up a property location by name.
+ * @name name of the property
+ * @return property handle or {@code null} if property isn't set
+ * @hide
+ */
+ @Nullable public static Handle find(@NonNull String name) {
+ long nativeHandle = native_find(name);
+ if (nativeHandle == 0) {
+ return null;
+ }
+ return new Handle(nativeHandle);
+ }
+
+ /**
+ * Handle to a pre-located property. Looking up a property handle in advance allows
+ * for optimal repeated lookup of a single property.
+ * @hide
+ */
+ public static final class Handle {
+
+ private final long mNativeHandle;
+
+ /**
+ * @return Value of the property
+ */
+ @NonNull public String get() {
+ return native_get(mNativeHandle);
+ }
+ /**
+ * @param def default value
+ * @return value or {@code def} on parse error
+ */
+ public int getInt(int def) {
+ return native_get_int(mNativeHandle, def);
+ }
+ /**
+ * @param def default value
+ * @return value or {@code def} on parse error
+ */
+ public long getLong(long def) {
+ return native_get_long(mNativeHandle, def);
+ }
+ /**
+ * @param def default value
+ * @return value or {@code def} on parse error
+ */
+ public boolean getBoolean(boolean def) {
+ return native_get_boolean(mNativeHandle, def);
+ }
+
+ private Handle(long nativeHandle) {
+ mNativeHandle = nativeHandle;
+ }
+ }
}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 4e17f7e..45ee4ef 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -171,6 +171,7 @@
* "it's system", because of isolated UIDs. Use {@link #isCore} for that.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static boolean isApp(int uid) {
if (uid > 0) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9c9829f..c15618b 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1295,8 +1295,11 @@
mContext.getContentResolver(),
Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM);
- boolean inCall = TelephonyManager.getDefault().getCallState()
- != TelephonyManager.CALL_STATE_IDLE;
+ boolean inCall = false;
+ TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+ if (telephonyManager != null) {
+ inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+ }
boolean isUserSwitchDisallowed = hasUserRestriction(DISALLOW_USER_SWITCH);
return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall
&& !isUserSwitchDisallowed;
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 702b41b..64d36a9 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -27,6 +27,8 @@
import android.net.Uri;
import android.util.MathUtils;
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -77,6 +79,7 @@
* @see #get(int)
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int EFFECT_THUD = Effect.THUD;
@@ -85,6 +88,7 @@
* @see #get(int)
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int EFFECT_POP = Effect.POP;
@@ -126,6 +130,7 @@
* @see #get(Uri, Context)
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int[] RINGTONES = {
Effect.RINGTONE_1,
@@ -493,6 +498,7 @@
out.writeInt(mAmplitude);
}
+ @UnsupportedAppUsage
public static final @android.annotation.NonNull Parcelable.Creator<OneShot> CREATOR =
new Parcelable.Creator<OneShot>() {
@Override
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 9cc9aac..825fc64 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -92,6 +92,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public WorkSource(int uid) {
mNum = 1;
@@ -138,12 +139,14 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public int size() {
return mNum;
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public int get(int index) {
return mUids[index];
@@ -165,6 +168,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public String getName(int index) {
return mNames != null ? mNames[index] : null;
@@ -419,6 +423,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public boolean add(int uid) {
if (mNum <= 0) {
@@ -439,6 +444,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
@TestApi
public boolean add(int uid, String name) {
if (mNum <= 0) {
diff --git a/core/java/android/os/health/HealthStatsParceler.java b/core/java/android/os/health/HealthStatsParceler.java
index de98359..384342c 100644
--- a/core/java/android/os/health/HealthStatsParceler.java
+++ b/core/java/android/os/health/HealthStatsParceler.java
@@ -19,10 +19,8 @@
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.ArrayMap;
-import java.util.Arrays;
-import java.util.Map;
+import dalvik.annotation.compat.UnsupportedAppUsage;
/**
* Class to allow sending the HealthStats through aidl generated glue.
@@ -41,6 +39,7 @@
private HealthStatsWriter mWriter;
private HealthStats mHealthStats;
+ @UnsupportedAppUsage
public static final @android.annotation.NonNull Parcelable.Creator<HealthStatsParceler> CREATOR
= new Parcelable.Creator<HealthStatsParceler>() {
public HealthStatsParceler createFromParcel(Parcel in) {
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index 0e00d5e..4c92c28 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -101,6 +101,19 @@
}
}
/**
+ * Start DynamicSystem installation.
+ *
+ * @return true if the call succeeds
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+ public boolean startInstallation() {
+ try {
+ return mService.startInstallation();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ /**
* Start DynamicSystem installation. This call may take an unbounded amount of time. The caller
* may use another thread to call the getStartProgress() to get the progress.
*
@@ -112,9 +125,9 @@
* true.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
- public Session startInstallation(String name, long size, boolean readOnly) {
+ public Session createPartition(String name, long size, boolean readOnly) {
try {
- if (mService.startInstallation(name, size, readOnly)) {
+ if (mService.createPartition(name, size, readOnly)) {
return new Session();
} else {
return null;
@@ -123,7 +136,18 @@
throw new RuntimeException(e.toString());
}
}
-
+ /**
+ * Finish a previously started installation. Installations without a cooresponding
+ * finishInstallation() will be cleaned up during device boot.
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+ public boolean finishInstallation() {
+ try {
+ return mService.finishInstallation();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
/**
* Query the progress of the current installation operation. This can be called while the
* installation is in progress.
diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
index 75f6785..69cbab2 100644
--- a/core/java/android/os/image/IDynamicSystemService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -21,15 +21,26 @@
interface IDynamicSystemService
{
/**
- * Start DynamicSystem installation. This call may take 60~90 seconds. The caller
+ * Start DynamicSystem installation.
+ * @return true if the call succeeds
+ */
+ boolean startInstallation();
+
+ /**
+ * Create a DSU partition. This call may take 60~90 seconds. The caller
* may use another thread to call the getStartProgress() to get the progress.
- *
* @param name The DSU partition name
* @param size Size of the DSU image in bytes
* @param readOnly True if this partition is readOnly
* @return true if the call succeeds
*/
- boolean startInstallation(@utf8InCpp String name, long size, boolean readOnly);
+ boolean createPartition(@utf8InCpp String name, long size, boolean readOnly);
+
+ /**
+ * Finish a previously started installation. Installations without
+ * a cooresponding finishInstallation() will be cleaned up during device boot.
+ */
+ boolean finishInstallation();
/**
* Query the progress of the current installation operation. This can be called while
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 6280600..aefe843 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -173,6 +173,7 @@
* @return the mount path
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public String getPath() {
return mPath.toString();
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 2f68eb4..f1d90be 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -1862,6 +1862,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String[] SYNC_WRITABLE_COLUMNS = new String[] {
_SYNC_ID,
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 82a3c40..391f3a2 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -43,8 +43,6 @@
import android.text.TextUtils;
import android.util.Log;
-import com.android.internal.telephony.PhoneConstants;
-
import java.util.List;
/**
@@ -610,7 +608,7 @@
* if the contact is unknown.
* @param context the context used to get the ContentResolver
* @param number the phone number to be added to the calls db
- * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
+ * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
* @param callType enumerated values for "incoming", "outgoing", or "missed"
@@ -645,7 +643,7 @@
* @param number the phone number to be added to the calls db
* @param viaNumber the secondary number that the incoming call received with. If the
* call was received with the SIM assigned number, then this field must be ''.
- * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
+ * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
* @param callType enumerated values for "incoming", "outgoing", or "missed"
@@ -686,7 +684,7 @@
* if it was outgoing. Otherwise it is ''.
* @param viaNumber the secondary number that the incoming call received with. If the
* call was received with the SIM assigned number, then this field must be ''.
- * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
+ * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
* @param callType enumerated values for "incoming", "outgoing", or "missed"
@@ -1048,22 +1046,22 @@
/**
* Remap network specified number presentation types
- * PhoneConstants.PRESENTATION_xxx to calllog number presentation types
+ * TelecomManager.PRESENTATION_xxx to calllog number presentation types
* Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
* from any future radio changes.
* If the number field is empty set the presentation type to Unknown.
*/
private static int getLogNumberPresentation(String number, int presentation) {
- if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+ if (presentation == TelecomManager.PRESENTATION_RESTRICTED) {
return presentation;
}
- if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
+ if (presentation == TelecomManager.PRESENTATION_PAYPHONE) {
return presentation;
}
if (TextUtils.isEmpty(number)
- || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
+ || presentation == TelecomManager.PRESENTATION_UNKNOWN) {
return PRESENTATION_UNKNOWN;
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index af3a16c..f10e184 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -126,6 +126,7 @@
* Prefix for column names that are not visible to client apps.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String HIDDEN_COLUMN_PREFIX = "x_";
@@ -6069,6 +6070,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final Uri ENTERPRISE_CONTENT_URI =
Uri.withAppendedPath(Data.ENTERPRISE_CONTENT_URI, "phones");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2263f52..ade0caf 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2048,6 +2048,7 @@
* This is the only type of reset available to non-system clients.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final int RESET_MODE_PACKAGE_DEFAULTS = 1;
@@ -6454,6 +6455,7 @@
* shortcut. Must be its flattened {@link ComponentName}.
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE =
"accessibility_shortcut_target_service";
@@ -6646,6 +6648,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED =
"accessibility_display_magnification_enabled";
@@ -8493,6 +8496,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
@@ -8676,6 +8680,7 @@
* The value is boolean (1 or 0).
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static final String NOTIFICATION_BADGING = "notification_badging";
@@ -11130,25 +11135,26 @@
*/
public static final String MODE_RINGER = "mode_ringer";
- /**
- * Overlay display devices setting.
- * The associated value is a specially formatted string that describes the
- * size and density of simulated secondary display devices.
- * <p>
- * Format: {width}x{height}/{dpi};...
- * </p><p>
- * Example:
- * <ul>
- * <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li>
- * <li><code>1920x1080/320;1280x720/213</code>: make two overlays, the first
- * at 1080p and the second at 720p.</li>
- * <li>If the value is empty, then no overlay display devices are created.</li>
- * </ul></p>
- *
- * @hide
- */
- @TestApi
- public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
+ /**
+ * Overlay display devices setting.
+ * The associated value is a specially formatted string that describes the
+ * size and density of simulated secondary display devices.
+ * <p>
+ * Format: {width}x{height}/{dpi};...
+ * </p><p>
+ * Example:
+ * <ul>
+ * <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li>
+ * <li><code>1920x1080/320;1280x720/213</code>: make two overlays, the first
+ * at 1080p and the second at 720p.</li>
+ * <li>If the value is empty, then no overlay display devices are created.</li>
+ * </ul></p>
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ @TestApi
+ public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
/**
* Threshold values for the duration and level of a discharge cycle,
@@ -11800,6 +11806,7 @@
* @hide
* @see com.android.server.power.batterysaver.BatterySaverPolicy
*/
+ @UnsupportedAppUsage
@TestApi
public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java
index 9184d6d..eefc1b7 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -22,7 +22,7 @@
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
-import android.os.telephony.TelephonyRegistryManager;
+import android.telephony.TelephonyRegistryManager;
import android.util.Log;
/**
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index 12c2580..bc6a9e8 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
@@ -104,6 +105,26 @@
"android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE";
/**
+ * Intent action sent by the LPA to launch a carrier app Activity for eSIM activation, e.g. a
+ * carrier login screen. Carrier apps wishing to support this activation method must implement
+ * an Activity that responds to this intent action. Upon completion, the Activity must return
+ * one of the following results to the LPA:
+ *
+ * <p>{@code Activity.RESULT_CANCELED}: The LPA should treat this as an back button and abort
+ * the activation flow.
+ * <p>{@code Activity.RESULT_OK}: The LPA should try to get an activation code from the carrier
+ * app by binding to the carrier app service implementing
+ * {@link #ACTION_BIND_CARRIER_PROVISIONING_SERVICE}.
+ * <p>{@code Activity.RESULT_OK} with
+ * {@link android.telephony.euicc.EuiccManager#EXTRA_USE_QR_SCANNER} set to true: The LPA should
+ * start a QR scanner for the user to scan an eSIM profile QR code.
+ * <p>For other results: The LPA should treat this as an error.
+ **/
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_START_CARRIER_ACTIVATION =
+ "android.service.euicc.action.START_CARRIER_ACTIVATION";
+
+ /**
* @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS
* The difference is this one is used by system to bring up the LUI.
*/
@@ -138,6 +159,15 @@
public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED =
"android.service.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED";
+ /**
+ * @see android.telephony.euicc.EuiccManager#ACTION_START_EUICC_ACTIVATION. This is
+ * a protected intent that can only be sent by the system, and requires the
+ * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_START_EUICC_ACTIVATION =
+ "android.service.euicc.action.START_EUICC_ACTIVATION";
+
// LUI resolution actions. These are called by the platform to resolve errors in situations that
// require user interaction.
// TODO(b/33075886): Define extras for any input parameters to these dialogs once they are
@@ -516,7 +546,7 @@
* @see android.telephony.euicc.EuiccManager#eraseSubscriptions
*
* @deprecated From R, callers should specify a flag for specific set of subscriptions to erase
- * and use {@link #onEraseSubscriptionsWithOptions(int, int)} instead
+ * and use {@link #onEraseSubscriptions(int, int)} instead
*/
@Deprecated
public abstract int onEraseSubscriptions(int slotId);
@@ -533,7 +563,7 @@
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
* @see android.telephony.euicc.EuiccManager#eraseSubscriptionsWithOptions
*/
- public int onEraseSubscriptionsWithOptions(int slotIndex, @ResetOption int options) {
+ public int onEraseSubscriptions(int slotIndex, @ResetOption int options) {
throw new UnsupportedOperationException(
"This method must be overridden to enable the ResetOption parameter");
}
@@ -779,8 +809,7 @@
mExecutor.execute(new Runnable() {
@Override
public void run() {
- int result = EuiccService.this.onEraseSubscriptionsWithOptions(
- slotIndex, options);
+ int result = EuiccService.this.onEraseSubscriptions(slotIndex, options);
try {
callback.onComplete(result);
} catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
similarity index 99%
rename from telephony/java/android/telephony/PhoneStateListener.java
rename to core/java/android/telephony/PhoneStateListener.java
index e5bfb4d..a65c8fd 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -35,8 +35,8 @@
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IPhoneStateListener;
+import com.android.internal.annotations.VisibleForTesting;
import dalvik.system.VMRuntime;
@@ -184,7 +184,8 @@
public static final int LISTEN_CELL_INFO = 0x00000400;
/**
- * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls.
+ * Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
+ * background and foreground calls.
*
* @hide
*/
diff --git a/telephony/java/android/telephony/Rlog.java b/core/java/android/telephony/Rlog.java
similarity index 100%
rename from telephony/java/android/telephony/Rlog.java
rename to core/java/android/telephony/Rlog.java
diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
similarity index 72%
rename from core/java/android/os/telephony/TelephonyRegistryManager.java
rename to core/java/android/telephony/TelephonyRegistryManager.java
index b674099..5c42730 100644
--- a/core/java/android/os/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -13,21 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.os.telephony;
+package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
+import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.telephony.Annotation;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.PreciseCallStates;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
@@ -35,14 +43,20 @@
import android.telephony.CellInfo;
import android.telephony.DisconnectCause;
import android.telephony.PhoneCapability;
-import android.telephony.PreciseCallState.State;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.ims.ImsReasonInfo;
+import android.util.Log;
+
+import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
+
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
/**
* A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update
@@ -59,9 +73,26 @@
private static final String TAG = "TelephonyRegistryManager";
private static ITelephonyRegistry sRegistry;
+ private final Context mContext;
+
+ /**
+ * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and
+ * its callback IOnSubscriptionsChangedListener.
+ */
+ private final Map<SubscriptionManager.OnSubscriptionsChangedListener,
+ IOnSubscriptionsChangedListener> mSubscriptionChangedListenerMap = new HashMap<>();
+ /**
+ * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and
+ * its callback IOnSubscriptionsChangedListener.
+ */
+ private final Map<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener,
+ IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap
+ = new HashMap<>();
+
/** @hide **/
- public TelephonyRegistryManager() {
+ public TelephonyRegistryManager(@NonNull Context context) {
+ mContext = context;
if (sRegistry == null) {
sRegistry = ITelephonyRegistry.Stub.asInterface(
ServiceManager.getService("telephony.registry"));
@@ -69,6 +100,113 @@
}
/**
+ * Register for changes to the list of active {@link SubscriptionInfo} records or to the
+ * individual records themselves. When a change occurs the onSubscriptionsChanged method of
+ * the listener will be invoked immediately if there has been a notification. The
+ * onSubscriptionChanged method will also be triggered once initially when calling this
+ * function.
+ *
+ * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener}
+ * with onSubscriptionsChanged overridden.
+ * @param executor the executor that will execute callbacks.
+ */
+ public void addOnSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener,
+ @NonNull Executor executor) {
+ IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
+ @Override
+ public void onSubscriptionsChanged () {
+ Log.d(TAG, "onSubscriptionsChangedListener callback received.");
+ executor.execute(() -> listener.onSubscriptionsChanged());
+ }
+ };
+ mSubscriptionChangedListenerMap.put(listener, callback);
+ try {
+ sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not
+ * strictly necessary as the listener will automatically be unregistered if an attempt to
+ * invoke the listener fails.
+ *
+ * @param listener that is to be unregistered.
+ */
+ public void removeOnSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) {
+ if (mSubscriptionChangedListenerMap.get(listener) == null) {
+ return;
+ }
+ try {
+ sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
+ mSubscriptionChangedListenerMap.get(listener));
+ mSubscriptionChangedListenerMap.remove(listener);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Register for changes to the list of opportunistic subscription records or to the
+ * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
+ * method of the listener will be invoked immediately if there has been a notification.
+ *
+ * @param listener an instance of
+ * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with
+ * onOpportunisticSubscriptionsChanged overridden.
+ * @param executor an Executor that will execute callbacks.
+ */
+ public void addOnOpportunisticSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener,
+ @NonNull Executor executor) {
+ /**
+ * The callback methods need to be called on the executor thread where
+ * this object was created. If the binder did that for us it'd be nice.
+ */
+ IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
+ @Override
+ public void onSubscriptionsChanged() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received.");
+ executor.execute(() -> listener.onOpportunisticSubscriptionsChanged());
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ };
+ mOpportunisticSubscriptionChangedListenerMap.put(listener, callback);
+ try {
+ sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(),
+ callback);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener}
+ * that is currently listening opportunistic subscriptions change. This is not strictly
+ * necessary as the listener will automatically be unregistered if an attempt to invoke the
+ * listener fails.
+ *
+ * @param listener that is to be unregistered.
+ */
+ public void removeOnOpportunisticSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) {
+ try {
+ sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
+ mOpportunisticSubscriptionChangedListenerMap.get(listener));
+ mOpportunisticSubscriptionChangedListenerMap.remove(listener);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
* Informs the system of an intentional upcoming carrier network change by a carrier app.
* This call only used to allow the system to provide alternative UI while telephony is
* performing an action that may result in intentional, temporary network lack of connectivity.
@@ -98,14 +236,33 @@
* @param slotIndex for which call state changed. Can be derived from subId except when subId is
* invalid.
* @param state latest call state. e.g, offhook, ringing
- * @param incomingNumer incoming phone number.
+ * @param incomingNumber incoming phone number.
*
* @hide
*/
public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state,
- String incomingNumer) {
+ String incomingNumber) {
try {
- sRegistry.notifyCallState(slotIndex, subId, state, incomingNumer);
+ sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Notify call state changed on all subscriptions.
+ *
+ * @param state latest call state. e.g, offhook, ringing
+ * @param incomingNumber incoming phone number.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public void notifyCallStateChangedForAllSubscriptions(@CallState int state,
+ @Nullable String incomingNumber) {
+ try {
+ sRegistry.notifyCallStateForAllSubs(state, incomingNumber);
} catch (RemoteException ex) {
// system server crash
}
@@ -466,8 +623,10 @@
*
* @hide
*/
- public void notifyPreciseCallState(int subId, int slotIndex, @State int ringCallPreciseState,
- @State int foregroundCallPreciseState, @State int backgroundCallPreciseState) {
+ public void notifyPreciseCallState(int subId, int slotIndex,
+ @PreciseCallStates int ringCallPreciseState,
+ @PreciseCallStates int foregroundCallPreciseState,
+ @PreciseCallStates int backgroundCallPreciseState) {
try {
sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
foregroundCallPreciseState, backgroundCallPreciseState);
@@ -545,4 +704,15 @@
}
}
+ /**
+ * @param activeDataSubId
+ * @hide
+ */
+ public void notifyActiveDataSubIdChanged(int activeDataSubId) {
+ try {
+ sRegistry.notifyActiveDataSubIdChanged(activeDataSubId);
+ } catch (RemoteException ex) {
+
+ }
+ }
}
diff --git a/core/java/android/util/TimingLogger.java b/core/java/android/util/TimingLogger.java
index be442da..5a4a512 100644
--- a/core/java/android/util/TimingLogger.java
+++ b/core/java/android/util/TimingLogger.java
@@ -44,7 +44,14 @@
* D/TAG ( 3459): methodA: 6 ms, work C
* D/TAG ( 3459): methodA: end, 16 ms
* </pre>
+ *
+ * @deprecated Use {@link android.os.Trace}, or
+ * <a href="https://developer.android.com/studio/profile/benchmark">Android Studio</a>. In
+ * general, milliseconds is the wrong granularity for method-level tracing. Rounding errors
+ * can overemphasize cheap operations, or underemphasize repeated operations. This timing
+ * system also does not take CPU scheduling or frequency into account.
*/
+@Deprecated
public class TimingLogger {
/**
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index 05d9167..6b200e1 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -21,6 +21,8 @@
import android.annotation.TestApi;
import android.graphics.Rect;
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
/**
* Represents a contextual mode of the user interface. Action modes can be used to provide
* alternative interaction modes and replace parts of the normal UI until finished.
@@ -279,6 +281,7 @@
* @return true if the UI used to show this action mode can take focus
* @hide Internal use only
*/
+ @UnsupportedAppUsage
@TestApi
public boolean isUiFocusable() {
return true;
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index e95b5ca..28eb79a 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -331,6 +331,7 @@
* @return the requested time between frames, in milliseconds
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public static long getFrameDelay() {
return sFrameDelay;
@@ -413,6 +414,7 @@
* @see #removeCallbacks
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
@@ -432,6 +434,7 @@
* @see #removeCallback
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public void postCallbackDelayed(int callbackType,
Runnable action, Object token, long delayMillis) {
@@ -482,6 +485,7 @@
* @see #postCallbackDelayed
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public void removeCallbacks(int callbackType, Runnable action, Object token) {
if (callbackType < 0 || callbackType > CALLBACK_LAST) {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 86e94f4..833e78f 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2613,6 +2613,7 @@
* @see #getActionButton()
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public final void setActionButton(int button) {
nativeSetActionButton(mNativePtr, button);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1f6c38f..a35eb1e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24700,6 +24700,7 @@
* @param isRoot true if the view belongs to the root namespace, false
* otherwise
*/
+ @UnsupportedAppUsage
@TestApi
public void setIsRootNamespace(boolean isRoot) {
if (isRoot) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2e5a750..450de6d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1686,6 +1686,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
@TestApi
public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 0x00000040;
@@ -1930,6 +1931,7 @@
equals = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
name = "COLOR_SPACE_AGNOSTIC")
})
+ @UnsupportedAppUsage
@TestApi
public int privateFlags;
diff --git a/core/java/com/android/internal/app/DisableCarModeActivity.java b/core/java/com/android/internal/app/DisableCarModeActivity.java
index 7943c61..d44312b 100644
--- a/core/java/com/android/internal/app/DisableCarModeActivity.java
+++ b/core/java/com/android/internal/app/DisableCarModeActivity.java
@@ -33,7 +33,9 @@
try {
IUiModeManager uiModeManager = IUiModeManager.Stub.asInterface(
ServiceManager.getService("uimode"));
- uiModeManager.disableCarMode(UiModeManager.DISABLE_CAR_MODE_GO_HOME);
+ uiModeManager.disableCarModeByCallingPackage(UiModeManager.DISABLE_CAR_MODE_GO_HOME
+ | UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES,
+ getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Failed to disable car mode", e);
}
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index aef4dbf..e3d07aa 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -208,7 +208,7 @@
* @return the maximized Locale instance.
*/
public static Locale addLikelySubtags(Locale locale) {
- return libcore.icu.ICU.addLikelySubtags(locale);
+ return ULocale.addLikelySubtags(ULocale.forLocale(locale)).toLocale();
}
/**
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index c11089b..49f77e1 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -194,7 +194,7 @@
private static Set<String> getSimCountries(Context context) {
Set<String> result = new HashSet<>();
- TelephonyManager tm = TelephonyManager.from(context);
+ TelephonyManager tm = context.getSystemService(TelephonyManager.class);
if (tm != null) {
String iso = tm.getSimCountryIso().toUpperCase(Locale.US);
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 5857642..7dcb12c 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -133,7 +133,7 @@
boolean isChangeEnabledByUid(long changeId, int uid);
/**
- * Add overrides to compatibility changes.
+ * Add overrides to compatibility changes. Kills the app to allow the changes to take effect.
*
* @param overrides Parcelable containing the compat change overrides to be applied.
* @param packageName The package name of the app whose changes will be overridden.
@@ -142,7 +142,28 @@
void setOverrides(in CompatibilityChangeConfig overrides, in String packageName);
/**
- * Revert overrides to compatibility changes.
+ * Add overrides to compatibility changes. Doesn't kill the app, to be only used in tests.
+ *
+ * @param overrides Parcelable containing the compat change overrides to be applied.
+ * @param packageName The package name of the app whose changes will be overridden.
+ *
+ */
+ void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName);
+
+ /**
+ * Removes an override previously added via {@link #setOverrides(CompatibilityChangeConfig,
+ * String)}. This restores the default behaviour for the given change and app, once any app
+ * processes have been restarted.
+ * Kills the app to allow the changes to take effect.
+ *
+ * @param changeId The ID of the change that was overridden.
+ * @param packageName The app package name that was overridden.
+ * @return {@code true} if an override existed;
+ */
+ boolean clearOverride(long changeId, String packageName);
+
+ /**
+ * Revert overrides to compatibility changes. Kills the app to allow the changes to take effect.
*
* @param packageName The package name of the app whose overrides will be cleared.
*
@@ -150,6 +171,15 @@
void clearOverrides(in String packageName);
/**
+ * Revert overrides to compatibility changes. Doesn't kill the app, to be only used in tests.
+ *
+ * @param packageName The package name of the app whose overrides will be cleared.
+ *
+ */
+ void clearOverridesForTest(in String packageName);
+
+
+ /**
* Get configs for an application.
*
* @param appInfo The application whose config will be returned.
diff --git a/core/java/com/android/internal/package-info.java b/core/java/com/android/internal/package-info.java
new file mode 100644
index 0000000..8a226db
--- /dev/null
+++ b/core/java/com/android/internal/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * @hide
+ */
+package com.android.internal;
diff --git a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl
similarity index 100%
rename from telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl
rename to core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
similarity index 99%
rename from telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
rename to core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 90019ee..084a3cc 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -29,6 +29,9 @@
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
+/**
+ * {@hide}
+ */
oneway interface IPhoneStateListener {
void onServiceStateChanged(in ServiceState serviceState);
void onSignalStrengthChanged(int asu);
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
similarity index 100%
rename from telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
rename to core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 486d24c..7b61277 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -87,6 +87,7 @@
"android_text_Hyphenator.cpp",
"android_os_Debug.cpp",
"android_os_GraphicsEnvironment.cpp",
+ "android_os_HidlMemory.cpp",
"android_os_HidlSupport.cpp",
"android_os_HwBinder.cpp",
"android_os_HwBlob.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 9a90555..2383731 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -191,6 +191,7 @@
extern int register_android_os_Trace(JNIEnv* env);
extern int register_android_os_FileObserver(JNIEnv *env);
extern int register_android_os_UEventObserver(JNIEnv* env);
+extern int register_android_os_HidlMemory(JNIEnv* env);
extern int register_android_os_MemoryFile(JNIEnv* env);
extern int register_android_os_SharedMemory(JNIEnv* env);
extern int register_android_net_LocalSocketImpl(JNIEnv* env);
@@ -667,6 +668,8 @@
char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
char dex2oatThreadsBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];
char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];
+ char dex2oatCpuSetBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX];
+ char dex2oatCpuSetImageBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX];
char dex2oat_isa_variant_key[PROPERTY_KEY_MAX];
char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX];
char dex2oat_isa_features_key[PROPERTY_KEY_MAX];
@@ -956,6 +959,10 @@
parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option");
parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j",
"-Ximage-compiler-option");
+ parseCompilerOption("dalvik.vm.dex2oat-cpu-set", dex2oatCpuSetBuf, "--cpu-set=",
+ "-Xcompiler-option");
+ parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=",
+ "-Ximage-compiler-option");
// The runtime will compile a boot image, when necessary, not using installd. Thus, we need to
// pass the instruction-set-features/variant as an image-compiler-option.
@@ -1468,6 +1475,7 @@
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
+ REG_JNI(register_android_os_HidlMemory),
REG_JNI(register_android_os_HidlSupport),
REG_JNI(register_android_os_HwBinder),
REG_JNI(register_android_os_HwBlob),
diff --git a/core/jni/android_os_HidlMemory.cpp b/core/jni/android_os_HidlMemory.cpp
new file mode 100644
index 0000000..69e4818
--- /dev/null
+++ b/core/jni/android_os_HidlMemory.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2019 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 "android_os_HidlMemory.h"
+#include "core_jni_helpers.h"
+#include "android_os_NativeHandle.h"
+
+#define PACKAGE_PATH "android/os"
+#define CLASS_NAME "HidlMemory"
+#define CLASS_PATH PACKAGE_PATH "/" CLASS_NAME
+
+namespace android {
+
+namespace {
+
+static struct {
+ jclass clazz;
+ jfieldID nativeContext; // long
+ jmethodID constructor; // HidlMemory(String, long, NativeHandle)
+ jmethodID getName; // String HidlMemory.getName()
+ jmethodID getSize; // int HidlMemory.getSize()
+ jmethodID getHandle; // NativeHandle HidlMemory.getHandle()
+} gFields;
+
+std::string stringFromJava(JNIEnv* env, jstring jstr) {
+ ScopedUtfChars s(env, jstr);
+ return s.c_str();
+}
+
+jstring stringToJava(JNIEnv* env, const std::string& cstr) {
+ return env->NewStringUTF(cstr.c_str());
+}
+
+static void nativeFinalize(JNIEnv* env, jobject jobj) {
+ jlong jNativeContext = env->GetLongField(jobj, gFields.nativeContext);
+ JHidlMemory* native = reinterpret_cast<JHidlMemory*>(jNativeContext);
+ delete native;
+}
+
+static JNINativeMethod gMethods[] = {
+ {"nativeFinalize", "()V", (void*) nativeFinalize},
+};
+
+} // namespace
+
+JHidlMemory::~JHidlMemory() {
+ if (mObj) {
+ // Must manually delete the underlying handle - hidl_memory doesn't own
+ // it.
+ native_handle_delete(const_cast<native_handle_t*>(mObj->handle()));
+ }
+}
+
+/* static */ const hardware::hidl_memory* JHidlMemory::fromJava(JNIEnv* env,
+ jobject jobj) {
+ // Try to get the result from cache.
+ env->MonitorEnter(jobj);
+ JHidlMemory* obj = getNativeContext(env, jobj);
+ if (!obj->mObj) {
+ // Create and cache.
+ obj->mObj = javaToNative(env, jobj);
+ }
+ env->MonitorExit(jobj);
+ return obj->mObj.get();
+}
+
+/* static */ jobject JHidlMemory::toJava(JNIEnv* env,
+ const hardware::hidl_memory& cobj) {
+ if (cobj.size() > std::numeric_limits<jlong>::max()) {
+ return nullptr;
+ }
+ jstring jname = stringToJava(env, cobj.name());
+ jlong jsize = static_cast<jlong>(cobj.size());
+ jobject jhandle =
+ JNativeHandle::MakeJavaNativeHandleObj(env, cobj.handle());
+
+ // We're sharing the handle of cobj, so the Java instance doesn't own it.
+ return env->NewObject(gFields.clazz,
+ gFields.constructor,
+ jname,
+ jsize,
+ jhandle,
+ false);
+}
+
+/* static */ std::unique_ptr<hardware::hidl_memory> JHidlMemory::javaToNative(
+ JNIEnv* env,
+ jobject jobj) {
+ jstring jname =
+ static_cast<jstring>(env->CallObjectMethod(jobj, gFields.getName));
+ jlong jsize = env->CallLongMethod(jobj, gFields.getSize);
+ jobject jhandle = env->CallObjectMethod(jobj, gFields.getHandle);
+
+ if (jsize > std::numeric_limits<size_t>::max()) {
+ return nullptr;
+ }
+
+ std::string cname = stringFromJava(env, jname);
+ size_t csize = jsize;
+ // We created the handle here, we're responsible to call
+ // native_handle_delete() on it. However, we don't assume ownership of the
+ // underlying fd, so we shouldn't call native_handle_close() on it.
+ native_handle_t* chandle = JNativeHandle::MakeCppNativeHandle(env, jhandle,
+ nullptr);
+ // hidl_memory doesn't take ownership of the handle here, so won't delete
+ // or close it.
+ return std::make_unique<hardware::hidl_memory>(cname, chandle, csize);
+}
+
+/* static */ JHidlMemory* JHidlMemory::getNativeContext(JNIEnv* env,
+ jobject jobj) {
+ env->MonitorEnter(jobj);
+ jlong jNativeContext = env->GetLongField(jobj, gFields.nativeContext);
+ JHidlMemory* native = reinterpret_cast<JHidlMemory*>(jNativeContext);
+ if (!native) {
+ native = new JHidlMemory();
+ env->SetLongField(jobj,
+ gFields.nativeContext,
+ reinterpret_cast<jlong>(native));
+ }
+ env->MonitorExit(jobj);
+ return native;
+}
+
+int register_android_os_HidlMemory(JNIEnv* env) {
+ jclass clazz = FindClassOrDie(env, CLASS_PATH);
+ gFields.clazz = MakeGlobalRefOrDie(env, clazz);
+
+ gFields.nativeContext = GetFieldIDOrDie(env, clazz, "mNativeContext", "J");
+
+ gFields.constructor = GetMethodIDOrDie(env,
+ clazz,
+ "<init>",
+ "(Ljava/lang/String;JL" PACKAGE_PATH "/NativeHandle;)V");
+ gFields.getName =
+ GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
+ gFields.getSize = GetMethodIDOrDie(env, clazz, "getSize", "()J");
+ gFields.getHandle = GetMethodIDOrDie(env,
+ clazz,
+ "getHandle",
+ "()L" PACKAGE_PATH "/NativeHandle;");
+
+ RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
+
+ return 0;
+}
+
+} // namespace android
+
diff --git a/core/jni/android_os_HidlMemory.h b/core/jni/android_os_HidlMemory.h
new file mode 100644
index 0000000..993a132
--- /dev/null
+++ b/core/jni/android_os_HidlMemory.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef ANDROID_OS_HIDL_MEMORY_H
+#define ANDROID_OS_HIDL_MEMORY_H
+
+#include <jni.h>
+#include <hidl/HidlSupport.h>
+
+namespace android {
+
+// A utility class for handling the android.os.HidlMemory class from JNI code.
+class JHidlMemory final {
+ public:
+ // Convert an android.os.HidlMemory object to its C++ counterpart,
+ // hardware::hidl_memory.
+ // No duplication of file descriptors is performed.
+ // The returned reference is owned by the underlying Java object.
+ // Returns nullptr if conversion cannot be done.
+ static const hardware::hidl_memory* fromJava(JNIEnv* env,
+ jobject jobj);
+
+ // Convert a hardware::hidl_memory object to its Java counterpart,
+ // android.os.HidlMemory.
+ // No duplication of file descriptors is performed.
+ // Returns nullptr if conversion cannot be done.
+ static jobject toJava(JNIEnv* env,
+ const hardware::hidl_memory& cobj);
+
+ ~JHidlMemory();
+
+ private:
+ // We store an instance of type JHidlMemory attached to every Java object
+ // of type HidlMemory, for holding any native context we need. This instance
+ // will get deleted when finalize() is called on the Java object.
+ // This method either extracts the native object from the Java object, or
+ // attached a new one if it doesn't yet exist.
+ static JHidlMemory* getNativeContext(JNIEnv* env, jobject obj);
+
+ // Convert an android.os.HidlMemory object to its C++ counterpart,
+ // hardware::hidl_memory.
+ // No duplication of file descriptors is performed.
+ // IMPORTANT: caller is responsible to native_handle_delete() the handle of the
+ // returned object. This is due to an underlying limitation of the hidl_handle
+ // type, where ownership of the handle implies ownership of the fd and we don't
+ // want the latter.
+ // Returns nullptr if conversion cannot be done.
+ static std::unique_ptr<hardware::hidl_memory> javaToNative(JNIEnv* env,
+ jobject jobj);
+
+ std::unique_ptr<hardware::hidl_memory> mObj;
+};
+
+int register_android_os_HidlMemory(JNIEnv* env);
+
+} // namespace android
+
+#endif //ANDROID_OS_HIDL_MEMORY_H
diff --git a/core/jni/android_os_HwBlob.cpp b/core/jni/android_os_HwBlob.cpp
index e5b72ca..0fb2911 100644
--- a/core/jni/android_os_HwBlob.cpp
+++ b/core/jni/android_os_HwBlob.cpp
@@ -340,6 +340,14 @@
return env->NewStringUTF(s->c_str());
}
+static jlong JHwBlob_native_getFieldHandle(JNIEnv* env,
+ jobject thiz,
+ jlong offset) {
+ sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
+
+ return reinterpret_cast<jlong>(blob->data()) + offset;
+}
+
#define DEFINE_BLOB_ARRAY_COPIER(Suffix,Type,NewType) \
static void JHwBlob_native_copyTo ## Suffix ## Array( \
JNIEnv *env, \
@@ -593,6 +601,7 @@
{ "getFloat", "(J)F", (void *)JHwBlob_native_getFloat },
{ "getDouble", "(J)D", (void *)JHwBlob_native_getDouble },
{ "getString", "(J)Ljava/lang/String;", (void *)JHwBlob_native_getString },
+ { "getFieldHandle", "(J)J", (void*) JHwBlob_native_getFieldHandle},
{ "copyToBoolArray", "(J[ZI)V", (void *)JHwBlob_native_copyToBoolArray },
{ "copyToInt8Array", "(J[BI)V", (void *)JHwBlob_native_copyToInt8Array },
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index f437a78..151dbfc 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -20,6 +20,7 @@
#include "android_os_HwParcel.h"
+#include "android_os_HidlMemory.h"
#include "android_os_HwBinder.h"
#include "android_os_HwBlob.h"
#include "android_os_NativeHandle.h"
@@ -27,6 +28,8 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <hidl/HidlBinderSupport.h>
+#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/Status.h>
#include <nativehelper/ScopedLocalRef.h>
@@ -650,6 +653,36 @@
signalExceptionForError(env, err);
}
+static void JHwParcel_native_writeHidlMemory(
+ JNIEnv *env, jobject thiz, jobject jmem) {
+
+ if (jmem == nullptr) {
+ jniThrowException(env, "java/lang/NullPointerException", nullptr);
+ return;
+ }
+
+ status_t err = OK;
+
+ // Convert the Java object to its C++ counterpart.
+ const hardware::hidl_memory* cmem = JHidlMemory::fromJava(env, jmem);
+ if (cmem == nullptr) {
+ err = BAD_VALUE;
+ }
+
+ if (err == OK) {
+ // Write it to the parcel.
+ hardware::Parcel* parcel =
+ JHwParcel::GetNativeContext(env, thiz)->getParcel();
+
+ size_t parentHandle;
+ err = parcel->writeBuffer(cmem, sizeof(*cmem), &parentHandle);
+ if (err == OK) {
+ err = hardware::writeEmbeddedToParcel(*cmem, parcel, parentHandle, 0);
+ }
+ }
+ signalExceptionForError(env, err);
+}
+
static jstring MakeStringObjFromHidlString(JNIEnv *env, const hidl_string &s) {
String16 utf16String(s.c_str(), s.size());
@@ -877,6 +910,74 @@
return objArray;
}
+static status_t readEmbeddedHidlMemory(JNIEnv* env,
+ hardware::Parcel* parcel,
+ const hardware::hidl_memory& mem,
+ size_t parentHandle,
+ size_t parentOffset,
+ jobject* result) {
+ status_t err = hardware::readEmbeddedFromParcel(mem,
+ *parcel,
+ parentHandle,
+ parentOffset);
+ if (err == OK) {
+ // Convert to Java.
+ *result = JHidlMemory::toJava(env, mem);
+ if (*result == nullptr) {
+ err = BAD_VALUE;
+ }
+ }
+ return err;
+}
+
+static jobject JHwParcel_native_readHidlMemory(
+ JNIEnv* env, jobject thiz) {
+ hardware::Parcel* parcel =
+ JHwParcel::GetNativeContext(env, thiz)->getParcel();
+
+ jobject result = nullptr;
+
+ const hardware::hidl_memory* mem;
+ size_t parentHandle;
+
+ status_t err = parcel->readBuffer(sizeof(*mem),
+ &parentHandle,
+ reinterpret_cast<const void**>(&mem));
+ if (err == OK) {
+ err = readEmbeddedHidlMemory(env,
+ parcel,
+ *mem,
+ parentHandle,
+ 0,
+ &result);
+ }
+
+ signalExceptionForError(env, err);
+ return result;
+}
+
+static jobject JHwParcel_native_readEmbeddedHidlMemory(
+ JNIEnv* env,
+ jobject thiz,
+ jlong fieldHandle,
+ jlong parentHandle,
+ jlong offset) {
+ hardware::Parcel* parcel =
+ JHwParcel::GetNativeContext(env, thiz)->getParcel();
+
+ jobject result = nullptr;
+ const hardware::hidl_memory* mem =
+ reinterpret_cast<const hardware::hidl_memory*>(fieldHandle);
+ status_t err = readEmbeddedHidlMemory(env,
+ parcel,
+ *mem,
+ parentHandle,
+ offset,
+ &result);
+ signalExceptionForError(env, err);
+ return result;
+}
+
static jobject JHwParcel_native_readStrongBinder(JNIEnv *env, jobject thiz) {
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
@@ -1075,6 +1176,14 @@
{ "release", "()V",
(void *)JHwParcel_native_release },
+ {"writeHidlMemory", "(L" PACKAGE_PATH "/HidlMemory;)V",
+ (void*) JHwParcel_native_writeHidlMemory},
+
+ {"readHidlMemory", "()L" PACKAGE_PATH "/HidlMemory;",
+ (void*) JHwParcel_native_readHidlMemory},
+
+ {"readEmbeddedHidlMemory", "(JJJ)L" PACKAGE_PATH "/HidlMemory;",
+ (void*) JHwParcel_native_readEmbeddedHidlMemory},
};
namespace android {
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 87f498a..7f3b32e 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -17,9 +17,13 @@
#define LOG_TAG "SysPropJNI"
+#include <utility>
+#include <optional>
+
#include "android-base/logging.h"
+#include "android-base/parsebool.h"
+#include "android-base/parseint.h"
#include "android-base/properties.h"
-#include "cutils/properties.h"
#include "utils/misc.h"
#include <utils/Log.h>
#include "jni.h"
@@ -28,86 +32,171 @@
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
-namespace android
-{
+#if defined(__BIONIC__)
+# include <sys/system_properties.h>
+#else
+struct prop_info;
+#endif
+namespace android {
namespace {
-template <typename T, typename Handler>
-T ConvertKeyAndForward(JNIEnv *env, jstring keyJ, T defJ, Handler handler) {
- std::string key;
- {
- // Scope the String access. If the handler can throw an exception,
- // releasing the string characters late would trigger an abort.
- ScopedUtfChars key_utf(env, keyJ);
- if (key_utf.c_str() == nullptr) {
- return defJ;
- }
- key = key_utf.c_str(); // This will make a copy, but we can't avoid
- // with the existing interface in
- // android::base.
- }
- return handler(key, defJ);
+using android::base::ParseBoolResult;
+
+template<typename Functor>
+void ReadProperty(const prop_info* prop, Functor&& functor)
+{
+#if defined(__BIONIC__)
+ auto thunk = [](void* cookie,
+ const char* /*name*/,
+ const char* value,
+ uint32_t /*serial*/) {
+ std::forward<Functor>(*static_cast<Functor*>(cookie))(value);
+ };
+ __system_property_read_callback(prop, thunk, &functor);
+#else
+ LOG(FATAL) << "fast property access supported only on device";
+#endif
}
-jstring SystemProperties_getSS(JNIEnv *env, jclass clazz, jstring keyJ,
+template<typename Functor>
+void ReadProperty(JNIEnv* env, jstring keyJ, Functor&& functor)
+{
+ ScopedUtfChars key(env, keyJ);
+ if (!key.c_str()) {
+ return;
+ }
+#if defined(__BIONIC__)
+ const prop_info* prop = __system_property_find(key.c_str());
+ if (!prop) {
+ return;
+ }
+ ReadProperty(prop, std::forward<Functor>(functor));
+#else
+ std::forward<Functor>(functor)(
+ android::base::GetProperty(key.c_str(), "").c_str());
+#endif
+}
+
+jstring SystemProperties_getSS(JNIEnv* env, jclass clazz, jstring keyJ,
jstring defJ)
{
- // Using ConvertKeyAndForward is sub-optimal for copying the key string,
- // but improves reuse and reasoning over code.
- auto handler = [&](const std::string& key, jstring defJ) {
- std::string prop_val = android::base::GetProperty(key, "");
- if (!prop_val.empty()) {
- return env->NewStringUTF(prop_val.c_str());
- };
- if (defJ != nullptr) {
- return defJ;
+ jstring ret = defJ;
+ ReadProperty(env, keyJ, [&](const char* value) {
+ if (value[0]) {
+ ret = env->NewStringUTF(value);
}
- // This function is specified to never return null (or have an
- // exception pending).
- return env->NewStringUTF("");
- };
- return ConvertKeyAndForward(env, keyJ, defJ, handler);
-}
-
-jstring SystemProperties_getS(JNIEnv *env, jclass clazz, jstring keyJ)
-{
- return SystemProperties_getSS(env, clazz, keyJ, nullptr);
+ });
+ if (ret == nullptr && !env->ExceptionCheck()) {
+ ret = env->NewStringUTF(""); // Legacy behavior
+ }
+ return ret;
}
template <typename T>
T SystemProperties_get_integral(JNIEnv *env, jclass, jstring keyJ,
T defJ)
{
- auto handler = [](const std::string& key, T defV) {
- return android::base::GetIntProperty<T>(key, defV);
- };
- return ConvertKeyAndForward(env, keyJ, defJ, handler);
+ T ret = defJ;
+ ReadProperty(env, keyJ, [&](const char* value) {
+ android::base::ParseInt<T>(value, &ret);
+ });
+ return ret;
+}
+
+static jboolean jbooleanFromParseBoolResult(ParseBoolResult parseResult, jboolean defJ) {
+ jboolean ret;
+ switch (parseResult) {
+ case ParseBoolResult::kError:
+ ret = defJ;
+ break;
+ case ParseBoolResult::kFalse:
+ ret = JNI_FALSE;
+ break;
+ case ParseBoolResult::kTrue:
+ ret = JNI_TRUE;
+ break;
+ }
+ return ret;
}
jboolean SystemProperties_get_boolean(JNIEnv *env, jclass, jstring keyJ,
jboolean defJ)
{
- auto handler = [](const std::string& key, jboolean defV) -> jboolean {
- bool result = android::base::GetBoolProperty(key, defV);
- return result ? JNI_TRUE : JNI_FALSE;
- };
- return ConvertKeyAndForward(env, keyJ, defJ, handler);
+ ParseBoolResult parseResult = ParseBoolResult::kError;
+ ReadProperty(env, keyJ, [&](const char* value) {
+ parseResult = android::base::ParseBool(value);
+ });
+ return jbooleanFromParseBoolResult(parseResult, defJ);
+}
+
+jlong SystemProperties_find(JNIEnv* env, jclass, jstring keyJ)
+{
+#if defined(__BIONIC__)
+ ScopedUtfChars key(env, keyJ);
+ if (!key.c_str()) {
+ return 0;
+ }
+ const prop_info* prop = __system_property_find(key.c_str());
+ return reinterpret_cast<jlong>(prop);
+#else
+ LOG(FATAL) << "fast property access supported only on device";
+ __builtin_unreachable(); // Silence warning
+#endif
+}
+
+jstring SystemProperties_getH(JNIEnv* env, jclass clazz, jlong propJ)
+{
+ jstring ret;
+ auto prop = reinterpret_cast<const prop_info*>(propJ);
+ ReadProperty(prop, [&](const char* value) {
+ ret = env->NewStringUTF(value);
+ });
+ return ret;
+}
+
+template <typename T>
+T SystemProperties_get_integralH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, T defJ)
+{
+ T ret = defJ;
+ auto prop = reinterpret_cast<const prop_info*>(propJ);
+ ReadProperty(prop, [&](const char* value) {
+ android::base::ParseInt<T>(value, &ret);
+ });
+ return ret;
+}
+
+jboolean SystemProperties_get_booleanH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, jboolean defJ)
+{
+ ParseBoolResult parseResult = ParseBoolResult::kError;
+ auto prop = reinterpret_cast<const prop_info*>(propJ);
+ ReadProperty(prop, [&](const char* value) {
+ parseResult = android::base::ParseBool(value);
+ });
+ return jbooleanFromParseBoolResult(parseResult, defJ);
}
void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ,
jstring valJ)
{
- auto handler = [&](const std::string& key, bool) {
- std::string val;
- if (valJ != nullptr) {
- ScopedUtfChars key_utf(env, valJ);
- val = key_utf.c_str();
+ ScopedUtfChars key(env, keyJ);
+ if (!key.c_str()) {
+ return;
+ }
+ std::optional<ScopedUtfChars> value;
+ if (valJ != nullptr) {
+ value.emplace(env, valJ);
+ if (!value->c_str()) {
+ return;
}
- return android::base::SetProperty(key, val);
- };
- if (!ConvertKeyAndForward(env, keyJ, true, handler)) {
- // Must have been a failure in SetProperty.
+ }
+ bool success;
+#if defined(__BIONIC__)
+ success = !__system_property_set(key.c_str(), value ? value->c_str() : "");
+#else
+ success = android::base::SetProperty(key.c_str(), value ? value->c_str() : "");
+#endif
+ if (!success) {
jniThrowException(env, "java/lang/RuntimeException",
"failed to set system property (check logcat for reason)");
}
@@ -157,8 +246,6 @@
int register_android_os_SystemProperties(JNIEnv *env)
{
const JNINativeMethod method_table[] = {
- { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
- (void*) SystemProperties_getS },
{ "native_get",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
(void*) SystemProperties_getSS },
@@ -168,6 +255,18 @@
(void*) SystemProperties_get_integral<jlong> },
{ "native_get_boolean", "(Ljava/lang/String;Z)Z",
(void*) SystemProperties_get_boolean },
+ { "native_find",
+ "(Ljava/lang/String;)J",
+ (void*) SystemProperties_find },
+ { "native_get",
+ "(J)Ljava/lang/String;",
+ (void*) SystemProperties_getH },
+ { "native_get_int", "(JI)I",
+ (void*) SystemProperties_get_integralH<jint> },
+ { "native_get_long", "(JJ)J",
+ (void*) SystemProperties_get_integralH<jlong> },
+ { "native_get_boolean", "(JZ)Z",
+ (void*) SystemProperties_get_booleanH },
{ "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SystemProperties_set },
{ "native_add_change_callback", "()V",
@@ -179,4 +278,4 @@
method_table, NELEM(method_table));
}
-};
+} // namespace android
diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h
index 16ef753..f03f427 100644
--- a/core/jni/core_jni_helpers.h
+++ b/core/jni/core_jni_helpers.h
@@ -22,6 +22,18 @@
#include <nativehelper/scoped_utf_chars.h>
#include <android_runtime/AndroidRuntime.h>
+// Host targets (layoutlib) do not differentiate between regular and critical native methods,
+// and they need all the JNI methods to have JNIEnv* and jclass/jobject as their first two arguments.
+// The following macro allows to have those arguments when compiling for host while omitting them when
+// compiling for Android.
+#ifdef __ANDROID__
+#define CRITICAL_JNI_PARAMS
+#define CRITICAL_JNI_PARAMS_COMMA
+#else
+#define CRITICAL_JNI_PARAMS JNIEnv*, jclass
+#define CRITICAL_JNI_PARAMS_COMMA JNIEnv*, jclass,
+#endif
+
namespace android {
// Defines some helpful functions.
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 3704ccd..8fabb23 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -34,6 +34,7 @@
// Static whitelist of open paths that the zygote is allowed to keep open.
static const char* kPathWhitelist[] = {
"/apex/com.android.conscrypt/javalib/conscrypt.jar",
+ "/apex/com.android.ipsec/javalib/ike.jar",
"/apex/com.android.media/javalib/updatable-media.jar",
"/dev/null",
"/dev/socket/zygote",
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index c023438..6bf4c43 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2401,4 +2401,11 @@
// OS: Q
// Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
+
+ // ---- End Q Constants, all Q constants go above this line ----
+
+ // OPEN: Settings > Developer Options > Platform Compat
+ // CATEGORY: SETTINGS
+ // OS: R
+ SETTINGS_PLATFORM_COMPAT_DASHBOARD = 1805;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1f20d7a..216b87f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -108,6 +108,8 @@
<protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" />
<protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" />
+ <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE_PRIVILEGED" />
+ <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE_PRIVILEGED" />
<protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" />
<protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" />
<protected-broadcast android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" />
@@ -142,7 +144,7 @@
<protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.UUID" />
<protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
- <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.action.ALIAS_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
<protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" />
@@ -1626,7 +1628,7 @@
@hide This should only be used by Settings and SystemUI.
-->
<permission android:name="android.permission.NETWORK_SETTINGS"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- Allows SetupWizard to call methods in Networking services
<p>Not for use by any other third-party or privileged applications.
@@ -2146,12 +2148,12 @@
<!-- Must be required by a telephony data service to ensure that only the
system can bind to it.
- <p>Protection level: signature
+ <p>Protection level: signature|telephony
@SystemApi
@hide
-->
<permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- Must be required by a NetworkService to ensure that only the
system can bind to it.
@@ -2172,11 +2174,11 @@
<!-- @SystemApi Must be required by an EuiccService to ensure that only the system can bind to
it.
- <p>Protection level: signature
+ <p>Protection level: signature|telephony
@hide
-->
<permission android:name="android.permission.BIND_EUICC_SERVICE"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- ================================== -->
<!-- Permissions for sdcard interaction -->
@@ -2956,7 +2958,7 @@
@hide
-->
<permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- @SystemApi Allows an application to use
{@link android.view.WindowManager.LayoutsParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
@@ -3736,7 +3738,7 @@
@hide
-->
<permission android:name="android.permission.DEVICE_POWER"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- Allows toggling battery saver on the system.
Superseded by DEVICE_POWER permission. @hide @SystemApi
@@ -3771,13 +3773,13 @@
<p>Not for use by third-party applications.
-->
<permission android:name="android.permission.BROADCAST_SMS"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- Allows an application to broadcast a WAP PUSH receipt notification.
<p>Not for use by third-party applications.
-->
<permission android:name="android.permission.BROADCAST_WAP_PUSH"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- @SystemApi Allows an application to broadcast privileged networking requests.
<p>Not for use by third-party applications.
@@ -4339,6 +4341,21 @@
it will be ignored.
@hide -->
<permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"
+ android:protectionLevel="signature|privileged" />
+
+ <!-- @SystemApi Allows entering or exiting car mode using a specified priority.
+ This permission is required to use UiModeManager while specifying a priority for the calling
+ app. A device manufacturer uses this permission to prioritize the apps which can
+ potentially request to enter car-mode on a device to help establish the correct behavior
+ where multiple such apps are active at the same time.
+ @hide -->
+ <permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"
+ android:protectionLevel="signature|privileged" />
+
+ <!-- @SystemApi Required to receive ACTION_ENTER_CAR_MODE_PRIVILEGED or
+ ACTION_EXIT_CAR_MODE_PRIVILEGED.
+ @hide -->
+ <permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES"
android:protectionLevel="signature|privileged" />
<!-- The system process is explicitly the only one allowed to launch the
@@ -4392,13 +4409,13 @@
{@link android.provider.BlockedNumberContract}.
@hide -->
<permission android:name="android.permission.READ_BLOCKED_NUMBERS"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- Allows the holder to write blocked numbers. See
{@link android.provider.BlockedNumberContract}.
@hide -->
<permission android:name="android.permission.WRITE_BLOCKED_NUMBERS"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|telephony" />
<!-- Must be required by an {@link android.service.vr.VrListenerService}, to ensure that only
the system can bind to it.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 77fca8f..17045d8 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -295,6 +295,9 @@
<!-- Additional flag from base permission type: this permission can be automatically
granted to the system app predictor -->
<flag name="appPredictor" value="0x200000" />
+ <!-- Additional flag from base permission type: this permission can be automatically
+ granted to the system telephony apps -->
+ <flag name="telephony" value="0x400000" />
</attr>
<!-- Flags indicating more context for a permission group. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6c0fe46..4b4baa9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -529,7 +529,7 @@
- TYPE_ETHERNET (9) is prepended to this list, and
- - the return value of TelephonyManager.isTetherApnRequired()
+ - the return value of TelephonyManager.isTetheringApnRequired()
determines how the array is further modified:
* TRUE (DUN REQUIRED).
@@ -3677,6 +3677,15 @@
-->
<string name="config_defaultWellbeingPackage" translatable="false"></string>
+
+ <!-- The package name for the system telephony apps.
+ This package must be trusted, as it will be granted with permissions with special telephony
+ protection level. Note, framework by default support multiple telephony apps, each package
+ name is separated by comma.
+ Example: "com.android.phone,com.android.stk,com.android.providers.telephony"
+ -->
+ <string name="config_telephonyPackages" translatable="false">"com.android.phone,com.android.stk,com.android.providers.telephony,com.android.ons"</string>
+
<!-- The component name for the default system attention service.
This service must be trusted, as it can be activated without explicit consent of the user.
See android.attention.AttentionManagerService.
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6efa2d6..e729b03 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3056,9 +3056,9 @@
<string name="ok">OK</string>
<!-- Preference framework strings. -->
<string name="cancel">Cancel</string>
- <!-- Preference framework strings. -->
+ <!-- Preference framework strings. {@deprecated Do not use. Incorrectly matches android.R.string.ok rather than "yes".} -->
<string name="yes">OK</string>
- <!-- Preference framework strings. -->
+ <!-- Preference framework strings. {@deprecated Do not use. Incorrectly matches android.R.string.cancel rather than "no".} -->
<string name="no">Cancel</string>
<!-- This is the generic "attention" string to be used in attention dialogs. Typically
combined with setIconAttribute(android.R.attr.alertDialogIcon)
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0804703..e8cd271 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3464,6 +3464,7 @@
<java-symbol type="string" name="config_defaultAutofillService" />
<java-symbol type="string" name="config_defaultTextClassifierPackage" />
<java-symbol type="string" name="config_defaultWellbeingPackage" />
+ <java-symbol type="string" name="config_telephonyPackages" />
<java-symbol type="string" name="config_defaultContentCaptureService" />
<java-symbol type="string" name="config_defaultAugmentedAutofillService" />
<java-symbol type="string" name="config_defaultAppPredictionService" />
diff --git a/core/tests/coretests/src/android/net/NetworkKeyTest.java b/core/tests/coretests/src/android/net/NetworkKeyTest.java
index 0f1c71d..c6c0b46 100644
--- a/core/tests/coretests/src/android/net/NetworkKeyTest.java
+++ b/core/tests/coretests/src/android/net/NetworkKeyTest.java
@@ -22,7 +22,7 @@
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiManager;
import androidx.test.runner.AndroidJUnit4;
@@ -65,7 +65,7 @@
@Test
public void createFromWifi_noneSsid() throws Exception {
- when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE);
+ when(mWifiInfo.getSSID()).thenReturn(WifiManager.UNKNOWN_SSID);
when(mWifiInfo.getBSSID()).thenReturn(VALID_BSSID);
assertNull(NetworkKey.createFromWifiInfo(mWifiInfo));
}
@@ -106,7 +106,7 @@
}
@Test
- public void createFromScanResult_nullWifiSsid() {
+ public void createFromScanResult_nullSsid() {
ScanResult scanResult = new ScanResult();
scanResult.BSSID = VALID_BSSID;
@@ -114,18 +114,18 @@
}
@Test
- public void createFromScanResult_emptyWifiSsid() {
+ public void createFromScanResult_emptySsid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded("");
+ scanResult.SSID = "";
scanResult.BSSID = VALID_BSSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
}
@Test
- public void createFromScanResult_noneWifiSsid() {
+ public void createFromScanResult_noneSsid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(WifiSsid.NONE);
+ scanResult.SSID = WifiManager.UNKNOWN_SSID;
scanResult.BSSID = VALID_BSSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
@@ -134,7 +134,7 @@
@Test
public void createFromScanResult_nullBssid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
}
@@ -142,7 +142,7 @@
@Test
public void createFromScanResult_emptyBssid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
scanResult.BSSID = "";
assertNull(NetworkKey.createFromScanResult(scanResult));
@@ -151,16 +151,16 @@
@Test
public void createFromScanResult_invalidBssid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
scanResult.BSSID = INVALID_BSSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
}
@Test
- public void createFromScanResult_validWifiSsid() {
+ public void createFromScanResult_validSsid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
scanResult.BSSID = VALID_BSSID;
NetworkKey expected = new NetworkKey(new WifiKey(VALID_SSID, VALID_BSSID));
diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 928351e..b48ac33 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -93,6 +93,27 @@
}
@SmallTest
+ private static void testHandle() throws Exception {
+ String value;
+ SystemProperties.Handle handle = SystemProperties.find("doesnotexist_2341431");
+ assertNull(handle);
+ SystemProperties.set(KEY, "abc");
+ handle = SystemProperties.find(KEY);
+ assertNotNull(handle);
+ value = handle.get();
+ assertEquals("abc", value);
+ SystemProperties.set(KEY, "blarg");
+ value = handle.get();
+ assertEquals("blarg", value);
+ SystemProperties.set(KEY, "1");
+ assertEquals(1, handle.getInt(-1));
+ assertEquals(1, handle.getLong(-1));
+ assertEquals(true, handle.getBoolean(false));
+ SystemProperties.set(KEY, "");
+ assertEquals(12345, handle.getInt(12345));
+ }
+
+ @SmallTest
public void testIntegralProperties() throws Exception {
testInt("", 123, 123);
testInt("", 0, 0);
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 80f3cc6..9064abf 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -238,6 +238,7 @@
<permission name="android.permission.BIND_CONNECTION_SERVICE"/>
<permission name="android.permission.BIND_INCALL_SERVICE"/>
<permission name="android.permission.CALL_PRIVILEGED"/>
+ <permission name="android.permission.HANDLE_CAR_MODE_CHANGES"/>
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MANAGE_ROLE_HOLDERS"/>
@@ -328,6 +329,8 @@
<permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
<!-- Permission required to test ExplicitHealthCheckServiceImpl. -->
<permission name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"/>
+ <!-- Permission required for UiModeManager cts test. -->
+ <permission name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/data/sounds/AudioPackage11.mk b/data/sounds/AudioPackage11.mk
index 99dfd0a..2392b33 100644
--- a/data/sounds/AudioPackage11.mk
+++ b/data/sounds/AudioPackage11.mk
@@ -32,7 +32,7 @@
$(LOCAL_PATH)/effects/ogg/Lock_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \
$(LOCAL_PATH)/effects/ogg/Unlock_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \
$(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \
- $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/ChargingStarted.ogg \.
+ $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/ChargingStarted.ogg \
$(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/InCallNotification.ogg \
$(LOCAL_PATH)/effects/material/ogg/WirelessChargingStarted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/WirelessChargingStarted.ogg \
$(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 646aa13..c0a0422 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -348,16 +348,6 @@
return list(prefix, UID_SELF);
}
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public boolean reset() {
- try {
- return mBinder.reset() == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
/**
* Attempt to lock the keystore for {@code user}.
*
@@ -922,15 +912,26 @@
}
}
- public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature,
- byte[] entropy) {
+ /**
+ * Android KeyStore finish operation.
+ *
+ * @param token Authentication token.
+ * @param arguments Keymaster arguments
+ * @param input Optional additional input data.
+ * @param signature Optional signature to be verified.
+ * @param entropy Optional additional entropy
+ * @return OperationResult that will indicate success or error of the operation.
+ */
+ public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] input,
+ byte[] signature, byte[] entropy) {
OperationPromise promise = new OperationPromise();
try {
mBinder.asBinder().linkToDeath(promise, 0);
arguments = arguments != null ? arguments : new KeymasterArguments();
entropy = entropy != null ? entropy : new byte[0];
+ input = input != null ? input : new byte[0];
signature = signature != null ? signature : new byte[0];
- int errorCode = mBinder.finish(promise, token, arguments, signature, entropy);
+ int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy);
if (errorCode == NO_ERROR) {
return promise.getFuture().get();
} else {
@@ -948,7 +949,7 @@
}
public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) {
- return finish(token, arguments, signature, null);
+ return finish(token, arguments, null, signature, null);
}
private class KeystoreResultPromise
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
index 441ee66..c6515ef 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
@@ -432,7 +432,7 @@
}
@Override
- public OperationResult finish(byte[] signature, byte[] additionalEntropy) {
+ public OperationResult finish(byte[] input, byte[] signature, byte[] additionalEntropy) {
if ((additionalEntropy != null) && (additionalEntropy.length > 0)) {
throw new ProviderException("AAD stream does not support additional entropy");
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 3dc884e..17aacb9 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -210,13 +210,9 @@
}
}
if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
- if (mKeySizeBits < 64) {
+ if (mKeySizeBits < 64 || mKeySizeBits > 512) {
throw new InvalidAlgorithmParameterException(
- "HMAC key size must be at least 64 bits.");
- }
- if (mKeySizeBits > 512 && spec.isStrongBoxBacked()) {
- throw new InvalidAlgorithmParameterException(
- "StrongBox HMAC key size must be smaller than 512 bits.");
+ "HMAC key sizes must be within 64-512 bits, inclusive.");
}
// JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index bd6ce7e..e3f43ef 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -1256,6 +1256,7 @@
*
* Sets whether to include a temporary unique ID field in the attestation certificate.
*/
+ @UnsupportedAppUsage
@TestApi
@NonNull
public Builder setUniqueIdIncluded(boolean uniqueIdIncluded) {
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
index e030478..75bea26 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -62,7 +62,7 @@
* Returns the result of the KeyStore {@code finish} operation or null if keystore couldn't
* be reached.
*/
- OperationResult finish(byte[] siganture, byte[] additionalEntropy);
+ OperationResult finish(byte[] input, byte[] siganture, byte[] additionalEntropy);
}
// Binder buffer is about 1MB, but it's shared between all active transactions of the process.
@@ -217,7 +217,8 @@
byte[] output = update(input, inputOffset, inputLength);
output = ArrayUtils.concat(output, flush());
- OperationResult opResult = mKeyStoreStream.finish(signature, additionalEntropy);
+ OperationResult opResult = mKeyStoreStream.finish(EmptyArray.BYTE, signature,
+ additionalEntropy);
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
@@ -334,8 +335,8 @@
}
@Override
- public OperationResult finish(byte[] signature, byte[] additionalEntropy) {
- return mKeyStore.finish(mOperationToken, null, signature, additionalEntropy);
+ public OperationResult finish(byte[] input, byte[] signature, byte[] additionalEntropy) {
+ return mKeyStore.finish(mOperationToken, null, input, signature, additionalEntropy);
}
}
}
diff --git a/media/java/android/media/tv/OWNER b/media/java/android/media/tv/OWNERS
similarity index 100%
rename from media/java/android/media/tv/OWNER
rename to media/java/android/media/tv/OWNERS
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 8c38d88..84a0e0d 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -26,7 +26,6 @@
#include <nativehelper/JNIHelp.h>
#include <binder/MemoryDealer.h>
-#include <drm/drm_framework_common.h>
#include <media/stagefright/foundation/ADebug.h>
#include <nativehelper/ScopedLocalRef.h>
@@ -160,8 +159,4 @@
return String8::format("JMediaDataSource(pid %d, uid %d)", getpid(), getuid());
}
-sp<DecryptHandle> JMediaDataSource::DrmInitialization(const char * /* mime */) {
- return NULL;
-}
-
} // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
index 39405d2..378baf4 100644
--- a/media/jni/android_media_MediaDataSource.h
+++ b/media/jni/android_media_MediaDataSource.h
@@ -47,7 +47,6 @@
virtual void close();
virtual uint32_t getFlags();
virtual String8 toString();
- virtual sp<DecryptHandle> DrmInitialization(const char *mime);
private:
// Protect all member variables with mLock because this object will be
diff --git a/media/lib/tvremote/OWNERS b/media/lib/tvremote/OWNERS
new file mode 100644
index 0000000..81d52e1
--- /dev/null
+++ b/media/lib/tvremote/OWNERS
@@ -0,0 +1,2 @@
+nutka@google.com
+skill@google.com
diff --git a/native/android/libandroid_net.map.txt b/native/android/libandroid_net.map.txt
index be3531d..8d4e900 100644
--- a/native/android/libandroid_net.map.txt
+++ b/native/android/libandroid_net.map.txt
@@ -1,15 +1,19 @@
-# They are also all available to vendor code.
+# The following symbols marked with # llndk are available to vendor code.
+# Unlike other VNDK libraries where keeping backwards compatibility is required
+# only within a platform release, these symbols need much longer suppport
+# because the same LLNDK library serves for both system and vendor partition
+# which might be a few years old.
LIBANDROID_NET {
global:
# These functions have been part of the NDK since API 24.
- android_getaddrinfofornetwork; # vndk
- android_setsocknetwork; # vndk
- android_setprocnetwork; # vndk
+ android_getaddrinfofornetwork; # llndk
+ android_setsocknetwork; # llndk
+ android_setprocnetwork; # llndk
# These functions have been part of the NDK since API 29.
- android_res_cancel; # vndk
- android_res_nquery; # vndk
- android_res_nresult; # vndk
- android_res_nsend; # vndk
+ android_res_cancel; # llndk
+ android_res_nquery; # llndk
+ android_res_nresult; # llndk
+ android_res_nsend; # llndk
local:
*;
};
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
index 5d84d64..1928ad9 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
@@ -21,7 +21,6 @@
import android.content.Intent;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
-import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.test.InstrumentationTestCase;
@@ -90,12 +89,10 @@
Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
- Rlog.d(TAG, "OnReceive redirection intent");
mReceiver.onReceive(mContext, intent);
mContext.waitForMs(100);
- Rlog.d(TAG, "verify carrier action: showPortalNotification");
verify(mNotificationMgr, times(1)).notify(mString.capture(), mInt.capture(),
mNotification.capture());
assertEquals(PORTAL_NOTIFICATION_ID, (int) mInt.getValue());
@@ -103,7 +100,6 @@
PendingIntent pendingIntent = mNotification.getValue().contentIntent;
assertNotNull(pendingIntent);
- Rlog.d(TAG, "verify carrier action: disable all metered apns");
verify(mTelephonyMgr).setCarrierDataEnabled(eq(false));
}
}
diff --git a/packages/CtsShim/Android.bp b/packages/CtsShim/Android.bp
new file mode 100644
index 0000000..7728464
--- /dev/null
+++ b/packages/CtsShim/Android.bp
@@ -0,0 +1,74 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You 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.
+//
+
+//##########################################################
+// Variant: Privileged app
+
+android_app_import {
+ name: "CtsShimPrivPrebuilt",
+
+ // this needs to be a privileged application
+ privileged: true,
+
+ // Make sure the build system doesn't try to resign the APK
+ dex_preopt: {
+ enabled: false,
+ },
+
+ arch: {
+ arm: {
+ apk: "apk/arm/CtsShimPriv.apk",
+ },
+ arm64: {
+ apk: "apk/arm/CtsShimPriv.apk",
+ },
+ x86: {
+ apk: "apk/x86/CtsShimPriv.apk",
+ },
+ x86_64: {
+ apk: "apk/x86/CtsShimPriv.apk",
+ },
+ },
+ presigned: true,
+}
+
+//##########################################################
+// Variant: System app
+
+android_app_import {
+ name: "CtsShimPrebuilt",
+
+ // Make sure the build system doesn't try to resign the APK
+ dex_preopt: {
+ enabled: false,
+ },
+
+ arch: {
+ arm: {
+ apk: "apk/arm/CtsShim.apk",
+ },
+ arm64: {
+ apk: "apk/arm/CtsShim.apk",
+ },
+ x86: {
+ apk: "apk/x86/CtsShim.apk",
+ },
+ x86_64: {
+ apk: "apk/x86/CtsShim.apk",
+ },
+ },
+ presigned: true,
+}
diff --git a/packages/CtsShim/Android.mk b/packages/CtsShim/Android.mk
deleted file mode 100644
index 12972f1..0000000
--- a/packages/CtsShim/Android.mk
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-###########################################################
-# Variant: Privileged app
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := CtsShimPrivPrebuilt
-LOCAL_MODULE_TAGS := optional
-# this needs to be a privileged application
-LOCAL_PRIVILEGED_MODULE := true
-LOCAL_MODULE_CLASS := APPS
-LOCAL_BUILT_MODULE_STEM := package.apk
-# Make sure the build system doesn't try to resign the APK
-LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_DEX_PREOPT := false
-LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
-
-LOCAL_SRC_FILES_arm := apk/arm/CtsShimPriv.apk
-LOCAL_SRC_FILES_arm64 := apk/arm/CtsShimPriv.apk
-LOCAL_SRC_FILES_x86 := apk/x86/CtsShimPriv.apk
-LOCAL_SRC_FILES_x86_64 := apk/x86/CtsShimPriv.apk
-
-include $(BUILD_PREBUILT)
-
-
-###########################################################
-# Variant: System app
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := CtsShimPrebuilt
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := APPS
-LOCAL_BUILT_MODULE_STEM := package.apk
-# Make sure the build system doesn't try to resign the APK
-LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_DEX_PREOPT := false
-LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
-
-LOCAL_SRC_FILES_arm := apk/arm/CtsShim.apk
-LOCAL_SRC_FILES_arm64 := apk/arm/CtsShim.apk
-LOCAL_SRC_FILES_x86 := apk/x86/CtsShim.apk
-LOCAL_SRC_FILES_x86_64 := apk/x86/CtsShim.apk
-
-include $(BUILD_PREBUILT)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/CtsShim/build/Android.bp b/packages/CtsShim/build/Android.bp
new file mode 100644
index 0000000..ede1fab
--- /dev/null
+++ b/packages/CtsShim/build/Android.bp
@@ -0,0 +1,117 @@
+// Copyright (C) 2019 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.
+
+// Build rules to build shim apks.
+
+//##########################################################
+// Variant: Privileged app upgrade
+
+android_app {
+ name: "CtsShimPrivUpgrade",
+ // this needs to be a privileged application
+ privileged: true,
+
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
+ dex_preopt: {
+ enabled: false,
+ },
+
+ manifest: "shim_priv_upgrade/AndroidManifest.xml",
+
+ compile_multilib: "both",
+ jni_libs: ["libshim_jni"],
+}
+
+genrule {
+ name: "generate_priv_manifest",
+ srcs: [
+ "shim_priv/AndroidManifest.xml",
+ ":CtsShimPrivUpgrade"
+ ],
+ out: ["AndroidManifest.xml"],
+ cmd: "sed -e s/__HASH__/`sha512sum -b $(location :CtsShimPrivUpgrade) | cut -d' ' -f1`/ $(location shim_priv/AndroidManifest.xml) > $(out)",
+}
+
+//##########################################################
+// Variant: Privileged app
+
+android_app {
+ name: "CtsShimPriv",
+ // this needs to be a privileged application
+ privileged: true,
+
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
+ dex_preopt: {
+ enabled: false,
+ },
+
+ manifest: ":generate_priv_manifest",
+
+ compile_multilib: "both",
+ jni_libs: ["libshim_jni"],
+ // Explicitly uncompress native libs rather than letting the build system doing it and destroy the
+ // v2/v3 signature.
+ use_embedded_native_libs: true,
+}
+
+//##########################################################
+// Variant: Privileged app upgrade w/ the wrong SHA
+
+android_app {
+ name: "CtsShimPrivUpgradeWrongSHA",
+ // this needs to be a privileged application
+ privileged: true,
+
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
+ dex_preopt: {
+ enabled: false,
+ },
+ // anything to make this package's SHA different from CtsShimPrivUpgrade
+ aaptflags: [
+ "--version-name",
+ "WrongSHA",
+ ],
+
+ manifest: "shim_priv_upgrade/AndroidManifest.xml",
+
+ compile_multilib: "both",
+ jni_libs: ["libshim_jni"],
+
+}
+
+//##########################################################
+// Variant: System app
+
+android_app {
+ name: "CtsShim",
+
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
+ dex_preopt: {
+ enabled: false,
+ },
+
+ manifest: "shim/AndroidManifest.xml",
+}
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
deleted file mode 100644
index 03eb0d9..0000000
--- a/packages/CtsShim/build/Android.mk
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You 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.
-#
-
-LOCAL_PATH := $(my-dir)
-
-###########################################################
-# Variant: Privileged app upgrade
-
-include $(CLEAR_VARS)
-# this needs to be a privileged application
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := current
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_DEX_PREOPT := false
-
-LOCAL_PACKAGE_NAME := CtsShimPrivUpgrade
-
-LOCAL_MANIFEST_FILE := shim_priv_upgrade/AndroidManifest.xml
-
-LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
-
-include $(BUILD_PACKAGE)
-my_shim_priv_upgrade_apk := $(LOCAL_BUILT_MODULE)
-
-###########################################################
-# Variant: Privileged app
-
-include $(CLEAR_VARS)
-# this needs to be a privileged application
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := current
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_DEX_PREOPT := false
-
-LOCAL_PACKAGE_NAME := CtsShimPriv
-
-# Generate the upgrade key by taking the hash of the built CtsShimPrivUpgrade apk
-gen := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,true)/AndroidManifest.xml
-$(gen): PRIVATE_CUSTOM_TOOL = sed -e "s/__HASH__/`sha512sum $(PRIVATE_INPUT_APK) | cut -d' ' -f1`/" $< >$@
-$(gen): PRIVATE_INPUT_APK := $(my_shim_priv_upgrade_apk)
-$(gen): $(LOCAL_PATH)/shim_priv/AndroidManifest.xml $(my_shim_priv_upgrade_apk)
- $(transform-generated-source)
-
-my_shim_priv_upgrade_apk :=
-
-LOCAL_FULL_MANIFEST_FILE := $(gen)
-
-LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
-
-LOCAL_USE_AAPT2 := true
-
-include $(BUILD_PACKAGE)
-
-###########################################################
-# Variant: Privileged app upgrade w/ the wrong SHA
-
-include $(CLEAR_VARS)
-# this needs to be a privileged application
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := current
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_DEX_PREOPT := false
-# anything to make this package's SHA different from CtsShimPrivUpgrade
-LOCAL_AAPT_FLAGS := --version-name WrongSHA
-
-LOCAL_PACKAGE_NAME := CtsShimPrivUpgradeWrongSHA
-
-LOCAL_MANIFEST_FILE := shim_priv_upgrade/AndroidManifest.xml
-
-LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
-
-include $(BUILD_PACKAGE)
-
-
-###########################################################
-# Variant: System app
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := current
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_DEX_PREOPT := false
-
-LOCAL_PACKAGE_NAME := CtsShim
-
-LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml
-
-LOCAL_USE_AAPT2 := true
-
-include $(BUILD_PACKAGE)
-
-###########################################################
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 738c425..19ae970 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -102,9 +102,10 @@
Thread thread =
new Thread(
() -> {
- mDynSystem.startInstallation("userdata", mUserdataSize, false);
+ mDynSystem.startInstallation();
+ mDynSystem.createPartition("userdata", mUserdataSize, false);
mInstallationSession =
- mDynSystem.startInstallation("system", mSystemSize, true);
+ mDynSystem.createPartition("system", mSystemSize, true);
});
thread.start();
@@ -157,6 +158,7 @@
reportedInstalledSize = installedSize;
}
}
+ mDynSystem.finishInstallation();
return null;
} catch (Exception e) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
index bc5a2c0..69bd0ed 100644
--- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -29,6 +29,8 @@
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
@@ -206,4 +208,15 @@
return sb.toString();
}
+ /**
+ * To get the formatting text for display in a potentially opposite-directionality context
+ * without garbling.
+ * @param subscriptionInfo {@link SubscriptionInfo} subscription information.
+ * @return Returns phone number with Bidi format.
+ */
+ public static String getBidiFormattedPhoneNumber(Context context,
+ SubscriptionInfo subscriptionInfo) {
+ final String phoneNumber = getFormattedPhoneNumber(context, subscriptionInfo);
+ return BidiFormatter.getInstance().unicodeWrap(phoneNumber, TextDirectionHeuristics.LTR);
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 9a95288..ec5bc96 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -363,12 +363,12 @@
/**
* Get name from remote device
- * @return {@link BluetoothDevice#getAliasName()} if
- * {@link BluetoothDevice#getAliasName()} is not null otherwise return
+ * @return {@link BluetoothDevice#getAlias()} if
+ * {@link BluetoothDevice#getAlias()} is not null otherwise return
* {@link BluetoothDevice#getAddress()}
*/
public String getName() {
- final String aliasName = mDevice.getAliasName();
+ final String aliasName = mDevice.getAlias();
return TextUtils.isEmpty(aliasName) ? getAddress() : aliasName;
}
@@ -426,7 +426,7 @@
* @return true if device's alias name is not null nor empty, false otherwise
*/
public boolean hasHumanReadableName() {
- return !TextUtils.isEmpty(mDevice.getAliasName());
+ return !TextUtils.isEmpty(mDevice.getAlias());
}
/**
@@ -573,7 +573,7 @@
}
if (BluetoothUtils.D) {
- Log.e(TAG, "updating profiles for " + mDevice.getAliasName() + ", " + mDevice);
+ Log.e(TAG, "updating profiles for " + mDevice.getAlias() + ", " + mDevice);
BluetoothClass bluetoothClass = mDevice.getBluetoothClass();
if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString());
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 33e7540..7050db1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -166,7 +166,7 @@
return cachedDevice.getName();
}
- String name = device.getAliasName();
+ String name = device.getAlias();
if (name != null) {
return name;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index ea3c1d9..092cbf3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -222,7 +222,8 @@
}
}
- return TelephonyManager.from(mContext).createForSubscriptionId(subscriptionId);
+ return mContext.getSystemService(
+ TelephonyManager.class).createForSubscriptionId(subscriptionId);
}
public void setMobileDataEnabled(boolean enabled) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
index d5d2e9e..f506b7c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
@@ -1,7 +1,7 @@
# Default reviewers for this and subdirectories.
+qal@google.com
+arcwang@google.com
+govenliu@google.com
asapperstein@google.com
-asargent@google.com
-dling@google.com
-zhfan@google.com
# Emergency approvers in case the above are not available
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index dc47de8..c37509b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -95,9 +95,9 @@
when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
when(mDevice3.getName()).thenReturn(DEVICE_NAME_3);
- when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1);
- when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2);
- when(mDevice3.getAliasName()).thenReturn(DEVICE_ALIAS_3);
+ when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1);
+ when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2);
+ when(mDevice3.getAlias()).thenReturn(DEVICE_ALIAS_3);
when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1);
when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
when(mDevice3.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
@@ -224,7 +224,7 @@
assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1);
final String newAliasName = "NewAliasName";
- when(mDevice1.getAliasName()).thenReturn(newAliasName);
+ when(mDevice1.getAlias()).thenReturn(newAliasName);
mCachedDeviceManager.onDeviceNameUpdated(mDevice1);
assertThat(cachedDevice1.getName()).isEqualTo(newAliasName);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 93dcbfe..999916d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -699,7 +699,7 @@
@Test
public void deviceName_testAliasNameAvailable() {
- when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);
+ when(mDevice.getAlias()).thenReturn(DEVICE_ALIAS);
when(mDevice.getName()).thenReturn(DEVICE_NAME);
CachedBluetoothDevice cachedBluetoothDevice =
new CachedBluetoothDevice(mContext, mProfileManager, mDevice);
@@ -722,7 +722,7 @@
@Test
public void deviceName_testRenameDevice() {
final String[] alias = {DEVICE_ALIAS};
- doAnswer(invocation -> alias[0]).when(mDevice).getAliasName();
+ doAnswer(invocation -> alias[0]).when(mDevice).getAlias();
doAnswer(invocation -> {
alias[0] = (String) invocation.getArguments()[0];
return true;
@@ -839,14 +839,14 @@
@Test
public void getName_aliasNameNotNull_returnAliasName() {
- when(mDevice.getAliasName()).thenReturn(DEVICE_NAME);
+ when(mDevice.getAlias()).thenReturn(DEVICE_NAME);
assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_NAME);
}
@Test
public void getName_aliasNameIsNull_returnAddress() {
- when(mDevice.getAliasName()).thenReturn(null);
+ when(mDevice.getAlias()).thenReturn(null);
assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_ADDRESS);
}
@@ -854,7 +854,7 @@
@Test
public void setName_setDeviceNameIsNotNull() {
final String name = "test name";
- when(mDevice.getAliasName()).thenReturn(DEVICE_NAME);
+ when(mDevice.getAlias()).thenReturn(DEVICE_NAME);
mCachedDevice.setName(name);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index 2b5466c..7be176a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -75,8 +75,8 @@
when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
- when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1);
- when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2);
+ when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1);
+ when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2);
when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS);
when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS);
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 3da5e76..f7bee30 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -75,7 +75,7 @@
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
- when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+ when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE))
.thenReturn(mSubscriptionManager);
when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 047ac59..13fc881 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -207,6 +207,9 @@
<!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
<uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
+ <!-- Permission requried for CTS test - UiModeManagerTest -->
+ <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index db2be0e..236f17e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -21,20 +21,24 @@
import android.app.ActivityManager;
import android.content.Context;
import android.net.ConnectivityManager;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiManager;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.UserManager;
import android.util.Log;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
/**
+ * Controller used to retrieve information related to a hotspot.
*/
@Singleton
public class HotspotControllerImpl implements HotspotController, WifiManager.SoftApCallback {
@@ -49,10 +53,11 @@
private final Context mContext;
private int mHotspotState;
- private int mNumConnectedDevices;
+ private volatile int mNumConnectedDevices;
private boolean mWaitingForTerminalState;
/**
+ * Controller used to retrieve information related to a hotspot.
*/
@Inject
public HotspotControllerImpl(Context context, @Named(MAIN_HANDLER_NAME) Handler mainHandler) {
@@ -96,7 +101,6 @@
/**
* Adds {@code callback} to the controller. The controller will update the callback on state
* changes. It will immediately trigger the callback added to notify current state.
- * @param callback
*/
@Override
public void addCallback(Callback callback) {
@@ -106,13 +110,16 @@
mCallbacks.add(callback);
if (mWifiManager != null) {
if (mCallbacks.size() == 1) {
- mWifiManager.registerSoftApCallback(this, mMainHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mMainHandler), this);
} else {
- // mWifiManager#registerSoftApCallback triggers a call to onNumClientsChanged
- // on the Main Handler. In order to always update the callback on added, we
- // make this call when adding callbacks after the first.
+ // mWifiManager#registerSoftApCallback triggers a call to
+ // onConnectedClientsChanged on the Main Handler. In order to always update
+ // the callback on added, we make this call when adding callbacks after the
+ // first.
mMainHandler.post(() ->
- callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices));
+ callback.onHotspotChanged(isHotspotEnabled(),
+ mNumConnectedDevices));
+
}
}
}
@@ -217,8 +224,8 @@
}
@Override
- public void onNumClientsChanged(int numConnectedDevices) {
- mNumConnectedDevices = numConnectedDevices;
+ public void onConnectedClientsChanged(List<WifiClient> clients) {
+ mNumConnectedDevices = clients.size();
fireHotspotChangedCallback();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index e75365e..c519f56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -22,6 +22,8 @@
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings.Global;
+import android.telephony.CellSignalStrength;
+import android.telephony.CellSignalStrengthCdma;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -48,6 +50,7 @@
import java.io.PrintWriter;
import java.util.BitSet;
import java.util.Objects;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -457,6 +460,18 @@
}
/**
+ * Extracts the CellSignalStrengthCdma from SignalStrength then returns the level
+ */
+ private final int getCdmaLevel() {
+ List<CellSignalStrengthCdma> signalStrengthCdma =
+ mSignalStrength.getCellSignalStrengths(CellSignalStrengthCdma.class);
+ if (!signalStrengthCdma.isEmpty()) {
+ return signalStrengthCdma.get(0).getLevel();
+ }
+ return CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ }
+
+ /**
* Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
* mDataState, and mSimState. It should be called any time one of these is updated.
* This will call listeners if necessary.
@@ -470,7 +485,7 @@
&& mSignalStrength != null;
if (mCurrentState.connected) {
if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
- mCurrentState.level = mSignalStrength.getCdmaLevel();
+ mCurrentState.level = getCdmaLevel();
} else {
mCurrentState.level = mSignalStrength.getLevel();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
index 3e4c4d6..631c580 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
@@ -42,6 +42,9 @@
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -67,10 +70,11 @@
mContext.addMockSystemService(WifiManager.class, mWifiManager);
doAnswer((InvocationOnMock invocation) -> {
- ((WifiManager.SoftApCallback) invocation.getArgument(0)).onNumClientsChanged(1);
+ ((WifiManager.SoftApCallback) invocation.getArgument(1))
+ .onConnectedClientsChanged(new ArrayList<>());
return null;
- }).when(mWifiManager).registerSoftApCallback(any(WifiManager.SoftApCallback.class),
- any(Handler.class));
+ }).when(mWifiManager).registerSoftApCallback(any(Executor.class),
+ any(WifiManager.SoftApCallback.class));
mController = new HotspotControllerImpl(mContext, new Handler(mLooper.getLooper()));
}
@@ -80,7 +84,7 @@
mController.addCallback(mCallback1);
mController.addCallback(mCallback2);
- verify(mWifiManager, times(1)).registerSoftApCallback(eq(mController), any());
+ verify(mWifiManager, times(1)).registerSoftApCallback(any(), eq(mController));
}
@Test
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 61bfb92..7b35f4d 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -20,12 +20,14 @@
srcs: [
"src/**/*.java",
":framework-tethering-shared-srcs",
+ ":net-module-utils-srcs",
":services-tethering-shared-srcs",
":servicescore-tethering-src",
],
static_libs: [
"androidx.annotation_annotation",
"netd_aidl_interface-java",
+ "netlink-client",
"networkstack-aidl-interfaces-java",
"android.hardware.tetheroffload.control-V1.0-java",
"tethering-client",
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java
index cf0e3b2..ca9b168 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -251,7 +251,7 @@
/** Check whether dun is required. */
public static boolean checkDunRequired(Context ctx, int id) {
final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
- return (tm != null) ? tm.isTetherApnRequired(id) : false;
+ return (tm != null) ? tm.isTetheringApnRequired(id) : false;
}
private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
index 9c65c0d..30bff35 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
@@ -145,7 +145,7 @@
@Test
public void testDunFromTelephonyManagerMeansDun() {
- when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(true);
+ when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(true);
final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -169,7 +169,7 @@
@Test
public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
- when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false);
+ when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false);
final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -212,7 +212,7 @@
@Test
public void testNoDefinedUpstreamTypesAddsEthernet() {
when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{});
- when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false);
+ when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -235,7 +235,7 @@
public void testDefinedUpstreamTypesSansEthernetAddsEthernet() {
when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(
new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
- when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false);
+ when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -253,7 +253,7 @@
public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() {
when(mResources.getIntArray(config_tether_upstream_types))
.thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI});
- when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false);
+ when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index ed68f32..084a747 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -31,6 +31,8 @@
"android.hardware.light-V2.0-java",
"android.hardware.power-V1.0-java",
"android.hardware.tv.cec-V1.0-java",
+ "app-compat-annotations",
+ "vintf-vibrator-java",
],
required: [
@@ -49,7 +51,6 @@
"android.hardware.biometrics.fingerprint-V2.1-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
- "android.hardware.vibrator-V1.4-java",
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 81eb4b3..ce4cdc8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -146,6 +146,7 @@
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
@@ -2185,6 +2186,11 @@
*/
@VisibleForTesting
public void systemReady() {
+ // Let PermissionMonitor#startMonitoring() running in the beginning of the systemReady
+ // before MultipathPolicyTracker.start(). Since mApps in PermissionMonitor needs to be
+ // populated first to ensure that listening network request which is sent by
+ // MultipathPolicyTracker won't be added NET_CAPABILITY_FOREGROUND capability.
+ mPermissionMonitor.startMonitoring();
mProxyTracker.loadGlobalProxy();
registerNetdEventCallback();
mTethering.systemReady();
@@ -2205,8 +2211,6 @@
mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
-
- mPermissionMonitor.startMonitoring();
}
/**
@@ -3050,7 +3054,8 @@
}
private void handleAsyncChannelHalfConnect(Message msg) {
- AsyncChannel ac = (AsyncChannel) msg.obj;
+ ensureRunningOnConnectivityServiceThread();
+ final AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkFactory connected");
@@ -3060,7 +3065,8 @@
// A network factory has connected. Send it all current NetworkRequests.
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.request.isListen()) continue;
- NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
+ ensureRunningOnConnectivityServiceThread();
+ NetworkAgentInfo nai = nri.mSatisfier;
final int score;
final int serial;
if (nai != null) {
@@ -3116,6 +3122,7 @@
// ConnectivityService, free its interfaces and clean up.
// Must be called on the Handler thread.
private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
+ ensureRunningOnConnectivityServiceThread();
if (DBG) {
log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
}
@@ -3162,14 +3169,17 @@
// Remove all previously satisfied requests.
for (int i = 0; i < nai.numNetworkRequests(); i++) {
NetworkRequest request = nai.requestAt(i);
- NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
+ final NetworkRequestInfo nri = mNetworkRequests.get(request);
+ ensureRunningOnConnectivityServiceThread();
+ final NetworkAgentInfo currentNetwork = nri.mSatisfier;
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
- clearNetworkForRequest(request.requestId);
+ nri.mSatisfier = null;
sendUpdatedScoreToFactories(request, null);
}
}
nai.clearLingerState();
if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
+ mDefaultNetworkNai = null;
updateDataActivityTracking(null /* newNetwork */, nai);
notifyLockdownVpn(nai);
ensureNetworkTransitionWakelock(nai.name());
@@ -3178,7 +3188,7 @@
if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
updateAllVpnsCapabilities();
}
- rematchAllNetworksAndRequests(null, 0);
+ rematchAllNetworksAndRequests();
mLingerMonitor.noteDisconnect(nai);
if (nai.created) {
// Tell netd to clean up the configuration for this network
@@ -3253,6 +3263,7 @@
}
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
+ ensureRunningOnConnectivityServiceThread();
mNetworkRequests.put(nri.request, nri);
mNetworkRequestInfoLogs.log("REGISTER " + nri);
if (nri.request.isListen()) {
@@ -3263,8 +3274,8 @@
}
}
}
- rematchAllNetworksAndRequests(null, 0);
- if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
+ rematchAllNetworksAndRequests();
+ if (nri.request.isRequest() && nri.mSatisfier == null) {
sendUpdatedScoreToFactories(nri.request, null);
}
}
@@ -3286,6 +3297,7 @@
// - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
// then it should be lingered.
private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
+ ensureRunningOnConnectivityServiceThread();
final int numRequests;
switch (reason) {
case TEARDOWN:
@@ -3310,6 +3322,7 @@
// If this Network is already the highest scoring Network for a request, or if
// there is hope for it to become one if it validated, then it is needed.
+ ensureRunningOnConnectivityServiceThread();
if (nri.request.isRequest() && nai.satisfies(nri.request) &&
(nai.isSatisfyingRequest(nri.request.requestId) ||
// Note that this catches two important cases:
@@ -3319,8 +3332,8 @@
// 2. Unvalidated WiFi will not be reaped when validated cellular
// is currently satisfying the request. This is desirable when
// WiFi ends up validating and out scoring cellular.
- getNetworkForRequest(nri.request.requestId).getCurrentScore() <
- nai.getCurrentScoreAsValidated())) {
+ nri.mSatisfier.getCurrentScore()
+ < nai.getCurrentScoreAsValidated())) {
return false;
}
}
@@ -3344,10 +3357,12 @@
}
private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
+ ensureRunningOnConnectivityServiceThread();
if (mNetworkRequests.get(nri.request) == null) {
return;
}
- if (getNetworkForRequest(nri.request.requestId) != null) {
+ ensureRunningOnConnectivityServiceThread();
+ if (nri.mSatisfier != null) {
return;
}
if (VDBG || (DBG && nri.request.isRequest())) {
@@ -3374,6 +3389,8 @@
}
private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
+ ensureRunningOnConnectivityServiceThread();
+
nri.unlinkDeathRecipient();
mNetworkRequests.remove(nri.request);
@@ -3393,7 +3410,8 @@
mNetworkRequestInfoLogs.log("RELEASE " + nri);
if (nri.request.isRequest()) {
boolean wasKept = false;
- NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
+ ensureRunningOnConnectivityServiceThread();
+ final NetworkAgentInfo nai = nri.mSatisfier;
if (nai != null) {
boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
nai.removeRequest(nri.request.requestId);
@@ -3410,7 +3428,7 @@
} else {
wasKept = true;
}
- clearNetworkForRequest(nri.request.requestId);
+ nri.mSatisfier = null;
if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
// Went from foreground to background.
updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
@@ -3499,13 +3517,12 @@
}
if (accept != nai.networkMisc.acceptUnvalidated) {
- int oldScore = nai.getCurrentScore();
nai.networkMisc.acceptUnvalidated = accept;
// If network becomes partial connectivity and user already accepted to use this
// network, we should respect the user's option and don't need to popup the
// PARTIAL_CONNECTIVITY notification to user again.
nai.networkMisc.acceptPartialConnectivity = accept;
- rematchAllNetworksAndRequests(nai, oldScore);
+ rematchAllNetworksAndRequests();
sendUpdatedScoreToFactories(nai);
}
@@ -3574,9 +3591,8 @@
return;
}
if (!nai.avoidUnvalidated) {
- int oldScore = nai.getCurrentScore();
nai.avoidUnvalidated = true;
- rematchAllNetworksAndRequests(nai, oldScore);
+ rematchAllNetworksAndRequests();
sendUpdatedScoreToFactories(nai);
}
}
@@ -3677,7 +3693,7 @@
private void rematchForAvoidBadWifiUpdate() {
- rematchAllNetworksAndRequests(null, 0);
+ rematchAllNetworksAndRequests();
for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) {
if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
sendUpdatedScoreToFactories(nai);
@@ -5093,6 +5109,11 @@
*/
private class NetworkRequestInfo implements IBinder.DeathRecipient {
final NetworkRequest request;
+ // The network currently satisfying this request, or null if none. Must only be touched
+ // on the handler thread. This only makes sense for network requests and not for listens,
+ // as defined by NetworkRequest#isRequest(). For listens, this is always null.
+ @Nullable
+ NetworkAgentInfo mSatisfier;
final PendingIntent mPendingIntent;
boolean mPendingIntentSent;
private final IBinder mBinder;
@@ -5479,16 +5500,6 @@
if (DBG) log("unregisterNetworkFactory for " + nfi.name);
}
- /**
- * NetworkAgentInfo supporting a request by requestId.
- * These have already been vetted (their Capabilities satisfy the request)
- * and the are the highest scored network available.
- * the are keyed off the Requests requestId.
- */
- // NOTE: Accessed on multiple threads, must be synchronized on itself.
- @GuardedBy("mNetworkForRequestId")
- private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = new SparseArray<>();
-
// NOTE: Accessed on multiple threads, must be synchronized on itself.
@GuardedBy("mNetworkForNetId")
private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
@@ -5506,7 +5517,11 @@
private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
+ @NonNull
private final NetworkRequest mDefaultRequest;
+ // The NetworkAgentInfo currently satisfying the default request, if any.
+ @Nullable
+ private volatile NetworkAgentInfo mDefaultNetworkNai = null;
// Request used to optionally keep mobile data active even when higher
// priority networks like Wi-Fi are active.
@@ -5516,26 +5531,8 @@
// priority networks like ethernet are active.
private final NetworkRequest mDefaultWifiRequest;
- private NetworkAgentInfo getNetworkForRequest(int requestId) {
- synchronized (mNetworkForRequestId) {
- return mNetworkForRequestId.get(requestId);
- }
- }
-
- private void clearNetworkForRequest(int requestId) {
- synchronized (mNetworkForRequestId) {
- mNetworkForRequestId.remove(requestId);
- }
- }
-
- private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) {
- synchronized (mNetworkForRequestId) {
- mNetworkForRequestId.put(requestId, nai);
- }
- }
-
private NetworkAgentInfo getDefaultNetwork() {
- return getNetworkForRequest(mDefaultRequest.requestId);
+ return mDefaultNetworkNai;
}
@Nullable
@@ -5968,7 +5965,7 @@
} else {
// If the requestable capabilities have changed or the score changed, we can't have been
// called by rematchNetworkAndRequests, so it's safe to start a rematch.
- rematchAllNetworksAndRequests(nai, oldScore);
+ rematchAllNetworksAndRequests();
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
}
@@ -6253,7 +6250,7 @@
}
}
- private void makeDefault(NetworkAgentInfo newNetwork) {
+ private void makeDefault(@NonNull final NetworkAgentInfo newNetwork) {
if (DBG) log("Switching to new default network: " + newNetwork);
try {
@@ -6262,6 +6259,7 @@
loge("Exception setting default network :" + e);
}
+ mDefaultNetworkNai = newNetwork;
notifyLockdownVpn(newNetwork);
handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes());
@@ -6296,6 +6294,41 @@
}
}
+ private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork(
+ @NonNull final NetworkAgentInfo newNetwork) {
+ final int score = newNetwork.getCurrentScore();
+ final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>();
+ for (NetworkRequestInfo nri : mNetworkRequests.values()) {
+ // Process requests in the first pass and listens in the second pass. This allows us to
+ // change a network's capabilities depending on which requests it has. This is only
+ // correct if the change in capabilities doesn't affect whether the network satisfies
+ // requests or not, and doesn't affect the network's score.
+ if (nri.request.isListen()) continue;
+
+ final NetworkAgentInfo currentNetwork = nri.mSatisfier;
+ final boolean satisfies = newNetwork.satisfies(nri.request);
+ if (newNetwork == currentNetwork && satisfies) continue;
+
+ // check if it satisfies the NetworkCapabilities
+ if (VDBG) log(" checking if request is satisfied: " + nri.request);
+ if (satisfies) {
+ // next check if it's better than any current network we're using for
+ // this request
+ if (VDBG || DDBG) {
+ log("currentScore = "
+ + (currentNetwork != null ? currentNetwork.getCurrentScore() : 0)
+ + ", newScore = " + score);
+ }
+ if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
+ reassignedRequests.put(nri, newNetwork);
+ }
+ } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
+ reassignedRequests.put(nri, null);
+ }
+ }
+ return reassignedRequests;
+ }
+
// Handles a network appearing or improving its score.
//
// - Evaluates all current NetworkRequests that can be
@@ -6309,10 +6342,6 @@
// - Tears down newNetwork if it just became validated
// but turns out to be unneeded.
//
- // - If reapUnvalidatedNetworks==REAP, tears down unvalidated
- // networks that have no chance (i.e. even if validated)
- // of becoming the highest scoring network.
- //
// NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy,
// it does not remove NetworkRequests that other Networks could better satisfy.
// If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}.
@@ -6320,11 +6349,9 @@
// as it performs better by a factor of the number of Networks.
//
// @param newNetwork is the network to be matched against NetworkRequests.
- // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be
- // performed to tear down unvalidated networks that have no chance (i.e. even if
- // validated) of becoming the highest scoring network.
- private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
- ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) {
+ // @param now the time the rematch starts, as returned by SystemClock.elapsedRealtime();
+ private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, long now) {
+ ensureRunningOnConnectivityServiceThread();
if (!newNetwork.everConnected) return;
boolean keep = newNetwork.isVPN();
boolean isNewDefault = false;
@@ -6335,74 +6362,54 @@
if (VDBG || DDBG) log("rematching " + newNetwork.name());
- // Find and migrate to this Network any NetworkRequests for
- // which this network is now the best.
- ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<>();
- ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
+ final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests =
+ computeRequestReassignmentForNetwork(newNetwork);
+
NetworkCapabilities nc = newNetwork.networkCapabilities;
if (VDBG) log(" network has: " + nc);
- for (NetworkRequestInfo nri : mNetworkRequests.values()) {
- // Process requests in the first pass and listens in the second pass. This allows us to
- // change a network's capabilities depending on which requests it has. This is only
- // correct if the change in capabilities doesn't affect whether the network satisfies
- // requests or not, and doesn't affect the network's score.
- if (nri.request.isListen()) continue;
- final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId);
- final boolean satisfies = newNetwork.satisfies(nri.request);
- if (newNetwork == currentNetwork && satisfies) {
- if (VDBG) {
- log("Network " + newNetwork.name() + " was already satisfying" +
- " request " + nri.request.requestId + ". No change.");
+ // Find and migrate to this Network any NetworkRequests for
+ // which this network is now the best.
+ final ArrayList<NetworkAgentInfo> removedRequests = new ArrayList<>();
+ final ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
+ for (final Map.Entry<NetworkRequestInfo, NetworkAgentInfo> entry :
+ reassignedRequests.entrySet()) {
+ final NetworkRequestInfo nri = entry.getKey();
+ final NetworkAgentInfo previousSatisfier = nri.mSatisfier;
+ final NetworkAgentInfo newSatisfier = entry.getValue();
+ if (newSatisfier != null) {
+ if (VDBG) log("rematch for " + newSatisfier.name());
+ if (previousSatisfier != null) {
+ if (VDBG || DDBG) {
+ log(" accepting network in place of " + previousSatisfier.name());
+ }
+ previousSatisfier.removeRequest(nri.request.requestId);
+ previousSatisfier.lingerRequest(nri.request, now, mLingerDelayMs);
+ removedRequests.add(previousSatisfier);
+ } else {
+ if (VDBG || DDBG) log(" accepting network in place of null");
}
+ newSatisfier.unlingerRequest(nri.request);
+ nri.mSatisfier = newSatisfier;
+ if (!newSatisfier.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request);
+ }
+ addedRequests.add(nri);
keep = true;
- continue;
- }
-
- // check if it satisfies the NetworkCapabilities
- if (VDBG) log(" checking if request is satisfied: " + nri.request);
- if (satisfies) {
- // next check if it's better than any current network we're using for
- // this request
- if (VDBG || DDBG) {
- log("currentScore = " +
- (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) +
- ", newScore = " + score);
- }
- if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
- if (VDBG) log("rematch for " + newNetwork.name());
- if (currentNetwork != null) {
- if (VDBG || DDBG){
- log(" accepting network in place of " + currentNetwork.name());
- }
- currentNetwork.removeRequest(nri.request.requestId);
- currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);
- affectedNetworks.add(currentNetwork);
- } else {
- if (VDBG || DDBG) log(" accepting network in place of null");
- }
- newNetwork.unlingerRequest(nri.request);
- setNetworkForRequest(nri.request.requestId, newNetwork);
- if (!newNetwork.addRequest(nri.request)) {
- Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
- }
- addedRequests.add(nri);
- keep = true;
- // Tell NetworkFactories about the new score, so they can stop
- // trying to connect if they know they cannot match it.
- // TODO - this could get expensive if we have a lot of requests for this
- // network. Think about if there is a way to reduce this. Push
- // netid->request mapping to each factory?
- sendUpdatedScoreToFactories(nri.request, newNetwork);
- if (isDefaultRequest(nri)) {
- isNewDefault = true;
- oldDefaultNetwork = currentNetwork;
- if (currentNetwork != null) {
- mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork);
- }
+ // Tell NetworkFactories about the new score, so they can stop
+ // trying to connect if they know they cannot match it.
+ // TODO - this could get expensive if we have a lot of requests for this
+ // network. Think about if there is a way to reduce this. Push
+ // netid->request mapping to each factory?
+ sendUpdatedScoreToFactories(nri.request, newSatisfier);
+ if (isDefaultRequest(nri)) {
+ isNewDefault = true;
+ oldDefaultNetwork = previousSatisfier;
+ if (previousSatisfier != null) {
+ mLingerMonitor.noteLingerDefaultNetwork(previousSatisfier, newSatisfier);
}
}
- } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
+ } else {
// If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri",
// mark it as no longer satisfying "nri". Because networks are processed by
// rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will
@@ -6415,13 +6422,14 @@
" request " + nri.request.requestId);
}
newNetwork.removeRequest(nri.request.requestId);
- if (currentNetwork == newNetwork) {
- clearNetworkForRequest(nri.request.requestId);
+ if (previousSatisfier == newNetwork) {
+ nri.mSatisfier = null;
+ if (isDefaultRequest(nri)) mDefaultNetworkNai = null;
sendUpdatedScoreToFactories(nri.request, null);
} else {
Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
newNetwork.name() +
- " without updating mNetworkForRequestId or factories!");
+ " without updating mSatisfier or factories!");
}
// TODO: Technically, sending CALLBACK_LOST here is
// incorrect if there is a replacement network currently
@@ -6433,6 +6441,7 @@
callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0);
}
}
+
if (isNewDefault) {
updateDataActivityTracking(newNetwork, oldDefaultNetwork);
// Notify system services that this network is up.
@@ -6472,7 +6481,7 @@
// Linger any networks that are no longer needed. This should be done after sending the
// available callback for newNetwork.
- for (NetworkAgentInfo nai : affectedNetworks) {
+ for (NetworkAgentInfo nai : removedRequests) {
updateLingerState(nai, now);
}
// Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it
@@ -6540,66 +6549,43 @@
mLegacyTypeTracker.add(TYPE_VPN, newNetwork);
}
}
- if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) {
- for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
- if (unneeded(nai, UnneededFor.TEARDOWN)) {
- if (nai.getLingerExpiry() > 0) {
- // This network has active linger timers and no requests, but is not
- // lingering. Linger it.
- //
- // One way (the only way?) this can happen if this network is unvalidated
- // and became unneeded due to another network improving its score to the
- // point where this network will no longer be able to satisfy any requests
- // even if it validates.
- updateLingerState(nai, now);
- } else {
- if (DBG) log("Reaping " + nai.name());
- teardownUnneededNetwork(nai);
- }
- }
- }
- }
}
/**
* Attempt to rematch all Networks with NetworkRequests. This may result in Networks
* being disconnected.
- * @param changed If only one Network's score or capabilities have been modified since the last
- * time this function was called, pass this Network in this argument, otherwise pass
- * null.
- * @param oldScore If only one Network has been changed but its NetworkCapabilities have not
- * changed, pass in the Network's score (from getCurrentScore()) prior to the change via
- * this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if
- * {@code changed} is {@code null}. This is because NetworkCapabilities influence a
- * network's score.
*/
- private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
- // TODO: This may get slow. The "changed" parameter is provided for future optimization
- // to avoid the slowness. It is not simply enough to process just "changed", for
- // example in the case where "changed"'s score decreases and another network should begin
- // satisfying a NetworkRequest that "changed" currently satisfies.
-
- // Optimization: Only reprocess "changed" if its score improved. This is safe because it
- // can only add more NetworkRequests satisfied by "changed", and this is exactly what
- // rematchNetworkAndRequests() handles.
+ private void rematchAllNetworksAndRequests() {
+ // TODO: This may be slow, and should be optimized. Unfortunately at this moment the
+ // processing is network-major instead of request-major (the code iterates through all
+ // networks, then for each it iterates for all requests), which is a problem for re-scoring
+ // requests. Once the code has switched to a request-major iteration style, this can
+ // be optimized to only do the processing needed.
final long now = SystemClock.elapsedRealtime();
- if (changed != null && oldScore < changed.getCurrentScore()) {
- rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now);
- } else {
- final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray(
- new NetworkAgentInfo[mNetworkAgentInfos.size()]);
- // Rematch higher scoring networks first to prevent requests first matching a lower
- // scoring network and then a higher scoring network, which could produce multiple
- // callbacks and inadvertently unlinger networks.
- Arrays.sort(nais);
- for (NetworkAgentInfo nai : nais) {
- rematchNetworkAndRequests(nai,
- // Only reap the last time through the loop. Reaping before all rematching
- // is complete could incorrectly teardown a network that hasn't yet been
- // rematched.
- (nai != nais[nais.length-1]) ? ReapUnvalidatedNetworks.DONT_REAP
- : ReapUnvalidatedNetworks.REAP,
- now);
+ final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray(
+ new NetworkAgentInfo[mNetworkAgentInfos.size()]);
+ // Rematch higher scoring networks first to prevent requests first matching a lower
+ // scoring network and then a higher scoring network, which could produce multiple
+ // callbacks and inadvertently unlinger networks.
+ Arrays.sort(nais);
+ for (NetworkAgentInfo nai : nais) {
+ rematchNetworkAndRequests(nai, now);
+ }
+ for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+ if (unneeded(nai, UnneededFor.TEARDOWN)) {
+ if (nai.getLingerExpiry() > 0) {
+ // This network has active linger timers and no requests, but is not
+ // lingering. Linger it.
+ //
+ // One way (the only way?) this can happen if this network is unvalidated
+ // and became unneeded due to another network improving its score to the
+ // point where this network will no longer be able to satisfy any requests
+ // even if it validates.
+ updateLingerState(nai, now);
+ } else {
+ if (DBG) log("Reaping " + nai.name());
+ teardownUnneededNetwork(nai);
+ }
}
}
}
@@ -6698,8 +6684,7 @@
}
// Consider network even though it is not yet validated.
- final long now = SystemClock.elapsedRealtime();
- rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now);
+ rematchAllNetworksAndRequests();
// This has to happen after matching the requests, because callbacks are just requests.
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
@@ -6720,7 +6705,7 @@
state == NetworkInfo.State.SUSPENDED)) {
// going into or coming out of SUSPEND: re-score and notify
if (networkAgent.getCurrentScore() != oldScore) {
- rematchAllNetworksAndRequests(networkAgent, oldScore);
+ rematchAllNetworksAndRequests();
}
updateCapabilities(networkAgent.getCurrentScore(), networkAgent,
networkAgent.networkCapabilities);
@@ -6734,19 +6719,9 @@
}
private void updateNetworkScore(NetworkAgentInfo nai, NetworkScore ns) {
- int score = ns.getIntExtension(NetworkScore.LEGACY_SCORE);
- if (VDBG || DDBG) log("updateNetworkScore for " + nai.name() + " to " + score);
- if (score < 0) {
- loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score +
- "). Bumping score to min of 0");
- score = 0;
- }
-
- final int oldScore = nai.getCurrentScore();
+ if (VDBG || DDBG) log("updateNetworkScore for " + nai.name() + " to " + ns);
nai.setNetworkScore(ns);
-
- rematchAllNetworksAndRequests(nai, oldScore);
-
+ rematchAllNetworksAndRequests();
sendUpdatedScoreToFactories(nai);
}
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 190e6cf..7b02b6e 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.content.pm.PackageManager;
-import android.gsi.GsiInstallParams;
import android.gsi.GsiProgress;
import android.gsi.IGsiService;
import android.gsi.IGsid;
@@ -47,6 +46,7 @@
private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
private static final String PATH_DEFAULT = "/data/gsi";
private Context mContext;
+ private String mInstallPath;
private volatile IGsiService mGsiService;
DynamicSystemService(Context context) {
@@ -115,8 +115,8 @@
}
@Override
- public boolean startInstallation(String name, long size, boolean readOnly)
- throws RemoteException {
+ public boolean startInstallation() throws RemoteException {
+ IGsiService service = getGsiService();
// priority from high to low: sysprop -> sdcard -> /data
String path = SystemProperties.get("os.aot.path");
if (path.isEmpty()) {
@@ -138,14 +138,19 @@
}
Slog.i(TAG, "startInstallation -> " + path);
}
+ mInstallPath = path;
+ if (service.openInstall(path) != 0) {
+ Slog.i(TAG, "Failed to open " + path);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean createPartition(String name, long size, boolean readOnly)
+ throws RemoteException {
IGsiService service = getGsiService();
- GsiInstallParams installParams = new GsiInstallParams();
- installParams.installDir = path;
- installParams.name = name;
- installParams.size = size;
- installParams.wipe = readOnly;
- installParams.readOnly = readOnly;
- if (service.beginGsiInstall(installParams) != 0) {
+ if (service.createPartition(name, size, readOnly) != 0) {
Slog.i(TAG, "Failed to install " + name);
return false;
}
@@ -153,6 +158,16 @@
}
@Override
+ public boolean finishInstallation() throws RemoteException {
+ IGsiService service = getGsiService();
+ if (service.closeInstall() != 0) {
+ Slog.i(TAG, "Failed to finish installation");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
public GsiProgress getInstallationProgress() throws RemoteException {
return getGsiService().getInstallProgress();
}
@@ -190,6 +205,8 @@
@Override
public boolean remove() throws RemoteException {
+ IGsiService gsiService = getGsiService();
+ String install_dir = gsiService.getInstalledGsiImageDir();
return getGsiService().removeGsi();
}
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 80d7ac9..9a7a4e7 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -60,12 +60,9 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
-import com.android.internal.os.TransferPipe;
-import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
@@ -908,17 +905,6 @@
}
writer.println("Current scorer: " + currentScorer);
- sendCacheUpdateCallback(new BiConsumer<INetworkScoreCache, Object>() {
- @Override
- public void accept(INetworkScoreCache networkScoreCache, Object cookie) {
- try {
- TransferPipe.dumpAsync(networkScoreCache.asBinder(), fd, args);
- } catch (IOException | RemoteException e) {
- writer.println("Failed to dump score cache: " + e);
- }
- }
- }, getScoreCacheLists());
-
synchronized (mServiceConnectionLock) {
if (mServiceConnection != null) {
mServiceConnection.dump(fd, writer, args);
diff --git a/services/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/RecoverySystemService.java
deleted file mode 100644
index 997178e..0000000
--- a/services/core/java/com/android/server/RecoverySystemService.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You 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;
-
-import android.content.Context;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.os.IRecoverySystem;
-import android.os.IRecoverySystemProgressListener;
-import android.os.PowerManager;
-import android.os.RecoverySystem;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.util.Slog;
-
-import libcore.io.IoUtils;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-
-/**
- * The recovery system service is responsible for coordinating recovery related
- * functions on the device. It sets up (or clears) the bootloader control block
- * (BCB), which will be read by the bootloader and the recovery image. It also
- * triggers /system/bin/uncrypt via init to de-encrypt an OTA package on the
- * /data partition so that it can be accessed under the recovery image.
- */
-public final class RecoverySystemService extends SystemService {
- private static final String TAG = "RecoverySystemService";
- private static final boolean DEBUG = false;
-
- // The socket at /dev/socket/uncrypt to communicate with uncrypt.
- private static final String UNCRYPT_SOCKET = "uncrypt";
-
- // The init services that communicate with /system/bin/uncrypt.
- private static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
- private static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
- private static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
-
- private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
-
- private static final Object sRequestLock = new Object();
-
- private Context mContext;
-
- public RecoverySystemService(Context context) {
- super(context);
- mContext = context;
- }
-
- @Override
- public void onStart() {
- publishBinderService(Context.RECOVERY_SERVICE, new BinderService());
- }
-
- private final class BinderService extends IRecoverySystem.Stub {
- @Override // Binder call
- public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
- if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
-
- synchronized (sRequestLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
-
- final boolean available = checkAndWaitForUncryptService();
- if (!available) {
- Slog.e(TAG, "uncrypt service is unavailable.");
- return false;
- }
-
- // Write the filename into UNCRYPT_PACKAGE_FILE to be read by
- // uncrypt.
- RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
-
- try (FileWriter uncryptFile = new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE)) {
- uncryptFile.write(filename + "\n");
- } catch (IOException e) {
- Slog.e(TAG, "IOException when writing \"" +
- RecoverySystem.UNCRYPT_PACKAGE_FILE + "\":", e);
- return false;
- }
-
- // Trigger uncrypt via init.
- SystemProperties.set("ctl.start", "uncrypt");
-
- // Connect to the uncrypt service socket.
- LocalSocket socket = connectService();
- if (socket == null) {
- Slog.e(TAG, "Failed to connect to uncrypt socket");
- return false;
- }
-
- // Read the status from the socket.
- DataInputStream dis = null;
- DataOutputStream dos = null;
- try {
- dis = new DataInputStream(socket.getInputStream());
- dos = new DataOutputStream(socket.getOutputStream());
- int lastStatus = Integer.MIN_VALUE;
- while (true) {
- int status = dis.readInt();
- // Avoid flooding the log with the same message.
- if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
- continue;
- }
- lastStatus = status;
-
- if (status >= 0 && status <= 100) {
- // Update status
- Slog.i(TAG, "uncrypt read status: " + status);
- if (listener != null) {
- try {
- listener.onProgress(status);
- } catch (RemoteException ignored) {
- Slog.w(TAG, "RemoteException when posting progress");
- }
- }
- if (status == 100) {
- Slog.i(TAG, "uncrypt successfully finished.");
- // Ack receipt of the final status code. uncrypt
- // waits for the ack so the socket won't be
- // destroyed before we receive the code.
- dos.writeInt(0);
- break;
- }
- } else {
- // Error in /system/bin/uncrypt.
- Slog.e(TAG, "uncrypt failed with status: " + status);
- // Ack receipt of the final status code. uncrypt waits
- // for the ack so the socket won't be destroyed before
- // we receive the code.
- dos.writeInt(0);
- return false;
- }
- }
- } catch (IOException e) {
- Slog.e(TAG, "IOException when reading status: ", e);
- return false;
- } finally {
- IoUtils.closeQuietly(dis);
- IoUtils.closeQuietly(dos);
- IoUtils.closeQuietly(socket);
- }
-
- return true;
- }
- }
-
- @Override // Binder call
- public boolean clearBcb() {
- if (DEBUG) Slog.d(TAG, "clearBcb");
- synchronized (sRequestLock) {
- return setupOrClearBcb(false, null);
- }
- }
-
- @Override // Binder call
- public boolean setupBcb(String command) {
- if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
- synchronized (sRequestLock) {
- return setupOrClearBcb(true, command);
- }
- }
-
- @Override // Binder call
- public void rebootRecoveryWithCommand(String command) {
- if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
- synchronized (sRequestLock) {
- if (!setupOrClearBcb(true, command)) {
- return;
- }
-
- // Having set up the BCB, go ahead and reboot.
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- pm.reboot(PowerManager.REBOOT_RECOVERY);
- }
- }
-
- /**
- * Check if any of the init services is still running. If so, we cannot
- * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
- * it may break the socket communication since init creates / deletes
- * the socket (/dev/socket/uncrypt) on service start / exit.
- */
- private boolean checkAndWaitForUncryptService() {
- for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
- final String uncryptService = SystemProperties.get(INIT_SERVICE_UNCRYPT);
- final String setupBcbService = SystemProperties.get(INIT_SERVICE_SETUP_BCB);
- final String clearBcbService = SystemProperties.get(INIT_SERVICE_CLEAR_BCB);
- final boolean busy = "running".equals(uncryptService) ||
- "running".equals(setupBcbService) || "running".equals(clearBcbService);
- if (DEBUG) {
- Slog.i(TAG, "retry: " + retry + " busy: " + busy +
- " uncrypt: [" + uncryptService + "]" +
- " setupBcb: [" + setupBcbService + "]" +
- " clearBcb: [" + clearBcbService + "]");
- }
-
- if (!busy) {
- return true;
- }
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- Slog.w(TAG, "Interrupted:", e);
- }
- }
-
- return false;
- }
-
- private LocalSocket connectService() {
- LocalSocket socket = new LocalSocket();
- boolean done = false;
- // The uncrypt socket will be created by init upon receiving the
- // service request. It may not be ready by this point. So we will
- // keep retrying until success or reaching timeout.
- for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
- try {
- socket.connect(new LocalSocketAddress(UNCRYPT_SOCKET,
- LocalSocketAddress.Namespace.RESERVED));
- done = true;
- break;
- } catch (IOException ignored) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- Slog.w(TAG, "Interrupted:", e);
- }
- }
- }
- if (!done) {
- Slog.e(TAG, "Timed out connecting to uncrypt socket");
- return null;
- }
- return socket;
- }
-
- private boolean setupOrClearBcb(boolean isSetup, String command) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
-
- final boolean available = checkAndWaitForUncryptService();
- if (!available) {
- Slog.e(TAG, "uncrypt service is unavailable.");
- return false;
- }
-
- if (isSetup) {
- SystemProperties.set("ctl.start", "setup-bcb");
- } else {
- SystemProperties.set("ctl.start", "clear-bcb");
- }
-
- // Connect to the uncrypt service socket.
- LocalSocket socket = connectService();
- if (socket == null) {
- Slog.e(TAG, "Failed to connect to uncrypt socket");
- return false;
- }
-
- DataInputStream dis = null;
- DataOutputStream dos = null;
- try {
- dis = new DataInputStream(socket.getInputStream());
- dos = new DataOutputStream(socket.getOutputStream());
-
- // Send the BCB commands if it's to setup BCB.
- if (isSetup) {
- byte[] cmdUtf8 = command.getBytes("UTF-8");
- dos.writeInt(cmdUtf8.length);
- dos.write(cmdUtf8, 0, cmdUtf8.length);
- }
-
- // Read the status from the socket.
- int status = dis.readInt();
-
- // Ack receipt of the status code. uncrypt waits for the ack so
- // the socket won't be destroyed before we receive the code.
- dos.writeInt(0);
-
- if (status == 100) {
- Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear") +
- " bcb successfully finished.");
- } else {
- // Error in /system/bin/uncrypt.
- Slog.e(TAG, "uncrypt failed with status: " + status);
- return false;
- }
- } catch (IOException e) {
- Slog.e(TAG, "IOException when communicating with uncrypt:", e);
- return false;
- } finally {
- IoUtils.closeQuietly(dis);
- IoUtils.closeQuietly(dos);
- IoUtils.closeQuietly(socket);
- }
-
- return true;
- }
- }
-}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 9693585..d1bc6af 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2803,12 +2803,6 @@
enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
- // When a user has secure lock screen, require secret to actually unlock.
- // This check is mostly in place for emulation mode.
- if (mLockPatternUtils.isSecure(userId) && ArrayUtils.isEmpty(secret)) {
- throw new IllegalStateException("Secret required to unlock secure user " + userId);
- }
-
try {
mVold.unlockUserKey(userId, serialNumber, encodeBytes(token),
encodeBytes(secret));
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 30a3563..d1e4231 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.annotation.IntRange;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -41,6 +42,7 @@
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -53,6 +55,7 @@
import android.service.dreams.Sandman;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
+import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.R;
@@ -66,6 +69,9 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
final class UiModeManagerService extends SystemService {
private static final String TAG = UiModeManager.class.getSimpleName();
@@ -81,6 +87,7 @@
private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
private int mNightMode = UiModeManager.MODE_NIGHT_NO;
+ private Map<Integer, String> mCarModePackagePriority = new HashMap<>();
private boolean mCarModeEnabled = false;
private boolean mCharging = false;
private boolean mPowerSave = false;
@@ -338,15 +345,25 @@
private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
@Override
- public void enableCarMode(int flags) {
+ public void enableCarMode(@UiModeManager.EnableCarMode int flags,
+ @IntRange(from = 0) int priority, String callingPackage) {
if (isUiModeLocked()) {
Slog.e(TAG, "enableCarMode while UI mode is locked");
return;
}
+
+ if (priority != UiModeManager.DEFAULT_PRIORITY
+ && getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Enabling car mode with a priority requires "
+ + "permission ENTER_CAR_MODE_PRIORITIZED");
+ }
+
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- setCarModeLocked(true, flags);
+ setCarModeLocked(true, flags, priority, callingPackage);
if (mSystemReady) {
updateLocked(flags, 0);
}
@@ -356,16 +373,49 @@
}
}
+ /**
+ * This method is only kept around for the time being; the AIDL has an UnsupportedAppUsage
+ * tag which means this method is technically considered part of the greylist "API".
+ * @param flags
+ */
@Override
- public void disableCarMode(int flags) {
+ public void disableCarMode(@UiModeManager.DisableCarMode int flags) {
+ disableCarModeByCallingPackage(flags, null /* callingPackage */);
+ }
+
+ /**
+ * Handles requests to disable car mode.
+ * @param flags Disable car mode flags
+ * @param callingPackage
+ */
+ @Override
+ public void disableCarModeByCallingPackage(@UiModeManager.DisableCarMode int flags,
+ String callingPackage) {
if (isUiModeLocked()) {
Slog.e(TAG, "disableCarMode while UI mode is locked");
return;
}
+
+ // If the caller is the system, we will allow the DISABLE_CAR_MODE_ALL_PRIORITIES car
+ // mode flag to be specified; this is so that the user can disable car mode at all
+ // priorities using the persistent notification.
+ boolean isSystemCaller = Binder.getCallingUid() == Process.SYSTEM_UID;
+ final int carModeFlags =
+ isSystemCaller ? flags : flags & ~UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES;
+
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- setCarModeLocked(false, 0);
+ // Determine if the caller has enabled car mode at a priority other than the
+ // default one. If they have, then attempt to disable at that priority.
+ int priority = mCarModePackagePriority.entrySet()
+ .stream()
+ .filter(e -> e.getValue().equals(callingPackage))
+ .findFirst()
+ .map(Map.Entry::getKey)
+ .orElse(UiModeManager.DEFAULT_PRIORITY);
+
+ setCarModeLocked(false, carModeFlags, priority, callingPackage);
if (mSystemReady) {
updateLocked(0, flags);
}
@@ -471,19 +521,32 @@
synchronized (mLock) {
pw.println("Current UI Mode Service state:");
pw.print(" mDockState="); pw.print(mDockState);
- pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
+ pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
+
pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" (");
- pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") ");
- pw.print(" mNightModeLocked="); pw.print(mNightModeLocked);
- pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
- pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
- pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags);
- pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch);
+ pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") ");
+ pw.print(" mNightModeLocked="); pw.println(mNightModeLocked);
+
+ pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
+ pw.print(" (carModeApps=");
+ for (Map.Entry<Integer, String> entry : mCarModePackagePriority.entrySet()) {
+ pw.print(entry.getKey());
+ pw.print(":");
+ pw.print(entry.getValue());
+ pw.print(" ");
+ }
+ pw.println("");
+ pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
+ pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags);
+ pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch);
+
pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
- pw.print(" mUiModeLocked="); pw.print(mUiModeLocked);
- pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
+ pw.print(" mUiModeLocked="); pw.print(mUiModeLocked);
+ pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
+
pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration);
- pw.print(" mSystemReady="); pw.println(mSystemReady);
+ pw.print(" mSystemReady="); pw.println(mSystemReady);
+
if (mTwilightManager != null) {
// We may not have a TwilightManager.
pw.print(" mTwilightService.getLastTwilightState()=");
@@ -506,12 +569,32 @@
}
}
- void setCarModeLocked(boolean enabled, int flags) {
- if (mCarModeEnabled != enabled) {
- mCarModeEnabled = enabled;
+ /**
+ * Updates the global car mode state.
+ * The device is considered to be in car mode if there exists an app at any priority level which
+ * has entered car mode.
+ *
+ * @param enabled {@code true} if the caller wishes to enable car mode, {@code false} otherwise.
+ * @param flags Flags used when enabling/disabling car mode.
+ * @param priority The priority level for entering or exiting car mode; defaults to
+ * {@link UiModeManager#DEFAULT_PRIORITY} for callers using
+ * {@link UiModeManager#enableCarMode(int)}. Callers using
+ * {@link UiModeManager#enableCarMode(int, int)} may specify a priority.
+ * @param packageName The package name of the app which initiated the request to enable or
+ * disable car mode.
+ */
+ void setCarModeLocked(boolean enabled, int flags, int priority, String packageName) {
+ if (enabled) {
+ enableCarMode(priority, packageName);
+ } else {
+ disableCarMode(flags, priority, packageName);
+ }
+ boolean isCarModeNowEnabled = isCarModeEnabled();
+ if (mCarModeEnabled != isCarModeNowEnabled) {
+ mCarModeEnabled = isCarModeNowEnabled;
// When exiting car mode, restore night mode from settings
- if (!mCarModeEnabled) {
+ if (!isCarModeNowEnabled) {
Context context = getContext();
updateNightModeFromSettings(context,
context.getResources(),
@@ -521,11 +604,102 @@
mCarModeEnableFlags = flags;
}
+ /**
+ * Handles disabling car mode.
+ * <p>
+ * Car mode can be disabled at a priority level if any of the following is true:
+ * 1. The priority being disabled is the {@link UiModeManager#DEFAULT_PRIORITY}.
+ * 2. The priority level is enabled and the caller is the app who originally enabled it.
+ * 3. The {@link UiModeManager#DISABLE_CAR_MODE_ALL_PRIORITIES} flag was specified, meaning all
+ * car mode priorities are disabled.
+ *
+ * @param flags Car mode flags.
+ * @param priority The priority level at which to disable car mode.
+ * @param packageName The calling package which initiated the request.
+ */
+ private void disableCarMode(int flags, int priority, String packageName) {
+ boolean isDisableAll = (flags & UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES) != 0;
+ boolean isPriorityTracked = mCarModePackagePriority.keySet().contains(priority);
+ boolean isDefaultPriority = priority == UiModeManager.DEFAULT_PRIORITY;
+ boolean isChangeAllowed =
+ // Anyone can disable the default priority.
+ isDefaultPriority
+ // If priority was enabled, only enabling package can disable it.
+ || isPriorityTracked && mCarModePackagePriority.get(priority).equals(packageName)
+ // Disable all priorities flag can disable all regardless.
+ || isDisableAll;
+ if (isChangeAllowed) {
+ Slog.d(TAG, "disableCarMode: disabling, priority=" + priority
+ + ", packageName=" + packageName);
+ if (isDisableAll) {
+ Set<Map.Entry<Integer, String>> entries =
+ new ArraySet<>(mCarModePackagePriority.entrySet());
+ mCarModePackagePriority.clear();
+
+ for (Map.Entry<Integer, String> entry : entries) {
+ notifyCarModeDisabled(entry.getKey(), entry.getValue());
+ }
+ } else {
+ mCarModePackagePriority.remove(priority);
+ notifyCarModeDisabled(priority, packageName);
+ }
+ }
+ }
+
+ /**
+ * Handles enabling car mode.
+ * <p>
+ * Car mode can be enabled at any priority if it has not already been enabled at that priority.
+ * The calling package is tracked for the first app which enters priority at the
+ * {@link UiModeManager#DEFAULT_PRIORITY}, though any app can disable it at that priority.
+ *
+ * @param priority The priority for enabling car mode.
+ * @param packageName The calling package which initiated the request.
+ */
+ private void enableCarMode(int priority, String packageName) {
+ boolean isPriorityTracked = mCarModePackagePriority.containsKey(priority);
+ boolean isPackagePresent = mCarModePackagePriority.containsValue(packageName);
+ if (!isPriorityTracked && !isPackagePresent) {
+ Slog.d(TAG, "enableCarMode: enabled at priority=" + priority + ", packageName="
+ + packageName);
+ mCarModePackagePriority.put(priority, packageName);
+ notifyCarModeEnabled(priority, packageName);
+ } else {
+ Slog.d(TAG, "enableCarMode: car mode at priority " + priority + " already enabled.");
+ }
+
+ }
+
+ private void notifyCarModeEnabled(int priority, String packageName) {
+ Intent intent = new Intent(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
+ intent.putExtra(UiModeManager.EXTRA_CALLING_PACKAGE, packageName);
+ intent.putExtra(UiModeManager.EXTRA_PRIORITY, priority);
+ getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
+ android.Manifest.permission.HANDLE_CAR_MODE_CHANGES);
+ }
+
+ private void notifyCarModeDisabled(int priority, String packageName) {
+ Intent intent = new Intent(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
+ intent.putExtra(UiModeManager.EXTRA_CALLING_PACKAGE, packageName);
+ intent.putExtra(UiModeManager.EXTRA_PRIORITY, priority);
+ getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
+ android.Manifest.permission.HANDLE_CAR_MODE_CHANGES);
+ }
+
+ /**
+ * Determines if car mode is enabled at any priority level.
+ * @return {@code true} if car mode is enabled, {@code false} otherwise.
+ */
+ private boolean isCarModeEnabled() {
+ return mCarModePackagePriority.size() > 0;
+ }
+
private void updateDockState(int newState) {
synchronized (mLock) {
if (newState != mDockState) {
mDockState = newState;
- setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR, 0);
+ setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR, 0,
+ UiModeManager.DEFAULT_PRIORITY, "" /* packageName */);
if (mSystemReady) {
updateLocked(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME, 0);
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index d622fb4..0db8495 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -28,8 +28,8 @@
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
+import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.V1_0.EffectStrength;
-import android.hardware.vibrator.V1_4.Capabilities;
import android.icu.text.DateFormat;
import android.media.AudioAttributes;
import android.media.AudioManager;
@@ -1153,7 +1153,7 @@
long duration = vibratorPerformEffect(prebaked.getId(),
prebaked.getEffectStrength(), vib);
long timeout = duration;
- if ((mCapabilities & Capabilities.PERFORM_COMPLETION_CALLBACK) != 0) {
+ if ((mCapabilities & IVibrator.CAP_PERFORM_CALLBACK) != 0) {
timeout *= ASYNC_TIMEOUT_MULTIPLIER;
}
if (timeout > 0) {
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 83ad4e7..454941c 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -89,6 +89,7 @@
"/system/bin/drmserver",
"/system/bin/mediadrmserver",
"/system/bin/mediaserver",
+ "/system/bin/netd",
"/system/bin/sdcard",
"/system/bin/surfaceflinger",
"/system/bin/vold",
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7609632..d07ec48 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -24,6 +24,7 @@
import static android.Manifest.permission.REMOVE_TASKS;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS;
import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
@@ -348,7 +349,6 @@
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
import com.android.server.appop.AppOpsService;
-import com.android.server.compat.CompatConfig;
import com.android.server.compat.PlatformCompat;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.firewall.IntentFirewall;
@@ -5048,8 +5048,9 @@
bindApplicationTimeMillis = SystemClock.elapsedRealtime();
mAtmInternal.preBindApplication(app.getWindowProcessController());
final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
- long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info);
+ long[] disabledCompatChanges = {};
if (mPlatformCompat != null) {
+ disabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
mPlatformCompat.resetReporting(app.info);
}
if (app.isolatedEntryPoint != null) {
@@ -5275,11 +5276,14 @@
// Inform checkpointing systems of success
try {
+ // This line is needed to CTS test for the correct exception handling
+ // See b/138952436#comment36 for context
+ Slog.i(TAG, "About to commit checkpoint");
IStorageManager storageManager = PackageHelper.getStorageManager();
storageManager.commitChanges();
} catch (Exception e) {
PowerManager pm = (PowerManager)
- mInjector.getContext().getSystemService(Context.POWER_SERVICE);
+ mContext.getSystemService(Context.POWER_SERVICE);
pm.reboot("Checkpoint commit failed");
}
@@ -15769,13 +15773,12 @@
boolean disableHiddenApiChecks = ai.usesNonSdkApi()
|| (flags & INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
- if (disableHiddenApiChecks) {
+ boolean disableTestApiChecks = disableHiddenApiChecks
+ || (flags & INSTR_FLAG_DISABLE_TEST_API_CHECKS) != 0;
+ if (disableHiddenApiChecks || disableTestApiChecks) {
enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
"disable hidden API checks");
}
- // Allow instrumented processes access to test APIs.
- // TODO(satayev): make this configurable via testing framework.
- boolean disableTestApiChecks = true;
final boolean mountExtStorageFull = isCallerShell()
&& (flags & INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL) != 0;
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 0c1388c..d9e4844 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -41,6 +41,7 @@
import android.app.usage.ConfigurationStats;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageStatsManager;
+import android.compat.Compatibility;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.Context;
@@ -80,15 +81,17 @@
import android.text.TextUtils;
import android.text.format.Time;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.DisplayMetrics;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
+import com.android.internal.compat.CompatibilityChangeConfig;
import com.android.internal.util.HexDump;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
-import com.android.server.compat.CompatConfig;
+import com.android.server.compat.PlatformCompat;
import java.io.BufferedReader;
import java.io.File;
@@ -2868,56 +2871,49 @@
return 0;
}
- private void killPackage(String packageName, PrintWriter pw) throws RemoteException {
- int uid = mPm.getPackageUid(packageName, 0, mUserId);
- if (uid < 0) {
- // uid is negative if the package wasn't found.
- pw.println("Didn't find package " + packageName + " on device.");
- } else {
- pw.println("Killing package " + packageName + " (UID " + uid + ").");
- final long origId = Binder.clearCallingIdentity();
- mInterface.killUid(UserHandle.getAppId(uid),
- UserHandle.USER_ALL, "killPackage");
- Binder.restoreCallingIdentity(origId);
- }
- }
-
private int runCompat(PrintWriter pw) throws RemoteException {
- final CompatConfig config = CompatConfig.get();
+ final PlatformCompat platformCompat = (PlatformCompat)
+ ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
String toggleValue = getNextArgRequired();
long changeId;
String changeIdString = getNextArgRequired();
try {
changeId = Long.parseLong(changeIdString);
} catch (NumberFormatException e) {
- changeId = config.lookupChangeId(changeIdString);
+ changeId = platformCompat.lookupChangeId(changeIdString);
}
if (changeId == -1) {
pw.println("Unknown or invalid change: '" + changeIdString + "'.");
+ return -1;
}
String packageName = getNextArgRequired();
+ if (!platformCompat.isKnownChangeId(changeId)) {
+ pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
+ + " could have no effect.");
+ }
+ ArraySet<Long> enabled = new ArraySet<>();
+ ArraySet<Long> disabled = new ArraySet<>();
switch (toggleValue) {
case "enable":
- if (!config.addOverride(changeId, packageName, true)) {
- pw.println("Warning! Change " + changeId + " is not known yet. Enabling it"
- + " could have no effect.");
- }
+ enabled.add(changeId);
pw.println("Enabled change " + changeId + " for " + packageName + ".");
- killPackage(packageName, pw);
+ CompatibilityChangeConfig overrides =
+ new CompatibilityChangeConfig(
+ new Compatibility.ChangeConfig(enabled, disabled));
+ platformCompat.setOverrides(overrides, packageName);
return 0;
case "disable":
- if (!config.addOverride(changeId, packageName, false)) {
- pw.println("Warning! Change " + changeId + " is not known yet. Disabling it"
- + " could have no effect.");
- }
+ disabled.add(changeId);
pw.println("Disabled change " + changeId + " for " + packageName + ".");
- killPackage(packageName, pw);
+ overrides =
+ new CompatibilityChangeConfig(
+ new Compatibility.ChangeConfig(enabled, disabled));
+ platformCompat.setOverrides(overrides, packageName);
return 0;
case "reset":
- if (config.removeOverride(changeId, packageName)) {
+ if (platformCompat.clearOverride(changeId, packageName)) {
pw.println("Reset change " + changeId + " for " + packageName
+ " to default value.");
- killPackage(packageName, pw);
} else {
pw.println("No override exists for changeId " + changeId + ".");
}
@@ -3032,7 +3028,8 @@
pw.println(" specified then send to all users.");
pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
- pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
+ pw.println(" [--user <USER_ID> | current]");
+ pw.println(" [--no-hidden-api-checks [--no-test-api-checks]]");
pw.println(" [--no-isolated-storage]");
pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
@@ -3052,6 +3049,8 @@
pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
pw.println(" current user if not specified.");
pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
+ pw.println(" --no-test-api-checks: disable restrictions to test APIs, if hidden");
+ pw.println(" API checks are enabled.");
pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
pw.println(" mount full external storage");
pw.println(" --no-window-animation: turn off window animations while running.");
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 5255316..0524f91 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -445,7 +445,7 @@
if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO) != 0) {
// We were asked to fetch Telephony data.
if (mTelephony == null) {
- mTelephony = TelephonyManager.from(mContext);
+ mTelephony = mContext.getSystemService(TelephonyManager.class);
}
if (mTelephony != null) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c2f4529..5674046 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -731,7 +731,7 @@
public void notePhoneState(int state) {
enforceCallingPermission();
- int simState = TelephonyManager.getDefault().getSimState();
+ int simState = mContext.getSystemService(TelephonyManager.class).getSimState();
synchronized (mStats) {
mStats.notePhoneStateLocked(state, simState);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 24569a6..48f08e3 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1461,10 +1461,13 @@
}
if (!TextUtils.isEmpty(packageName)) {
PackageManager pm = mContext.getPackageManager();
+ ActivityManager am =
+ (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
+
if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
== PackageManager.PERMISSION_GRANTED) {
try {
- assistantUid = pm.getPackageUid(packageName, 0);
+ assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser());
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG,
"updateAssistantUId() could not find UID for package: " + packageName);
@@ -3908,8 +3911,7 @@
final boolean muteSystem = (zenPolicy.priorityCategories
& NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0;
final boolean muteNotificationAndRing = ZenModeConfig
- .areAllPriorityOnlyNotificationZenSoundsMuted(
- mNm.getConsolidatedNotificationPolicy());
+ .areAllPriorityOnlyNotificationZenSoundsMuted(zenPolicy);
return muteAlarms && isAlarm(streamType)
|| muteMedia && isMedia(streamType)
|| muteSystem && isSystem(streamType)
@@ -3921,11 +3923,13 @@
}
/**
- * DND total silence: media and alarms streams are tied to the muted ringer
- * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)}
- * DND alarms only: notification, ringer + system muted (by default tied to muted ringer mode)
- * DND priority only: alarms, media, system streams can be muted separate from ringer based on
- * zenPolicy (this method determines which streams)
+ * Notifications, ringer and system sounds are controlled by the ringer:
+ * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can
+ * also be muted by DND based on the DND mode:
+ * DND total silence: media and alarms streams can be muted by DND
+ * DND alarms only: no streams additionally controlled by DND
+ * DND priority only: alarms, media, system, ringer and notification streams can be muted by
+ * DND. The current applied zenPolicy determines which streams will be muted by DND.
* @return true if changed, else false
*/
private boolean updateZenModeAffectedStreams() {
@@ -3946,6 +3950,11 @@
& NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
}
+
+ if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(zenPolicy)) {
+ zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
+ zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
+ }
}
if (mZenModeAffectedStreams != zenModeAffectedStreams) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index d6ec22b..490cce3 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -43,13 +43,14 @@
import java.util.Set;
import javax.xml.datatype.DatatypeConfigurationException;
+
/**
* This class maintains state relating to platform compatibility changes.
*
* <p>It stores the default configuration for each change, and any per-package overrides that have
* been configured.
*/
-public final class CompatConfig {
+final class CompatConfig {
private static final String TAG = "CompatConfig";
@@ -61,13 +62,13 @@
private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();
@VisibleForTesting
- public CompatConfig() {
+ CompatConfig() {
}
/**
* @return The static instance of this class to be used within the system server.
*/
- public static CompatConfig get() {
+ static CompatConfig get() {
return sInstance;
}
@@ -77,7 +78,7 @@
*
* @param change The change to add. Any change with the same ID will be overwritten.
*/
- public void addChange(CompatChange change) {
+ void addChange(CompatChange change) {
synchronized (mChanges) {
mChanges.put(change.getId(), change);
}
@@ -89,10 +90,10 @@
*
* @param app The app in question
* @return A sorted long array of change IDs. We use a primitive array to minimize memory
- * footprint: Every app process will store this array statically so we aim to reduce
- * overhead as much as possible.
+ * footprint: Every app process will store this array statically so we aim to reduce
+ * overhead as much as possible.
*/
- public long[] getDisabledChanges(ApplicationInfo app) {
+ long[] getDisabledChanges(ApplicationInfo app) {
LongArray disabled = new LongArray();
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
@@ -113,7 +114,7 @@
* @param name Name of the change to look up
* @return The change ID, or {@code -1} if no change with that name exists.
*/
- public long lookupChangeId(String name) {
+ long lookupChangeId(String name) {
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
if (TextUtils.equals(mChanges.valueAt(i).getName(), name)) {
@@ -128,11 +129,11 @@
* Find if a given change is enabled for a given application.
*
* @param changeId The ID of the change in question
- * @param app App to check for
+ * @param app App to check for
* @return {@code true} if the change is enabled for this app. Also returns {@code true} if the
- * change ID is not known, as unknown changes are enabled by default.
+ * change ID is not known, as unknown changes are enabled by default.
*/
- public boolean isChangeEnabled(long changeId, ApplicationInfo app) {
+ boolean isChangeEnabled(long changeId, ApplicationInfo app) {
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
if (c == null) {
@@ -150,14 +151,15 @@
*
* <p>Note, package overrides are not persistent and will be lost on system or runtime restart.
*
- * @param changeId The ID of the change to be overridden. Note, this call will succeed even if
- * this change is not known; it will only have any effect if any code in the
- * platform is gated on the ID given.
+ * @param changeId The ID of the change to be overridden. Note, this call will succeed even
+ * if
+ * this change is not known; it will only have any effect if any code in the
+ * platform is gated on the ID given.
* @param packageName The app package name to override the change for.
- * @param enabled If the change should be enabled or disabled.
+ * @param enabled If the change should be enabled or disabled.
* @return {@code true} if the change existed before adding the override.
*/
- public boolean addOverride(long changeId, String packageName, boolean enabled) {
+ boolean addOverride(long changeId, String packageName, boolean enabled) {
boolean alreadyKnown = true;
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
@@ -172,15 +174,27 @@
}
/**
+ * Check whether the change is known to the compat config.
+ *
+ * @return {@code true} if the change is known.
+ */
+ boolean isKnownChangeId(long changeId) {
+ synchronized (mChanges) {
+ CompatChange c = mChanges.get(changeId);
+ return c != null;
+ }
+ }
+
+ /**
* Removes an override previously added via {@link #addOverride(long, String, boolean)}. This
* restores the default behaviour for the given change and app, once any app processes have been
* restarted.
*
- * @param changeId The ID of the change that was overridden.
+ * @param changeId The ID of the change that was overridden.
* @param packageName The app package name that was overridden.
* @return {@code true} if an override existed;
*/
- public boolean removeOverride(long changeId, String packageName) {
+ boolean removeOverride(long changeId, String packageName) {
boolean overrideExists = false;
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
@@ -191,22 +205,22 @@
}
return overrideExists;
}
+
/**
* Overrides the enabled state for a given change and app. This method is intended to be used
* *only* for debugging purposes.
*
* <p>Note, package overrides are not persistent and will be lost on system or runtime restart.
*
- * @param overrides list of overrides to default changes config.
+ * @param overrides list of overrides to default changes config.
* @param packageName app for which the overrides will be applied.
*/
- public void addOverrides(
- CompatibilityChangeConfig overrides, String packageName) {
+ void addOverrides(CompatibilityChangeConfig overrides, String packageName) {
synchronized (mChanges) {
- for (Long changeId: overrides.enabledChanges()) {
+ for (Long changeId : overrides.enabledChanges()) {
addOverride(changeId, packageName, true);
}
- for (Long changeId: overrides.disabledChanges()) {
+ for (Long changeId : overrides.disabledChanges()) {
addOverride(changeId, packageName, false);
}
}
@@ -221,7 +235,7 @@
*
* @param packageName The package for which the overrides should be purged.
*/
- public void removePackageOverrides(String packageName) {
+ void removePackageOverrides(String packageName) {
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
mChanges.valueAt(i).removePackageOverride(packageName);
@@ -230,11 +244,11 @@
}
/**
- * Dumps the current list of compatibility config information.
- *
- * @param pw The {@link PrintWriter} instance to which the information will be dumped.
- */
- public void dumpConfig(PrintWriter pw) {
+ * Dumps the current list of compatibility config information.
+ *
+ * @param pw The {@link PrintWriter} instance to which the information will be dumped.
+ */
+ void dumpConfig(PrintWriter pw) {
synchronized (mChanges) {
if (mChanges.size() == 0) {
pw.println("No compat overrides.");
@@ -252,10 +266,10 @@
*
* @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped.
* @return A {@link CompatibilityChangeConfig} which contains the compat config info for the
- * given app.
+ * given app.
*/
- public CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
+ CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
Set<Long> enabled = new HashSet<>();
Set<Long> disabled = new HashSet<>();
synchronized (mChanges) {
@@ -276,15 +290,15 @@
*
* @return An array of {@link CompatibilityChangeInfo} with the current changes.
*/
- public CompatibilityChangeInfo[] dumpChanges() {
+ CompatibilityChangeInfo[] dumpChanges() {
synchronized (mChanges) {
CompatibilityChangeInfo[] changeInfos = new CompatibilityChangeInfo[mChanges.size()];
for (int i = 0; i < mChanges.size(); ++i) {
CompatChange change = mChanges.valueAt(i);
changeInfos[i] = new CompatibilityChangeInfo(change.getId(),
- change.getName(),
- change.getEnableAfterTargetSdk(),
- change.getDisabled());
+ change.getName(),
+ change.getEnableAfterTargetSdk(),
+ change.getDisabled());
}
return changeInfos;
}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 75e2d22..ae5ad7e 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,9 +16,13 @@
package com.android.server.compat;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
import android.util.StatsLog;
@@ -106,12 +110,32 @@
@Override
public void setOverrides(CompatibilityChangeConfig overrides, String packageName) {
CompatConfig.get().addOverrides(overrides, packageName);
+ killPackage(packageName);
+ }
+
+ @Override
+ public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) {
+ CompatConfig.get().addOverrides(overrides, packageName);
}
@Override
public void clearOverrides(String packageName) {
CompatConfig config = CompatConfig.get();
config.removePackageOverrides(packageName);
+ killPackage(packageName);
+ }
+
+ @Override
+ public void clearOverridesForTest(String packageName) {
+ CompatConfig config = CompatConfig.get();
+ config.removePackageOverrides(packageName);
+ }
+
+ @Override
+ public boolean clearOverride(long changeId, String packageName) {
+ boolean existed = CompatConfig.get().removeOverride(changeId, packageName);
+ killPackage(packageName);
+ return existed;
}
@Override
@@ -124,6 +148,39 @@
return CompatConfig.get().dumpChanges();
}
+ /**
+ * Check whether the change is known to the compat config.
+ * @param changeId
+ * @return {@code true} if the change is known.
+ */
+ public boolean isKnownChangeId(long changeId) {
+ return CompatConfig.get().isKnownChangeId(changeId);
+
+ }
+
+ /**
+ * Retrieves the set of disabled changes for a given app. Any change ID not in the returned
+ * array is by default enabled for the app.
+ *
+ * @param appInfo The app in question
+ * @return A sorted long array of change IDs. We use a primitive array to minimize memory
+ * footprint: Every app process will store this array statically so we aim to reduce
+ * overhead as much as possible.
+ */
+ public long[] getDisabledChanges(ApplicationInfo appInfo) {
+ return CompatConfig.get().getDisabledChanges(appInfo);
+ }
+
+ /**
+ * Look up a change ID by name.
+ *
+ * @param name Name of the change to look up
+ * @return The change ID, or {@code -1} if no change with that name exists.
+ */
+ public long lookupChangeId(String name) {
+ return CompatConfig.get().lookupChangeId(name);
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
@@ -151,4 +208,34 @@
private void reportChange(long changeId, int uid, int state) {
mChangeReporter.reportChange(uid, changeId, state);
}
+
+ private void killPackage(String packageName) {
+ int uid = -1;
+ try {
+ uid = mContext.getPackageManager().getPackageUid(packageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Didn't find package " + packageName + " on device.", e);
+ return;
+ }
+
+ Slog.d(TAG, "Killing package " + packageName + " (UID " + uid + ").");
+ killUid(UserHandle.getAppId(uid),
+ UserHandle.USER_ALL, "PlatformCompat overrides");
+ }
+
+ private void killUid(int appId, int userId, String reason) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ IActivityManager am = ActivityManager.getService();
+ if (am != null) {
+ try {
+ am.killUid(appId, userId, reason);
+ } catch (RemoteException e) {
+ /* ignore - same process */
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index b3804c4..acedc36 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -286,8 +286,8 @@
private void startStateMachineUpdaters(Handler handler) {
mCarrierConfigChange.startListening();
- TelephonyManager.from(mContext).listen(mPhoneStateListener,
- PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+ mContext.getSystemService(TelephonyManager.class).listen(
+ mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_STATE);
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
index 2e72fbd..93227bd 100644
--- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -321,7 +321,11 @@
private void handleUpdateNetworkState(Network network, boolean isConnected,
NetworkCapabilities capabilities) {
- boolean networkAvailable = isConnected && TelephonyManager.getDefault().getDataEnabled();
+ boolean networkAvailable = false;
+ TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+ if (telephonyManager != null) {
+ networkAvailable = isConnected && telephonyManager.getDataEnabled();
+ }
NetworkAttributes networkAttributes = updateTrackedNetworksState(isConnected, network,
capabilities);
String apn = networkAttributes.mApn;
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 41806ca..08c9426 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -337,7 +337,7 @@
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
- wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
+ wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir());
service.registerLocalService();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0d9dcff..faac78d 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -7234,7 +7234,7 @@
}
private void listenForCallState() {
- TelephonyManager.from(getContext()).listen(new PhoneStateListener() {
+ getContext().getSystemService(TelephonyManager.class).listen(new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (mCallState == state) return;
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index 8facce1..dbe8367 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -49,6 +49,7 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
import com.android.server.IntentResolver;
import java.io.PrintWriter;
@@ -375,8 +376,11 @@
addProvidersLocked(pkg, chatty);
addServicesLocked(pkg, chatty);
}
- final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
- PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
+ // expect single setupwizard package
+ final String setupWizardPackage = ArrayUtils.firstOrNull(
+ sPackageManagerInternal.getKnownPackageNames(
+ PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
+
for (int i = newIntents.size() - 1; i >= 0; --i) {
final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i);
final PackageParser.Package disabledPkg = sPackageManagerInternal
@@ -410,8 +414,11 @@
final List<ActivityIntentInfo> protectedFilters = mProtectedFilters;
mProtectedFilters = null;
- final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
- PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
+ // expect single setupwizard package
+ final String setupWizardPackage = ArrayUtils.firstOrNull(
+ sPackageManagerInternal.getKnownPackageNames(
+ PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
+
if (DEBUG_FILTERS && setupWizardPackage == null) {
Slog.i(TAG, "No setup wizard;"
+ " All protected intents capped to priority 0");
diff --git a/services/core/java/com/android/server/pm/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java
index f326f1d..ec48713 100644
--- a/services/core/java/com/android/server/pm/InstructionSets.java
+++ b/services/core/java/com/android/server/pm/InstructionSets.java
@@ -22,11 +22,11 @@
import android.text.TextUtils;
import android.util.ArraySet;
+import dalvik.system.VMRuntime;
+
import java.util.ArrayList;
import java.util.List;
-import dalvik.system.VMRuntime;
-
/**
* Provides various methods for obtaining and converting of instruction sets.
*
@@ -113,12 +113,15 @@
return allInstructionSets;
}
- public static String getPrimaryInstructionSet(ApplicationInfo info) {
- if (info.primaryCpuAbi == null) {
+ /**
+ * Calculates the primary instruction set based on the computed Abis of a given package.
+ */
+ public static String getPrimaryInstructionSet(PackageAbiHelper.Abis abis) {
+ if (abis.primary == null) {
return getPreferredInstructionSet();
}
- return VMRuntime.getInstructionSet(info.primaryCpuAbi);
+ return VMRuntime.getInstructionSet(abis.primary);
}
}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 62ea95b..f8c173f 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -32,6 +32,9 @@
per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
+per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
+per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
+per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
# security
per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java
new file mode 100644
index 0000000..6f46564
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 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.pm;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageParser;
+import android.util.Pair;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.util.Set;
+
+@VisibleForTesting
+interface PackageAbiHelper {
+ /**
+ * Derive and get the location of native libraries for the given package,
+ * which varies depending on where and how the package was installed.
+ */
+ NativeLibraryPaths getNativeLibraryPaths(
+ PackageParser.Package pkg, File appLib32InstallDir);
+
+ /**
+ * Calculate the abis for a bundled app. These can uniquely be determined from the contents of
+ * the system partition, i.e whether it contains 64 or 32 bit shared libraries etc. We do not
+ * validate any of this information, and instead assume that the system was built sensibly.
+ */
+ Abis getBundledAppAbis(PackageParser.Package pkg);
+
+ /**
+ * Derive the ABI of a non-system package located at {@code pkg}. This information
+ * is derived purely on the basis of the contents of {@code pkg} and {@code cpuAbiOverride}.
+ *
+ * If {@code extractLibs} is true, native libraries are extracted from the app if required.
+ */
+ Pair<Abis, NativeLibraryPaths> derivePackageAbi(
+ PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs)
+ throws PackageManagerException;
+
+ /**
+ * Calculates adjusted ABIs for a set of packages belonging to a shared user so that they all
+ * match. i.e, so that all packages can be run inside a single process if required.
+ *
+ * Optionally, callers can pass in a parsed package via {@code scannedPackage} in which case
+ * this function will either try and make the ABI for all packages in
+ * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of
+ * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This
+ * variant is used when installing or updating a package that belongs to a shared user.
+ *
+ * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
+ * adds unnecessary complexity.
+ *
+ * @return the calculated primary abi that should be set for all non-specified packages
+ * belonging to the shared user.
+ */
+ @Nullable
+ String getAdjustedAbiForSharedUser(
+ Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage);
+
+ /**
+ * The native library paths and related properties that should be set on a
+ * {@link android.content.pm.PackageParser.Package}.
+ */
+ final class NativeLibraryPaths {
+ public final String nativeLibraryRootDir;
+ public final boolean nativeLibraryRootRequiresIsa;
+ public final String nativeLibraryDir;
+ public final String secondaryNativeLibraryDir;
+
+ @VisibleForTesting
+ NativeLibraryPaths(String nativeLibraryRootDir,
+ boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir,
+ String secondaryNativeLibraryDir) {
+ this.nativeLibraryRootDir = nativeLibraryRootDir;
+ this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+ this.nativeLibraryDir = nativeLibraryDir;
+ this.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+ }
+
+ public void applyTo(PackageParser.Package pkg) {
+ pkg.applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir;
+ pkg.applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+ pkg.applicationInfo.nativeLibraryDir = nativeLibraryDir;
+ pkg.applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+ }
+ }
+
+ /**
+ * The primary and secondary ABIs that should be set on a package and its package setting.
+ */
+ final class Abis {
+ public final String primary;
+ public final String secondary;
+
+ @VisibleForTesting
+ Abis(String primary, String secondary) {
+ this.primary = primary;
+ this.secondary = secondary;
+ }
+
+ Abis(PackageParser.Package pkg) {
+ this(pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi);
+ }
+
+ public void applyTo(PackageParser.Package pkg) {
+ pkg.applicationInfo.primaryCpuAbi = primary;
+ pkg.applicationInfo.secondaryCpuAbi = secondary;
+ }
+ public void applyTo(PackageSetting pkgSetting) {
+ // pkgSetting might be null during rescan following uninstall of updates
+ // to a bundled app, so accommodate that possibility. The settings in
+ // that case will be established later from the parsed package.
+ //
+ // If the settings aren't null, sync them up with what we've derived.
+ if (pkgSetting != null) {
+ pkgSetting.primaryCpuAbiString = primary;
+ pkgSetting.secondaryCpuAbiString = secondary;
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
new file mode 100644
index 0000000..1d3d24c
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2019 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.pm;
+
+import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+import static android.content.pm.PackageParser.isApkFile;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
+import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
+import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
+import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
+import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
+
+import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.Trace;
+import android.text.TextUtils;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.util.ArrayUtils;
+
+import dalvik.system.VMRuntime;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+final class PackageAbiHelperImpl implements PackageAbiHelper {
+
+ private static String calculateBundledApkRoot(final String codePathString) {
+ final File codePath = new File(codePathString);
+ final File codeRoot;
+ if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
+ codeRoot = Environment.getRootDirectory();
+ } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
+ codeRoot = Environment.getOemDirectory();
+ } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
+ codeRoot = Environment.getVendorDirectory();
+ } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+ codeRoot = Environment.getOdmDirectory();
+ } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
+ codeRoot = Environment.getProductDirectory();
+ } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+ codeRoot = Environment.getSystemExtDirectory();
+ } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+ codeRoot = Environment.getOdmDirectory();
+ } else {
+ // Unrecognized code path; take its top real segment as the apk root:
+ // e.g. /something/app/blah.apk => /something
+ try {
+ File f = codePath.getCanonicalFile();
+ File parent = f.getParentFile(); // non-null because codePath is a file
+ File tmp;
+ while ((tmp = parent.getParentFile()) != null) {
+ f = parent;
+ parent = tmp;
+ }
+ codeRoot = f;
+ Slog.w(PackageManagerService.TAG, "Unrecognized code path "
+ + codePath + " - using " + codeRoot);
+ } catch (IOException e) {
+ // Can't canonicalize the code path -- shenanigans?
+ Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath);
+ return Environment.getRootDirectory().getPath();
+ }
+ }
+ return codeRoot.getPath();
+ }
+
+ // Utility method that returns the relative package path with respect
+ // to the installation directory. Like say for /data/data/com.test-1.apk
+ // string com.test-1 is returned.
+ private static String deriveCodePathName(String codePath) {
+ if (codePath == null) {
+ return null;
+ }
+ final File codeFile = new File(codePath);
+ final String name = codeFile.getName();
+ if (codeFile.isDirectory()) {
+ return name;
+ } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
+ final int lastDot = name.lastIndexOf('.');
+ return name.substring(0, lastDot);
+ } else {
+ Slog.w(PackageManagerService.TAG, "Odd, " + codePath + " doesn't look like an APK");
+ return null;
+ }
+ }
+
+ private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
+ PackageManagerException {
+ if (copyRet < 0) {
+ if (copyRet != PackageManager.NO_NATIVE_LIBRARIES
+ && copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+ throw new PackageManagerException(copyRet, message);
+ }
+ }
+ }
+
+ @Override
+ public NativeLibraryPaths getNativeLibraryPaths(
+ PackageParser.Package pkg, File appLib32InstallDir) {
+ return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.codePath,
+ pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(),
+ pkg.applicationInfo.isUpdatedSystemApp());
+ }
+
+ private static NativeLibraryPaths getNativeLibraryPaths(final Abis abis,
+ final File appLib32InstallDir, final String codePath, final String sourceDir,
+ final boolean isSystemApp, final boolean isUpdatedSystemApp) {
+ final File codeFile = new File(codePath);
+ final boolean bundledApp = isSystemApp && !isUpdatedSystemApp;
+
+ final String nativeLibraryRootDir;
+ final boolean nativeLibraryRootRequiresIsa;
+ final String nativeLibraryDir;
+ final String secondaryNativeLibraryDir;
+
+ if (isApkFile(codeFile)) {
+ // Monolithic install
+ if (bundledApp) {
+ // If "/system/lib64/apkname" exists, assume that is the per-package
+ // native library directory to use; otherwise use "/system/lib/apkname".
+ final String apkRoot = calculateBundledApkRoot(sourceDir);
+ final boolean is64Bit = VMRuntime.is64BitInstructionSet(
+ getPrimaryInstructionSet(abis));
+
+ // This is a bundled system app so choose the path based on the ABI.
+ // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
+ // is just the default path.
+ final String apkName = deriveCodePathName(codePath);
+ final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
+ nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
+ apkName).getAbsolutePath();
+
+ if (abis.secondary != null) {
+ final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
+ secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
+ secondaryLibDir, apkName).getAbsolutePath();
+ } else {
+ secondaryNativeLibraryDir = null;
+ }
+ } else {
+ final String apkName = deriveCodePathName(codePath);
+ nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
+ .getAbsolutePath();
+ secondaryNativeLibraryDir = null;
+ }
+
+ nativeLibraryRootRequiresIsa = false;
+ nativeLibraryDir = nativeLibraryRootDir;
+ } else {
+ // Cluster install
+ nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
+ nativeLibraryRootRequiresIsa = true;
+
+ nativeLibraryDir = new File(nativeLibraryRootDir,
+ getPrimaryInstructionSet(abis)).getAbsolutePath();
+
+ if (abis.secondary != null) {
+ secondaryNativeLibraryDir = new File(nativeLibraryRootDir,
+ VMRuntime.getInstructionSet(abis.secondary)).getAbsolutePath();
+ } else {
+ secondaryNativeLibraryDir = null;
+ }
+ }
+ return new NativeLibraryPaths(nativeLibraryRootDir, nativeLibraryRootRequiresIsa,
+ nativeLibraryDir, secondaryNativeLibraryDir);
+ }
+
+ @Override
+ public Abis getBundledAppAbis(PackageParser.Package pkg) {
+ final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
+
+ // If "/system/lib64/apkname" exists, assume that is the per-package
+ // native library directory to use; otherwise use "/system/lib/apkname".
+ final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
+ final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName);
+ return abis;
+ }
+
+ /**
+ * Deduces the ABI of a bundled app and sets the relevant fields on the
+ * parsed pkg object.
+ *
+ * @param apkRoot the root of the installed apk, something like {@code /system} or
+ * {@code /oem} under which system libraries are installed.
+ * @param apkName the name of the installed package.
+ */
+ private Abis getBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
+ final File codeFile = new File(pkg.codePath);
+
+ final boolean has64BitLibs;
+ final boolean has32BitLibs;
+
+ final String primaryCpuAbi;
+ final String secondaryCpuAbi;
+ if (isApkFile(codeFile)) {
+ // Monolithic install
+ has64BitLibs =
+ (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
+ has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
+ } else {
+ // Cluster install
+ final File rootDir = new File(codeFile, LIB_DIR_NAME);
+ if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
+ && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
+ final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
+ has64BitLibs = (new File(rootDir, isa)).exists();
+ } else {
+ has64BitLibs = false;
+ }
+ if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
+ && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
+ final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
+ has32BitLibs = (new File(rootDir, isa)).exists();
+ } else {
+ has32BitLibs = false;
+ }
+ }
+
+ if (has64BitLibs && !has32BitLibs) {
+ // The package has 64 bit libs, but not 32 bit libs. Its primary
+ // ABI should be 64 bit. We can safely assume here that the bundled
+ // native libraries correspond to the most preferred ABI in the list.
+
+ primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ secondaryCpuAbi = null;
+ } else if (has32BitLibs && !has64BitLibs) {
+ // The package has 32 bit libs but not 64 bit libs. Its primary
+ // ABI should be 32 bit.
+
+ primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ secondaryCpuAbi = null;
+ } else if (has32BitLibs && has64BitLibs) {
+ // The application has both 64 and 32 bit bundled libraries. We check
+ // here that the app declares multiArch support, and warn if it doesn't.
+ //
+ // We will be lenient here and record both ABIs. The primary will be the
+ // ABI that's higher on the list, i.e, a device that's configured to prefer
+ // 64 bit apps will see a 64 bit primary ABI,
+
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
+ Slog.e(PackageManagerService.TAG,
+ "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
+ }
+
+ if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
+ primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ } else {
+ primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ }
+ } else {
+ primaryCpuAbi = null;
+ secondaryCpuAbi = null;
+ }
+ return new Abis(primaryCpuAbi, secondaryCpuAbi);
+ }
+
+ @Override
+ public Pair<Abis, NativeLibraryPaths> derivePackageAbi(
+ PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs)
+ throws PackageManagerException {
+ // Give ourselves some initial paths; we'll come back for another
+ // pass once we've determined ABI below.
+ final NativeLibraryPaths initialLibraryPaths = getNativeLibraryPaths(new Abis(pkg),
+ PackageManagerService.sAppLib32InstallDir, pkg.codePath,
+ pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(),
+ pkg.applicationInfo.isUpdatedSystemApp());
+
+ // We shouldn't attempt to extract libs from system app when it was not updated.
+ if (PackageManagerService.isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
+ extractLibs = false;
+ }
+
+ final String nativeLibraryRootStr = initialLibraryPaths.nativeLibraryRootDir;
+ final boolean useIsaSpecificSubdirs = initialLibraryPaths.nativeLibraryRootRequiresIsa;
+
+ String primaryCpuAbi = null;
+ String secondaryCpuAbi = null;
+
+ NativeLibraryHelper.Handle handle = null;
+ try {
+ handle = NativeLibraryHelper.Handle.create(pkg);
+ // TODO(multiArch): This can be null for apps that didn't go through the
+ // usual installation process. We can calculate it again, like we
+ // do during install time.
+ //
+ // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
+ // unnecessary.
+ final File nativeLibraryRoot = new File(nativeLibraryRootStr);
+
+ // Null out the abis so that they can be recalculated.
+ primaryCpuAbi = null;
+ secondaryCpuAbi = null;
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0) {
+ // Warn if we've set an abiOverride for multi-lib packages..
+ // By definition, we need to copy both 32 and 64 bit libraries for
+ // such packages.
+ if (pkg.cpuAbiOverride != null
+ && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
+ Slog.w(PackageManagerService.TAG,
+ "Ignoring abiOverride for multi arch application.");
+ }
+
+ int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
+ int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
+ if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+ if (extractLibs) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+ abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+ nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
+ useIsaSpecificSubdirs);
+ } else {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+ abi32 = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_32_BIT_ABIS);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ // Shared library native code should be in the APK zip aligned
+ if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Shared library native lib extraction not supported");
+ }
+
+ maybeThrowExceptionForMultiArchCopy(
+ "Error unpackaging 32 bit native libs for multiarch app.", abi32);
+
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+ if (extractLibs) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+ abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+ nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
+ useIsaSpecificSubdirs);
+ } else {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+ abi64 = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_64_BIT_ABIS);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ maybeThrowExceptionForMultiArchCopy(
+ "Error unpackaging 64 bit native libs for multiarch app.", abi64);
+
+ if (abi64 >= 0) {
+ // Shared library native libs should be in the APK zip aligned
+ if (extractLibs && pkg.isLibrary()) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Shared library native lib extraction not supported");
+ }
+ primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
+ }
+
+ if (abi32 >= 0) {
+ final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
+ if (abi64 >= 0) {
+ if (pkg.use32bitAbi) {
+ secondaryCpuAbi = primaryCpuAbi;
+ primaryCpuAbi = abi;
+ } else {
+ secondaryCpuAbi = abi;
+ }
+ } else {
+ primaryCpuAbi = abi;
+ }
+ }
+ } else {
+ String[] abiList = (cpuAbiOverride != null)
+ ? new String[]{cpuAbiOverride} : Build.SUPPORTED_ABIS;
+
+ // Enable gross and lame hacks for apps that are built with old
+ // SDK tools. We must scan their APKs for renderscript bitcode and
+ // not launch them if it's present. Don't bother checking on devices
+ // that don't have 64 bit support.
+ boolean needsRenderScriptOverride = false;
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null
+ && NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ needsRenderScriptOverride = true;
+ }
+
+ final int copyRet;
+ if (extractLibs) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+ copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+ nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
+ } else {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+ copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Error unpackaging native libs for app, errorCode=" + copyRet);
+ }
+
+ if (copyRet >= 0) {
+ // Shared libraries that have native libs must be multi-architecture
+ if (pkg.isLibrary()) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Shared library with native libs must be multiarch");
+ }
+ primaryCpuAbi = abiList[copyRet];
+ } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES
+ && cpuAbiOverride != null) {
+ primaryCpuAbi = cpuAbiOverride;
+ } else if (needsRenderScriptOverride) {
+ primaryCpuAbi = abiList[0];
+ }
+ }
+ } catch (IOException ioe) {
+ Slog.e(PackageManagerService.TAG, "Unable to get canonical file " + ioe.toString());
+ } finally {
+ IoUtils.closeQuietly(handle);
+ }
+
+ // Now that we've calculated the ABIs and determined if it's an internal app,
+ // we will go ahead and populate the nativeLibraryPath.
+
+ final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi);
+ return new Pair<>(abis,
+ getNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir,
+ pkg.codePath, pkg.applicationInfo.sourceDir,
+ pkg.applicationInfo.isSystemApp(),
+ pkg.applicationInfo.isUpdatedSystemApp()));
+ }
+
+ /**
+ * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
+ * i.e, so that all packages can be run inside a single process if required.
+ *
+ * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
+ * this function will either try and make the ABI for all packages in
+ * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of
+ * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This
+ * variant is used when installing or updating a package that belongs to a shared user.
+ *
+ * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
+ * adds unnecessary complexity.
+ */
+ @Override
+ @Nullable
+ public String getAdjustedAbiForSharedUser(
+ Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
+ String requiredInstructionSet = null;
+ if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
+ requiredInstructionSet = VMRuntime.getInstructionSet(
+ scannedPackage.applicationInfo.primaryCpuAbi);
+ }
+
+ PackageSetting requirer = null;
+ for (PackageSetting ps : packagesForUser) {
+ // If packagesForUser contains scannedPackage, we skip it. This will happen
+ // when scannedPackage is an update of an existing package. Without this check,
+ // we will never be able to change the ABI of any package belonging to a shared
+ // user, even if it's compatible with other packages.
+ if (scannedPackage != null && scannedPackage.packageName.equals(ps.name)) {
+ continue;
+ }
+ if (ps.primaryCpuAbiString == null) {
+ continue;
+ }
+
+ final String instructionSet =
+ VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
+ if (requiredInstructionSet != null && !requiredInstructionSet.equals(instructionSet)) {
+ // We have a mismatch between instruction sets (say arm vs arm64) warn about
+ // this but there's not much we can do.
+ String errorMessage = "Instruction set mismatch, "
+ + ((requirer == null) ? "[caller]" : requirer)
+ + " requires " + requiredInstructionSet + " whereas " + ps
+ + " requires " + instructionSet;
+ Slog.w(PackageManagerService.TAG, errorMessage);
+ }
+
+ if (requiredInstructionSet == null) {
+ requiredInstructionSet = instructionSet;
+ requirer = ps;
+ }
+ }
+
+ if (requiredInstructionSet == null) {
+ return null;
+ }
+ final String adjustedAbi;
+ if (requirer != null) {
+ // requirer != null implies that either scannedPackage was null or that
+ // scannedPackage did not require an ABI, in which case we have to adjust
+ // scannedPackage to match the ABI of the set (which is the same as
+ // requirer's ABI)
+ adjustedAbi = requirer.primaryCpuAbiString;
+ } else {
+ // requirer == null implies that we're updating all ABIs in the set to
+ // match scannedPackage.
+ adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
+ }
+ return adjustedAbi;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 6f9a918..4eddb930 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -23,6 +23,7 @@
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
+import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
@@ -1484,7 +1485,29 @@
"Too many files for apex install");
}
- mResolvedBaseFile = addedFiles[0];
+ try {
+ resolveStageDirLocked();
+ } catch (IOException e) {
+ throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
+ "Failed to resolve stage location", e);
+ }
+
+ File addedFile = addedFiles[0]; // there is only one file
+
+ // Ensure file name has proper suffix
+ final String sourceName = addedFile.getName();
+ final String targetName = sourceName.endsWith(APEX_FILE_EXTENSION)
+ ? sourceName
+ : sourceName + APEX_FILE_EXTENSION;
+ if (!FileUtils.isValidExtFilename(targetName)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Invalid filename: " + targetName);
+ }
+
+ final File targetFile = new File(mResolvedStageDir, targetName);
+ resolveAndStageFile(addedFile, targetFile);
+
+ mResolvedBaseFile = targetFile;
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 868b90a..8d31b34 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -93,14 +93,12 @@
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
-import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
-import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
@@ -278,6 +276,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
@@ -433,7 +432,7 @@
// user, but by default initialize to this.
public static final boolean DEBUG_DEXOPT = false;
- private static final boolean DEBUG_ABI_SELECTION = false;
+ static final boolean DEBUG_ABI_SELECTION = false;
private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
private static final boolean DEBUG_APP_DATA = false;
@@ -663,7 +662,8 @@
private static final File sAppInstallDir =
new File(Environment.getDataDirectory(), "app");
/** Directory where installed application's 32-bit native libraries are copied. */
- private static final File sAppLib32InstallDir =
+ @VisibleForTesting
+ static final File sAppLib32InstallDir =
new File(Environment.getDataDirectory(), "app-lib");
// ----------------------------------------------------------------
@@ -754,6 +754,30 @@
private final ApexManager mApexManager;
+ private final Injector mInjector;
+
+ /**
+ * Unit tests will instantiate and / or extend to mock dependencies / behaviors.
+ */
+ @VisibleForTesting
+ static class Injector {
+ private final UserManagerInternal mUserManager;
+ private final PackageAbiHelper mAbiHelper;
+
+ Injector(UserManagerInternal userManager, PackageAbiHelper abiHelper) {
+ mUserManager = userManager;
+ mAbiHelper = abiHelper;
+ }
+
+ public UserManagerInternal getUserManager() {
+ return mUserManager;
+ }
+
+ public PackageAbiHelper getAbiHelper() {
+ return mAbiHelper;
+ }
+ }
+
class PackageParserCallback implements PackageParser.Callback {
@Override public final boolean hasFeature(String feature) {
return PackageManagerService.this.hasSystemFeature(feature, 0);
@@ -1406,6 +1430,7 @@
final @Nullable String mConfiguratorPackage;
final @Nullable String mAppPredictionServicePackage;
final @Nullable String mIncidentReportApproverPackage;
+ final @Nullable String[] mTelephonyPackages;
final @NonNull String mServicesSystemSharedLibraryPackageName;
final @NonNull String mSharedSystemSharedLibraryPackageName;
@@ -2092,8 +2117,8 @@
// survive long enough to benefit of background optimizations.
for (int userId : firstUserIds) {
PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
- // There's a race currently where some install events may interleave with an uninstall.
- // This can lead to package info being null (b/36642664).
+ // There's a race currently where some install events may interleave with an
+ // uninstall. This can lead to package info being null (b/36642664).
if (info != null) {
mDexManager.notifyPackageInstalled(info, userId);
}
@@ -2163,6 +2188,7 @@
* external/removable/unprotected storage.
* @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the
* corresponding {@link StorageEnum} storage type value if it is.
+ * corresponding {@link StorageEnum} storage type value if it is.
*/
private static int getPackageExternalStorageType(VolumeInfo packageVolume,
boolean packageIsExternal) {
@@ -2420,6 +2446,11 @@
mPermissionManager.getPermissionSettings(), mPackages);
}
}
+
+ // TODO(b/137961986): We should pass this via constructor, but would first need to create
+ // a packages lock that could also be passed in.
+ mInjector = new Injector(getUserManagerInternal(), new PackageAbiHelperImpl());
+
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
@@ -3116,6 +3147,7 @@
mContext.getString(R.string.config_deviceConfiguratorPackageName);
mAppPredictionServicePackage = getAppPredictionServicePackageName();
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
+ mTelephonyPackages = getTelephonyPackageNames();
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths.
@@ -3126,7 +3158,9 @@
// the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though.
final List<String> changedAbiCodePath =
- adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
+ applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
+ mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
+ setting.packages, null /*scannedPackage*/));
if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
final String codePathString = changedAbiCodePath.get(i);
@@ -9395,7 +9429,8 @@
null /* originalPkgSetting */, null, parseFlags, scanFlags,
(pkg == mPlatformPackage), user);
applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
- final ScanResult scanResult = scanPackageOnlyLI(request, mFactoryTest, -1L);
+ final ScanResult scanResult =
+ scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
}
@@ -10757,7 +10792,8 @@
}
/** The result of a package scan. */
- private static class ScanResult {
+ @VisibleForTesting
+ static class ScanResult {
/** The request that initiated the scan that produced this result. */
public final ScanRequest request;
/** Whether or not the package scan was successful */
@@ -10796,7 +10832,8 @@
}
/** A package to be scanned */
- private static class ScanRequest {
+ @VisibleForTesting
+ static class ScanRequest {
/** The parsed package */
@NonNull public final PackageParser.Package pkg;
/** The package this package replaces */
@@ -10989,7 +11026,7 @@
pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
originalPkgSetting, realPkgName, parseFlags, scanFlags,
(pkg == mPlatformPackage), user);
- return scanPackageOnlyLI(request, mFactoryTest, currentTime);
+ return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
}
}
@@ -11214,20 +11251,70 @@
}
/**
+ * Applies the adjusted ABI calculated by
+ * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, PackageParser.Package)} to all
+ * relevant packages and settings.
+ * @param sharedUserSetting The {@code SharedUserSetting} to adjust
+ * @param scannedPackage the package being scanned or null
+ * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
+ * @return the list of code paths that belong to packages that had their ABIs adjusted.
+ */
+ private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
+ PackageParser.Package scannedPackage, String adjustedAbi) {
+ if (scannedPackage != null) {
+ scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
+ }
+ List<String> changedAbiCodePath = null;
+ for (PackageSetting ps : sharedUserSetting.packages) {
+ if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
+ if (ps.primaryCpuAbiString != null) {
+ continue;
+ }
+
+ ps.primaryCpuAbiString = adjustedAbi;
+ if (ps.pkg != null && ps.pkg.applicationInfo != null
+ && !TextUtils.equals(
+ adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
+ ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
+ if (DEBUG_ABI_SELECTION) {
+ Slog.i(TAG,
+ "Adjusting ABI for " + ps.name + " to " + adjustedAbi
+ + " (scannedPackage="
+ + (scannedPackage != null ? scannedPackage : "null")
+ + ")");
+ }
+ if (changedAbiCodePath == null) {
+ changedAbiCodePath = new ArrayList<>();
+ }
+ changedAbiCodePath.add(ps.codePathString);
+ }
+ }
+ }
+ return changedAbiCodePath;
+ }
+
+
+ /**
* Just scans the package without any side effects.
* <p>Not entirely true at the moment. There is still one side effect -- this
* method potentially modifies a live {@link PackageSetting} object representing
* the package being scanned. This will be resolved in the future.
*
+ * @param injector injector for acquiring dependencies
* @param request Information about the package to be scanned
* @param isUnderFactoryTest Whether or not the device is under factory test
* @param currentTime The current time, in millis
* @return The results of the scan
*/
@GuardedBy("mInstallLock")
- private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
+ @VisibleForTesting
+ @NonNull
+ static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
+ Injector injector,
boolean isUnderFactoryTest, long currentTime)
- throws PackageManagerException {
+ throws PackageManagerException {
+ final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
+ final UserManagerInternal userManager = injector.getUserManager();
final PackageParser.Package pkg = request.pkg;
PackageSetting pkgSetting = request.pkgSetting;
final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
@@ -11333,7 +11420,7 @@
if (!createNewPackage) {
final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
- setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
+ setInstantAppForUser(userManager, pkgSetting, userId, instantApp, fullApp);
}
// TODO(patb): see if we can do away with disabled check here.
if (disabledPkgSetting != null
@@ -11379,7 +11466,10 @@
if (needToDeriveAbi) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
final boolean extractNativeLibs = !pkg.isLibrary();
- derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
+ final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
+ packageAbiHelper.derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
+ derivedAbi.first.applyTo(pkg);
+ derivedAbi.second.applyTo(pkg);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
// Some system apps still use directory structure for native libraries
@@ -11387,8 +11477,13 @@
// structure. Try to detect abi based on directory structure.
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
pkg.applicationInfo.primaryCpuAbi == null) {
- setBundledAppAbisAndRoots(pkg, pkgSetting);
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
+ pkg);
+ abis.applyTo(pkg);
+ abis.applyTo(pkgSetting);
+ final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
+ packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ nativeLibraryPaths.applyTo(pkg);
}
} else {
// This is not a first boot or an upgrade, don't bother deriving the
@@ -11397,7 +11492,9 @@
pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
+ packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ nativeLibraryPaths.applyTo(pkg);
if (DEBUG_ABI_SELECTION) {
Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
@@ -11418,7 +11515,9 @@
// ABIs we've determined above. For non-moves, the path will be updated based on the
// ABIs we determined during compilation, but the path will depend on the final
// package path (after the rename away from the stage path).
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
+ packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ nativeLibraryPaths.applyTo(pkg);
}
// This is a special case for the "system" package, where the ABI is
@@ -11472,8 +11571,9 @@
// We also do this *before* we perform dexopt on this package, so that
// we can avoid redundant dexopts, and also to make sure we've got the
// code and package path correct.
- changedAbiCodePath =
- adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
+ changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, pkg,
+ packageAbiHelper.getAdjustedAbiForSharedUser(
+ pkgSetting.sharedUser.packages, pkg));
}
if (isUnderFactoryTest && pkg.requestedPermissions.contains(
@@ -12323,264 +12423,6 @@
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- /**
- * Derive the ABI of a non-system package located at {@code scanFile}. This information
- * is derived purely on the basis of the contents of {@code scanFile} and
- * {@code cpuAbiOverride}.
- *
- * If {@code extractLibs} is true, native libraries are extracted from the app if required.
- */
- private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
- boolean extractLibs)
- throws PackageManagerException {
- // Give ourselves some initial paths; we'll come back for another
- // pass once we've determined ABI below.
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
-
- // We shouldn't attempt to extract libs from system app when it was not updated.
- if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
- extractLibs = false;
- }
-
- final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
- final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
-
- NativeLibraryHelper.Handle handle = null;
- try {
- handle = NativeLibraryHelper.Handle.create(pkg);
- // TODO(multiArch): This can be null for apps that didn't go through the
- // usual installation process. We can calculate it again, like we
- // do during install time.
- //
- // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
- // unnecessary.
- final File nativeLibraryRoot = new File(nativeLibraryRootStr);
-
- // Null out the abis so that they can be recalculated.
- pkg.applicationInfo.primaryCpuAbi = null;
- pkg.applicationInfo.secondaryCpuAbi = null;
- if (isMultiArch(pkg.applicationInfo)) {
- // Warn if we've set an abiOverride for multi-lib packages..
- // By definition, we need to copy both 32 and 64 bit libraries for
- // such packages.
- if (pkg.cpuAbiOverride != null
- && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
- Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
- }
-
- int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
- int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
- if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
- if (extractLibs) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
- abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
- useIsaSpecificSubdirs);
- } else {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
- abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- // Shared library native code should be in the APK zip aligned
- if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Shared library native lib extraction not supported");
- }
-
- maybeThrowExceptionForMultiArchCopy(
- "Error unpackaging 32 bit native libs for multiarch app.", abi32);
-
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
- if (extractLibs) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
- abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
- useIsaSpecificSubdirs);
- } else {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
- abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- maybeThrowExceptionForMultiArchCopy(
- "Error unpackaging 64 bit native libs for multiarch app.", abi64);
-
- if (abi64 >= 0) {
- // Shared library native libs should be in the APK zip aligned
- if (extractLibs && pkg.isLibrary()) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Shared library native lib extraction not supported");
- }
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
- }
-
- if (abi32 >= 0) {
- final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
- if (abi64 >= 0) {
- if (pkg.use32bitAbi) {
- pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
- pkg.applicationInfo.primaryCpuAbi = abi;
- } else {
- pkg.applicationInfo.secondaryCpuAbi = abi;
- }
- } else {
- pkg.applicationInfo.primaryCpuAbi = abi;
- }
- }
- } else {
- String[] abiList = (cpuAbiOverride != null) ?
- new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
-
- // Enable gross and lame hacks for apps that are built with old
- // SDK tools. We must scan their APKs for renderscript bitcode and
- // not launch them if it's present. Don't bother checking on devices
- // that don't have 64 bit support.
- boolean needsRenderScriptOverride = false;
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
- NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
- abiList = Build.SUPPORTED_32_BIT_ABIS;
- needsRenderScriptOverride = true;
- }
-
- final int copyRet;
- if (extractLibs) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
- copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
- } else {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
- copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-
- if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Error unpackaging native libs for app, errorCode=" + copyRet);
- }
-
- if (copyRet >= 0) {
- // Shared libraries that have native libs must be multi-architecture
- if (pkg.isLibrary()) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Shared library with native libs must be multiarch");
- }
- pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
- } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
- pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
- } else if (needsRenderScriptOverride) {
- pkg.applicationInfo.primaryCpuAbi = abiList[0];
- }
- }
- } catch (IOException ioe) {
- Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
- } finally {
- IoUtils.closeQuietly(handle);
- }
-
- // Now that we've calculated the ABIs and determined if it's an internal app,
- // we will go ahead and populate the nativeLibraryPath.
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
- }
-
- /**
- * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
- * i.e, so that all packages can be run inside a single process if required.
- *
- * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
- * this function will either try and make the ABI for all packages in {@code packagesForUser}
- * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
- * the ABI selected for {@code packagesForUser}. This variant is used when installing or
- * updating a package that belongs to a shared user.
- *
- * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
- * adds unnecessary complexity.
- */
- private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
- Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
- List<String> changedAbiCodePath = null;
- String requiredInstructionSet = null;
- if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
- requiredInstructionSet = VMRuntime.getInstructionSet(
- scannedPackage.applicationInfo.primaryCpuAbi);
- }
-
- PackageSetting requirer = null;
- for (PackageSetting ps : packagesForUser) {
- // If packagesForUser contains scannedPackage, we skip it. This will happen
- // when scannedPackage is an update of an existing package. Without this check,
- // we will never be able to change the ABI of any package belonging to a shared
- // user, even if it's compatible with other packages.
- if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
- if (ps.primaryCpuAbiString == null) {
- continue;
- }
-
- final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
- if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
- // We have a mismatch between instruction sets (say arm vs arm64) warn about
- // this but there's not much we can do.
- String errorMessage = "Instruction set mismatch, "
- + ((requirer == null) ? "[caller]" : requirer)
- + " requires " + requiredInstructionSet + " whereas " + ps
- + " requires " + instructionSet;
- Slog.w(TAG, errorMessage);
- }
-
- if (requiredInstructionSet == null) {
- requiredInstructionSet = instructionSet;
- requirer = ps;
- }
- }
- }
-
- if (requiredInstructionSet != null) {
- String adjustedAbi;
- if (requirer != null) {
- // requirer != null implies that either scannedPackage was null or that scannedPackage
- // did not require an ABI, in which case we have to adjust scannedPackage to match
- // the ABI of the set (which is the same as requirer's ABI)
- adjustedAbi = requirer.primaryCpuAbiString;
- if (scannedPackage != null) {
- scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
- }
- } else {
- // requirer == null implies that we're updating all ABIs in the set to
- // match scannedPackage.
- adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
- }
-
- for (PackageSetting ps : packagesForUser) {
- if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
- if (ps.primaryCpuAbiString != null) {
- continue;
- }
-
- ps.primaryCpuAbiString = adjustedAbi;
- if (ps.pkg != null && ps.pkg.applicationInfo != null &&
- !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
- ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
- if (DEBUG_ABI_SELECTION) {
- Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
- + " (requirer="
- + (requirer != null ? requirer.pkg : "null")
- + ", scannedPackage="
- + (scannedPackage != null ? scannedPackage : "null")
- + ")");
- }
- if (changedAbiCodePath == null) {
- changedAbiCodePath = new ArrayList<>();
- }
- changedAbiCodePath.add(ps.codePathString);
- }
- }
- }
- }
- return changedAbiCodePath;
- }
-
private void setUpCustomResolverActivity(PackageParser.Package pkg) {
synchronized (mPackages) {
mResolverReplaced = true;
@@ -12632,207 +12474,6 @@
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
}
- private static String calculateBundledApkRoot(final String codePathString) {
- final File codePath = new File(codePathString);
- final File codeRoot;
- if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
- codeRoot = Environment.getRootDirectory();
- } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
- codeRoot = Environment.getOemDirectory();
- } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
- codeRoot = Environment.getVendorDirectory();
- } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
- codeRoot = Environment.getOdmDirectory();
- } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
- codeRoot = Environment.getProductDirectory();
- } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
- codeRoot = Environment.getSystemExtDirectory();
- } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
- codeRoot = Environment.getOdmDirectory();
- } else {
- // Unrecognized code path; take its top real segment as the apk root:
- // e.g. /something/app/blah.apk => /something
- try {
- File f = codePath.getCanonicalFile();
- File parent = f.getParentFile(); // non-null because codePath is a file
- File tmp;
- while ((tmp = parent.getParentFile()) != null) {
- f = parent;
- parent = tmp;
- }
- codeRoot = f;
- Slog.w(TAG, "Unrecognized code path "
- + codePath + " - using " + codeRoot);
- } catch (IOException e) {
- // Can't canonicalize the code path -- shenanigans?
- Slog.w(TAG, "Can't canonicalize code path " + codePath);
- return Environment.getRootDirectory().getPath();
- }
- }
- return codeRoot.getPath();
- }
-
- /**
- * Derive and set the location of native libraries for the given package,
- * which varies depending on where and how the package was installed.
- */
- private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
- final ApplicationInfo info = pkg.applicationInfo;
- final String codePath = pkg.codePath;
- final File codeFile = new File(codePath);
- final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
-
- info.nativeLibraryRootDir = null;
- info.nativeLibraryRootRequiresIsa = false;
- info.nativeLibraryDir = null;
- info.secondaryNativeLibraryDir = null;
-
- if (isApkFile(codeFile)) {
- // Monolithic install
- if (bundledApp) {
- // If "/system/lib64/apkname" exists, assume that is the per-package
- // native library directory to use; otherwise use "/system/lib/apkname".
- final String apkRoot = calculateBundledApkRoot(info.sourceDir);
- final boolean is64Bit = VMRuntime.is64BitInstructionSet(
- getPrimaryInstructionSet(info));
-
- // This is a bundled system app so choose the path based on the ABI.
- // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
- // is just the default path.
- final String apkName = deriveCodePathName(codePath);
- final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
- info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
- apkName).getAbsolutePath();
-
- if (info.secondaryCpuAbi != null) {
- final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
- info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
- secondaryLibDir, apkName).getAbsolutePath();
- }
- } else {
- final String apkName = deriveCodePathName(codePath);
- info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
- .getAbsolutePath();
- }
-
- info.nativeLibraryRootRequiresIsa = false;
- info.nativeLibraryDir = info.nativeLibraryRootDir;
- } else {
- // Cluster install
- info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
- info.nativeLibraryRootRequiresIsa = true;
-
- info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
- getPrimaryInstructionSet(info)).getAbsolutePath();
-
- if (info.secondaryCpuAbi != null) {
- info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
- VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
- }
- }
- }
-
- /**
- * Calculate the abis and roots for a bundled app. These can uniquely
- * be determined from the contents of the system partition, i.e whether
- * it contains 64 or 32 bit shared libraries etc. We do not validate any
- * of this information, and instead assume that the system was built
- * sensibly.
- */
- private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
- PackageSetting pkgSetting) {
- final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
-
- // If "/system/lib64/apkname" exists, assume that is the per-package
- // native library directory to use; otherwise use "/system/lib/apkname".
- final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
- setBundledAppAbi(pkg, apkRoot, apkName);
- // pkgSetting might be null during rescan following uninstall of updates
- // to a bundled app, so accommodate that possibility. The settings in
- // that case will be established later from the parsed package.
- //
- // If the settings aren't null, sync them up with what we've just derived.
- // note that apkRoot isn't stored in the package settings.
- if (pkgSetting != null) {
- pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
- pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
- }
- }
-
- /**
- * Deduces the ABI of a bundled app and sets the relevant fields on the
- * parsed pkg object.
- *
- * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
- * under which system libraries are installed.
- * @param apkName the name of the installed package.
- */
- private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
- final File codeFile = new File(pkg.codePath);
-
- final boolean has64BitLibs;
- final boolean has32BitLibs;
- if (isApkFile(codeFile)) {
- // Monolithic install
- has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
- has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
- } else {
- // Cluster install
- final File rootDir = new File(codeFile, LIB_DIR_NAME);
- if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
- && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
- final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
- has64BitLibs = (new File(rootDir, isa)).exists();
- } else {
- has64BitLibs = false;
- }
- if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
- && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
- final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
- has32BitLibs = (new File(rootDir, isa)).exists();
- } else {
- has32BitLibs = false;
- }
- }
-
- if (has64BitLibs && !has32BitLibs) {
- // The package has 64 bit libs, but not 32 bit libs. Its primary
- // ABI should be 64 bit. We can safely assume here that the bundled
- // native libraries correspond to the most preferred ABI in the list.
-
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = null;
- } else if (has32BitLibs && !has64BitLibs) {
- // The package has 32 bit libs but not 64 bit libs. Its primary
- // ABI should be 32 bit.
-
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = null;
- } else if (has32BitLibs && has64BitLibs) {
- // The application has both 64 and 32 bit bundled libraries. We check
- // here that the app declares multiArch support, and warn if it doesn't.
- //
- // We will be lenient here and record both ABIs. The primary will be the
- // ABI that's higher on the list, i.e, a device that's configured to prefer
- // 64 bit apps will see a 64 bit primary ABI,
-
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
- Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
- }
-
- if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
- } else {
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
- }
- } else {
- pkg.applicationInfo.primaryCpuAbi = null;
- pkg.applicationInfo.secondaryCpuAbi = null;
- }
- }
-
private void killApplication(String pkgName, int appId, String reason) {
killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
}
@@ -13554,7 +13195,8 @@
// upgrade app from instant to full; we don't allow app downgrade
installed = true;
}
- setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
+ setInstantAppForUser(
+ getUserManagerInternal(), pkgSetting, userId, instantApp, fullApp);
}
if (installed) {
@@ -13602,8 +13244,8 @@
}
}
- static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
- boolean instantApp, boolean fullApp) {
+ static void setInstantAppForUser(UserManagerInternal userManager, PackageSetting pkgSetting,
+ int userId, boolean instantApp, boolean fullApp) {
// no state specified; do nothing
if (!instantApp && !fullApp) {
return;
@@ -13615,7 +13257,7 @@
pkgSetting.setInstantApp(false /*instantApp*/, userId);
}
} else {
- for (int currentUserId : sUserManager.getUserIds()) {
+ for (int currentUserId : userManager.getUserIds()) {
if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
} else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
@@ -15450,17 +15092,6 @@
TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
mPendingEnableRollback.append(enableRollbackToken, this);
- final int[] installedUsers;
- synchronized (mPackages) {
- PackageSetting ps = mSettings.getPackageLPr(pkgLite.packageName);
- if (ps != null) {
- installedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(),
- true);
- } else {
- installedUsers = new int[0];
- }
- }
-
Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
enableRollbackIntent.putExtra(
PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
@@ -15469,9 +15100,6 @@
PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS,
installFlags);
enableRollbackIntent.putExtra(
- PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS,
- installedUsers);
- enableRollbackIntent.putExtra(
PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER,
getRollbackUser().getIdentifier());
enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
@@ -15889,16 +15517,6 @@
}
}
- private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
- PackageManagerException {
- if (copyRet < 0) {
- if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
- copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
- throw new PackageManagerException(copyRet, message);
- }
- }
- }
-
/**
* Logic to handle movement of existing installed applications.
*/
@@ -16025,26 +15643,6 @@
return result;
}
- // Utility method that returns the relative package path with respect
- // to the installation directory. Like say for /data/data/com.test-1.apk
- // string com.test-1 is returned.
- static String deriveCodePathName(String codePath) {
- if (codePath == null) {
- return null;
- }
- final File codeFile = new File(codePath);
- final String name = codeFile.getName();
- if (codeFile.isDirectory()) {
- return name;
- } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
- final int lastDot = name.lastIndexOf('.');
- return name.substring(0, lastDot);
- } else {
- Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
- return null;
- }
- }
-
static class PackageInstalledInfo {
String name;
int uid;
@@ -16977,7 +16575,8 @@
final PrepareResult prepareResult;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
- prepareResult = preparePackageLI(request.args, request.installResult);
+ prepareResult =
+ preparePackageLI(request.args, request.installResult);
} catch (PrepareFailure prepareFailure) {
request.installResult.setError(prepareFailure.error,
prepareFailure.getMessage());
@@ -17637,7 +17236,11 @@
String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
args.abiOverride : pkg.cpuAbiOverride);
final boolean extractNativeLibs = !pkg.isLibrary();
- derivePackageAbi(pkg, abiOverride, extractNativeLibs);
+ final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
+ derivedAbi = mInjector.getAbiHelper().derivePackageAbi(
+ pkg, abiOverride, extractNativeLibs);
+ derivedAbi.first.applyTo(pkg);
+ derivedAbi.second.applyTo(pkg);
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
@@ -18166,10 +17769,6 @@
}
}
- private static boolean isMultiArch(ApplicationInfo info) {
- return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
- }
-
private static boolean isExternal(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
@@ -18178,7 +17777,7 @@
return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
- private static boolean isSystemApp(PackageParser.Package pkg) {
+ static boolean isSystemApp(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
@@ -21175,6 +20774,16 @@
}
@Override
+ public String[] getTelephonyPackageNames() {
+ String names = mContext.getString(R.string.config_telephonyPackages);
+ String[] telephonyPackageNames = null;
+ if (!TextUtils.isEmpty(names)) {
+ telephonyPackageNames = names.trim().split(",");
+ }
+ return telephonyPackageNames;
+ }
+
+ @Override
public void setApplicationEnabledSetting(String appPackageName,
int newState, int flags, int userId, String callingPackage) {
if (!sUserManager.exists(userId)) return;
@@ -24323,34 +23932,36 @@
}
@Override
- public String getKnownPackageName(int knownPackage, int userId) {
+ public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
switch(knownPackage) {
case PackageManagerInternal.PACKAGE_BROWSER:
- return getDefaultBrowserPackageName(userId);
+ return new String[]{getDefaultBrowserPackageName(userId)};
case PackageManagerInternal.PACKAGE_INSTALLER:
- return mRequiredInstallerPackage;
+ return new String[]{mRequiredInstallerPackage};
case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
- return mSetupWizardPackage;
+ return new String[]{mSetupWizardPackage};
case PackageManagerInternal.PACKAGE_SYSTEM:
- return "android";
+ return new String[]{"android"};
case PackageManagerInternal.PACKAGE_VERIFIER:
- return mRequiredVerifierPackage;
+ return new String[]{mRequiredVerifierPackage};
case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
- return mSystemTextClassifierPackage;
+ return new String[]{mSystemTextClassifierPackage};
case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
- return mRequiredPermissionControllerPackage;
+ return new String[]{mRequiredPermissionControllerPackage};
case PackageManagerInternal.PACKAGE_WELLBEING:
- return mWellbeingPackage;
+ return new String[]{mWellbeingPackage};
case PackageManagerInternal.PACKAGE_DOCUMENTER:
- return mDocumenterPackage;
+ return new String[]{mDocumenterPackage};
case PackageManagerInternal.PACKAGE_CONFIGURATOR:
- return mConfiguratorPackage;
+ return new String[]{mConfiguratorPackage};
case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
- return mIncidentReportApproverPackage;
+ return new String[]{mIncidentReportApproverPackage};
case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
- return mAppPredictionServicePackage;
+ return new String[]{mAppPredictionServicePackage};
+ case PackageManagerInternal.PACKAGE_TELEPHONY:
+ return mTelephonyPackages;
}
- return null;
+ return ArrayUtils.emptyArray(String.class);
}
@Override
@@ -24506,6 +24117,12 @@
public List<ResolveInfo> queryIntentActivities(
Intent intent, int flags, int filterCallingUid, int userId) {
final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
+ return queryIntentActivities(intent, resolvedType, flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public List<ResolveInfo> queryIntentActivities(
+ Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
return PackageManagerService.this
.queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 58f262c..029673f 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -270,7 +270,8 @@
updateAvailable = orig.updateAvailable;
}
- private PackageUserState modifyUserState(int userId) {
+ @VisibleForTesting
+ PackageUserState modifyUserState(int userId) {
PackageUserState state = mUserState.get(userId);
if (state == null) {
state = new PackageUserState();
@@ -463,6 +464,18 @@
state.harmfulAppWarning = harmfulAppWarning;
}
+ void setUserState(int userId, PackageUserState otherState) {
+ setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed,
+ otherState.stopped, otherState.notLaunched, otherState.hidden,
+ otherState.distractionFlags, otherState.suspended, otherState.suspendingPackage,
+ otherState.dialogInfo, otherState.suspendedAppExtras,
+ otherState.suspendedLauncherExtras, otherState.instantApp,
+ otherState.virtualPreload, otherState.lastDisableAppCaller,
+ otherState.enabledComponents, otherState.disabledComponents,
+ otherState.domainVerificationStatus, otherState.appLinkGeneration,
+ otherState.installReason, otherState.harmfulAppWarning);
+ }
+
ArraySet<String> getEnabledComponents(int userId) {
return readUserState(userId).enabledComponents;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 3bc2236..4ecfbfe 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3337,7 +3337,8 @@
int flags, ComponentName cn, String scheme, PatternMatcher ssp,
IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
final List<ResolveInfo> ri =
- pmInternal.queryIntentActivities(intent, flags, Binder.getCallingUid(), 0);
+ pmInternal.queryIntentActivities(
+ intent, intent.getType(), flags, Binder.getCallingUid(), 0);
if (PackageManagerService.DEBUG_PREFERRED) {
Log.d(TAG, "Queried " + intent + " results: " + ri);
}
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 15dc6ae..0101366 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -8,6 +8,20 @@
},
{
"name": "CtsCompilationTestCases"
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
}
],
"imports": [
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 9948a3a..b8d3ca5 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -317,9 +317,13 @@
case ArtManager.PROFILE_APPS :
return SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
case ArtManager.PROFILE_BOOT_IMAGE:
+ // The device config property overrides the system property version.
+ boolean profileBootClassPath = SystemProperties.getBoolean(
+ "persist.device_config.runtime_native_boot.profilebootclasspath",
+ SystemProperties.getBoolean("dalvik.vm.profilebootclasspath", false));
return (Build.IS_USERDEBUG || Build.IS_ENG) &&
SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false) &&
- SystemProperties.getBoolean("dalvik.vm.profilebootimage", false);
+ profileBootClassPath;
default:
throw new IllegalArgumentException("Invalid profile type:" + profileType);
}
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 6d22faa..c39dcfe 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -276,6 +276,9 @@
public boolean isAppPredictor() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0;
}
+ public boolean isTelephony() {
+ return (protectionLevel & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0;
+ }
public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
if (!origPackageName.equals(sourcePackageName)) {
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index f762985..5870986 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -436,17 +436,20 @@
// Installer
grantSystemFixedPermissionsToSystemPackage(
- getKnownPackage(PackageManagerInternal.PACKAGE_INSTALLER, userId),
+ ArrayUtils.firstOrNull(getKnownPackages(
+ PackageManagerInternal.PACKAGE_INSTALLER, userId)),
userId, STORAGE_PERMISSIONS);
// Verifier
- final String verifier = getKnownPackage(PackageManagerInternal.PACKAGE_VERIFIER, userId);
+ final String verifier = ArrayUtils.firstOrNull(getKnownPackages(
+ PackageManagerInternal.PACKAGE_VERIFIER, userId));
grantSystemFixedPermissionsToSystemPackage(verifier, userId, STORAGE_PERMISSIONS);
grantPermissionsToSystemPackage(verifier, userId, PHONE_PERMISSIONS, SMS_PERMISSIONS);
// SetupWizard
grantPermissionsToSystemPackage(
- getKnownPackage(PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId), userId,
+ ArrayUtils.firstOrNull(getKnownPackages(
+ PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId)), userId,
PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
CAMERA_PERMISSIONS);
@@ -595,7 +598,8 @@
userId, CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS);
// Browser
- String browserPackage = getKnownPackage(PackageManagerInternal.PACKAGE_BROWSER, userId);
+ String browserPackage = ArrayUtils.firstOrNull(getKnownPackages(
+ PackageManagerInternal.PACKAGE_BROWSER, userId));
if (browserPackage == null) {
browserPackage = getDefaultSystemHandlerActivityPackageForCategory(
Intent.CATEGORY_APP_BROWSER, userId);
@@ -760,8 +764,8 @@
}
}
- private String getKnownPackage(int knownPkgId, int userId) {
- return mServiceInternal.getKnownPackageName(knownPkgId, userId);
+ private @NonNull String[] getKnownPackages(int knownPkgId, int userId) {
+ return mServiceInternal.getKnownPackageNames(knownPkgId, userId);
}
private void grantDefaultPermissionsToDefaultSystemDialerApp(
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 6d1f2d3..6a7c622 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1706,8 +1706,9 @@
}
}
}
- final String systemPackageName = mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
+ // expect single system package
+ String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
final PackageParser.Package systemPackage =
mPackageManagerInt.getPackage(systemPackageName);
@@ -1823,18 +1824,19 @@
// need a separate flag anymore. Hence we need to check which
// permissions are needed by the permission controller
if (!allowed && bp.isInstaller()
- && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
- || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
+ pkg.packageName) || ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
- UserHandle.USER_SYSTEM)))) {
+ UserHandle.USER_SYSTEM), pkg.packageName)) {
// If this permission is to be granted to the system installer and
// this app is an installer, then it gets the permission.
allowed = true;
}
if (!allowed && bp.isVerifier()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
+ pkg.packageName)) {
// If this permission is to be granted to the system verifier and
// this app is a verifier, then it gets the permission.
allowed = true;
@@ -1850,53 +1852,64 @@
allowed = origPermissions.hasInstallPermission(perm);
}
if (!allowed && bp.isSetup()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
+ pkg.packageName)) {
// If this permission is to be granted to the system setup wizard and
// this app is a setup wizard, then it gets the permission.
allowed = true;
}
if (!allowed && bp.isSystemTextClassifier()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
- UserHandle.USER_SYSTEM))) {
+ UserHandle.USER_SYSTEM), pkg.packageName)) {
// Special permissions for the system default text classifier.
allowed = true;
}
if (!allowed && bp.isConfigurator()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_CONFIGURATOR,
- UserHandle.USER_SYSTEM))) {
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_CONFIGURATOR,
+ UserHandle.USER_SYSTEM), pkg.packageName)) {
// Special permissions for the device configurator.
allowed = true;
}
if (!allowed && bp.isWellbeing()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
+ pkg.packageName)) {
// Special permission granted only to the OEM specified wellbeing app
allowed = true;
}
if (!allowed && bp.isDocumenter()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
+ pkg.packageName)) {
// If this permission is to be granted to the documenter and
// this app is the documenter, then it gets the permission.
allowed = true;
}
if (!allowed && bp.isIncidentReportApprover()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
- UserHandle.USER_SYSTEM))) {
+ UserHandle.USER_SYSTEM), pkg.packageName)) {
// If this permission is to be granted to the incident report approver and
// this app is the incident report approver, then it gets the permission.
allowed = true;
}
if (!allowed && bp.isAppPredictor()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
+ pkg.packageName)) {
// Special permissions for the system app predictor.
allowed = true;
}
+ if (!allowed && bp.isTelephony()
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM),
+ pkg.packageName)) {
+ // Special permissions for the system telephony apps.
+ allowed = true;
+ }
}
return allowed;
}
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
new file mode 100644
index 0000000..fe18fbf
--- /dev/null
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You 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.recoverysystem;
+
+import android.content.Context;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.IRecoverySystem;
+import android.os.IRecoverySystemProgressListener;
+import android.os.PowerManager;
+import android.os.RecoverySystem;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.SystemService;
+
+import libcore.io.IoUtils;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * The recovery system service is responsible for coordinating recovery related
+ * functions on the device. It sets up (or clears) the bootloader control block
+ * (BCB), which will be read by the bootloader and the recovery image. It also
+ * triggers /system/bin/uncrypt via init to de-encrypt an OTA package on the
+ * /data partition so that it can be accessed under the recovery image.
+ */
+public class RecoverySystemService extends IRecoverySystem.Stub {
+ private static final String TAG = "RecoverySystemService";
+ private static final boolean DEBUG = false;
+
+ // The socket at /dev/socket/uncrypt to communicate with uncrypt.
+ private static final String UNCRYPT_SOCKET = "uncrypt";
+
+ // The init services that communicate with /system/bin/uncrypt.
+ @VisibleForTesting
+ static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
+ @VisibleForTesting
+ static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
+ @VisibleForTesting
+ static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
+
+ private static final Object sRequestLock = new Object();
+
+ private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
+
+ private final Injector mInjector;
+ private final Context mContext;
+
+ static class Injector {
+ protected final Context mContext;
+
+ Injector(Context context) {
+ mContext = context;
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public PowerManager getPowerManager() {
+ return (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ }
+
+ public String systemPropertiesGet(String key) {
+ return SystemProperties.get(key);
+ }
+
+ public void systemPropertiesSet(String key, String value) {
+ SystemProperties.set(key, value);
+ }
+
+ public boolean uncryptPackageFileDelete() {
+ return RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
+ }
+
+ public String getUncryptPackageFileName() {
+ return RecoverySystem.UNCRYPT_PACKAGE_FILE.getName();
+ }
+
+ public FileWriter getUncryptPackageFileWriter() throws IOException {
+ return new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE);
+ }
+
+ public UncryptSocket connectService() {
+ UncryptSocket socket = new UncryptSocket();
+ if (!socket.connectService()) {
+ socket.close();
+ return null;
+ }
+ return socket;
+ }
+
+ public void threadSleep(long millis) throws InterruptedException {
+ Thread.sleep(millis);
+ }
+ }
+
+ /**
+ * Handles the lifecycle events for the RecoverySystemService.
+ */
+ public static final class Lifecycle extends SystemService {
+ public Lifecycle(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ RecoverySystemService recoverySystemService = new RecoverySystemService(getContext());
+ publishBinderService(Context.RECOVERY_SERVICE, recoverySystemService);
+ }
+ }
+
+ private RecoverySystemService(Context context) {
+ this(new Injector(context));
+ }
+
+ @VisibleForTesting
+ RecoverySystemService(Injector injector) {
+ mInjector = injector;
+ mContext = injector.getContext();
+ }
+
+ @Override // Binder call
+ public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
+ if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
+
+ synchronized (sRequestLock) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+
+ if (!checkAndWaitForUncryptService()) {
+ Slog.e(TAG, "uncrypt service is unavailable.");
+ return false;
+ }
+
+ // Write the filename into uncrypt package file to be read by
+ // uncrypt.
+ mInjector.uncryptPackageFileDelete();
+
+ try (FileWriter uncryptFile = mInjector.getUncryptPackageFileWriter()) {
+ uncryptFile.write(filename + "\n");
+ } catch (IOException e) {
+ Slog.e(TAG, "IOException when writing \""
+ + mInjector.getUncryptPackageFileName() + "\":", e);
+ return false;
+ }
+
+ // Trigger uncrypt via init.
+ mInjector.systemPropertiesSet("ctl.start", "uncrypt");
+
+ // Connect to the uncrypt service socket.
+ UncryptSocket socket = mInjector.connectService();
+ if (socket == null) {
+ Slog.e(TAG, "Failed to connect to uncrypt socket");
+ return false;
+ }
+
+ // Read the status from the socket.
+ try {
+ int lastStatus = Integer.MIN_VALUE;
+ while (true) {
+ int status = socket.getPercentageUncrypted();
+ // Avoid flooding the log with the same message.
+ if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
+ continue;
+ }
+ lastStatus = status;
+
+ if (status >= 0 && status <= 100) {
+ // Update status
+ Slog.i(TAG, "uncrypt read status: " + status);
+ if (listener != null) {
+ try {
+ listener.onProgress(status);
+ } catch (RemoteException ignored) {
+ Slog.w(TAG, "RemoteException when posting progress");
+ }
+ }
+ if (status == 100) {
+ Slog.i(TAG, "uncrypt successfully finished.");
+ // Ack receipt of the final status code. uncrypt
+ // waits for the ack so the socket won't be
+ // destroyed before we receive the code.
+ socket.sendAck();
+ break;
+ }
+ } else {
+ // Error in /system/bin/uncrypt.
+ Slog.e(TAG, "uncrypt failed with status: " + status);
+ // Ack receipt of the final status code. uncrypt waits
+ // for the ack so the socket won't be destroyed before
+ // we receive the code.
+ socket.sendAck();
+ return false;
+ }
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "IOException when reading status: ", e);
+ return false;
+ } finally {
+ socket.close();
+ }
+
+ return true;
+ }
+ }
+
+ @Override // Binder call
+ public boolean clearBcb() {
+ if (DEBUG) Slog.d(TAG, "clearBcb");
+ synchronized (sRequestLock) {
+ return setupOrClearBcb(false, null);
+ }
+ }
+
+ @Override // Binder call
+ public boolean setupBcb(String command) {
+ if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
+ synchronized (sRequestLock) {
+ return setupOrClearBcb(true, command);
+ }
+ }
+
+ @Override // Binder call
+ public void rebootRecoveryWithCommand(String command) {
+ if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
+ synchronized (sRequestLock) {
+ if (!setupOrClearBcb(true, command)) {
+ return;
+ }
+
+ // Having set up the BCB, go ahead and reboot.
+ PowerManager pm = mInjector.getPowerManager();
+ pm.reboot(PowerManager.REBOOT_RECOVERY);
+ }
+ }
+
+ /**
+ * Check if any of the init services is still running. If so, we cannot
+ * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
+ * it may break the socket communication since init creates / deletes
+ * the socket (/dev/socket/uncrypt) on service start / exit.
+ */
+ private boolean checkAndWaitForUncryptService() {
+ for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
+ final String uncryptService = mInjector.systemPropertiesGet(INIT_SERVICE_UNCRYPT);
+ final String setupBcbService = mInjector.systemPropertiesGet(INIT_SERVICE_SETUP_BCB);
+ final String clearBcbService = mInjector.systemPropertiesGet(INIT_SERVICE_CLEAR_BCB);
+ final boolean busy = "running".equals(uncryptService)
+ || "running".equals(setupBcbService) || "running".equals(clearBcbService);
+ if (DEBUG) {
+ Slog.i(TAG, "retry: " + retry + " busy: " + busy
+ + " uncrypt: [" + uncryptService + "]"
+ + " setupBcb: [" + setupBcbService + "]"
+ + " clearBcb: [" + clearBcbService + "]");
+ }
+
+ if (!busy) {
+ return true;
+ }
+
+ try {
+ mInjector.threadSleep(1000);
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "Interrupted:", e);
+ }
+ }
+
+ return false;
+ }
+
+ private boolean setupOrClearBcb(boolean isSetup, String command) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+
+ final boolean available = checkAndWaitForUncryptService();
+ if (!available) {
+ Slog.e(TAG, "uncrypt service is unavailable.");
+ return false;
+ }
+
+ if (isSetup) {
+ mInjector.systemPropertiesSet("ctl.start", "setup-bcb");
+ } else {
+ mInjector.systemPropertiesSet("ctl.start", "clear-bcb");
+ }
+
+ // Connect to the uncrypt service socket.
+ UncryptSocket socket = mInjector.connectService();
+ if (socket == null) {
+ Slog.e(TAG, "Failed to connect to uncrypt socket");
+ return false;
+ }
+
+ try {
+ // Send the BCB commands if it's to setup BCB.
+ if (isSetup) {
+ socket.sendCommand(command);
+ }
+
+ // Read the status from the socket.
+ int status = socket.getPercentageUncrypted();
+
+ // Ack receipt of the status code. uncrypt waits for the ack so
+ // the socket won't be destroyed before we receive the code.
+ socket.sendAck();
+
+ if (status == 100) {
+ Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear")
+ + " bcb successfully finished.");
+ } else {
+ // Error in /system/bin/uncrypt.
+ Slog.e(TAG, "uncrypt failed with status: " + status);
+ return false;
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "IOException when communicating with uncrypt:", e);
+ return false;
+ } finally {
+ socket.close();
+ }
+
+ return true;
+ }
+
+ /**
+ * Provides a wrapper for the low-level details of framing packets sent to the uncrypt
+ * socket.
+ */
+ public static class UncryptSocket {
+ private LocalSocket mLocalSocket;
+ private DataInputStream mInputStream;
+ private DataOutputStream mOutputStream;
+
+ /**
+ * Attempt to connect to the uncrypt service. Connection will be retried for up to
+ * {@link #SOCKET_CONNECTION_MAX_RETRY} times. If the connection is unsuccessful, the
+ * socket will be closed. If the connection is successful, the connection must be closed
+ * by the caller.
+ *
+ * @return true if connection was successful, false if unsuccessful
+ */
+ public boolean connectService() {
+ mLocalSocket = new LocalSocket();
+ boolean done = false;
+ // The uncrypt socket will be created by init upon receiving the
+ // service request. It may not be ready by this point. So we will
+ // keep retrying until success or reaching timeout.
+ for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
+ try {
+ mLocalSocket.connect(new LocalSocketAddress(UNCRYPT_SOCKET,
+ LocalSocketAddress.Namespace.RESERVED));
+ done = true;
+ break;
+ } catch (IOException ignored) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "Interrupted:", e);
+ }
+ }
+ }
+ if (!done) {
+ Slog.e(TAG, "Timed out connecting to uncrypt socket");
+ close();
+ return false;
+ }
+
+ try {
+ mInputStream = new DataInputStream(mLocalSocket.getInputStream());
+ mOutputStream = new DataOutputStream(mLocalSocket.getOutputStream());
+ } catch (IOException e) {
+ close();
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sends a command to the uncrypt service.
+ *
+ * @param command command to send to the uncrypt service
+ * @throws IOException if the socket is closed or there was an error writing to the socket
+ */
+ public void sendCommand(String command) throws IOException {
+ if (mLocalSocket.isClosed()) {
+ throw new IOException("socket is closed");
+ }
+
+ byte[] cmdUtf8 = command.getBytes(StandardCharsets.UTF_8);
+ mOutputStream.writeInt(cmdUtf8.length);
+ mOutputStream.write(cmdUtf8, 0, cmdUtf8.length);
+ }
+
+ /**
+ * Reads the status from the uncrypt service which is usually represented as a percentage.
+ * @return an integer representing the percentage completed
+ * @throws IOException if the socket was closed or there was an error reading the socket
+ */
+ public int getPercentageUncrypted() throws IOException {
+ if (mLocalSocket.isClosed()) {
+ throw new IOException("socket is closed");
+ }
+
+ return mInputStream.readInt();
+ }
+
+ /**
+ * Sends a confirmation to the uncrypt service.
+ * @throws IOException if the socket was closed or there was an error writing to the socket
+ */
+ public void sendAck() throws IOException {
+ if (mLocalSocket.isClosed()) {
+ throw new IOException("socket is closed");
+ }
+
+ mOutputStream.writeInt(0);
+ }
+
+ /**
+ * Closes the socket and all underlying data streams.
+ */
+ public void close() {
+ IoUtils.closeQuietly(mInputStream);
+ IoUtils.closeQuietly(mOutputStream);
+ IoUtils.closeQuietly(mLocalSocket);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index 56e1d08..cae09ea3 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -20,7 +20,7 @@
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.os.storage.StorageManager;
import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
import android.util.SparseLongArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -52,17 +52,18 @@
}
/**
- * Creates an app data snapshot for a specified {@code packageRollbackInfo}. Updates said {@code
- * packageRollbackInfo} with the inodes of the CE user data snapshot folders.
+ * Creates an app data snapshot for a specified {@code packageRollbackInfo} and the specified
+ * {@code userIds}. Updates said {@code packageRollbackInfo} with the inodes of the CE user data
+ * snapshot folders.
*/
- public void snapshotAppData(int snapshotId, PackageRollbackInfo packageRollbackInfo) {
- final int[] installedUsers = packageRollbackInfo.getInstalledUsers().toArray();
- for (int user : installedUsers) {
+ public void snapshotAppData(
+ int snapshotId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
+ for (int user : userIds) {
final int storageFlags;
if (isUserCredentialLocked(user)) {
// We've encountered a user that hasn't unlocked on a FBE device, so we can't copy
// across app user data until the user unlocks their device.
- Log.v(TAG, "User: " + user + " isn't unlocked, skipping CE userdata backup.");
+ Slog.v(TAG, "User: " + user + " isn't unlocked, skipping CE userdata backup.");
storageFlags = Installer.FLAG_STORAGE_DE;
packageRollbackInfo.addPendingBackup(user);
} else {
@@ -76,10 +77,11 @@
packageRollbackInfo.putCeSnapshotInode(user, ceSnapshotInode);
}
} catch (InstallerException ie) {
- Log.e(TAG, "Unable to create app data snapshot for: "
+ Slog.e(TAG, "Unable to create app data snapshot for: "
+ packageRollbackInfo.getPackageName() + ", userId: " + user, ie);
}
}
+ packageRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds));
}
/**
@@ -96,14 +98,14 @@
final IntArray pendingBackups = packageRollbackInfo.getPendingBackups();
final List<RestoreInfo> pendingRestores = packageRollbackInfo.getPendingRestores();
- boolean changedRollbackData = false;
+ boolean changedRollback = false;
// If we still have a userdata backup pending for this user, it implies that the user
// hasn't unlocked their device between the point of backup and the point of restore,
// so the data cannot have changed. We simply skip restoring CE data in this case.
if (pendingBackups != null && pendingBackups.indexOf(userId) != -1) {
pendingBackups.remove(pendingBackups.indexOf(userId));
- changedRollbackData = true;
+ changedRollback = true;
} else {
// There's no pending CE backup for this user, which means that we successfully
// managed to backup data for the user, which means we seek to restore it
@@ -111,7 +113,7 @@
// We've encountered a user that hasn't unlocked on a FBE device, so we can't
// copy across app user data until the user unlocks their device.
pendingRestores.add(new RestoreInfo(userId, appId, seInfo));
- changedRollbackData = true;
+ changedRollback = true;
} else {
// This user has unlocked, we can proceed to restore both CE and DE data.
storageFlags = storageFlags | Installer.FLAG_STORAGE_CE;
@@ -122,11 +124,11 @@
mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(), appId, seInfo,
userId, rollbackId, storageFlags);
} catch (InstallerException ie) {
- Log.e(TAG, "Unable to restore app data snapshot: "
+ Slog.e(TAG, "Unable to restore app data snapshot: "
+ packageRollbackInfo.getPackageName(), ie);
}
- return changedRollbackData;
+ return changedRollback;
}
/**
@@ -148,7 +150,7 @@
ceSnapshotInodes.delete(user);
}
} catch (InstallerException ie) {
- Log.e(TAG, "Unable to delete app data snapshot for "
+ Slog.e(TAG, "Unable to delete app data snapshot for "
+ packageRollbackInfo.getPackageName(), ie);
}
}
@@ -158,29 +160,29 @@
* Packages pending backup for the given user are added to {@code pendingBackupPackages} along
* with their corresponding {@code PackageRollbackInfo}.
*
- * @return the list of {@code RollbackData} that has pending backups. Note that some of the
+ * @return the list of rollbacks that have pending backups. Note that some of the
* backups won't be performed, because they might be counteracted by pending restores.
*/
- private static List<RollbackData> computePendingBackups(int userId,
+ private static List<Rollback> computePendingBackups(int userId,
Map<String, PackageRollbackInfo> pendingBackupPackages,
- List<RollbackData> rollbacks) {
- List<RollbackData> rd = new ArrayList<>();
+ List<Rollback> rollbacks) {
+ List<Rollback> rollbacksWithPendingBackups = new ArrayList<>();
- for (RollbackData data : rollbacks) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (Rollback rollback : rollbacks) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
final IntArray pendingBackupUsers = info.getPendingBackups();
if (pendingBackupUsers != null) {
final int idx = pendingBackupUsers.indexOf(userId);
if (idx != -1) {
pendingBackupPackages.put(info.getPackageName(), info);
- if (rd.indexOf(data) == -1) {
- rd.add(data);
+ if (rollbacksWithPendingBackups.indexOf(rollback) == -1) {
+ rollbacksWithPendingBackups.add(rollback);
}
}
}
}
}
- return rd;
+ return rollbacksWithPendingBackups;
}
/**
@@ -188,45 +190,45 @@
* Packages pending restore are added to {@code pendingRestores} along with their corresponding
* {@code PackageRollbackInfo}.
*
- * @return the list of {@code RollbackData} that has pending restores. Note that some of the
+ * @return the list of rollbacks that have pending restores. Note that some of the
* restores won't be performed, because they might be counteracted by pending backups.
*/
- private static List<RollbackData> computePendingRestores(int userId,
+ private static List<Rollback> computePendingRestores(int userId,
Map<String, PackageRollbackInfo> pendingRestorePackages,
- List<RollbackData> rollbacks) {
- List<RollbackData> rd = new ArrayList<>();
+ List<Rollback> rollbacks) {
+ List<Rollback> rollbacksWithPendingRestores = new ArrayList<>();
- for (RollbackData data : rollbacks) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (Rollback rollback : rollbacks) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
final RestoreInfo ri = info.getRestoreInfo(userId);
if (ri != null) {
pendingRestorePackages.put(info.getPackageName(), info);
- if (rd.indexOf(data) == -1) {
- rd.add(data);
+ if (rollbacksWithPendingRestores.indexOf(rollback) == -1) {
+ rollbacksWithPendingRestores.add(rollback);
}
}
}
}
- return rd;
+ return rollbacksWithPendingRestores;
}
/**
- * Commits the list of pending backups and restores for a given {@code userId}. For the pending
- * backups updates corresponding {@code changedRollbackData} with a mapping from {@code userId}
- * to a inode of theirs CE user data snapshot.
+ * Commits the list of pending backups and restores for a given {@code userId}. For rollbacks
+ * with pending backups, updates the {@code Rollback} instance with a mapping from
+ * {@code userId} to inode of the CE user data snapshot.
*
- * @return the set of {@code RollbackData} that have been changed and should be stored on disk.
+ * @return the set of rollbacks with changes that should be stored on disk.
*/
- public Set<RollbackData> commitPendingBackupAndRestoreForUser(int userId,
- List<RollbackData> rollbacks) {
+ public Set<Rollback> commitPendingBackupAndRestoreForUser(int userId,
+ List<Rollback> rollbacks) {
final Map<String, PackageRollbackInfo> pendingBackupPackages = new HashMap<>();
- final List<RollbackData> pendingBackups = computePendingBackups(userId,
+ final List<Rollback> pendingBackups = computePendingBackups(userId,
pendingBackupPackages, rollbacks);
final Map<String, PackageRollbackInfo> pendingRestorePackages = new HashMap<>();
- final List<RollbackData> pendingRestores = computePendingRestores(userId,
+ final List<Rollback> pendingRestores = computePendingRestores(userId,
pendingRestorePackages, rollbacks);
// First remove unnecessary backups, i.e. when user did not unlock their phone between the
@@ -246,18 +248,19 @@
}
if (!pendingBackupPackages.isEmpty()) {
- for (RollbackData data : pendingBackups) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (Rollback rollback : pendingBackups) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
final IntArray pendingBackupUsers = info.getPendingBackups();
final int idx = pendingBackupUsers.indexOf(userId);
if (idx != -1) {
try {
long ceSnapshotInode = mInstaller.snapshotAppData(info.getPackageName(),
- userId, data.info.getRollbackId(), Installer.FLAG_STORAGE_CE);
+ userId, rollback.info.getRollbackId(),
+ Installer.FLAG_STORAGE_CE);
info.putCeSnapshotInode(userId, ceSnapshotInode);
pendingBackupUsers.remove(idx);
} catch (InstallerException ie) {
- Log.e(TAG,
+ Slog.e(TAG,
"Unable to create app data snapshot for: "
+ info.getPackageName() + ", userId: " + userId, ie);
}
@@ -267,17 +270,17 @@
}
if (!pendingRestorePackages.isEmpty()) {
- for (RollbackData data : pendingRestores) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (Rollback rollback : pendingRestores) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
final RestoreInfo ri = info.getRestoreInfo(userId);
if (ri != null) {
try {
mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
- ri.seInfo, userId, data.info.getRollbackId(),
+ ri.seInfo, userId, rollback.info.getRollbackId(),
Installer.FLAG_STORAGE_CE);
info.removeRestoreInfo(ri);
} catch (InstallerException ie) {
- Log.e(TAG, "Unable to restore app data snapshot for: "
+ Slog.e(TAG, "Unable to restore app data snapshot for: "
+ info.getPackageName(), ie);
}
}
@@ -285,7 +288,7 @@
}
}
- final Set<RollbackData> changed = new HashSet<>(pendingBackups);
+ final Set<Rollback> changed = new HashSet<>(pendingBackups);
changed.addAll(pendingRestores);
return changed;
}
diff --git a/services/core/java/com/android/server/rollback/RollbackData.java b/services/core/java/com/android/server/rollback/Rollback.java
similarity index 85%
rename from services/core/java/com/android/server/rollback/RollbackData.java
rename to services/core/java/com/android/server/rollback/Rollback.java
index b37e268..0d5746b 100644
--- a/services/core/java/com/android/server/rollback/RollbackData.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -32,7 +32,7 @@
* Information about a rollback available for a set of atomically installed
* packages.
*/
-class RollbackData {
+class Rollback {
@IntDef(flag = true, prefix = { "ROLLBACK_STATE_" }, value = {
ROLLBACK_STATE_ENABLING,
ROLLBACK_STATE_AVAILABLE,
@@ -102,13 +102,13 @@
public boolean restoreUserDataInProgress = false;
/**
- * Constructs a new, empty RollbackData instance.
+ * Constructs a new, empty Rollback instance.
*
* @param rollbackId the id of the rollback.
* @param backupDir the directory where the rollback data is stored.
* @param stagedSessionId the session id if this is a staged rollback, -1 otherwise.
*/
- RollbackData(int rollbackId, File backupDir, int stagedSessionId) {
+ Rollback(int rollbackId, File backupDir, int stagedSessionId) {
this.info = new RollbackInfo(rollbackId,
/* packages */ new ArrayList<>(),
/* isStaged */ stagedSessionId != -1,
@@ -121,9 +121,9 @@
}
/**
- * Constructs a RollbackData instance with full rollback data information.
+ * Constructs a pre-populated Rollback instance.
*/
- RollbackData(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
+ Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
@RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) {
this.info = info;
this.backupDir = backupDir;
@@ -143,9 +143,9 @@
static String rollbackStateToString(@RollbackState int state) {
switch (state) {
- case RollbackData.ROLLBACK_STATE_ENABLING: return "enabling";
- case RollbackData.ROLLBACK_STATE_AVAILABLE: return "available";
- case RollbackData.ROLLBACK_STATE_COMMITTED: return "committed";
+ case Rollback.ROLLBACK_STATE_ENABLING: return "enabling";
+ case Rollback.ROLLBACK_STATE_AVAILABLE: return "available";
+ case Rollback.ROLLBACK_STATE_COMMITTED: return "committed";
}
throw new AssertionError("Invalid rollback state: " + state);
}
@@ -153,9 +153,9 @@
static @RollbackState int rollbackStateFromString(String state)
throws ParseException {
switch (state) {
- case "enabling": return RollbackData.ROLLBACK_STATE_ENABLING;
- case "available": return RollbackData.ROLLBACK_STATE_AVAILABLE;
- case "committed": return RollbackData.ROLLBACK_STATE_COMMITTED;
+ case "enabling": return Rollback.ROLLBACK_STATE_ENABLING;
+ case "available": return Rollback.ROLLBACK_STATE_AVAILABLE;
+ case "committed": return Rollback.ROLLBACK_STATE_COMMITTED;
}
throw new ParseException("Invalid rollback state: " + state, 0);
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index e107c9a..42f3e2fd 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -45,14 +45,13 @@
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.Process;
-import android.os.UserHandle; // duped to avoid merge conflict
-import android.os.UserManager; // out of order to avoid merge conflict
import android.os.SystemClock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.DeviceConfig;
import android.util.ArraySet;
import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.SparseLongArray;
@@ -76,6 +75,7 @@
import java.util.List;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -110,14 +110,13 @@
@GuardedBy("mLock")
private final SparseBooleanArray mAllocatedRollbackIds = new SparseBooleanArray();
- // Package rollback data for rollbacks we are in the process of enabling.
+ // Rollbacks we are in the process of enabling.
@GuardedBy("mLock")
private final Set<NewRollback> mNewRollbacks = new ArraySet<>();
// The list of all rollbacks, including available and committed rollbacks.
- // This list is null until the rollback data has been loaded.
@GuardedBy("mLock")
- private List<RollbackData> mRollbacks;
+ private final List<Rollback> mRollbacks;
private final RollbackStore mRollbackStore;
@@ -128,7 +127,7 @@
private final AppDataRollbackHelper mAppDataRollbackHelper;
// This field stores the difference in Millis between the uptime (millis since device
- // has booted) and current time (device wall clock) - it's used to update rollback data
+ // has booted) and current time (device wall clock) - it's used to update rollback
// timestamps when the time is changed, by the user or by change of timezone.
// No need for guarding with lock because value is only accessed in handler thread.
private long mRelativeBootTime = calculateRelativeBootTime();
@@ -139,29 +138,25 @@
// SystemService#onStart.
mInstaller = new Installer(mContext);
mInstaller.onStart();
- mHandlerThread = new HandlerThread("RollbackManagerServiceHandler");
- mHandlerThread.start();
-
- // Monitor the handler thread
- Watchdog.getInstance().addThread(getHandler(), HANDLER_THREAD_TIMEOUT_DURATION_MILLIS);
mRollbackStore = new RollbackStore(new File(Environment.getDataDirectory(), "rollback"));
mPackageHealthObserver = new RollbackPackageHealthObserver(mContext);
mAppDataRollbackHelper = new AppDataRollbackHelper(mInstaller);
- // Kick off loading of the rollback data from strorage in a background
- // thread.
- // TODO: Consider loading the rollback data directly here instead, to
- // avoid the need to call ensureRollbackDataLoaded every time before
- // accessing the rollback data?
- // TODO: Test that this kicks off initial scheduling of rollback
- // expiration.
- getHandler().post(() -> ensureRollbackDataLoaded());
+ // Load rollback data from device storage.
+ synchronized (mLock) {
+ mRollbacks = mRollbackStore.loadRollbacks();
+ for (Rollback rollback : mRollbacks) {
+ mAllocatedRollbackIds.put(rollback.info.getRollbackId(), true);
+ }
+ }
- // TODO: Make sure to register these call backs when a new user is
- // added too.
- SessionCallback sessionCallback = new SessionCallback();
+ // Kick off and start monitoring the handler thread.
+ mHandlerThread = new HandlerThread("RollbackManagerServiceHandler");
+ mHandlerThread.start();
+ Watchdog.getInstance().addThread(getHandler(), HANDLER_THREAD_TIMEOUT_DURATION_MILLIS);
+
for (UserInfo userInfo : UserManager.get(mContext).getUsers(true)) {
registerUserCallbacks(userInfo.getUserHandle());
}
@@ -171,7 +166,7 @@
try {
enableRollbackFilter.addDataType("application/vnd.android.package-archive");
} catch (IntentFilter.MalformedMimeTypeException e) {
- Log.e(TAG, "addDataType", e);
+ Slog.e(TAG, "addDataType", e);
}
mContext.registerReceiver(new BroadcastReceiver() {
@@ -182,16 +177,14 @@
PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, -1);
int installFlags = intent.getIntExtra(
PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS, 0);
- int[] installedUsers = intent.getIntArrayExtra(
- PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS);
int user = intent.getIntExtra(
PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER, 0);
File newPackageCodePath = new File(intent.getData().getPath());
getHandler().post(() -> {
- boolean success = enableRollback(installFlags, newPackageCodePath,
- installedUsers, user, token);
+ boolean success =
+ enableRollback(installFlags, newPackageCodePath, user, token);
int ret = PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED;
if (!success) {
ret = PackageManagerInternal.ENABLE_ROLLBACK_FAILED;
@@ -251,13 +244,10 @@
private void registerUserCallbacks(UserHandle user) {
Context context = getContextAsUser(user);
if (context == null) {
- Log.e(TAG, "Unable to register user callbacks for user " + user);
+ Slog.e(TAG, "Unable to register user callbacks for user " + user);
return;
}
- // TODO: Reuse the same SessionCallback and broadcast receiver
- // instances, rather than creating new instances for each user.
-
context.getPackageManager().getPackageInstaller()
.registerSessionCallback(new SessionCallback(), getHandler());
@@ -281,44 +271,15 @@
}, filter, null, getHandler());
}
- /**
- * This method posts a blocking call to the handler thread, so it should not be called from
- * that same thread.
- * @throws {@link IllegalStateException} if called from {@link #mHandlerThread}
- */
@Override
public ParceledListSlice getAvailableRollbacks() {
enforceManageRollbacks("getAvailableRollbacks");
- if (Thread.currentThread().equals(mHandlerThread)) {
- Log.wtf(TAG, "Calling getAvailableRollbacks from mHandlerThread "
- + "causes a deadlock");
- throw new IllegalStateException("Cannot call RollbackManager#getAvailableRollbacks "
- + "from the handler thread!");
- }
-
- // Wait for the handler thread to get the list of available rollbacks
- // to get the most up-to-date results. This is intended to reduce test
- // flakiness when checking available rollbacks immediately after
- // installing a package with rollback enabled.
- final LinkedBlockingQueue<Boolean> result = new LinkedBlockingQueue<>();
- getHandler().post(() -> result.offer(true));
-
- try {
- result.take();
- } catch (InterruptedException ie) {
- // We may not get the most up-to-date information, but whatever we
- // can get now is better than nothing, so log but otherwise ignore
- // the exception.
- Log.w(TAG, "Interrupted while waiting for handler thread in getAvailableRollbacks");
- }
-
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mRollbacks.size(); ++i) {
- RollbackData data = mRollbacks.get(i);
- if (data.state == RollbackData.ROLLBACK_STATE_AVAILABLE) {
- rollbacks.add(data.info);
+ Rollback rollback = mRollbacks.get(i);
+ if (rollback.state == Rollback.ROLLBACK_STATE_AVAILABLE) {
+ rollbacks.add(rollback.info);
}
}
return new ParceledListSlice<>(rollbacks);
@@ -326,16 +287,15 @@
}
@Override
- public ParceledListSlice<RollbackInfo> getRecentlyExecutedRollbacks() {
+ public ParceledListSlice<RollbackInfo> getRecentlyCommittedRollbacks() {
enforceManageRollbacks("getRecentlyCommittedRollbacks");
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mRollbacks.size(); ++i) {
- RollbackData data = mRollbacks.get(i);
- if (data.state == RollbackData.ROLLBACK_STATE_COMMITTED) {
- rollbacks.add(data.info);
+ Rollback rollback = mRollbacks.get(i);
+ if (rollback.state == Rollback.ROLLBACK_STATE_COMMITTED) {
+ rollbacks.add(rollback.info);
}
}
return new ParceledListSlice<>(rollbacks);
@@ -345,7 +305,7 @@
@Override
public void commitRollback(int rollbackId, ParceledListSlice causePackages,
String callerPackageName, IntentSender statusReceiver) {
- enforceManageRollbacks("executeRollback");
+ enforceManageRollbacks("commitRollback");
final int callingUid = Binder.getCallingUid();
AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
@@ -365,13 +325,11 @@
final long timeDifference = mRelativeBootTime - oldRelativeBootTime;
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
-
- Iterator<RollbackData> iter = mRollbacks.iterator();
+ Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
- RollbackData data = iter.next();
- data.timestamp = data.timestamp.plusMillis(timeDifference);
- saveRollbackData(data);
+ Rollback rollback = iter.next();
+ rollback.timestamp = rollback.timestamp.plusMillis(timeDifference);
+ saveRollback(rollback);
}
}
}
@@ -393,10 +351,10 @@
*/
private void commitRollbackInternal(int rollbackId, List<VersionedPackage> causePackages,
String callerPackageName, IntentSender statusReceiver) {
- Log.i(TAG, "Initiating rollback");
+ Slog.i(TAG, "Initiating rollback");
- RollbackData data = getRollbackForId(rollbackId);
- if (data == null || data.state != RollbackData.ROLLBACK_STATE_AVAILABLE) {
+ Rollback rollback = getRollbackForId(rollbackId);
+ if (rollback == null || rollback.state != Rollback.ROLLBACK_STATE_AVAILABLE) {
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
"Rollback unavailable");
return;
@@ -404,7 +362,7 @@
// Get a context for the caller to use to install the downgraded
// version of the package.
- Context context = null;
+ final Context context;
try {
context = mContext.createPackageContext(callerPackageName, 0);
} catch (PackageManager.NameNotFoundException e) {
@@ -420,14 +378,14 @@
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
parentParams.setRequestDowngrade(true);
parentParams.setMultiPackage();
- if (data.isStaged()) {
+ if (rollback.isStaged()) {
parentParams.setStaged();
}
int parentSessionId = packageInstaller.createSession(parentParams);
PackageInstaller.Session parentSession = packageInstaller.openSession(parentSessionId);
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
// TODO: We can't get the installerPackageName for apex
@@ -442,7 +400,7 @@
params.setRequestDowngrade(true);
params.setRequiredInstalledVersionCode(
info.getVersionRolledBackFrom().getLongVersionCode());
- if (data.isStaged()) {
+ if (rollback.isStaged()) {
params.setStaged();
}
if (info.isApex()) {
@@ -450,9 +408,8 @@
}
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
-
File[] packageCodePaths = RollbackStore.getPackageCodePaths(
- data, info.getPackageName());
+ rollback, info.getPackageName());
if (packageCodePaths == null) {
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
"Backup copy of package inaccessible");
@@ -493,8 +450,8 @@
// TODO: Could this cause a rollback to be
// resurrected if it should otherwise have
// expired by now?
- data.state = RollbackData.ROLLBACK_STATE_AVAILABLE;
- data.restoreUserDataInProgress = false;
+ rollback.state = Rollback.ROLLBACK_STATE_AVAILABLE;
+ rollback.restoreUserDataInProgress = false;
}
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_INSTALL,
"Rollback downgrade install failed: "
@@ -504,35 +461,37 @@
}
synchronized (mLock) {
- if (!data.isStaged()) {
+ if (!rollback.isStaged()) {
// All calls to restoreUserData should have
// completed by now for a non-staged install.
- data.restoreUserDataInProgress = false;
+ rollback.restoreUserDataInProgress = false;
}
- data.info.setCommittedSessionId(parentSessionId);
- data.info.getCausePackages().addAll(causePackages);
+ rollback.info.setCommittedSessionId(parentSessionId);
+ rollback.info.getCausePackages().addAll(causePackages);
}
- mRollbackStore.deletePackageCodePaths(data);
- saveRollbackData(data);
+ mRollbackStore.deletePackageCodePaths(rollback);
+ saveRollback(rollback);
sendSuccess(statusReceiver);
Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED);
- mContext.sendBroadcastAsUser(broadcast, UserHandle.SYSTEM,
- Manifest.permission.MANAGE_ROLLBACKS);
+ for (UserInfo userInfo : UserManager.get(mContext).getUsers(true)) {
+ mContext.sendBroadcastAsUser(broadcast, userInfo.getUserHandle(),
+ Manifest.permission.MANAGE_ROLLBACKS);
+ }
});
}
);
synchronized (mLock) {
- data.state = RollbackData.ROLLBACK_STATE_COMMITTED;
- data.restoreUserDataInProgress = true;
+ rollback.state = Rollback.ROLLBACK_STATE_COMMITTED;
+ rollback.restoreUserDataInProgress = true;
}
parentSession.commit(receiver.getIntentSender());
} catch (IOException e) {
- Log.e(TAG, "Rollback failed", e);
+ Slog.e(TAG, "Rollback failed", e);
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
"IOException: " + e.toString());
return;
@@ -545,13 +504,21 @@
Manifest.permission.TEST_MANAGE_ROLLBACKS,
"reloadPersistedData");
- synchronized (mLock) {
- mRollbacks = null;
- }
+ CountDownLatch latch = new CountDownLatch(1);
getHandler().post(() -> {
updateRollbackLifetimeDurationInMillis();
- ensureRollbackDataLoaded();
+ synchronized (mLock) {
+ mRollbacks.clear();
+ mRollbacks.addAll(mRollbackStore.loadRollbacks());
+ }
+ latch.countDown();
});
+
+ try {
+ latch.await();
+ } catch (InterruptedException ie) {
+ throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
+ }
}
@Override
@@ -560,14 +527,21 @@
Manifest.permission.TEST_MANAGE_ROLLBACKS,
"expireRollbackForPackage");
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
- Iterator<RollbackData> iter = mRollbacks.iterator();
+ Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
- RollbackData data = iter.next();
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ Rollback rollback = iter.next();
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
if (info.getPackageName().equals(packageName)) {
iter.remove();
- deleteRollback(data);
+ deleteRollback(rollback);
+ break;
+ }
+ }
+ }
+ for (NewRollback newRollback : mNewRollbacks) {
+ for (PackageRollbackInfo info : newRollback.rollback.info.getPackages()) {
+ if (info.getPackageName().equals(packageName)) {
+ newRollback.isCancelled = true;
break;
}
}
@@ -575,18 +549,32 @@
}
}
+ @Override
+ public void blockRollbackManager(long millis) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.TEST_MANAGE_ROLLBACKS,
+ "blockRollbackManager");
+ getHandler().post(() -> {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
+ }
+ });
+ }
+
void onUnlockUser(int userId) {
getHandler().post(() -> {
- final List<RollbackData> rollbacks;
+ final List<Rollback> rollbacks;
synchronized (mLock) {
rollbacks = new ArrayList<>(mRollbacks);
}
- final Set<RollbackData> changed =
+ final Set<Rollback> changed =
mAppDataRollbackHelper.commitPendingBackupAndRestoreForUser(userId, rollbacks);
- for (RollbackData rd : changed) {
- saveRollbackData(rd);
+ for (Rollback rollback : changed) {
+ saveRollback(rollback);
}
});
}
@@ -609,20 +597,19 @@
getHandler().post(() -> {
// Check to see if any rollback-enabled staged sessions or staged
// rollback sessions been applied.
- List<RollbackData> enabling = new ArrayList<>();
- List<RollbackData> restoreInProgress = new ArrayList<>();
+ List<Rollback> enabling = new ArrayList<>();
+ List<Rollback> restoreInProgress = new ArrayList<>();
Set<String> apexPackageNames = new HashSet<>();
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
- for (RollbackData data : mRollbacks) {
- if (data.isStaged()) {
- if (data.state == RollbackData.ROLLBACK_STATE_ENABLING) {
- enabling.add(data);
- } else if (data.restoreUserDataInProgress) {
- restoreInProgress.add(data);
+ for (Rollback rollback : mRollbacks) {
+ if (rollback.isStaged()) {
+ if (rollback.state == Rollback.ROLLBACK_STATE_ENABLING) {
+ enabling.add(rollback);
+ } else if (rollback.restoreUserDataInProgress) {
+ restoreInProgress.add(rollback);
}
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
if (info.isApex()) {
apexPackageNames.add(info.getPackageName());
}
@@ -631,35 +618,32 @@
}
}
- for (RollbackData data : enabling) {
+ for (Rollback rollback : enabling) {
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
PackageInstaller.SessionInfo session = installer.getSessionInfo(
- data.stagedSessionId);
- // TODO: What if session is null?
- if (session != null) {
- if (session.isStagedSessionApplied()) {
- makeRollbackAvailable(data);
- } else if (session.isStagedSessionFailed()) {
- // TODO: Do we need to remove this from
- // mRollbacks, or is it okay to leave as
- // unavailable until the next reboot when it will go
- // away on its own?
- deleteRollback(data);
- }
+ rollback.stagedSessionId);
+ if (session == null || session.isStagedSessionFailed()) {
+ // TODO: Do we need to remove this from
+ // mRollbacks, or is it okay to leave as
+ // unavailable until the next reboot when it will go
+ // away on its own?
+ deleteRollback(rollback);
+ } else if (session.isStagedSessionApplied()) {
+ makeRollbackAvailable(rollback);
}
}
- for (RollbackData data : restoreInProgress) {
+ for (Rollback rollback : restoreInProgress) {
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
PackageInstaller.SessionInfo session = installer.getSessionInfo(
- data.stagedSessionId);
+ rollback.stagedSessionId);
// TODO: What if session is null?
if (session != null) {
if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) {
synchronized (mLock) {
- data.restoreUserDataInProgress = false;
+ rollback.restoreUserDataInProgress = false;
}
- saveRollbackData(data);
+ saveRollback(rollback);
}
}
}
@@ -676,42 +660,6 @@
}
/**
- * Load rollback data from storage if it has not already been loaded.
- * After calling this funciton, mAvailableRollbacks and
- * mRecentlyExecutedRollbacks will be non-null.
- */
- private void ensureRollbackDataLoaded() {
- synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
- }
- }
-
- /**
- * Load rollback data from storage if it has not already been loaded.
- * After calling this function, mRollbacks will be non-null.
- */
- @GuardedBy("mLock")
- private void ensureRollbackDataLoadedLocked() {
- if (mRollbacks == null) {
- loadAllRollbackDataLocked();
- }
- }
-
- /**
- * Load all rollback data from storage.
- * Note: We do potentially heavy IO here while holding mLock, because we
- * have to have the rollback data loaded before we can do anything else
- * meaningful.
- */
- @GuardedBy("mLock")
- private void loadAllRollbackDataLocked() {
- mRollbacks = mRollbackStore.loadAllRollbackData();
- for (RollbackData data : mRollbacks) {
- mAllocatedRollbackIds.put(data.info.getRollbackId(), true);
- }
- }
-
- /**
* Called when a package has been replaced with a different version.
* Removes all backups for the package not matching the currently
* installed package version.
@@ -722,20 +670,19 @@
VersionedPackage installedVersion = getInstalledPackageVersion(packageName);
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
- Iterator<RollbackData> iter = mRollbacks.iterator();
+ Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
- RollbackData data = iter.next();
+ Rollback rollback = iter.next();
// TODO: Should we remove rollbacks in the ENABLING state here?
- if (data.state == RollbackData.ROLLBACK_STATE_AVAILABLE
- || data.state == RollbackData.ROLLBACK_STATE_ENABLING) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ if (rollback.state == Rollback.ROLLBACK_STATE_AVAILABLE
+ || rollback.state == Rollback.ROLLBACK_STATE_ENABLING) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
if (info.getPackageName().equals(packageName)
&& !packageVersionsEqual(
info.getVersionRolledBackFrom(),
installedVersion)) {
iter.remove();
- deleteRollback(data);
+ deleteRollback(rollback);
break;
}
}
@@ -761,7 +708,7 @@
*/
private void sendFailure(IntentSender statusReceiver, @RollbackManager.Status int status,
String message) {
- Log.e(TAG, message);
+ Slog.e(TAG, message);
try {
final Intent fillIn = new Intent();
fillIn.putExtra(RollbackManager.EXTRA_STATUS, status);
@@ -791,19 +738,18 @@
Instant now = Instant.now();
Instant oldest = null;
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
-
- Iterator<RollbackData> iter = mRollbacks.iterator();
+ Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
- RollbackData data = iter.next();
- if (data.state != RollbackData.ROLLBACK_STATE_AVAILABLE) {
+ Rollback rollback = iter.next();
+ if (rollback.state != Rollback.ROLLBACK_STATE_AVAILABLE) {
continue;
}
- if (!now.isBefore(data.timestamp.plusMillis(mRollbackLifetimeDurationInMillis))) {
+ if (!now.isBefore(
+ rollback.timestamp.plusMillis(mRollbackLifetimeDurationInMillis))) {
iter.remove();
- deleteRollback(data);
- } else if (oldest == null || oldest.isAfter(data.timestamp)) {
- oldest = data.timestamp;
+ deleteRollback(rollback);
+ } else if (oldest == null || oldest.isAfter(rollback.timestamp)) {
+ oldest = rollback.timestamp;
}
}
}
@@ -858,13 +804,12 @@
*
* @param installFlags information about what is being installed.
* @param newPackageCodePath path to the package about to be installed.
- * @param installedUsers the set of users for which a given package is installed.
* @param user the user that owns the install session to enable rollback on.
* @param token the distinct rollback token sent by package manager.
* @return true if enabling the rollback succeeds, false otherwise.
*/
- private boolean enableRollback(int installFlags, File newPackageCodePath,
- int[] installedUsers, @UserIdInt int user, int token) {
+ private boolean enableRollback(
+ int installFlags, File newPackageCodePath, @UserIdInt int user, int token) {
// Find the session id associated with this install.
// TODO: It would be nice if package manager or package installer told
@@ -876,7 +821,7 @@
// session.
final Context context = getContextAsUser(UserHandle.of(user));
if (context == null) {
- Log.e(TAG, "Unable to create context for install session user.");
+ Slog.e(TAG, "Unable to create context for install session user.");
return false;
}
@@ -903,45 +848,21 @@
}
if (parentSession == null || packageSession == null) {
- Log.e(TAG, "Unable to find session for enabled rollback.");
+ Slog.e(TAG, "Unable to find session for enabled rollback.");
return false;
}
// Check to see if this is the apk session for a staged session with
// rollback enabled.
- // TODO: This check could be made more efficient.
- RollbackData rd = null;
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
for (int i = 0; i < mRollbacks.size(); ++i) {
- RollbackData data = mRollbacks.get(i);
- if (data.apkSessionId == parentSession.getSessionId()) {
- rd = data;
- break;
- }
- }
- }
-
- if (rd != null) {
- // This is the apk session for a staged session. We do not need to create a new rollback
- // for this session.
- PackageParser.PackageLite newPackage = null;
- try {
- newPackage = PackageParser.parsePackageLite(
- new File(packageSession.resolvedBaseCodePath), 0);
- } catch (PackageParser.PackageParserException e) {
- Log.e(TAG, "Unable to parse new package", e);
- return false;
- }
- String packageName = newPackage.packageName;
- for (PackageRollbackInfo info : rd.info.getPackages()) {
- if (info.getPackageName().equals(packageName)) {
- info.getInstalledUsers().addAll(IntArray.wrap(installedUsers));
+ Rollback rollback = mRollbacks.get(i);
+ if (rollback.apkSessionId == parentSession.getSessionId()) {
+ // This is the apk session for a staged session with rollback enabled. We do not
+ // need to create a new rollback for this session.
return true;
}
}
- Log.e(TAG, "Unable to find package in apk session");
- return false;
}
NewRollback newRollback;
@@ -957,7 +878,7 @@
}
newRollback.addToken(token);
- return enableRollbackForPackageSession(newRollback.data, packageSession, installedUsers);
+ return enableRollbackForPackageSession(newRollback.rollback, packageSession);
}
/**
@@ -967,21 +888,21 @@
*
* @return true on success, false on failure.
*/
- private boolean enableRollbackForPackageSession(RollbackData data,
- PackageInstaller.SessionInfo session, @NonNull int[] installedUsers) {
+ private boolean enableRollbackForPackageSession(Rollback rollback,
+ PackageInstaller.SessionInfo session) {
// TODO: Don't attempt to enable rollback for split installs.
final int installFlags = session.installFlags;
if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
- Log.e(TAG, "Rollback is not enabled.");
+ Slog.e(TAG, "Rollback is not enabled.");
return false;
}
if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
- Log.e(TAG, "Rollbacks not supported for instant app install");
+ Slog.e(TAG, "Rollbacks not supported for instant app install");
return false;
}
if (session.resolvedBaseCodePath == null) {
- Log.e(TAG, "Session code path has not been resolved.");
+ Slog.e(TAG, "Session code path has not been resolved.");
return false;
}
@@ -990,17 +911,17 @@
try {
newPackage = PackageParser.parsePackageLite(new File(session.resolvedBaseCodePath), 0);
} catch (PackageParser.PackageParserException e) {
- Log.e(TAG, "Unable to parse new package", e);
+ Slog.e(TAG, "Unable to parse new package", e);
return false;
}
String packageName = newPackage.packageName;
- Log.i(TAG, "Enabling rollback for install of " + packageName
+ Slog.i(TAG, "Enabling rollback for install of " + packageName
+ ", session:" + session.sessionId);
String installerPackageName = session.getInstallerPackageName();
if (!enableRollbackAllowed(installerPackageName, packageName)) {
- Log.e(TAG, "Installer " + installerPackageName
+ Slog.e(TAG, "Installer " + installerPackageName
+ " is not allowed to enable rollback on " + packageName);
return false;
}
@@ -1016,7 +937,7 @@
} catch (PackageManager.NameNotFoundException e) {
// TODO: Support rolling back fresh package installs rather than
// fail here. Test this case.
- Log.e(TAG, packageName + " is not installed");
+ Slog.e(TAG, packageName + " is not installed");
return false;
}
@@ -1026,24 +947,23 @@
PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(
newVersion, installedVersion,
new IntArray() /* pendingBackups */, new ArrayList<>() /* pendingRestores */,
- isApex, IntArray.wrap(installedUsers),
- new SparseLongArray() /* ceSnapshotInodes */);
+ isApex, new IntArray(), new SparseLongArray() /* ceSnapshotInodes */);
try {
ApplicationInfo appInfo = pkgInfo.applicationInfo;
- RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir);
+ RollbackStore.backupPackageCodePath(rollback, packageName, appInfo.sourceDir);
if (!ArrayUtils.isEmpty(appInfo.splitSourceDirs)) {
for (String sourceDir : appInfo.splitSourceDirs) {
- RollbackStore.backupPackageCodePath(data, packageName, sourceDir);
+ RollbackStore.backupPackageCodePath(rollback, packageName, sourceDir);
}
}
} catch (IOException e) {
- Log.e(TAG, "Unable to copy package for rollback for " + packageName, e);
+ Slog.e(TAG, "Unable to copy package for rollback for " + packageName, e);
return false;
}
synchronized (mLock) {
- data.info.getPackages().add(packageRollbackInfo);
+ rollback.info.getPackages().add(packageRollbackInfo);
}
return true;
}
@@ -1057,7 +977,7 @@
}
getHandler().post(() -> {
- snapshotUserDataInternal(packageName);
+ snapshotUserDataInternal(packageName, userIds);
restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token);
final PackageManagerInternal pmi = LocalServices.getService(
PackageManagerInternal.class);
@@ -1065,20 +985,20 @@
});
}
- private void snapshotUserDataInternal(String packageName) {
+ private void snapshotUserDataInternal(String packageName, int[] userIds) {
synchronized (mLock) {
// staged installs
- ensureRollbackDataLoadedLocked();
for (int i = 0; i < mRollbacks.size(); i++) {
- RollbackData data = mRollbacks.get(i);
- if (data.state != RollbackData.ROLLBACK_STATE_ENABLING) {
+ Rollback rollback = mRollbacks.get(i);
+ if (rollback.state != Rollback.ROLLBACK_STATE_ENABLING) {
continue;
}
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
if (info.getPackageName().equals(packageName)) {
- mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info);
- saveRollbackData(data);
+ mAppDataRollbackHelper.snapshotAppData(
+ rollback.info.getRollbackId(), info, userIds);
+ saveRollback(rollback);
break;
}
}
@@ -1086,11 +1006,11 @@
// non-staged installs
PackageRollbackInfo info;
for (NewRollback rollback : mNewRollbacks) {
- info = getPackageRollbackInfo(rollback.data, packageName);
+ info = getPackageRollbackInfo(rollback.rollback, packageName);
if (info != null) {
- mAppDataRollbackHelper.snapshotAppData(rollback.data.info.getRollbackId(),
- info);
- saveRollbackData(rollback.data);
+ mAppDataRollbackHelper.snapshotAppData(
+ rollback.rollback.info.getRollbackId(), info, userIds);
+ saveRollback(rollback.rollback);
}
}
}
@@ -1099,32 +1019,31 @@
private void restoreUserDataInternal(String packageName, int[] userIds, int appId,
long ceDataInode, String seInfo, int token) {
PackageRollbackInfo info = null;
- RollbackData rollbackData = null;
+ Rollback rollback = null;
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
for (int i = 0; i < mRollbacks.size(); ++i) {
- RollbackData data = mRollbacks.get(i);
- if (data.restoreUserDataInProgress) {
- info = getPackageRollbackInfo(data, packageName);
+ Rollback candidate = mRollbacks.get(i);
+ if (candidate.restoreUserDataInProgress) {
+ info = getPackageRollbackInfo(candidate, packageName);
if (info != null) {
- rollbackData = data;
+ rollback = candidate;
break;
}
}
}
}
- if (rollbackData == null) {
+ if (rollback == null) {
return;
}
for (int userId : userIds) {
- final boolean changedRollbackData = mAppDataRollbackHelper.restoreAppData(
- rollbackData.info.getRollbackId(), info, userId, appId, seInfo);
+ final boolean changedRollback = mAppDataRollbackHelper.restoreAppData(
+ rollback.info.getRollbackId(), info, userId, appId, seInfo);
// We've updated metadata about this rollback, so save it to flash.
- if (changedRollbackData) {
- saveRollbackData(rollbackData);
+ if (changedRollback) {
+ saveRollback(rollback);
}
}
}
@@ -1143,7 +1062,7 @@
final PackageInstaller.SessionInfo session = installer.getSessionInfo(sessionId);
if (session == null) {
- Log.e(TAG, "No matching install session for: " + sessionId);
+ Slog.e(TAG, "No matching install session for: " + sessionId);
result.offer(false);
return;
}
@@ -1154,9 +1073,8 @@
}
if (!session.isMultiPackage()) {
- if (!enableRollbackForPackageSession(newRollback.data, session,
- new int[0])) {
- Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
+ if (!enableRollbackForPackageSession(newRollback.rollback, session)) {
+ Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
result.offer(false);
return;
}
@@ -1165,13 +1083,12 @@
final PackageInstaller.SessionInfo childSession =
installer.getSessionInfo(childSessionId);
if (childSession == null) {
- Log.e(TAG, "No matching child install session for: " + childSessionId);
+ Slog.e(TAG, "No matching child install session for: " + childSessionId);
result.offer(false);
return;
}
- if (!enableRollbackForPackageSession(newRollback.data, childSession,
- new int[0])) {
- Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
+ if (!enableRollbackForPackageSession(newRollback.rollback, childSession)) {
+ Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
result.offer(false);
return;
}
@@ -1184,7 +1101,7 @@
try {
return result.take();
} catch (InterruptedException ie) {
- Log.e(TAG, "Interrupted while waiting for notifyStagedSession response");
+ Slog.e(TAG, "Interrupted while waiting for notifyStagedSession response");
return false;
}
}
@@ -1195,21 +1112,20 @@
throw new SecurityException("notifyStagedApkSession may only be called by the system.");
}
getHandler().post(() -> {
- RollbackData rd = null;
+ Rollback rollback = null;
synchronized (mLock) {
- ensureRollbackDataLoadedLocked();
for (int i = 0; i < mRollbacks.size(); ++i) {
- RollbackData data = mRollbacks.get(i);
- if (data.stagedSessionId == originalSessionId) {
- data.apkSessionId = apkSessionId;
- rd = data;
+ Rollback candidate = mRollbacks.get(i);
+ if (candidate.stagedSessionId == originalSessionId) {
+ candidate.apkSessionId = apkSessionId;
+ rollback = candidate;
break;
}
}
}
- if (rd != null) {
- saveRollbackData(rd);
+ if (rollback != null) {
+ saveRollback(rollback);
}
});
}
@@ -1289,7 +1205,8 @@
private boolean packageVersionsEqual(VersionedPackage a, VersionedPackage b) {
- return a.getPackageName().equals(b.getPackageName())
+ return a != null && b != null
+ && a.getPackageName().equals(b.getPackageName())
&& a.getLongVersionCode() == b.getLongVersionCode();
}
@@ -1318,7 +1235,7 @@
}
if (newRollback != null) {
- RollbackData rollback = completeEnableRollback(newRollback, success);
+ Rollback rollback = completeEnableRollback(newRollback, success);
if (rollback != null && !rollback.isStaged()) {
makeRollbackAvailable(rollback);
}
@@ -1331,32 +1248,32 @@
* This should be called after rollback has been enabled for all packages
* in the rollback. It does not make the rollback available yet.
*
- * @return the rollback data for a successfully enable-completed rollback,
+ * @return the Rollback instance for a successfully enable-completed rollback,
* or null on error.
*/
- private RollbackData completeEnableRollback(NewRollback newRollback, boolean success) {
- RollbackData data = newRollback.data;
+ private Rollback completeEnableRollback(NewRollback newRollback, boolean success) {
+ Rollback rollback = newRollback.rollback;
if (!success) {
// The install session was aborted, clean up the pending install.
- deleteRollback(data);
+ deleteRollback(rollback);
return null;
}
if (newRollback.isCancelled) {
- Log.e(TAG, "Rollback has been cancelled by PackageManager");
- deleteRollback(data);
+ Slog.e(TAG, "Rollback has been cancelled by PackageManager");
+ deleteRollback(rollback);
return null;
}
- // It's safe to access data.info outside a synchronized block because
+ // It's safe to access rollback.info outside a synchronized block because
// this is running on the handler thread and all changes to the
- // data.info occur on the handler thread.
- if (data.info.getPackages().size() != newRollback.packageSessionIds.length) {
- Log.e(TAG, "Failed to enable rollback for all packages in session.");
- deleteRollback(data);
+ // rollback.info occur on the handler thread.
+ if (rollback.info.getPackages().size() != newRollback.packageSessionIds.length) {
+ Slog.e(TAG, "Failed to enable rollback for all packages in session.");
+ deleteRollback(rollback);
return null;
}
- saveRollbackData(data);
+ saveRollback(rollback);
synchronized (mLock) {
// Note: There is a small window of time between when
// the session has been committed by the package
@@ -1364,26 +1281,25 @@
// here. Presumably the window is small enough that
// nobody will want to roll back the newly installed
// package before we make the rollback available.
- // TODO: We'll lose the rollback data if the
+ // TODO: We'll lose the rollback if the
// device reboots between when the session is
// committed and this point. Revisit this after
// adding support for rollback of staged installs.
- ensureRollbackDataLoadedLocked();
- mRollbacks.add(data);
+ mRollbacks.add(rollback);
}
- return data;
+ return rollback;
}
- private void makeRollbackAvailable(RollbackData data) {
+ private void makeRollbackAvailable(Rollback rollback) {
// TODO: What if the rollback has since been expired, for example due
// to a new package being installed. Won't this revive an expired
// rollback? Consider adding a ROLLBACK_STATE_EXPIRED to address this.
synchronized (mLock) {
- data.state = RollbackData.ROLLBACK_STATE_AVAILABLE;
- data.timestamp = Instant.now();
+ rollback.state = Rollback.ROLLBACK_STATE_AVAILABLE;
+ rollback.timestamp = Instant.now();
}
- saveRollbackData(data);
+ saveRollback(rollback);
// TODO(zezeozue): Provide API to explicitly start observing instead
// of doing this for all rollbacks. If we do this for all rollbacks,
@@ -1391,8 +1307,8 @@
// After enabling and commiting any rollback, observe packages and
// prepare to rollback if packages crashes too frequently.
List<String> packages = new ArrayList<>();
- for (int i = 0; i < data.info.getPackages().size(); i++) {
- packages.add(data.info.getPackages().get(i).getPackageName());
+ for (int i = 0; i < rollback.info.getPackages().size(); i++) {
+ packages.add(rollback.info.getPackages().get(i).getPackageName());
}
mPackageHealthObserver.startObservingHealth(packages,
mRollbackLifetimeDurationInMillis);
@@ -1400,18 +1316,14 @@
}
/*
- * Returns the RollbackData, if any, for a rollback with the given
- * rollbackId.
+ * Returns the rollback with the given rollbackId, if any.
*/
- private RollbackData getRollbackForId(int rollbackId) {
+ private Rollback getRollbackForId(int rollbackId) {
synchronized (mLock) {
- // TODO: Have ensureRollbackDataLoadedLocked return the list of
- // available rollbacks, to hopefully avoid forgetting to call it?
- ensureRollbackDataLoadedLocked();
for (int i = 0; i < mRollbacks.size(); ++i) {
- RollbackData data = mRollbacks.get(i);
- if (data.info.getRollbackId() == rollbackId) {
- return data;
+ Rollback rollback = mRollbacks.get(i);
+ if (rollback.info.getRollbackId() == rollbackId) {
+ return rollback;
}
}
}
@@ -1421,11 +1333,11 @@
/**
* Returns the {@code PackageRollbackInfo} associated with {@code packageName} from
- * a specified {@code RollbackData}.
+ * a specified {@code Rollback}.
*/
- private static PackageRollbackInfo getPackageRollbackInfo(RollbackData data,
+ private static PackageRollbackInfo getPackageRollbackInfo(Rollback rollback,
String packageName) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
if (info.getPackageName().equals(packageName)) {
return info;
}
@@ -1449,30 +1361,30 @@
throw new IllegalStateException("Failed to allocate rollback ID");
}
- private void deleteRollback(RollbackData rollbackData) {
- for (PackageRollbackInfo info : rollbackData.info.getPackages()) {
- IntArray installedUsers = info.getInstalledUsers();
- for (int i = 0; i < installedUsers.size(); i++) {
- int userId = installedUsers.get(i);
- mAppDataRollbackHelper.destroyAppDataSnapshot(rollbackData.info.getRollbackId(),
+ private void deleteRollback(Rollback rollback) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
+ IntArray snapshottedUsers = info.getSnapshottedUsers();
+ for (int i = 0; i < snapshottedUsers.size(); i++) {
+ int userId = snapshottedUsers.get(i);
+ mAppDataRollbackHelper.destroyAppDataSnapshot(rollback.info.getRollbackId(),
info, userId);
}
}
- mRollbackStore.deleteRollbackData(rollbackData);
+ mRollbackStore.deleteRollback(rollback);
}
/**
- * Saves rollback data, swallowing any IOExceptions.
+ * Saves a rollback, swallowing any IOExceptions.
* For those times when it's not obvious what to do about the IOException.
* TODO: Double check we can't do a better job handling the IOException in
* a cases where this method is called.
*/
- private void saveRollbackData(RollbackData rollbackData) {
+ private void saveRollback(Rollback rollback) {
try {
- mRollbackStore.saveRollbackData(rollbackData);
+ mRollbackStore.saveRollback(rollback);
} catch (IOException ioe) {
- Log.e(TAG, "Unable to save rollback info for: "
- + rollbackData.info.getRollbackId(), ioe);
+ Slog.e(TAG, "Unable to save rollback for: "
+ + rollback.info.getRollbackId(), ioe);
}
}
@@ -1480,14 +1392,14 @@
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
synchronized (mLock) {
- for (RollbackData data : mRollbacks) {
- RollbackInfo info = data.info;
+ for (Rollback rollback : mRollbacks) {
+ RollbackInfo info = rollback.info;
ipw.println(info.getRollbackId() + ":");
ipw.increaseIndent();
- ipw.println("-state: " + data.getStateAsString());
- ipw.println("-timestamp: " + data.timestamp);
- if (data.stagedSessionId != -1) {
- ipw.println("-stagedSessionId: " + data.stagedSessionId);
+ ipw.println("-state: " + rollback.getStateAsString());
+ ipw.println("-timestamp: " + rollback.timestamp);
+ if (rollback.stagedSessionId != -1) {
+ ipw.println("-stagedSessionId: " + rollback.stagedSessionId);
}
ipw.println("-packages:");
ipw.increaseIndent();
@@ -1497,7 +1409,7 @@
+ " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
}
ipw.decreaseIndent();
- if (data.state == RollbackData.ROLLBACK_STATE_COMMITTED) {
+ if (rollback.state == Rollback.ROLLBACK_STATE_COMMITTED) {
ipw.println("-causePackages:");
ipw.increaseIndent();
for (VersionedPackage cPkg : info.getCausePackages()) {
@@ -1523,7 +1435,7 @@
}
private static class NewRollback {
- public final RollbackData data;
+ public final Rollback rollback;
/**
* This array holds all of the rollback tokens associated with package sessions included
@@ -1541,9 +1453,9 @@
public final int[] packageSessionIds;
/**
- * Flag to determine whether the RollbackData has been cancelled.
+ * Flag to determine whether the rollback has been cancelled.
*
- * <p>RollbackData could be invalidated and cancelled if RollbackManager receives
+ * <p>Rollback could be invalidated and cancelled if RollbackManager receives
* {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} from {@link PackageManager}.
*
* <p>The main underlying assumption here is that if enabling the rollback times out, then
@@ -1553,8 +1465,8 @@
*/
public boolean isCancelled = false;
- NewRollback(RollbackData data, int[] packageSessionIds) {
- this.data = data;
+ NewRollback(Rollback rollback, int[] packageSessionIds) {
+ this.rollback = rollback;
this.packageSessionIds = packageSessionIds;
}
@@ -1569,13 +1481,13 @@
NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) {
int rollbackId = allocateRollbackIdLocked();
- final RollbackData data;
+ final Rollback rollback;
int parentSessionId = parentSession.getSessionId();
if (parentSession.isStaged()) {
- data = mRollbackStore.createStagedRollback(rollbackId, parentSessionId);
+ rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId);
} else {
- data = mRollbackStore.createNonStagedRollback(rollbackId);
+ rollback = mRollbackStore.createNonStagedRollback(rollbackId);
}
int[] packageSessionIds;
@@ -1585,7 +1497,7 @@
packageSessionIds = new int[]{parentSessionId};
}
- return new NewRollback(data, packageSessionIds);
+ return new NewRollback(rollback, packageSessionIds);
}
/**
@@ -1596,10 +1508,10 @@
NewRollback getNewRollbackForPackageSessionLocked(int packageSessionId) {
// We expect mNewRollbacks to be a very small list; linear search
// should be plenty fast.
- for (NewRollback newRollbackData : mNewRollbacks) {
- for (int id : newRollbackData.packageSessionIds) {
+ for (NewRollback newRollback: mNewRollbacks) {
+ for (int id : newRollback.packageSessionIds) {
if (id == packageSessionId) {
- return newRollbackData;
+ return newRollback;
}
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 8a26368c..b2448f6 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -16,8 +16,8 @@
package com.android.server.rollback;
-import static com.android.server.rollback.RollbackData.rollbackStateFromString;
-import static com.android.server.rollback.RollbackData.rollbackStateToString;
+import static com.android.server.rollback.Rollback.rollbackStateFromString;
+import static com.android.server.rollback.Rollback.rollbackStateToString;
import android.annotation.NonNull;
import android.content.pm.VersionedPackage;
@@ -25,7 +25,7 @@
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.content.rollback.RollbackInfo;
import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
import android.util.SparseLongArray;
import libcore.io.IoUtils;
@@ -73,17 +73,17 @@
}
/**
- * Reads the rollback data from persistent storage.
+ * Reads the rollbacks from persistent storage.
*/
- List<RollbackData> loadAllRollbackData() {
- List<RollbackData> rollbacks = new ArrayList<>();
+ List<Rollback> loadRollbacks() {
+ List<Rollback> rollbacks = new ArrayList<>();
mRollbackDataDir.mkdirs();
for (File rollbackDir : mRollbackDataDir.listFiles()) {
if (rollbackDir.isDirectory()) {
try {
- rollbacks.add(loadRollbackData(rollbackDir));
+ rollbacks.add(loadRollback(rollbackDir));
} catch (IOException e) {
- Log.e(TAG, "Unable to read rollback data at " + rollbackDir, e);
+ Slog.e(TAG, "Unable to read rollback at " + rollbackDir, e);
removeFile(rollbackDir);
}
}
@@ -191,21 +191,21 @@
}
/**
- * Creates a new RollbackData instance for a non-staged rollback with
+ * Creates a new Rollback instance for a non-staged rollback with
* backupDir assigned.
*/
- RollbackData createNonStagedRollback(int rollbackId) {
+ Rollback createNonStagedRollback(int rollbackId) {
File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
- return new RollbackData(rollbackId, backupDir, -1);
+ return new Rollback(rollbackId, backupDir, -1);
}
/**
- * Creates a new RollbackData instance for a staged rollback with
+ * Creates a new Rollback instance for a staged rollback with
* backupDir assigned.
*/
- RollbackData createStagedRollback(int rollbackId, int stagedSessionId) {
+ Rollback createStagedRollback(int rollbackId, int stagedSessionId) {
File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId));
- return new RollbackData(rollbackId, backupDir, stagedSessionId);
+ return new Rollback(rollbackId, backupDir, stagedSessionId);
}
/**
@@ -213,10 +213,10 @@
* For packages containing splits, this method should be called for each
* of the package's split apks in addition to the base apk.
*/
- static void backupPackageCodePath(RollbackData data, String packageName, String codePath)
+ static void backupPackageCodePath(Rollback rollback, String packageName, String codePath)
throws IOException {
File sourceFile = new File(codePath);
- File targetDir = new File(data.backupDir, packageName);
+ File targetDir = new File(rollback.backupDir, packageName);
targetDir.mkdirs();
File targetFile = new File(targetDir, sourceFile.getName());
@@ -228,8 +228,8 @@
* Returns the apk or apex files backed up for the given package.
* Includes the base apk and any splits. Returns null if none found.
*/
- static File[] getPackageCodePaths(RollbackData data, String packageName) {
- File targetDir = new File(data.backupDir, packageName);
+ static File[] getPackageCodePaths(Rollback rollback, String packageName) {
+ File targetDir = new File(rollback.backupDir, packageName);
File[] files = targetDir.listFiles();
if (files == null || files.length == 0) {
return null;
@@ -241,27 +241,27 @@
* Deletes all backed up apks and apex files associated with the given
* rollback.
*/
- static void deletePackageCodePaths(RollbackData data) {
- for (PackageRollbackInfo info : data.info.getPackages()) {
- File targetDir = new File(data.backupDir, info.getPackageName());
+ static void deletePackageCodePaths(Rollback rollback) {
+ for (PackageRollbackInfo info : rollback.info.getPackages()) {
+ File targetDir = new File(rollback.backupDir, info.getPackageName());
removeFile(targetDir);
}
}
/**
- * Saves the rollback data to persistent storage.
+ * Saves the given rollback to persistent storage.
*/
- void saveRollbackData(RollbackData data) throws IOException {
+ void saveRollback(Rollback rollback) throws IOException {
try {
JSONObject dataJson = new JSONObject();
- dataJson.put("info", rollbackInfoToJson(data.info));
- dataJson.put("timestamp", data.timestamp.toString());
- dataJson.put("stagedSessionId", data.stagedSessionId);
- dataJson.put("state", rollbackStateToString(data.state));
- dataJson.put("apkSessionId", data.apkSessionId);
- dataJson.put("restoreUserDataInProgress", data.restoreUserDataInProgress);
+ dataJson.put("info", rollbackInfoToJson(rollback.info));
+ dataJson.put("timestamp", rollback.timestamp.toString());
+ dataJson.put("stagedSessionId", rollback.stagedSessionId);
+ dataJson.put("state", rollbackStateToString(rollback.state));
+ dataJson.put("apkSessionId", rollback.apkSessionId);
+ dataJson.put("restoreUserDataInProgress", rollback.restoreUserDataInProgress);
- PrintWriter pw = new PrintWriter(new File(data.backupDir, "rollback.json"));
+ PrintWriter pw = new PrintWriter(new File(rollback.backupDir, "rollback.json"));
pw.println(dataJson.toString());
pw.close();
} catch (JSONException e) {
@@ -270,23 +270,23 @@
}
/**
- * Removes all persistant storage associated with the given rollback data.
+ * Removes all persistent storage associated with the given rollback.
*/
- void deleteRollbackData(RollbackData data) {
- removeFile(data.backupDir);
+ void deleteRollback(Rollback rollback) {
+ removeFile(rollback.backupDir);
}
/**
* Reads the metadata for a rollback from the given directory.
* @throws IOException in case of error reading the data.
*/
- private static RollbackData loadRollbackData(File backupDir) throws IOException {
+ private static Rollback loadRollback(File backupDir) throws IOException {
try {
File rollbackJsonFile = new File(backupDir, "rollback.json");
JSONObject dataJson = new JSONObject(
IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));
- return new RollbackData(
+ return new Rollback(
rollbackInfoFromJson(dataJson.getJSONObject("info")),
backupDir,
Instant.parse(dataJson.getString("timestamp")),
@@ -319,13 +319,14 @@
IntArray pendingBackups = info.getPendingBackups();
List<RestoreInfo> pendingRestores = info.getPendingRestores();
- IntArray installedUsers = info.getInstalledUsers();
+ IntArray snapshottedUsers = info.getSnapshottedUsers();
json.put("pendingBackups", convertToJsonArray(pendingBackups));
json.put("pendingRestores", convertToJsonArray(pendingRestores));
json.put("isApex", info.isApex());
- json.put("installedUsers", convertToJsonArray(installedUsers));
+ // Field is named 'installedUsers' for legacy reasons.
+ json.put("installedUsers", convertToJsonArray(snapshottedUsers));
json.put("ceSnapshotInodes", ceSnapshotInodesToJson(info.getCeSnapshotInodes()));
return json;
@@ -345,12 +346,13 @@
final boolean isApex = json.getBoolean("isApex");
- final IntArray installedUsers = convertToIntArray(json.getJSONArray("installedUsers"));
+ // Field is named 'installedUsers' for legacy reasons.
+ final IntArray snapshottedUsers = convertToIntArray(json.getJSONArray("installedUsers"));
final SparseLongArray ceSnapshotInodes = ceSnapshotInodesFromJson(
json.getJSONArray("ceSnapshotInodes"));
return new PackageRollbackInfo(versionRolledBackFrom, versionRolledBackTo,
- pendingBackups, pendingRestores, isApex, installedUsers, ceSnapshotInodes);
+ pendingBackups, pendingRestores, isApex, snapshottedUsers, ceSnapshotInodes);
}
private static JSONArray versionedPackagesToJson(List<VersionedPackage> packages)
diff --git a/services/core/java/com/android/server/rollback/TEST_MAPPING b/services/core/java/com/android/server/rollback/TEST_MAPPING
index 8c7b5ac..2cc931b 100644
--- a/services/core/java/com/android/server/rollback/TEST_MAPPING
+++ b/services/core/java/com/android/server/rollback/TEST_MAPPING
@@ -1,12 +1,6 @@
{
"presubmit": [
{
- "name": "RollbackTest"
- },
- {
- "name": "StagedRollbackTest"
- },
- {
"name": "FrameworksServicesTests",
"options": [
{
@@ -21,6 +15,9 @@
},
{
"path": "cts/hostsidetests/rollback"
+ },
+ {
+ "path": "frameworks/base/tests/RollbackTest"
}
]
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 6175d41..7b3fbb9 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -130,7 +130,6 @@
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
- "android.hardware.vibrator@1.4",
"android.hardware.vr@1.0",
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 3726228..746610d 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "VibratorService"
-#include <android/hardware/vibrator/1.4/IVibrator.h>
+#include <android/hardware/vibrator/1.3/IVibrator.h>
#include <android/hardware/vibrator/BnVibratorCallback.h>
#include <android/hardware/vibrator/IVibrator.h>
#include <binder/IServiceManager.h>
@@ -43,166 +43,41 @@
namespace V1_1 = android::hardware::vibrator::V1_1;
namespace V1_2 = android::hardware::vibrator::V1_2;
namespace V1_3 = android::hardware::vibrator::V1_3;
-namespace V1_4 = android::hardware::vibrator::V1_4;
namespace aidl = android::hardware::vibrator;
namespace android {
static jmethodID sMethodIdOnComplete;
-// TODO(b/141828236): remove HIDL 1.4 and re-write all of this code to remove
-// shim
-class VibratorShim : public V1_4::IVibrator {
- public:
- VibratorShim(const sp<aidl::IVibrator>& vib) : mVib(vib) {}
+static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
+ static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
+static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
+ static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
+static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
+ static_cast<uint8_t>(aidl::EffectStrength::STRONG));
- Return<V1_0::Status> on(uint32_t timeoutMs) override {
- return on_1_4(timeoutMs, nullptr);
- }
+static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
+ static_cast<uint8_t>(aidl::Effect::CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
+ static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) ==
+ static_cast<uint8_t>(aidl::Effect::TICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) ==
+ static_cast<uint8_t>(aidl::Effect::THUD));
+static_assert(static_cast<uint8_t>(V1_3::Effect::POP) ==
+ static_cast<uint8_t>(aidl::Effect::POP));
+static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
+ static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
+ static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
+static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
+ static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
+static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
+ static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
+ static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
- Return<V1_0::Status> off() override {
- return toHidlStatus(mVib->off());
- }
-
- Return<bool> supportsAmplitudeControl() override {
- int32_t cap = 0;
- if (!mVib->getCapabilities(&cap).isOk()) return false;
- if (mUnderExternalControl) {
- return (cap & aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
- } else {
- return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
- }
- }
-
- Return<V1_0::Status> setAmplitude(uint8_t amplitude) override {
- return toHidlStatus(mVib->setAmplitude(amplitude));
- }
-
- Return<void> perform(V1_0::Effect effect, V1_0::EffectStrength strength,
- perform_cb _hidl_cb) override {
- return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
- }
-
- Return<void> perform_1_1(V1_1::Effect_1_1 effect, V1_0::EffectStrength strength,
- perform_1_1_cb _hidl_cb) override {
- return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
- }
-
- Return<void> perform_1_2(V1_2::Effect effect, V1_0::EffectStrength strength,
- perform_1_2_cb _hidl_cb) override {
- return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
- }
-
- Return<bool> supportsExternalControl() override {
- int32_t cap = 0;
- if (!mVib->getCapabilities(&cap).isOk()) return false;
- return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0;
- }
-
- Return<V1_0::Status> setExternalControl(bool enabled) override {
- Return<V1_0::Status> status = toHidlStatus(mVib->setExternalControl(enabled));
- if (status.isOk() && status == V1_0::Status::OK) {
- mUnderExternalControl = enabled;
- }
- return status;
- }
-
- Return<void> perform_1_3(V1_3::Effect effect, V1_0::EffectStrength strength,
- perform_1_3_cb _hidl_cb) override {
- return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
- }
-
- Return<uint32_t> getCapabilities() override {
- static_assert(static_cast<int32_t>(V1_4::Capabilities::ON_COMPLETION_CALLBACK) ==
- static_cast<int32_t>(aidl::IVibrator::CAP_ON_CALLBACK));
- static_assert(static_cast<int32_t>(V1_4::Capabilities::PERFORM_COMPLETION_CALLBACK) ==
- static_cast<int32_t>(aidl::IVibrator::CAP_PERFORM_CALLBACK));
-
- int32_t cap;
- if (!mVib->getCapabilities(&cap).isOk()) return 0;
- return (cap & (aidl::IVibrator::CAP_ON_CALLBACK |
- aidl::IVibrator::CAP_PERFORM_CALLBACK)) > 0;
- }
-
- Return<V1_0::Status> on_1_4(uint32_t timeoutMs,
- const sp<V1_4::IVibratorCallback>& callback) override {
- sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
- return toHidlStatus(mVib->on(timeoutMs, cb));
- }
-
- Return<void> perform_1_4(V1_3::Effect effect, V1_0::EffectStrength strength,
- const sp<V1_4::IVibratorCallback>& callback,
- perform_1_4_cb _hidl_cb) override {
- static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
- static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
- static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
- static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
- static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
- static_cast<uint8_t>(aidl::EffectStrength::STRONG));
- static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
- static_cast<uint8_t>(aidl::Effect::CLICK));
- static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
- static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
- static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) ==
- static_cast<uint8_t>(aidl::Effect::TICK));
- static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) ==
- static_cast<uint8_t>(aidl::Effect::THUD));
- static_assert(static_cast<uint8_t>(V1_3::Effect::POP) ==
- static_cast<uint8_t>(aidl::Effect::POP));
- static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
- static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
- static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
- static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
- static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
- static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
- static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
-
- sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
- int timeoutMs = 0;
- Return<V1_0::Status> status = toHidlStatus(
- mVib->perform(static_cast<aidl::Effect>(effect),
- static_cast<aidl::EffectStrength>(strength), cb, &timeoutMs));
-
- if (status.isOk()) {
- _hidl_cb(status, timeoutMs);
- return android::hardware::Status::ok();
- } else {
- return android::hardware::details::StatusOf<V1_0::Status, void>(status);
- }
- }
- private:
- sp<aidl::IVibrator> mVib;
- bool mUnderExternalControl = false;
-
- Return<V1_0::Status> toHidlStatus(const android::binder::Status& status) {
- switch(status.exceptionCode()) {
- using android::hardware::Status;
- case Status::EX_NONE: return V1_0::Status::OK;
- case Status::EX_ILLEGAL_ARGUMENT: return V1_0::Status::BAD_VALUE;
- case Status::EX_UNSUPPORTED_OPERATION: return V1_0::Status::UNSUPPORTED_OPERATION;
- case Status::EX_TRANSACTION_FAILED: {
- return Status::fromStatusT(status.transactionError());
- }
- }
- return V1_0::Status::UNKNOWN_ERROR;
- }
-
- class CallbackShim : public aidl::BnVibratorCallback {
- public:
- CallbackShim(const sp<V1_4::IVibratorCallback>& cb) : mCb(cb) {}
- binder::Status onComplete() {
- mCb->onComplete();
- return binder::Status::ok(); // oneway, local call
- }
- private:
- sp<V1_4::IVibratorCallback> mCb;
- };
-};
-
-class VibratorCallback : public V1_4::IVibratorCallback {
+class VibratorCallback {
public:
VibratorCallback(JNIEnv *env, jobject vibration) :
mVibration(MakeGlobalRefOrDie(env, vibration)) {}
@@ -212,47 +87,92 @@
env->DeleteGlobalRef(mVibration);
}
- Return<void> onComplete() override {
+ void onComplete() {
auto env = AndroidRuntime::getJNIEnv();
env->CallVoidMethod(mVibration, sMethodIdOnComplete);
- return Void();
}
private:
jobject mVibration;
};
+class AidlVibratorCallback : public aidl::BnVibratorCallback {
+ public:
+ AidlVibratorCallback(JNIEnv *env, jobject vibration) :
+ mCb(env, vibration) {}
+
+ binder::Status onComplete() override {
+ mCb.onComplete();
+ return binder::Status::ok(); // oneway, local call
+ }
+
+ private:
+ VibratorCallback mCb;
+};
+
static constexpr int NUM_TRIES = 2;
+template<class R>
+inline R NoneStatus() {
+ using ::android::hardware::Status;
+ return Status::fromExceptionCode(Status::EX_NONE);
+}
+
+template<>
+inline binder::Status NoneStatus() {
+ using binder::Status;
+ return Status::fromExceptionCode(Status::EX_NONE);
+}
+
// Creates a Return<R> with STATUS::EX_NULL_POINTER.
template<class R>
-inline Return<R> NullptrStatus() {
+inline R NullptrStatus() {
using ::android::hardware::Status;
- return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+}
+
+template<>
+inline binder::Status NullptrStatus() {
+ using binder::Status;
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+}
+
+template <typename I>
+sp<I> getService() {
+ return I::getService();
+}
+
+template <>
+sp<aidl::IVibrator> getService() {
+ return waitForVintfService<aidl::IVibrator>();
+}
+
+template <typename I>
+sp<I> tryGetService() {
+ return I::tryGetService();
+}
+
+template <>
+sp<aidl::IVibrator> tryGetService() {
+ return checkVintfService<aidl::IVibrator>();
}
template <typename I>
class HalWrapper {
public:
static std::unique_ptr<HalWrapper> Create() {
- sp<aidl::IVibrator> aidlVib = waitForVintfService<aidl::IVibrator>();
- if (aidlVib) {
- return std::unique_ptr<HalWrapper>(new HalWrapper(new VibratorShim(aidlVib)));
- }
-
// Assume that if getService returns a nullptr, HAL is not available on the
// device.
- auto hal = I::getService();
+ auto hal = getService<I>();
return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr;
}
// Helper used to transparently deal with the vibrator HAL becoming unavailable.
template<class R, class... Args0, class... Args1>
- Return<R> call(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+ R call(R (I::* fn)(Args0...), Args1&&... args1) {
// Return<R> doesn't have a default constructor, so make a Return<R> with
// STATUS::EX_NONE.
- using ::android::hardware::Status;
- Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
+ R ret{NoneStatus<R>()};
// Note that ret is guaranteed to be changed after this loop.
for (int i = 0; i < NUM_TRIES; ++i) {
@@ -266,12 +186,7 @@
ALOGE("Failed to issue command to vibrator HAL. Retrying.");
// Restoring connection to the HAL.
- sp<aidl::IVibrator> aidlVib = checkVintfService<aidl::IVibrator>();
- if (aidlVib) {
- mHal = new VibratorShim(aidlVib);
- } else {
- mHal = I::tryGetService();
- }
+ mHal = tryGetService<I>();
}
return ret;
}
@@ -290,7 +205,7 @@
}
template<class R, class I, class... Args0, class... Args1>
-Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+R halCall(R (I::* fn)(Args0...), Args1&&... args1) {
auto hal = getHal<I>();
return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>();
}
@@ -307,110 +222,192 @@
static void vibratorInit(JNIEnv *env, jclass clazz)
{
- halCall(&V1_0::IVibrator::ping).isOk();
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ // IBinder::pingBinder isn't accessible as a pointer function
+ // but getCapabilities can serve the same purpose
+ int32_t cap;
+ hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk();
+ } else {
+ halCall(&V1_0::IVibrator::ping).isOk();
+ }
}
static jboolean vibratorExists(JNIEnv* /* env */, jclass /* clazz */)
{
- return halCall(&V1_0::IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
+ bool ok;
+
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ // IBinder::pingBinder isn't accessible as a pointer function
+ // but getCapabilities can serve the same purpose
+ int32_t cap;
+ ok = hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk();
+ } else {
+ ok = halCall(&V1_0::IVibrator::ping).isOk();
+ }
+ return ok ? JNI_TRUE : JNI_FALSE;
}
static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms)
{
- Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
- if (retStatus != Status::OK) {
- ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr);
+ if (!status.isOk()) {
+ ALOGE("vibratorOn command failed: %s", status.toString8().string());
+ }
+ } else {
+ Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
+ if (retStatus != Status::OK) {
+ ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+ }
}
}
static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */)
{
- Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
- if (retStatus != Status::OK) {
- ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ auto status = hal->call(&aidl::IVibrator::off);
+ if (!status.isOk()) {
+ ALOGE("vibratorOff command failed: %s", status.toString8().string());
+ }
+ } else {
+ Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
+ if (retStatus != Status::OK) {
+ ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+ }
}
}
static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jclass) {
- return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ int32_t cap = 0;
+ if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
+ return false;
+ }
+ return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+ } else {
+ return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);
+ }
}
static void vibratorSetAmplitude(JNIEnv*, jclass, jint amplitude) {
- Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
- .withDefault(Status::UNKNOWN_ERROR);
- if (status != Status::OK) {
- ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
- static_cast<uint32_t>(status));
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ auto status = hal->call(&aidl::IVibrator::IVibrator::setAmplitude, amplitude);
+ if (!status.isOk()) {
+ ALOGE("Failed to set vibrator amplitude: %s", status.toString8().string());
+ }
+ } else {
+ Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
+ .withDefault(Status::UNKNOWN_ERROR);
+ if (status != Status::OK) {
+ ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
+ static_cast<uint32_t>(status));
+ }
}
}
static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) {
- return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false);
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ int32_t cap = 0;
+ if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
+ return false;
+ }
+ return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0;
+ } else {
+ return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false);
+ }
}
static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) {
- Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled))
- .withDefault(Status::UNKNOWN_ERROR);
- if (status != Status::OK) {
- ALOGE("Failed to set vibrator external control (%" PRIu32 ").",
- static_cast<uint32_t>(status));
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ auto status = hal->call(&aidl::IVibrator::IVibrator::setExternalControl, enabled);
+ if (!status.isOk()) {
+ ALOGE("Failed to set vibrator external control: %s", status.toString8().string());
+ }
+ } else {
+ Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled))
+ .withDefault(Status::UNKNOWN_ERROR);
+ if (status != Status::OK) {
+ ALOGE("Failed to set vibrator external control (%" PRIu32 ").",
+ static_cast<uint32_t>(status));
+ }
}
}
static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong strength,
jobject vibration) {
- Status status;
- uint32_t lengthMs;
- auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
- status = retStatus;
- lengthMs = retLengthMs;
- };
- EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ int32_t lengthMs;
+ sp<AidlVibratorCallback> effectCallback = new AidlVibratorCallback(env, vibration);
+ aidl::Effect effectType(static_cast<aidl::Effect>(strength));
+ aidl::EffectStrength effectStrength(static_cast<aidl::EffectStrength>(strength));
- Return<void> ret;
- if (auto hal = getHal<V1_4::IVibrator>(); hal && isValidEffect<V1_3::Effect>(effect)) {
- sp<VibratorCallback> effectCallback = new VibratorCallback(env, vibration);
- ret = hal->call(&V1_4::IVibrator::perform_1_4, static_cast<V1_3::Effect>(effect),
- effectStrength, effectCallback, callback);
- } else if (isValidEffect<V1_0::Effect>(effect)) {
- ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect),
- effectStrength, callback);
- } else if (isValidEffect<Effect_1_1>(effect)) {
- ret = halCall(&V1_1::IVibrator::perform_1_1, static_cast<Effect_1_1>(effect),
- effectStrength, callback);
- } else if (isValidEffect<V1_2::Effect>(effect)) {
- ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect),
- effectStrength, callback);
- } else if (isValidEffect<V1_3::Effect>(effect)) {
- ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect),
- effectStrength, callback);
- } else {
- ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
- static_cast<int32_t>(effect));
- return -1;
- }
-
- if (!ret.isOk()) {
- ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
- return -1;
- }
-
- if (status == Status::OK) {
+ auto status = hal->call(&aidl::IVibrator::perform, effectType, effectStrength, effectCallback, &lengthMs);
+ if (!status.isOk()) {
+ if (status.exceptionCode() != binder::Status::EX_UNSUPPORTED_OPERATION) {
+ ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+ ": %s", static_cast<int64_t>(effect), static_cast<int32_t>(strength), status.toString8().string());
+ }
+ return -1;
+ }
return lengthMs;
- } else if (status != Status::UNSUPPORTED_OPERATION) {
- // Don't warn on UNSUPPORTED_OPERATION, that's a normal event and just means the motor
- // doesn't have a pre-defined waveform to perform for it, so we should just give the
- // opportunity to fall back to the framework waveforms.
- ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
- ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
- static_cast<int32_t>(strength), static_cast<uint32_t>(status));
+ } else {
+ Status status;
+ uint32_t lengthMs;
+ auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
+ status = retStatus;
+ lengthMs = retLengthMs;
+ };
+ EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+
+ Return<void> ret;
+ if (isValidEffect<V1_0::Effect>(effect)) {
+ ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect),
+ effectStrength, callback);
+ } else if (isValidEffect<Effect_1_1>(effect)) {
+ ret = halCall(&V1_1::IVibrator::perform_1_1, static_cast<Effect_1_1>(effect),
+ effectStrength, callback);
+ } else if (isValidEffect<V1_2::Effect>(effect)) {
+ ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect),
+ effectStrength, callback);
+ } else if (isValidEffect<V1_3::Effect>(effect)) {
+ ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect),
+ effectStrength, callback);
+ } else {
+ ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
+ static_cast<int32_t>(effect));
+ return -1;
+ }
+
+ if (!ret.isOk()) {
+ ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
+ return -1;
+ }
+
+ if (status == Status::OK) {
+ return lengthMs;
+ } else if (status != Status::UNSUPPORTED_OPERATION) {
+ // Don't warn on UNSUPPORTED_OPERATION, that's a normal event and just means the motor
+ // doesn't have a pre-defined waveform to perform for it, so we should just give the
+ // opportunity to fall back to the framework waveforms.
+ ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+ ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
+ static_cast<int32_t>(strength), static_cast<uint32_t>(status));
+ }
}
return -1;
}
static jlong vibratorGetCapabilities(JNIEnv*, jclass) {
- return halCall(&V1_4::IVibrator::getCapabilities).withDefault(0);
+ if (auto hal = getHal<aidl::IVibrator>()) {
+ int32_t cap = 0;
+ if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
+ return 0;
+ }
+ return cap;
+ }
+
+ return 0;
}
static const JNINativeMethod method_table[] = {
diff --git a/services/devicepolicy/Android.bp b/services/devicepolicy/Android.bp
index 47790ce..dbe0d81 100644
--- a/services/devicepolicy/Android.bp
+++ b/services/devicepolicy/Android.bp
@@ -4,5 +4,6 @@
libs: [
"services.core",
+ "app-compat-annotations",
],
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 37931be..2e56fb0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1939,7 +1939,7 @@
}
TelephonyManager getTelephonyManager() {
- return TelephonyManager.from(mContext);
+ return mContext.getSystemService(TelephonyManager.class);
}
TrustManager getTrustManager() {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 16c60ca..313f884 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -135,6 +135,7 @@
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import com.android.server.power.ThermalManagerService;
+import com.android.server.recoverysystem.RecoverySystemService;
import com.android.server.restrictions.RestrictionsManagerService;
import com.android.server.role.RoleManagerService;
import com.android.server.rollback.RollbackManagerService;
@@ -698,7 +699,7 @@
// Bring up recovery system in case a rescue party needs a reboot
traceBeginAndSlog("StartRecoverySystemService");
- mSystemServiceManager.startService(RecoverySystemService.class);
+ mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
traceEnd();
// Now that we have the bare essentials of the OS up and running, take
diff --git a/services/net/Android.bp b/services/net/Android.bp
index c56ecd6..45430ea 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -1,38 +1,26 @@
java_library_static {
name: "services.net",
srcs: [
+ ":net-module-utils-srcs",
":tethering-servicesnet-srcs",
"java/**/*.java",
],
static_libs: [
"dnsresolver_aidl_interface-V2-java",
"netd_aidl_interface-unstable-java",
+ "netlink-client",
"networkstack-client",
"tethering-client",
],
}
filegroup {
- name: "services-networkstack-shared-srcs",
- srcs: [
- "java/android/net/ip/InterfaceController.java", // TODO: move to NetworkStack with tethering
- "java/android/net/util/InterfaceParams.java", // TODO: move to NetworkStack with IpServer
- "java/android/net/shared/*.java",
- "java/android/net/netlink/*.java",
- ],
-}
-
-filegroup {
name: "services-tethering-shared-srcs",
srcs: [
":framework-annotations",
"java/android/net/ConnectivityModuleConnector.java",
"java/android/net/NetworkStackClient.java",
- "java/android/net/ip/InterfaceController.java",
- "java/android/net/netlink/*.java",
- "java/android/net/util/InterfaceParams.java",
"java/android/net/util/NetdService.java",
"java/android/net/util/NetworkConstants.java",
- "java/android/net/util/SharedLog.java"
],
}
diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java
index 69e2406..865e3b8 100644
--- a/services/net/java/android/net/NetworkStackClient.java
+++ b/services/net/java/android/net/NetworkStackClient.java
@@ -103,7 +103,7 @@
// checks here should be kept in sync with PermissionUtil.
if (caller != Process.SYSTEM_UID
&& caller != Process.NETWORK_STACK_UID
- && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)) {
+ && UserHandle.getAppId(caller) != Process.BLUETOOTH_UID) {
throw new SecurityException(
"Only the system server should try to bind to the network stack.");
}
diff --git a/services/net/java/android/net/ip/InterfaceController.java b/services/net/java/android/net/ip/InterfaceController.java
deleted file mode 100644
index 970bc9c..0000000
--- a/services/net/java/android/net/ip/InterfaceController.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import android.net.INetd;
-import android.net.InterfaceConfigurationParcel;
-import android.net.LinkAddress;
-import android.net.util.SharedLog;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.system.OsConstants;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-
-
-/**
- * Encapsulates the multiple IP configuration operations performed on an interface.
- *
- * TODO: refactor/eliminate the redundant ways to set and clear addresses.
- *
- * @hide
- */
-public class InterfaceController {
- private final static boolean DBG = false;
-
- private final String mIfName;
- private final INetd mNetd;
- private final SharedLog mLog;
-
- public InterfaceController(String ifname, INetd netd, SharedLog log) {
- mIfName = ifname;
- mNetd = netd;
- mLog = log;
- }
-
- private boolean setInterfaceAddress(LinkAddress addr) {
- final InterfaceConfigurationParcel ifConfig = new InterfaceConfigurationParcel();
- ifConfig.ifName = mIfName;
- ifConfig.ipv4Addr = addr.getAddress().getHostAddress();
- ifConfig.prefixLength = addr.getPrefixLength();
- ifConfig.hwAddr = "";
- ifConfig.flags = new String[0];
- try {
- mNetd.interfaceSetCfg(ifConfig);
- } catch (RemoteException | ServiceSpecificException e) {
- logError("Setting IPv4 address to %s/%d failed: %s",
- ifConfig.ipv4Addr, ifConfig.prefixLength, e);
- return false;
- }
- return true;
- }
-
- /**
- * Set the IPv4 address of the interface.
- */
- public boolean setIPv4Address(LinkAddress address) {
- if (!(address.getAddress() instanceof Inet4Address)) {
- return false;
- }
- return setInterfaceAddress(address);
- }
-
- /**
- * Clear the IPv4Address of the interface.
- */
- public boolean clearIPv4Address() {
- return setInterfaceAddress(new LinkAddress("0.0.0.0/0"));
- }
-
- private boolean setEnableIPv6(boolean enabled) {
- try {
- mNetd.interfaceSetEnableIPv6(mIfName, enabled);
- } catch (RemoteException | ServiceSpecificException e) {
- logError("%s IPv6 failed: %s", (enabled ? "enabling" : "disabling"), e);
- return false;
- }
- return true;
- }
-
- /**
- * Enable IPv6 on the interface.
- */
- public boolean enableIPv6() {
- return setEnableIPv6(true);
- }
-
- /**
- * Disable IPv6 on the interface.
- */
- public boolean disableIPv6() {
- return setEnableIPv6(false);
- }
-
- /**
- * Enable or disable IPv6 privacy extensions on the interface.
- * @param enabled Whether the extensions should be enabled.
- */
- public boolean setIPv6PrivacyExtensions(boolean enabled) {
- try {
- mNetd.interfaceSetIPv6PrivacyExtensions(mIfName, enabled);
- } catch (RemoteException | ServiceSpecificException e) {
- logError("error %s IPv6 privacy extensions: %s",
- (enabled ? "enabling" : "disabling"), e);
- return false;
- }
- return true;
- }
-
- /**
- * Set IPv6 address generation mode on the interface.
- *
- * <p>IPv6 should be disabled before changing the mode.
- */
- public boolean setIPv6AddrGenModeIfSupported(int mode) {
- try {
- mNetd.setIPv6AddrGenMode(mIfName, mode);
- } catch (RemoteException e) {
- logError("Unable to set IPv6 addrgen mode: %s", e);
- return false;
- } catch (ServiceSpecificException e) {
- if (e.errorCode != OsConstants.EOPNOTSUPP) {
- logError("Unable to set IPv6 addrgen mode: %s", e);
- return false;
- }
- }
- return true;
- }
-
- /**
- * Add an address to the interface.
- */
- public boolean addAddress(LinkAddress addr) {
- return addAddress(addr.getAddress(), addr.getPrefixLength());
- }
-
- /**
- * Add an address to the interface.
- */
- public boolean addAddress(InetAddress ip, int prefixLen) {
- try {
- mNetd.interfaceAddAddress(mIfName, ip.getHostAddress(), prefixLen);
- } catch (ServiceSpecificException | RemoteException e) {
- logError("failed to add %s/%d: %s", ip, prefixLen, e);
- return false;
- }
- return true;
- }
-
- /**
- * Remove an address from the interface.
- */
- public boolean removeAddress(InetAddress ip, int prefixLen) {
- try {
- mNetd.interfaceDelAddress(mIfName, ip.getHostAddress(), prefixLen);
- } catch (ServiceSpecificException | RemoteException e) {
- logError("failed to remove %s/%d: %s", ip, prefixLen, e);
- return false;
- }
- return true;
- }
-
- /**
- * Remove all addresses from the interface.
- */
- public boolean clearAllAddresses() {
- try {
- mNetd.interfaceClearAddrs(mIfName);
- } catch (Exception e) {
- logError("Failed to clear addresses: %s", e);
- return false;
- }
- return true;
- }
-
- private void logError(String fmt, Object... args) {
- mLog.e(String.format(fmt, args));
- }
-}
diff --git a/services/net/java/android/net/netlink/ConntrackMessage.java b/services/net/java/android/net/netlink/ConntrackMessage.java
deleted file mode 100644
index 6978739..0000000
--- a/services/net/java/android/net/netlink/ConntrackMessage.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netlink;
-
-import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-
-import static java.nio.ByteOrder.BIG_ENDIAN;
-
-import android.system.OsConstants;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-
-/**
- * A NetlinkMessage subclass for netlink conntrack messages.
- *
- * see also: <linux_src>/include/uapi/linux/netfilter/nfnetlink_conntrack.h
- *
- * @hide
- */
-public class ConntrackMessage extends NetlinkMessage {
- public static final int STRUCT_SIZE = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
-
- public static final short NFNL_SUBSYS_CTNETLINK = 1;
- public static final short IPCTNL_MSG_CT_NEW = 0;
-
- // enum ctattr_type
- public static final short CTA_TUPLE_ORIG = 1;
- public static final short CTA_TUPLE_REPLY = 2;
- public static final short CTA_TIMEOUT = 7;
-
- // enum ctattr_tuple
- public static final short CTA_TUPLE_IP = 1;
- public static final short CTA_TUPLE_PROTO = 2;
-
- // enum ctattr_ip
- public static final short CTA_IP_V4_SRC = 1;
- public static final short CTA_IP_V4_DST = 2;
-
- // enum ctattr_l4proto
- public static final short CTA_PROTO_NUM = 1;
- public static final short CTA_PROTO_SRC_PORT = 2;
- public static final short CTA_PROTO_DST_PORT = 3;
-
- public static byte[] newIPv4TimeoutUpdateRequest(
- int proto, Inet4Address src, int sport, Inet4Address dst, int dport, int timeoutSec) {
- // *** STYLE WARNING ***
- //
- // Code below this point uses extra block indentation to highlight the
- // packing of nested tuple netlink attribute types.
- final StructNlAttr ctaTupleOrig = new StructNlAttr(CTA_TUPLE_ORIG,
- new StructNlAttr(CTA_TUPLE_IP,
- new StructNlAttr(CTA_IP_V4_SRC, src),
- new StructNlAttr(CTA_IP_V4_DST, dst)),
- new StructNlAttr(CTA_TUPLE_PROTO,
- new StructNlAttr(CTA_PROTO_NUM, (byte) proto),
- new StructNlAttr(CTA_PROTO_SRC_PORT, (short) sport, BIG_ENDIAN),
- new StructNlAttr(CTA_PROTO_DST_PORT, (short) dport, BIG_ENDIAN)));
-
- final StructNlAttr ctaTimeout = new StructNlAttr(CTA_TIMEOUT, timeoutSec, BIG_ENDIAN);
-
- final int payloadLength = ctaTupleOrig.getAlignedLength() + ctaTimeout.getAlignedLength();
- final byte[] bytes = new byte[STRUCT_SIZE + payloadLength];
- final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
- byteBuffer.order(ByteOrder.nativeOrder());
-
- final ConntrackMessage ctmsg = new ConntrackMessage();
- ctmsg.mHeader.nlmsg_len = bytes.length;
- ctmsg.mHeader.nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
- ctmsg.mHeader.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
- ctmsg.mHeader.nlmsg_seq = 1;
- ctmsg.pack(byteBuffer);
-
- ctaTupleOrig.pack(byteBuffer);
- ctaTimeout.pack(byteBuffer);
-
- return bytes;
- }
-
- protected StructNfGenMsg mNfGenMsg;
-
- private ConntrackMessage() {
- super(new StructNlMsgHdr());
- mNfGenMsg = new StructNfGenMsg((byte) OsConstants.AF_INET);
- }
-
- public void pack(ByteBuffer byteBuffer) {
- mHeader.pack(byteBuffer);
- mNfGenMsg.pack(byteBuffer);
- }
-}
diff --git a/services/net/java/android/net/netlink/InetDiagMessage.java b/services/net/java/android/net/netlink/InetDiagMessage.java
deleted file mode 100644
index ca07630..0000000
--- a/services/net/java/android/net/netlink/InetDiagMessage.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 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.net.netlink;
-
-import static android.net.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY;
-import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-import static android.os.Process.INVALID_UID;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.NETLINK_INET_DIAG;
-
-import android.annotation.Nullable;
-import android.net.util.SocketUtils;
-import android.system.ErrnoException;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * A NetlinkMessage subclass for netlink inet_diag messages.
- *
- * see also: <linux_src>/include/uapi/linux/inet_diag.h
- *
- * @hide
- */
-public class InetDiagMessage extends NetlinkMessage {
- public static final String TAG = "InetDiagMessage";
- private static final int TIMEOUT_MS = 500;
-
- public static byte[] InetDiagReqV2(int protocol, InetSocketAddress local,
- InetSocketAddress remote, int family, short flags) {
- return InetDiagReqV2(protocol, local, remote, family, flags, 0 /* pad */,
- 0 /* idiagExt */, StructInetDiagReqV2.INET_DIAG_REQ_V2_ALL_STATES);
- }
-
- /**
- * Construct an inet_diag_req_v2 message. This method will throw {@code NullPointerException}
- * if local and remote are not both null or both non-null.
- *
- * @param protocol the request protocol type. This should be set to one of IPPROTO_TCP,
- * IPPROTO_UDP, or IPPROTO_UDPLITE.
- * @param local local socket address of the target socket. This will be packed into a
- * {@Code StructInetDiagSockId}. Request to diagnose for all sockets if both of
- * local or remote address is null.
- * @param remote remote socket address of the target socket. This will be packed into a
- * {@Code StructInetDiagSockId}. Request to diagnose for all sockets if both of
- * local or remote address is null.
- * @param family the ip family of the request message. This should be set to either AF_INET or
- * AF_INET6 for IPv4 or IPv6 sockets respectively.
- * @param flags message flags. See <linux_src>/include/uapi/linux/netlink.h.
- * @param pad for raw socket protocol specification.
- * @param idiagExt a set of flags defining what kind of extended information to report.
- * @param state a bit mask that defines a filter of socket states.
- *
- * @return bytes array representation of the message
- **/
- public static byte[] InetDiagReqV2(int protocol, @Nullable InetSocketAddress local,
- @Nullable InetSocketAddress remote, int family, short flags, int pad, int idiagExt,
- int state) throws NullPointerException {
- final byte[] bytes = new byte[StructNlMsgHdr.STRUCT_SIZE + StructInetDiagReqV2.STRUCT_SIZE];
- final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
- byteBuffer.order(ByteOrder.nativeOrder());
-
- final StructNlMsgHdr nlMsgHdr = new StructNlMsgHdr();
- nlMsgHdr.nlmsg_len = bytes.length;
- nlMsgHdr.nlmsg_type = SOCK_DIAG_BY_FAMILY;
- nlMsgHdr.nlmsg_flags = flags;
- nlMsgHdr.pack(byteBuffer);
- final StructInetDiagReqV2 inetDiagReqV2 =
- new StructInetDiagReqV2(protocol, local, remote, family, pad, idiagExt, state);
-
- inetDiagReqV2.pack(byteBuffer);
- return bytes;
- }
-
- public StructInetDiagMsg mStructInetDiagMsg;
-
- private InetDiagMessage(StructNlMsgHdr header) {
- super(header);
- mStructInetDiagMsg = new StructInetDiagMsg();
- }
-
- public static InetDiagMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
- final InetDiagMessage msg = new InetDiagMessage(header);
- msg.mStructInetDiagMsg = StructInetDiagMsg.parse(byteBuffer);
- return msg;
- }
-
- private static int lookupUidByFamily(int protocol, InetSocketAddress local,
- InetSocketAddress remote, int family, short flags,
- FileDescriptor fd)
- throws ErrnoException, InterruptedIOException {
- byte[] msg = InetDiagReqV2(protocol, local, remote, family, flags);
- NetlinkSocket.sendMessage(fd, msg, 0, msg.length, TIMEOUT_MS);
- ByteBuffer response = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT_MS);
-
- final NetlinkMessage nlMsg = NetlinkMessage.parse(response);
- final StructNlMsgHdr hdr = nlMsg.getHeader();
- if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) {
- return INVALID_UID;
- }
- if (nlMsg instanceof InetDiagMessage) {
- return ((InetDiagMessage) nlMsg).mStructInetDiagMsg.idiag_uid;
- }
- return INVALID_UID;
- }
-
- private static final int FAMILY[] = {AF_INET6, AF_INET};
-
- private static int lookupUid(int protocol, InetSocketAddress local,
- InetSocketAddress remote, FileDescriptor fd)
- throws ErrnoException, InterruptedIOException {
- int uid;
-
- for (int family : FAMILY) {
- /**
- * For exact match lookup, swap local and remote for UDP lookups due to kernel
- * bug which will not be fixed. See aosp/755889 and
- * https://www.mail-archive.com/netdev@vger.kernel.org/msg248638.html
- */
- if (protocol == IPPROTO_UDP) {
- uid = lookupUidByFamily(protocol, remote, local, family, NLM_F_REQUEST, fd);
- } else {
- uid = lookupUidByFamily(protocol, local, remote, family, NLM_F_REQUEST, fd);
- }
- if (uid != INVALID_UID) {
- return uid;
- }
- }
-
- /**
- * For UDP it's possible for a socket to send packets to arbitrary destinations, even if the
- * socket is not connected (and even if the socket is connected to a different destination).
- * If we want this API to work for such packets, then on miss we need to do a second lookup
- * with only the local address and port filled in.
- * Always use flags == NLM_F_REQUEST | NLM_F_DUMP for wildcard.
- */
- if (protocol == IPPROTO_UDP) {
- try {
- InetSocketAddress wildcard = new InetSocketAddress(
- Inet6Address.getByName("::"), 0);
- uid = lookupUidByFamily(protocol, local, wildcard, AF_INET6,
- (short) (NLM_F_REQUEST | NLM_F_DUMP), fd);
- if (uid != INVALID_UID) {
- return uid;
- }
- wildcard = new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), 0);
- uid = lookupUidByFamily(protocol, local, wildcard, AF_INET,
- (short) (NLM_F_REQUEST | NLM_F_DUMP), fd);
- if (uid != INVALID_UID) {
- return uid;
- }
- } catch (UnknownHostException e) {
- Log.e(TAG, e.toString());
- }
- }
- return INVALID_UID;
- }
-
- /**
- * Use an inet_diag socket to look up the UID associated with the input local and remote
- * address/port and protocol of a connection.
- */
- public static int getConnectionOwnerUid(int protocol, InetSocketAddress local,
- InetSocketAddress remote) {
- int uid = INVALID_UID;
- FileDescriptor fd = null;
- try {
- fd = NetlinkSocket.forProto(NETLINK_INET_DIAG);
- NetlinkSocket.connectToKernel(fd);
- uid = lookupUid(protocol, local, remote, fd);
- } catch (ErrnoException | SocketException | IllegalArgumentException
- | InterruptedIOException e) {
- Log.e(TAG, e.toString());
- } finally {
- if (fd != null) {
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException e) {
- Log.e(TAG, e.toString());
- }
- }
- }
- return uid;
- }
-
- @Override
- public String toString() {
- return "InetDiagMessage{ "
- + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, "
- + "inet_diag_msg{"
- + (mStructInetDiagMsg == null ? "" : mStructInetDiagMsg.toString()) + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/NetlinkConstants.java b/services/net/java/android/net/netlink/NetlinkConstants.java
deleted file mode 100644
index fc1551c..0000000
--- a/services/net/java/android/net/netlink/NetlinkConstants.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.system.OsConstants;
-import com.android.internal.util.HexDump;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * Various constants and static helper methods for netlink communications.
- *
- * Values taken from:
- *
- * <linux_src>/include/uapi/linux/netlink.h
- * <linux_src>/include/uapi/linux/rtnetlink.h
- *
- * @hide
- */
-public class NetlinkConstants {
- private NetlinkConstants() {}
-
- public static final int NLA_ALIGNTO = 4;
-
- public static final int alignedLengthOf(short length) {
- final int intLength = (int) length & 0xffff;
- return alignedLengthOf(intLength);
- }
-
- public static final int alignedLengthOf(int length) {
- if (length <= 0) { return 0; }
- return (((length + NLA_ALIGNTO - 1) / NLA_ALIGNTO) * NLA_ALIGNTO);
- }
-
- public static String stringForAddressFamily(int family) {
- if (family == OsConstants.AF_INET) { return "AF_INET"; }
- if (family == OsConstants.AF_INET6) { return "AF_INET6"; }
- if (family == OsConstants.AF_NETLINK) { return "AF_NETLINK"; }
- return String.valueOf(family);
- }
-
- public static String stringForProtocol(int protocol) {
- if (protocol == OsConstants.IPPROTO_TCP) { return "IPPROTO_TCP"; }
- if (protocol == OsConstants.IPPROTO_UDP) { return "IPPROTO_UDP"; }
- return String.valueOf(protocol);
- }
-
- public static String hexify(byte[] bytes) {
- if (bytes == null) { return "(null)"; }
- return HexDump.toHexString(bytes);
- }
-
- public static String hexify(ByteBuffer buffer) {
- if (buffer == null) { return "(null)"; }
- return HexDump.toHexString(
- buffer.array(), buffer.position(), buffer.remaining());
- }
-
- // Known values for struct nlmsghdr nlm_type.
- public static final short NLMSG_NOOP = 1; // Nothing
- public static final short NLMSG_ERROR = 2; // Error
- public static final short NLMSG_DONE = 3; // End of a dump
- public static final short NLMSG_OVERRUN = 4; // Data lost
- public static final short NLMSG_MAX_RESERVED = 15; // Max reserved value
-
- public static final short RTM_NEWLINK = 16;
- public static final short RTM_DELLINK = 17;
- public static final short RTM_GETLINK = 18;
- public static final short RTM_SETLINK = 19;
- public static final short RTM_NEWADDR = 20;
- public static final short RTM_DELADDR = 21;
- public static final short RTM_GETADDR = 22;
- public static final short RTM_NEWROUTE = 24;
- public static final short RTM_DELROUTE = 25;
- public static final short RTM_GETROUTE = 26;
- public static final short RTM_NEWNEIGH = 28;
- public static final short RTM_DELNEIGH = 29;
- public static final short RTM_GETNEIGH = 30;
- public static final short RTM_NEWRULE = 32;
- public static final short RTM_DELRULE = 33;
- public static final short RTM_GETRULE = 34;
- public static final short RTM_NEWNDUSEROPT = 68;
-
- /* see <linux_src>/include/uapi/linux/sock_diag.h */
- public static final short SOCK_DIAG_BY_FAMILY = 20;
-
- public static String stringForNlMsgType(short nlm_type) {
- switch (nlm_type) {
- case NLMSG_NOOP: return "NLMSG_NOOP";
- case NLMSG_ERROR: return "NLMSG_ERROR";
- case NLMSG_DONE: return "NLMSG_DONE";
- case NLMSG_OVERRUN: return "NLMSG_OVERRUN";
- case RTM_NEWLINK: return "RTM_NEWLINK";
- case RTM_DELLINK: return "RTM_DELLINK";
- case RTM_GETLINK: return "RTM_GETLINK";
- case RTM_SETLINK: return "RTM_SETLINK";
- case RTM_NEWADDR: return "RTM_NEWADDR";
- case RTM_DELADDR: return "RTM_DELADDR";
- case RTM_GETADDR: return "RTM_GETADDR";
- case RTM_NEWROUTE: return "RTM_NEWROUTE";
- case RTM_DELROUTE: return "RTM_DELROUTE";
- case RTM_GETROUTE: return "RTM_GETROUTE";
- case RTM_NEWNEIGH: return "RTM_NEWNEIGH";
- case RTM_DELNEIGH: return "RTM_DELNEIGH";
- case RTM_GETNEIGH: return "RTM_GETNEIGH";
- case RTM_NEWRULE: return "RTM_NEWRULE";
- case RTM_DELRULE: return "RTM_DELRULE";
- case RTM_GETRULE: return "RTM_GETRULE";
- case RTM_NEWNDUSEROPT: return "RTM_NEWNDUSEROPT";
- default:
- return "unknown RTM type: " + String.valueOf(nlm_type);
- }
- }
-}
diff --git a/services/net/java/android/net/netlink/NetlinkErrorMessage.java b/services/net/java/android/net/netlink/NetlinkErrorMessage.java
deleted file mode 100644
index e275574..0000000
--- a/services/net/java/android/net/netlink/NetlinkErrorMessage.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.net.netlink.StructNlMsgHdr;
-import android.net.netlink.NetlinkMessage;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * A NetlinkMessage subclass for netlink error messages.
- *
- * @hide
- */
-public class NetlinkErrorMessage extends NetlinkMessage {
-
- public static NetlinkErrorMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
- final NetlinkErrorMessage errorMsg = new NetlinkErrorMessage(header);
-
- errorMsg.mNlMsgErr = StructNlMsgErr.parse(byteBuffer);
- if (errorMsg.mNlMsgErr == null) {
- return null;
- }
-
- return errorMsg;
- }
-
- private StructNlMsgErr mNlMsgErr;
-
- NetlinkErrorMessage(StructNlMsgHdr header) {
- super(header);
- mNlMsgErr = null;
- }
-
- public StructNlMsgErr getNlMsgError() {
- return mNlMsgErr;
- }
-
- @Override
- public String toString() {
- return "NetlinkErrorMessage{ "
- + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, "
- + "nlmsgerr{" + (mNlMsgErr == null ? "" : mNlMsgErr.toString()) + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/NetlinkMessage.java b/services/net/java/android/net/netlink/NetlinkMessage.java
deleted file mode 100644
index a325db8..0000000
--- a/services/net/java/android/net/netlink/NetlinkMessage.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkErrorMessage;
-import android.net.netlink.RtNetlinkNeighborMessage;
-import android.net.netlink.StructNlAttr;
-import android.net.netlink.StructNlMsgHdr;
-import android.util.Log;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * NetlinkMessage base class for other, more specific netlink message types.
- *
- * Classes that extend NetlinkMessage should:
- * - implement a public static parse(StructNlMsgHdr, ByteBuffer) method
- * - returning either null (parse errors) or a new object of the subclass
- * type (cast-able to NetlinkMessage)
- *
- * NetlinkMessage.parse() should be updated to know which nlmsg_type values
- * correspond with which message subclasses.
- *
- * @hide
- */
-public class NetlinkMessage {
- private final static String TAG = "NetlinkMessage";
-
- public static NetlinkMessage parse(ByteBuffer byteBuffer) {
- final int startPosition = (byteBuffer != null) ? byteBuffer.position() : -1;
- final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(byteBuffer);
- if (nlmsghdr == null) {
- return null;
- }
-
- int payloadLength = NetlinkConstants.alignedLengthOf(nlmsghdr.nlmsg_len);
- payloadLength -= StructNlMsgHdr.STRUCT_SIZE;
- if (payloadLength < 0 || payloadLength > byteBuffer.remaining()) {
- // Malformed message or runt buffer. Pretend the buffer was consumed.
- byteBuffer.position(byteBuffer.limit());
- return null;
- }
-
- switch (nlmsghdr.nlmsg_type) {
- //case NetlinkConstants.NLMSG_NOOP:
- case NetlinkConstants.NLMSG_ERROR:
- return (NetlinkMessage) NetlinkErrorMessage.parse(nlmsghdr, byteBuffer);
- case NetlinkConstants.NLMSG_DONE:
- byteBuffer.position(byteBuffer.position() + payloadLength);
- return new NetlinkMessage(nlmsghdr);
- //case NetlinkConstants.NLMSG_OVERRUN:
- case NetlinkConstants.RTM_NEWNEIGH:
- case NetlinkConstants.RTM_DELNEIGH:
- case NetlinkConstants.RTM_GETNEIGH:
- return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer);
- case NetlinkConstants.SOCK_DIAG_BY_FAMILY:
- return (NetlinkMessage) InetDiagMessage.parse(nlmsghdr, byteBuffer);
- default:
- if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) {
- // Netlink control message. Just parse the header for now,
- // pretending the whole message was consumed.
- byteBuffer.position(byteBuffer.position() + payloadLength);
- return new NetlinkMessage(nlmsghdr);
- }
- return null;
- }
- }
-
- protected StructNlMsgHdr mHeader;
-
- public NetlinkMessage(StructNlMsgHdr nlmsghdr) {
- mHeader = nlmsghdr;
- }
-
- public StructNlMsgHdr getHeader() {
- return mHeader;
- }
-
- @Override
- public String toString() {
- return "NetlinkMessage{" + (mHeader == null ? "" : mHeader.toString()) + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java
deleted file mode 100644
index 7311fc5..0000000
--- a/services/net/java/android/net/netlink/NetlinkSocket.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
-import static android.system.OsConstants.AF_NETLINK;
-import static android.system.OsConstants.EIO;
-import static android.system.OsConstants.EPROTO;
-import static android.system.OsConstants.ETIMEDOUT;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_RCVBUF;
-import static android.system.OsConstants.SO_RCVTIMEO;
-import static android.system.OsConstants.SO_SNDTIMEO;
-
-import android.net.util.SocketUtils;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-
-/**
- * NetlinkSocket
- *
- * A small static class to assist with AF_NETLINK socket operations.
- *
- * @hide
- */
-public class NetlinkSocket {
- private static final String TAG = "NetlinkSocket";
-
- public static final int DEFAULT_RECV_BUFSIZE = 8 * 1024;
- public static final int SOCKET_RECV_BUFSIZE = 64 * 1024;
-
- public static void sendOneShotKernelMessage(int nlProto, byte[] msg) throws ErrnoException {
- final String errPrefix = "Error in NetlinkSocket.sendOneShotKernelMessage";
- final long IO_TIMEOUT = 300L;
-
- final FileDescriptor fd = forProto(nlProto);
-
- try {
- connectToKernel(fd);
- sendMessage(fd, msg, 0, msg.length, IO_TIMEOUT);
- final ByteBuffer bytes = recvMessage(fd, DEFAULT_RECV_BUFSIZE, IO_TIMEOUT);
- // recvMessage() guaranteed to not return null if it did not throw.
- final NetlinkMessage response = NetlinkMessage.parse(bytes);
- if (response != null && response instanceof NetlinkErrorMessage &&
- (((NetlinkErrorMessage) response).getNlMsgError() != null)) {
- final int errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
- if (errno != 0) {
- // TODO: consider ignoring EINVAL (-22), which appears to be
- // normal when probing a neighbor for which the kernel does
- // not already have / no longer has a link layer address.
- Log.e(TAG, errPrefix + ", errmsg=" + response.toString());
- // Note: convert kernel errnos (negative) into userspace errnos (positive).
- throw new ErrnoException(response.toString(), Math.abs(errno));
- }
- } else {
- final String errmsg;
- if (response == null) {
- bytes.position(0);
- errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
- } else {
- errmsg = response.toString();
- }
- Log.e(TAG, errPrefix + ", errmsg=" + errmsg);
- throw new ErrnoException(errmsg, EPROTO);
- }
- } catch (InterruptedIOException e) {
- Log.e(TAG, errPrefix, e);
- throw new ErrnoException(errPrefix, ETIMEDOUT, e);
- } catch (SocketException e) {
- Log.e(TAG, errPrefix, e);
- throw new ErrnoException(errPrefix, EIO, e);
- } finally {
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException e) {
- // Nothing we can do here
- }
- }
- }
-
- public static FileDescriptor forProto(int nlProto) throws ErrnoException {
- final FileDescriptor fd = Os.socket(AF_NETLINK, SOCK_DGRAM, nlProto);
- Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, SOCKET_RECV_BUFSIZE);
- return fd;
- }
-
- public static void connectToKernel(FileDescriptor fd) throws ErrnoException, SocketException {
- Os.connect(fd, makeNetlinkSocketAddress(0, 0));
- }
-
- private static void checkTimeout(long timeoutMs) {
- if (timeoutMs < 0) {
- throw new IllegalArgumentException("Negative timeouts not permitted");
- }
- }
-
- /**
- * Wait up to |timeoutMs| (or until underlying socket error) for a
- * netlink message of at most |bufsize| size.
- *
- * Multi-threaded calls with different timeouts will cause unexpected results.
- */
- public static ByteBuffer recvMessage(FileDescriptor fd, int bufsize, long timeoutMs)
- throws ErrnoException, IllegalArgumentException, InterruptedIOException {
- checkTimeout(timeoutMs);
-
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(timeoutMs));
-
- ByteBuffer byteBuffer = ByteBuffer.allocate(bufsize);
- int length = Os.read(fd, byteBuffer);
- if (length == bufsize) {
- Log.w(TAG, "maximum read");
- }
- byteBuffer.position(0);
- byteBuffer.limit(length);
- byteBuffer.order(ByteOrder.nativeOrder());
- return byteBuffer;
- }
-
- /**
- * Send a message to a peer to which this socket has previously connected,
- * waiting at most |timeoutMs| milliseconds for the send to complete.
- *
- * Multi-threaded calls with different timeouts will cause unexpected results.
- */
- public static int sendMessage(
- FileDescriptor fd, byte[] bytes, int offset, int count, long timeoutMs)
- throws ErrnoException, IllegalArgumentException, InterruptedIOException {
- checkTimeout(timeoutMs);
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(timeoutMs));
- return Os.write(fd, bytes, offset, count);
- }
-}
diff --git a/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java b/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java
deleted file mode 100644
index e784fbb..0000000
--- a/services/net/java/android/net/netlink/RtNetlinkNeighborMessage.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-
-import android.net.netlink.StructNdaCacheInfo;
-import android.net.netlink.StructNdMsg;
-import android.net.netlink.StructNlAttr;
-import android.net.netlink.StructNlMsgHdr;
-import android.net.netlink.NetlinkMessage;
-import android.system.OsConstants;
-import android.util.Log;
-
-import java.net.InetAddress;
-import java.net.Inet6Address;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-
-/**
- * A NetlinkMessage subclass for rtnetlink neighbor messages.
- *
- * see also: <linux_src>/include/uapi/linux/neighbour.h
- *
- * @hide
- */
-public class RtNetlinkNeighborMessage extends NetlinkMessage {
- public static final short NDA_UNSPEC = 0;
- public static final short NDA_DST = 1;
- public static final short NDA_LLADDR = 2;
- public static final short NDA_CACHEINFO = 3;
- public static final short NDA_PROBES = 4;
- public static final short NDA_VLAN = 5;
- public static final short NDA_PORT = 6;
- public static final short NDA_VNI = 7;
- public static final short NDA_IFINDEX = 8;
- public static final short NDA_MASTER = 9;
-
- private static StructNlAttr findNextAttrOfType(short attrType, ByteBuffer byteBuffer) {
- while (byteBuffer != null && byteBuffer.remaining() > 0) {
- final StructNlAttr nlAttr = StructNlAttr.peek(byteBuffer);
- if (nlAttr == null) {
- break;
- }
- if (nlAttr.nla_type == attrType) {
- return StructNlAttr.parse(byteBuffer);
- }
- if (byteBuffer.remaining() < nlAttr.getAlignedLength()) {
- break;
- }
- byteBuffer.position(byteBuffer.position() + nlAttr.getAlignedLength());
- }
- return null;
- }
-
- public static RtNetlinkNeighborMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
- final RtNetlinkNeighborMessage neighMsg = new RtNetlinkNeighborMessage(header);
-
- neighMsg.mNdmsg = StructNdMsg.parse(byteBuffer);
- if (neighMsg.mNdmsg == null) {
- return null;
- }
-
- // Some of these are message-type dependent, and not always present.
- final int baseOffset = byteBuffer.position();
- StructNlAttr nlAttr = findNextAttrOfType(NDA_DST, byteBuffer);
- if (nlAttr != null) {
- neighMsg.mDestination = nlAttr.getValueAsInetAddress();
- }
-
- byteBuffer.position(baseOffset);
- nlAttr = findNextAttrOfType(NDA_LLADDR, byteBuffer);
- if (nlAttr != null) {
- neighMsg.mLinkLayerAddr = nlAttr.nla_value;
- }
-
- byteBuffer.position(baseOffset);
- nlAttr = findNextAttrOfType(NDA_PROBES, byteBuffer);
- if (nlAttr != null) {
- neighMsg.mNumProbes = nlAttr.getValueAsInt(0);
- }
-
- byteBuffer.position(baseOffset);
- nlAttr = findNextAttrOfType(NDA_CACHEINFO, byteBuffer);
- if (nlAttr != null) {
- neighMsg.mCacheInfo = StructNdaCacheInfo.parse(nlAttr.getValueAsByteBuffer());
- }
-
- final int kMinConsumed = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE;
- final int kAdditionalSpace = NetlinkConstants.alignedLengthOf(
- neighMsg.mHeader.nlmsg_len - kMinConsumed);
- if (byteBuffer.remaining() < kAdditionalSpace) {
- byteBuffer.position(byteBuffer.limit());
- } else {
- byteBuffer.position(baseOffset + kAdditionalSpace);
- }
-
- return neighMsg;
- }
-
- /**
- * A convenience method to create an RTM_GETNEIGH request message.
- */
- public static byte[] newGetNeighborsRequest(int seqNo) {
- final int length = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE;
- final byte[] bytes = new byte[length];
- final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
- byteBuffer.order(ByteOrder.nativeOrder());
-
- final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
- nlmsghdr.nlmsg_len = length;
- nlmsghdr.nlmsg_type = NetlinkConstants.RTM_GETNEIGH;
- nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- nlmsghdr.nlmsg_seq = seqNo;
- nlmsghdr.pack(byteBuffer);
-
- final StructNdMsg ndmsg = new StructNdMsg();
- ndmsg.pack(byteBuffer);
-
- return bytes;
- }
-
- /**
- * A convenience method to create an RTM_NEWNEIGH message, to modify
- * the kernel's state information for a specific neighbor.
- */
- public static byte[] newNewNeighborMessage(
- int seqNo, InetAddress ip, short nudState, int ifIndex, byte[] llAddr) {
- final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
- nlmsghdr.nlmsg_type = NetlinkConstants.RTM_NEWNEIGH;
- nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
- nlmsghdr.nlmsg_seq = seqNo;
-
- final RtNetlinkNeighborMessage msg = new RtNetlinkNeighborMessage(nlmsghdr);
- msg.mNdmsg = new StructNdMsg();
- msg.mNdmsg.ndm_family =
- (byte) ((ip instanceof Inet6Address) ? OsConstants.AF_INET6 : OsConstants.AF_INET);
- msg.mNdmsg.ndm_ifindex = ifIndex;
- msg.mNdmsg.ndm_state = nudState;
- msg.mDestination = ip;
- msg.mLinkLayerAddr = llAddr; // might be null
-
- final byte[] bytes = new byte[msg.getRequiredSpace()];
- nlmsghdr.nlmsg_len = bytes.length;
- final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
- byteBuffer.order(ByteOrder.nativeOrder());
- msg.pack(byteBuffer);
- return bytes;
- }
-
- private StructNdMsg mNdmsg;
- private InetAddress mDestination;
- private byte[] mLinkLayerAddr;
- private int mNumProbes;
- private StructNdaCacheInfo mCacheInfo;
-
- private RtNetlinkNeighborMessage(StructNlMsgHdr header) {
- super(header);
- mNdmsg = null;
- mDestination = null;
- mLinkLayerAddr = null;
- mNumProbes = 0;
- mCacheInfo = null;
- }
-
- public StructNdMsg getNdHeader() {
- return mNdmsg;
- }
-
- public InetAddress getDestination() {
- return mDestination;
- }
-
- public byte[] getLinkLayerAddress() {
- return mLinkLayerAddr;
- }
-
- public int getProbes() {
- return mNumProbes;
- }
-
- public StructNdaCacheInfo getCacheInfo() {
- return mCacheInfo;
- }
-
- public int getRequiredSpace() {
- int spaceRequired = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE;
- if (mDestination != null) {
- spaceRequired += NetlinkConstants.alignedLengthOf(
- StructNlAttr.NLA_HEADERLEN + mDestination.getAddress().length);
- }
- if (mLinkLayerAddr != null) {
- spaceRequired += NetlinkConstants.alignedLengthOf(
- StructNlAttr.NLA_HEADERLEN + mLinkLayerAddr.length);
- }
- // Currently we don't write messages with NDA_PROBES nor NDA_CACHEINFO
- // attributes appended. Fix later, if necessary.
- return spaceRequired;
- }
-
- private static void packNlAttr(short nlType, byte[] nlValue, ByteBuffer byteBuffer) {
- final StructNlAttr nlAttr = new StructNlAttr();
- nlAttr.nla_type = nlType;
- nlAttr.nla_value = nlValue;
- nlAttr.nla_len = (short) (StructNlAttr.NLA_HEADERLEN + nlAttr.nla_value.length);
- nlAttr.pack(byteBuffer);
- }
-
- public void pack(ByteBuffer byteBuffer) {
- getHeader().pack(byteBuffer) ;
- mNdmsg.pack(byteBuffer);
-
- if (mDestination != null) {
- packNlAttr(NDA_DST, mDestination.getAddress(), byteBuffer);
- }
- if (mLinkLayerAddr != null) {
- packNlAttr(NDA_LLADDR, mLinkLayerAddr, byteBuffer);
- }
- }
-
- @Override
- public String toString() {
- final String ipLiteral = (mDestination == null) ? "" : mDestination.getHostAddress();
- return "RtNetlinkNeighborMessage{ "
- + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, "
- + "ndmsg{" + (mNdmsg == null ? "" : mNdmsg.toString()) + "}, "
- + "destination{" + ipLiteral + "} "
- + "linklayeraddr{" + NetlinkConstants.hexify(mLinkLayerAddr) + "} "
- + "probes{" + mNumProbes + "} "
- + "cacheinfo{" + (mCacheInfo == null ? "" : mCacheInfo.toString()) + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructInetDiagMsg.java b/services/net/java/android/net/netlink/StructInetDiagMsg.java
deleted file mode 100644
index da824ad..0000000
--- a/services/net/java/android/net/netlink/StructInetDiagMsg.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 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.net.netlink;
-
-import static java.nio.ByteOrder.BIG_ENDIAN;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import java.net.Inet4Address;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import android.util.Log;
-
-/**
- * struct inet_diag_msg
- *
- * see <linux_src>/include/uapi/linux/inet_diag.h
- *
- * struct inet_diag_msg {
- * __u8 idiag_family;
- * __u8 idiag_state;
- * __u8 idiag_timer;
- * __u8 idiag_retrans;
- * struct inet_diag_sockid id;
- * __u32 idiag_expires;
- * __u32 idiag_rqueue;
- * __u32 idiag_wqueue;
- * __u32 idiag_uid;
- * __u32 idiag_inode;
- * };
- *
- * @hide
- */
-public class StructInetDiagMsg {
- public static final int STRUCT_SIZE = 4 + StructInetDiagSockId.STRUCT_SIZE + 20;
- private static final int IDIAG_UID_OFFSET = StructNlMsgHdr.STRUCT_SIZE + 4 +
- StructInetDiagSockId.STRUCT_SIZE + 12;
- public int idiag_uid;
-
- public static StructInetDiagMsg parse(ByteBuffer byteBuffer) {
- StructInetDiagMsg struct = new StructInetDiagMsg();
- struct.idiag_uid = byteBuffer.getInt(IDIAG_UID_OFFSET);
- return struct;
- }
-
- @Override
- public String toString() {
- return "StructInetDiagMsg{ "
- + "idiag_uid{" + idiag_uid + "}, "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructInetDiagReqV2.java b/services/net/java/android/net/netlink/StructInetDiagReqV2.java
deleted file mode 100644
index 2268113..0000000
--- a/services/net/java/android/net/netlink/StructInetDiagReqV2.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 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.net.netlink;
-
-import android.annotation.Nullable;
-
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-
-/**
- * struct inet_diag_req_v2
- *
- * see <linux_src>/include/uapi/linux/inet_diag.h
- *
- * struct inet_diag_req_v2 {
- * __u8 sdiag_family;
- * __u8 sdiag_protocol;
- * __u8 idiag_ext;
- * __u8 pad;
- * __u32 idiag_states;
- * struct inet_diag_sockid id;
- * };
- *
- * @hide
- */
-public class StructInetDiagReqV2 {
- public static final int STRUCT_SIZE = 8 + StructInetDiagSockId.STRUCT_SIZE;
-
- private final byte mSdiagFamily;
- private final byte mSdiagProtocol;
- private final byte mIdiagExt;
- private final byte mPad;
- private final StructInetDiagSockId mId;
- private final int mState;
- public static final int INET_DIAG_REQ_V2_ALL_STATES = (int) 0xffffffff;
-
- public StructInetDiagReqV2(int protocol, InetSocketAddress local, InetSocketAddress remote,
- int family) {
- this(protocol, local, remote, family, 0 /* pad */, 0 /* extension */,
- INET_DIAG_REQ_V2_ALL_STATES);
- }
-
- public StructInetDiagReqV2(int protocol, @Nullable InetSocketAddress local,
- @Nullable InetSocketAddress remote, int family, int pad, int extension, int state)
- throws NullPointerException {
- mSdiagFamily = (byte) family;
- mSdiagProtocol = (byte) protocol;
- // Request for all sockets if no specific socket is requested. Specify the local and remote
- // socket address information for target request socket.
- if ((local == null) != (remote == null)) {
- throw new NullPointerException("Local and remote must be both null or both non-null");
- }
- mId = ((local != null && remote != null) ? new StructInetDiagSockId(local, remote) : null);
- mPad = (byte) pad;
- mIdiagExt = (byte) extension;
- mState = state;
- }
-
- public void pack(ByteBuffer byteBuffer) {
- // The ByteOrder must have already been set by the caller.
- byteBuffer.put((byte) mSdiagFamily);
- byteBuffer.put((byte) mSdiagProtocol);
- byteBuffer.put((byte) mIdiagExt);
- byteBuffer.put((byte) mPad);
- byteBuffer.putInt(mState);
- if (mId != null) mId.pack(byteBuffer);
- }
-
- @Override
- public String toString() {
- final String familyStr = NetlinkConstants.stringForAddressFamily(mSdiagFamily);
- final String protocolStr = NetlinkConstants.stringForAddressFamily(mSdiagProtocol);
-
- return "StructInetDiagReqV2{ "
- + "sdiag_family{" + familyStr + "}, "
- + "sdiag_protocol{" + protocolStr + "}, "
- + "idiag_ext{" + mIdiagExt + ")}, "
- + "pad{" + mPad + "}, "
- + "idiag_states{" + Integer.toHexString(mState) + "}, "
- + ((mId != null) ? mId.toString() : "inet_diag_sockid=null")
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructInetDiagSockId.java b/services/net/java/android/net/netlink/StructInetDiagSockId.java
deleted file mode 100644
index 2e9fa25..0000000
--- a/services/net/java/android/net/netlink/StructInetDiagSockId.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 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.net.netlink;
-
-import static java.nio.ByteOrder.BIG_ENDIAN;
-
-import java.net.Inet4Address;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * struct inet_diag_req_v2
- *
- * see <linux_src>/include/uapi/linux/inet_diag.h
- *
- * struct inet_diag_sockid {
- * __be16 idiag_sport;
- * __be16 idiag_dport;
- * __be32 idiag_src[4];
- * __be32 idiag_dst[4];
- * __u32 idiag_if;
- * __u32 idiag_cookie[2];
- * #define INET_DIAG_NOCOOKIE (~0U)
- * };
- *
- * @hide
- */
-public class StructInetDiagSockId {
- public static final int STRUCT_SIZE = 48;
-
- private final InetSocketAddress mLocSocketAddress;
- private final InetSocketAddress mRemSocketAddress;
- private final byte[] INET_DIAG_NOCOOKIE = new byte[]{
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
- private final byte[] IPV4_PADDING = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- public StructInetDiagSockId(InetSocketAddress loc, InetSocketAddress rem) {
- mLocSocketAddress = loc;
- mRemSocketAddress = rem;
- }
-
- public void pack(ByteBuffer byteBuffer) {
- byteBuffer.order(BIG_ENDIAN);
- byteBuffer.putShort((short) mLocSocketAddress.getPort());
- byteBuffer.putShort((short) mRemSocketAddress.getPort());
- byteBuffer.put(mLocSocketAddress.getAddress().getAddress());
- if (mLocSocketAddress.getAddress() instanceof Inet4Address) {
- byteBuffer.put(IPV4_PADDING);
- }
- byteBuffer.put(mRemSocketAddress.getAddress().getAddress());
- if (mRemSocketAddress.getAddress() instanceof Inet4Address) {
- byteBuffer.put(IPV4_PADDING);
- }
- byteBuffer.order(ByteOrder.nativeOrder());
- byteBuffer.putInt(0);
- byteBuffer.put(INET_DIAG_NOCOOKIE);
- }
-
- @Override
- public String toString() {
- return "StructInetDiagSockId{ "
- + "idiag_sport{" + mLocSocketAddress.getPort() + "}, "
- + "idiag_dport{" + mRemSocketAddress.getPort() + "}, "
- + "idiag_src{" + mLocSocketAddress.getAddress().getHostAddress() + "}, "
- + "idiag_dst{" + mRemSocketAddress.getAddress().getHostAddress() + "}, "
- + "idiag_if{" + 0 + "} "
- + "idiag_cookie{INET_DIAG_NOCOOKIE}"
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructNdMsg.java b/services/net/java/android/net/netlink/StructNdMsg.java
deleted file mode 100644
index e34ec39..0000000
--- a/services/net/java/android/net/netlink/StructNdMsg.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.net.netlink.NetlinkConstants;
-import android.system.OsConstants;
-import java.nio.ByteBuffer;
-
-
-/**
- * struct ndmsg
- *
- * see: <linux_src>/include/uapi/linux/neighbour.h
- *
- * @hide
- */
-public class StructNdMsg {
- // Already aligned.
- public static final int STRUCT_SIZE = 12;
-
- // Neighbor Cache Entry States
- public static final short NUD_NONE = 0x00;
- public static final short NUD_INCOMPLETE = 0x01;
- public static final short NUD_REACHABLE = 0x02;
- public static final short NUD_STALE = 0x04;
- public static final short NUD_DELAY = 0x08;
- public static final short NUD_PROBE = 0x10;
- public static final short NUD_FAILED = 0x20;
- public static final short NUD_NOARP = 0x40;
- public static final short NUD_PERMANENT = 0x80;
-
- public static String stringForNudState(short nudState) {
- switch (nudState) {
- case NUD_NONE: return "NUD_NONE";
- case NUD_INCOMPLETE: return "NUD_INCOMPLETE";
- case NUD_REACHABLE: return "NUD_REACHABLE";
- case NUD_STALE: return "NUD_STALE";
- case NUD_DELAY: return "NUD_DELAY";
- case NUD_PROBE: return "NUD_PROBE";
- case NUD_FAILED: return "NUD_FAILED";
- case NUD_NOARP: return "NUD_NOARP";
- case NUD_PERMANENT: return "NUD_PERMANENT";
- default:
- return "unknown NUD state: " + String.valueOf(nudState);
- }
- }
-
- public static boolean isNudStateConnected(short nudState) {
- return ((nudState & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)) != 0);
- }
-
- public static boolean isNudStateValid(short nudState) {
- return (isNudStateConnected(nudState) ||
- ((nudState & (NUD_PROBE|NUD_STALE|NUD_DELAY)) != 0));
- }
-
- // Neighbor Cache Entry Flags
- public static byte NTF_USE = (byte) 0x01;
- public static byte NTF_SELF = (byte) 0x02;
- public static byte NTF_MASTER = (byte) 0x04;
- public static byte NTF_PROXY = (byte) 0x08;
- public static byte NTF_ROUTER = (byte) 0x80;
-
- public static String stringForNudFlags(byte flags) {
- final StringBuilder sb = new StringBuilder();
- if ((flags & NTF_USE) != 0) {
- sb.append("NTF_USE");
- }
- if ((flags & NTF_SELF) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NTF_SELF");
- }
- if ((flags & NTF_MASTER) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NTF_MASTER");
- }
- if ((flags & NTF_PROXY) != 0) {
- if (sb.length() > 0) { sb.append("|");
- }
- sb.append("NTF_PROXY"); }
- if ((flags & NTF_ROUTER) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NTF_ROUTER");
- }
- return sb.toString();
- }
-
- private static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
- return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
- }
-
- public static StructNdMsg parse(ByteBuffer byteBuffer) {
- if (!hasAvailableSpace(byteBuffer)) { return null; }
-
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the possible
- // exception of usage within unittests.
- final StructNdMsg struct = new StructNdMsg();
- struct.ndm_family = byteBuffer.get();
- final byte pad1 = byteBuffer.get();
- final short pad2 = byteBuffer.getShort();
- struct.ndm_ifindex = byteBuffer.getInt();
- struct.ndm_state = byteBuffer.getShort();
- struct.ndm_flags = byteBuffer.get();
- struct.ndm_type = byteBuffer.get();
- return struct;
- }
-
- public byte ndm_family;
- public int ndm_ifindex;
- public short ndm_state;
- public byte ndm_flags;
- public byte ndm_type;
-
- public StructNdMsg() {
- ndm_family = (byte) OsConstants.AF_UNSPEC;
- }
-
- public void pack(ByteBuffer byteBuffer) {
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the exception
- // of usage within unittests.
- byteBuffer.put(ndm_family);
- byteBuffer.put((byte) 0); // pad1
- byteBuffer.putShort((short) 0); // pad2
- byteBuffer.putInt(ndm_ifindex);
- byteBuffer.putShort(ndm_state);
- byteBuffer.put(ndm_flags);
- byteBuffer.put(ndm_type);
- }
-
- public boolean nudConnected() {
- return isNudStateConnected(ndm_state);
- }
-
- public boolean nudValid() {
- return isNudStateValid(ndm_state);
- }
-
- @Override
- public String toString() {
- final String stateStr = "" + ndm_state + " (" + stringForNudState(ndm_state) + ")";
- final String flagsStr = "" + ndm_flags + " (" + stringForNudFlags(ndm_flags) + ")";
- return "StructNdMsg{ "
- + "family{" + NetlinkConstants.stringForAddressFamily((int) ndm_family) + "}, "
- + "ifindex{" + ndm_ifindex + "}, "
- + "state{" + stateStr + "}, "
- + "flags{" + flagsStr + "}, "
- + "type{" + ndm_type + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructNdaCacheInfo.java b/services/net/java/android/net/netlink/StructNdaCacheInfo.java
deleted file mode 100644
index 16cf563..0000000
--- a/services/net/java/android/net/netlink/StructNdaCacheInfo.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.system.Os;
-import android.system.OsConstants;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * struct nda_cacheinfo
- *
- * see: <linux_src>/include/uapi/linux/neighbour.h
- *
- * @hide
- */
-public class StructNdaCacheInfo {
- // Already aligned.
- public static final int STRUCT_SIZE = 16;
-
- private static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
- return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
- }
-
- public static StructNdaCacheInfo parse(ByteBuffer byteBuffer) {
- if (!hasAvailableSpace(byteBuffer)) { return null; }
-
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the possible
- // exception of usage within unittests.
- final StructNdaCacheInfo struct = new StructNdaCacheInfo();
- struct.ndm_used = byteBuffer.getInt();
- struct.ndm_confirmed = byteBuffer.getInt();
- struct.ndm_updated = byteBuffer.getInt();
- struct.ndm_refcnt = byteBuffer.getInt();
- return struct;
- }
-
- // TODO: investigate whether this can change during device runtime and
- // decide what (if anything) should be done about that.
- private static final long CLOCK_TICKS_PER_SECOND = Os.sysconf(OsConstants._SC_CLK_TCK);
-
- private static long ticksToMilliSeconds(int intClockTicks) {
- final long longClockTicks = (long) intClockTicks & 0xffffffff;
- return (longClockTicks * 1000) / CLOCK_TICKS_PER_SECOND;
- }
-
- /**
- * Explanatory notes, for reference.
- *
- * Before being returned to user space, the neighbor entry times are
- * converted to clock_t's like so:
- *
- * ndm_used = jiffies_to_clock_t(now - neigh->used);
- * ndm_confirmed = jiffies_to_clock_t(now - neigh->confirmed);
- * ndm_updated = jiffies_to_clock_t(now - neigh->updated);
- *
- * meaning that these values are expressed as "clock ticks ago". To
- * convert these clock ticks to seconds divide by sysconf(_SC_CLK_TCK).
- * When _SC_CLK_TCK is 100, for example, the ndm_* times are expressed
- * in centiseconds.
- *
- * These values are unsigned, but fortunately being expressed as "some
- * clock ticks ago", these values are typically very small (and
- * 2^31 centiseconds = 248 days).
- *
- * By observation, it appears that:
- * ndm_used: the last time ARP/ND took place for this neighbor
- * ndm_confirmed: the last time ARP/ND succeeded for this neighbor OR
- * higher layer confirmation (TCP or MSG_CONFIRM)
- * was received
- * ndm_updated: the time when the current NUD state was entered
- */
- public int ndm_used;
- public int ndm_confirmed;
- public int ndm_updated;
- public int ndm_refcnt;
-
- public StructNdaCacheInfo() {}
-
- public long lastUsed() {
- return ticksToMilliSeconds(ndm_used);
- }
-
- public long lastConfirmed() {
- return ticksToMilliSeconds(ndm_confirmed);
- }
-
- public long lastUpdated() {
- return ticksToMilliSeconds(ndm_updated);
- }
-
- @Override
- public String toString() {
- return "NdaCacheInfo{ "
- + "ndm_used{" + lastUsed() + "}, "
- + "ndm_confirmed{" + lastConfirmed() + "}, "
- + "ndm_updated{" + lastUpdated() + "}, "
- + "ndm_refcnt{" + ndm_refcnt + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructNfGenMsg.java b/services/net/java/android/net/netlink/StructNfGenMsg.java
deleted file mode 100644
index 8155977..0000000
--- a/services/net/java/android/net/netlink/StructNfGenMsg.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netlink;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * struct nfgenmsg
- *
- * see <linux_src>/include/uapi/linux/netfilter/nfnetlink.h
- *
- * @hide
- */
-public class StructNfGenMsg {
- public static final int STRUCT_SIZE = 2 + Short.BYTES;
-
- public static final int NFNETLINK_V0 = 0;
-
- final public byte nfgen_family;
- final public byte version;
- final public short res_id; // N.B.: this is big endian in the kernel
-
- public StructNfGenMsg(byte family) {
- nfgen_family = family;
- version = (byte) NFNETLINK_V0;
- res_id = (short) 0;
- }
-
- public void pack(ByteBuffer byteBuffer) {
- byteBuffer.put(nfgen_family);
- byteBuffer.put(version);
- byteBuffer.putShort(res_id);
- }
-}
diff --git a/services/net/java/android/net/netlink/StructNlAttr.java b/services/net/java/android/net/netlink/StructNlAttr.java
deleted file mode 100644
index 28a4e88..0000000
--- a/services/net/java/android/net/netlink/StructNlAttr.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.net.netlink.NetlinkConstants;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-
-
-/**
- * struct nlattr
- *
- * see: <linux_src>/include/uapi/linux/netlink.h
- *
- * @hide
- */
-public class StructNlAttr {
- // Already aligned.
- public static final int NLA_HEADERLEN = 4;
- public static final int NLA_F_NESTED = (1 << 15);
-
- public static short makeNestedType(short type) {
- return (short) (type | NLA_F_NESTED);
- }
-
- // Return a (length, type) object only, without consuming any bytes in
- // |byteBuffer| and without copying or interpreting any value bytes.
- // This is used for scanning over a packed set of struct nlattr's,
- // looking for instances of a particular type.
- public static StructNlAttr peek(ByteBuffer byteBuffer) {
- if (byteBuffer == null || byteBuffer.remaining() < NLA_HEADERLEN) {
- return null;
- }
- final int baseOffset = byteBuffer.position();
-
- // Assume the byte order of the buffer is the expected byte order of the value.
- final StructNlAttr struct = new StructNlAttr(byteBuffer.order());
- // The byte order of nla_len and nla_type is always native.
- final ByteOrder originalOrder = byteBuffer.order();
- byteBuffer.order(ByteOrder.nativeOrder());
- try {
- struct.nla_len = byteBuffer.getShort();
- struct.nla_type = byteBuffer.getShort();
- } finally {
- byteBuffer.order(originalOrder);
- }
-
- byteBuffer.position(baseOffset);
- if (struct.nla_len < NLA_HEADERLEN) {
- // Malformed.
- return null;
- }
- return struct;
- }
-
- public static StructNlAttr parse(ByteBuffer byteBuffer) {
- final StructNlAttr struct = peek(byteBuffer);
- if (struct == null || byteBuffer.remaining() < struct.getAlignedLength()) {
- return null;
- }
-
- final int baseOffset = byteBuffer.position();
- byteBuffer.position(baseOffset + NLA_HEADERLEN);
-
- int valueLen = ((int) struct.nla_len) & 0xffff;
- valueLen -= NLA_HEADERLEN;
- if (valueLen > 0) {
- struct.nla_value = new byte[valueLen];
- byteBuffer.get(struct.nla_value, 0, valueLen);
- byteBuffer.position(baseOffset + struct.getAlignedLength());
- }
- return struct;
- }
-
- public short nla_len = (short) NLA_HEADERLEN;
- public short nla_type;
- public byte[] nla_value;
-
- // The byte order used to read/write the value member. Netlink length and
- // type members are always read/written in native order.
- private ByteOrder mByteOrder = ByteOrder.nativeOrder();
-
- public StructNlAttr() {}
-
- public StructNlAttr(ByteOrder byteOrder) {
- mByteOrder = byteOrder;
- }
-
- public StructNlAttr(short type, byte value) {
- nla_type = type;
- setValue(new byte[1]);
- nla_value[0] = value;
- }
-
- public StructNlAttr(short type, short value) {
- this(type, value, ByteOrder.nativeOrder());
- }
-
- public StructNlAttr(short type, short value, ByteOrder order) {
- this(order);
- nla_type = type;
- setValue(new byte[Short.BYTES]);
- getValueAsByteBuffer().putShort(value);
- }
-
- public StructNlAttr(short type, int value) {
- this(type, value, ByteOrder.nativeOrder());
- }
-
- public StructNlAttr(short type, int value, ByteOrder order) {
- this(order);
- nla_type = type;
- setValue(new byte[Integer.BYTES]);
- getValueAsByteBuffer().putInt(value);
- }
-
- public StructNlAttr(short type, InetAddress ip) {
- nla_type = type;
- setValue(ip.getAddress());
- }
-
- public StructNlAttr(short type, StructNlAttr... nested) {
- this();
- nla_type = makeNestedType(type);
-
- int payloadLength = 0;
- for (StructNlAttr nla : nested) payloadLength += nla.getAlignedLength();
- setValue(new byte[payloadLength]);
-
- final ByteBuffer buf = getValueAsByteBuffer();
- for (StructNlAttr nla : nested) {
- nla.pack(buf);
- }
- }
-
- public int getAlignedLength() {
- return NetlinkConstants.alignedLengthOf(nla_len);
- }
-
- public ByteBuffer getValueAsByteBuffer() {
- if (nla_value == null) { return null; }
- final ByteBuffer byteBuffer = ByteBuffer.wrap(nla_value);
- byteBuffer.order(mByteOrder);
- return byteBuffer;
- }
-
- public int getValueAsInt(int defaultValue) {
- final ByteBuffer byteBuffer = getValueAsByteBuffer();
- if (byteBuffer == null || byteBuffer.remaining() != Integer.BYTES) {
- return defaultValue;
- }
- return getValueAsByteBuffer().getInt();
- }
-
- public InetAddress getValueAsInetAddress() {
- if (nla_value == null) { return null; }
-
- try {
- return InetAddress.getByAddress(nla_value);
- } catch (UnknownHostException ignored) {
- return null;
- }
- }
-
- public void pack(ByteBuffer byteBuffer) {
- final ByteOrder originalOrder = byteBuffer.order();
- final int originalPosition = byteBuffer.position();
-
- byteBuffer.order(ByteOrder.nativeOrder());
- try {
- byteBuffer.putShort(nla_len);
- byteBuffer.putShort(nla_type);
- if (nla_value != null) byteBuffer.put(nla_value);
- } finally {
- byteBuffer.order(originalOrder);
- }
- byteBuffer.position(originalPosition + getAlignedLength());
- }
-
- private void setValue(byte[] value) {
- nla_value = value;
- nla_len = (short) (NLA_HEADERLEN + ((nla_value != null) ? nla_value.length : 0));
- }
-
- @Override
- public String toString() {
- return "StructNlAttr{ "
- + "nla_len{" + nla_len + "}, "
- + "nla_type{" + nla_type + "}, "
- + "nla_value{" + NetlinkConstants.hexify(nla_value) + "}, "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructNlMsgErr.java b/services/net/java/android/net/netlink/StructNlMsgErr.java
deleted file mode 100644
index 6fcc6e69d..0000000
--- a/services/net/java/android/net/netlink/StructNlMsgErr.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.StructNlMsgHdr;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * struct nlmsgerr
- *
- * see <linux_src>/include/uapi/linux/netlink.h
- *
- * @hide
- */
-public class StructNlMsgErr {
- public static final int STRUCT_SIZE = Integer.BYTES + StructNlMsgHdr.STRUCT_SIZE;
-
- public static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
- return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
- }
-
- public static StructNlMsgErr parse(ByteBuffer byteBuffer) {
- if (!hasAvailableSpace(byteBuffer)) { return null; }
-
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the exception
- // of usage within unittests.
- final StructNlMsgErr struct = new StructNlMsgErr();
- struct.error = byteBuffer.getInt();
- struct.msg = StructNlMsgHdr.parse(byteBuffer);
- return struct;
- }
-
- public int error;
- public StructNlMsgHdr msg;
-
- public void pack(ByteBuffer byteBuffer) {
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the possible
- // exception of usage within unittests.
- byteBuffer.putInt(error);
- if (msg != null) {
- msg.pack(byteBuffer);
- }
- }
-
- @Override
- public String toString() {
- return "StructNlMsgErr{ "
- + "error{" + error + "}, "
- + "msg{" + (msg == null ? "" : msg.toString()) + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/netlink/StructNlMsgHdr.java b/services/net/java/android/net/netlink/StructNlMsgHdr.java
deleted file mode 100644
index 98ab5e7..0000000
--- a/services/net/java/android/net/netlink/StructNlMsgHdr.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import android.net.netlink.NetlinkConstants;
-import java.nio.ByteBuffer;
-
-
-/**
- * struct nlmsghdr
- *
- * see <linux_src>/include/uapi/linux/netlink.h
- *
- * @hide
- */
-public class StructNlMsgHdr {
- // Already aligned.
- public static final int STRUCT_SIZE = 16;
-
- public static final short NLM_F_REQUEST = 0x0001;
- public static final short NLM_F_MULTI = 0x0002;
- public static final short NLM_F_ACK = 0x0004;
- public static final short NLM_F_ECHO = 0x0008;
- // Flags for a GET request.
- public static final short NLM_F_ROOT = 0x0100;
- public static final short NLM_F_MATCH = 0x0200;
- public static final short NLM_F_DUMP = NLM_F_ROOT|NLM_F_MATCH;
- // Flags for a NEW request.
- public static final short NLM_F_REPLACE = 0x100;
- public static final short NLM_F_EXCL = 0x200;
- public static final short NLM_F_CREATE = 0x400;
- public static final short NLM_F_APPEND = 0x800;
-
-
- public static String stringForNlMsgFlags(short flags) {
- final StringBuilder sb = new StringBuilder();
- if ((flags & NLM_F_REQUEST) != 0) {
- sb.append("NLM_F_REQUEST");
- }
- if ((flags & NLM_F_MULTI) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NLM_F_MULTI");
- }
- if ((flags & NLM_F_ACK) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NLM_F_ACK");
- }
- if ((flags & NLM_F_ECHO) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NLM_F_ECHO");
- }
- if ((flags & NLM_F_ROOT) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NLM_F_ROOT");
- }
- if ((flags & NLM_F_MATCH) != 0) {
- if (sb.length() > 0) { sb.append("|"); }
- sb.append("NLM_F_MATCH");
- }
- return sb.toString();
- }
-
- public static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
- return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
- }
-
- public static StructNlMsgHdr parse(ByteBuffer byteBuffer) {
- if (!hasAvailableSpace(byteBuffer)) { return null; }
-
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the exception
- // of usage within unittests.
- final StructNlMsgHdr struct = new StructNlMsgHdr();
- struct.nlmsg_len = byteBuffer.getInt();
- struct.nlmsg_type = byteBuffer.getShort();
- struct.nlmsg_flags = byteBuffer.getShort();
- struct.nlmsg_seq = byteBuffer.getInt();
- struct.nlmsg_pid = byteBuffer.getInt();
-
- if (struct.nlmsg_len < STRUCT_SIZE) {
- // Malformed.
- return null;
- }
- return struct;
- }
-
- public int nlmsg_len;
- public short nlmsg_type;
- public short nlmsg_flags;
- public int nlmsg_seq;
- public int nlmsg_pid;
-
- public StructNlMsgHdr() {
- nlmsg_len = 0;
- nlmsg_type = 0;
- nlmsg_flags = 0;
- nlmsg_seq = 0;
- nlmsg_pid = 0;
- }
-
- public void pack(ByteBuffer byteBuffer) {
- // The ByteOrder must have already been set by the caller. In most
- // cases ByteOrder.nativeOrder() is correct, with the possible
- // exception of usage within unittests.
- byteBuffer.putInt(nlmsg_len);
- byteBuffer.putShort(nlmsg_type);
- byteBuffer.putShort(nlmsg_flags);
- byteBuffer.putInt(nlmsg_seq);
- byteBuffer.putInt(nlmsg_pid);
- }
-
- @Override
- public String toString() {
- final String typeStr = "" + nlmsg_type
- + "(" + NetlinkConstants.stringForNlMsgType(nlmsg_type) + ")";
- final String flagsStr = "" + nlmsg_flags
- + "(" + stringForNlMsgFlags(nlmsg_flags) + ")";
- return "StructNlMsgHdr{ "
- + "nlmsg_len{" + nlmsg_len + "}, "
- + "nlmsg_type{" + typeStr + "}, "
- + "nlmsg_flags{" + flagsStr + ")}, "
- + "nlmsg_seq{" + nlmsg_seq + "}, "
- + "nlmsg_pid{" + nlmsg_pid + "} "
- + "}";
- }
-}
diff --git a/services/net/java/android/net/shared/InitialConfiguration.java b/services/net/java/android/net/shared/InitialConfiguration.java
deleted file mode 100644
index 007c8ca9..0000000
--- a/services/net/java/android/net/shared/InitialConfiguration.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import static android.net.shared.ParcelableUtil.fromParcelableArray;
-import static android.net.shared.ParcelableUtil.toParcelableArray;
-import static android.text.TextUtils.join;
-
-import android.net.InetAddresses;
-import android.net.InitialConfigurationParcelable;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Predicate;
-
-/** @hide */
-public class InitialConfiguration {
- public final Set<LinkAddress> ipAddresses = new HashSet<>();
- public final Set<IpPrefix> directlyConnectedRoutes = new HashSet<>();
- public final Set<InetAddress> dnsServers = new HashSet<>();
-
- private static final int RFC6177_MIN_PREFIX_LENGTH = 48;
- private static final int RFC7421_PREFIX_LENGTH = 64;
-
- public static final InetAddress INET6_ANY = InetAddresses.parseNumericAddress("::");
-
- /**
- * Create a InitialConfiguration that is a copy of the specified configuration.
- */
- public static InitialConfiguration copy(InitialConfiguration config) {
- if (config == null) {
- return null;
- }
- InitialConfiguration configCopy = new InitialConfiguration();
- configCopy.ipAddresses.addAll(config.ipAddresses);
- configCopy.directlyConnectedRoutes.addAll(config.directlyConnectedRoutes);
- configCopy.dnsServers.addAll(config.dnsServers);
- return configCopy;
- }
-
- @Override
- public String toString() {
- return String.format(
- "InitialConfiguration(IPs: {%s}, prefixes: {%s}, DNS: {%s})",
- join(", ", ipAddresses), join(", ", directlyConnectedRoutes),
- join(", ", dnsServers));
- }
-
- /**
- * Tests whether the contents of this IpConfiguration represent a valid configuration.
- */
- public boolean isValid() {
- if (ipAddresses.isEmpty()) {
- return false;
- }
-
- // For every IP address, there must be at least one prefix containing that address.
- for (LinkAddress addr : ipAddresses) {
- if (!any(directlyConnectedRoutes, (p) -> p.contains(addr.getAddress()))) {
- return false;
- }
- }
- // For every dns server, there must be at least one prefix containing that address.
- for (InetAddress addr : dnsServers) {
- if (!any(directlyConnectedRoutes, (p) -> p.contains(addr))) {
- return false;
- }
- }
- // All IPv6 LinkAddresses have an RFC7421-suitable prefix length
- // (read: compliant with RFC4291#section2.5.4).
- if (any(ipAddresses, not(InitialConfiguration::isPrefixLengthCompliant))) {
- return false;
- }
- // If directlyConnectedRoutes contains an IPv6 default route
- // then ipAddresses MUST contain at least one non-ULA GUA.
- if (any(directlyConnectedRoutes, InitialConfiguration::isIPv6DefaultRoute)
- && all(ipAddresses, not(InitialConfiguration::isIPv6GUA))) {
- return false;
- }
- // The prefix length of routes in directlyConnectedRoutes be within reasonable
- // bounds for IPv6: /48-/64 just as we’d accept in RIOs.
- if (any(directlyConnectedRoutes, not(InitialConfiguration::isPrefixLengthCompliant))) {
- return false;
- }
- // There no more than one IPv4 address
- if (ipAddresses.stream().filter(InitialConfiguration::isIPv4).count() > 1) {
- return false;
- }
-
- return true;
- }
-
- /**
- * @return true if the given list of addressess and routes satisfies provisioning for this
- * InitialConfiguration. LinkAddresses and RouteInfo objects are not compared with equality
- * because addresses and routes seen by Netlink will contain additional fields like flags,
- * interfaces, and so on. If this InitialConfiguration has no IP address specified, the
- * provisioning check always fails.
- *
- * If the given list of routes is null, only addresses are taken into considerations.
- */
- public boolean isProvisionedBy(List<LinkAddress> addresses, List<RouteInfo> routes) {
- if (ipAddresses.isEmpty()) {
- return false;
- }
-
- for (LinkAddress addr : ipAddresses) {
- if (!any(addresses, (addrSeen) -> addr.isSameAddressAs(addrSeen))) {
- return false;
- }
- }
-
- if (routes != null) {
- for (IpPrefix prefix : directlyConnectedRoutes) {
- if (!any(routes, (routeSeen) -> isDirectlyConnectedRoute(routeSeen, prefix))) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- /**
- * Convert this configuration to a {@link InitialConfigurationParcelable}.
- */
- public InitialConfigurationParcelable toStableParcelable() {
- final InitialConfigurationParcelable p = new InitialConfigurationParcelable();
- p.ipAddresses = ipAddresses.toArray(new LinkAddress[0]);
- p.directlyConnectedRoutes = directlyConnectedRoutes.toArray(new IpPrefix[0]);
- p.dnsServers = toParcelableArray(
- dnsServers, IpConfigurationParcelableUtil::parcelAddress, String.class);
- return p;
- }
-
- /**
- * Create an instance of {@link InitialConfiguration} based on the contents of the specified
- * {@link InitialConfigurationParcelable}.
- */
- public static InitialConfiguration fromStableParcelable(InitialConfigurationParcelable p) {
- if (p == null) return null;
- final InitialConfiguration config = new InitialConfiguration();
- config.ipAddresses.addAll(Arrays.asList(p.ipAddresses));
- config.directlyConnectedRoutes.addAll(Arrays.asList(p.directlyConnectedRoutes));
- config.dnsServers.addAll(
- fromParcelableArray(p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress));
- return config;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof InitialConfiguration)) return false;
- final InitialConfiguration other = (InitialConfiguration) obj;
- return ipAddresses.equals(other.ipAddresses)
- && directlyConnectedRoutes.equals(other.directlyConnectedRoutes)
- && dnsServers.equals(other.dnsServers);
- }
-
- private static boolean isDirectlyConnectedRoute(RouteInfo route, IpPrefix prefix) {
- return !route.hasGateway() && prefix.equals(route.getDestination());
- }
-
- private static boolean isPrefixLengthCompliant(LinkAddress addr) {
- return isIPv4(addr) || isCompliantIPv6PrefixLength(addr.getPrefixLength());
- }
-
- private static boolean isPrefixLengthCompliant(IpPrefix prefix) {
- return isIPv4(prefix) || isCompliantIPv6PrefixLength(prefix.getPrefixLength());
- }
-
- private static boolean isCompliantIPv6PrefixLength(int prefixLength) {
- return (RFC6177_MIN_PREFIX_LENGTH <= prefixLength)
- && (prefixLength <= RFC7421_PREFIX_LENGTH);
- }
-
- private static boolean isIPv4(IpPrefix prefix) {
- return prefix.getAddress() instanceof Inet4Address;
- }
-
- private static boolean isIPv4(LinkAddress addr) {
- return addr.getAddress() instanceof Inet4Address;
- }
-
- private static boolean isIPv6DefaultRoute(IpPrefix prefix) {
- return prefix.getAddress().equals(INET6_ANY);
- }
-
- private static boolean isIPv6GUA(LinkAddress addr) {
- return addr.isIpv6() && addr.isGlobalPreferred();
- }
-
- // TODO: extract out into CollectionUtils.
-
- /**
- * Indicate whether any element of the specified iterable verifies the specified predicate.
- */
- public static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
- for (T t : coll) {
- if (fn.test(t)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Indicate whether all elements of the specified iterable verifies the specified predicate.
- */
- public static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
- return !any(coll, not(fn));
- }
-
- /**
- * Create a predicate that returns the opposite value of the specified predicate.
- */
- public static <T> Predicate<T> not(Predicate<T> fn) {
- return (t) -> !fn.test(t);
- }
-}
diff --git a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
deleted file mode 100644
index 172dc24..0000000
--- a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.DhcpResultsParcelable;
-import android.net.InetAddresses;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-
-/**
- * Collection of utility methods to convert to and from stable AIDL parcelables for IpClient
- * configuration classes.
- * @hide
- */
-public final class IpConfigurationParcelableUtil {
- /**
- * Convert DhcpResults to a DhcpResultsParcelable.
- */
- public static DhcpResultsParcelable toStableParcelable(@Nullable DhcpResults results) {
- if (results == null) return null;
- final DhcpResultsParcelable p = new DhcpResultsParcelable();
- p.baseConfiguration = results.toStaticIpConfiguration();
- p.leaseDuration = results.leaseDuration;
- p.mtu = results.mtu;
- p.serverAddress = parcelAddress(results.serverAddress);
- p.vendorInfo = results.vendorInfo;
- p.serverHostName = results.serverHostName;
- return p;
- }
-
- /**
- * Convert a DhcpResultsParcelable to DhcpResults.
- */
- public static DhcpResults fromStableParcelable(@Nullable DhcpResultsParcelable p) {
- if (p == null) return null;
- final DhcpResults results = new DhcpResults(p.baseConfiguration);
- results.leaseDuration = p.leaseDuration;
- results.mtu = p.mtu;
- results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
- results.vendorInfo = p.vendorInfo;
- results.serverHostName = p.serverHostName;
- return results;
- }
-
- /**
- * Convert InetAddress to String.
- * TODO: have an InetAddressParcelable
- */
- public static String parcelAddress(@Nullable InetAddress addr) {
- if (addr == null) return null;
- return addr.getHostAddress();
- }
-
- /**
- * Convert String to InetAddress.
- * TODO: have an InetAddressParcelable
- */
- public static InetAddress unparcelAddress(@Nullable String addr) {
- if (addr == null) return null;
- return InetAddresses.parseNumericAddress(addr);
- }
-}
diff --git a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
deleted file mode 100644
index 1729da6..0000000
--- a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import android.annotation.Nullable;
-import android.net.LinkProperties;
-import android.net.ProxyInfo;
-
-/**
- * Collection of utility methods to convert to and from stable AIDL parcelables for LinkProperties
- * and its attributes.
- * @hide
- */
-public final class LinkPropertiesParcelableUtil {
- // Temporary methods to facilitate migrating clients away from LinkPropertiesParcelable
- // TODO: remove the following methods after migrating clients.
-
- /**
- * @deprecated conversion to stable parcelable is no longer necessary.
- */
- @Deprecated
- public static LinkProperties toStableParcelable(@Nullable LinkProperties lp) {
- return lp;
- }
-
- /**
- * @deprecated conversion to stable parcelable is no longer necessary.
- */
- @Deprecated
- public static ProxyInfo toStableParcelable(@Nullable ProxyInfo info) {
- return info;
- }
-}
diff --git a/services/net/java/android/net/shared/NetworkMonitorUtils.java b/services/net/java/android/net/shared/NetworkMonitorUtils.java
deleted file mode 100644
index 46e9c73..0000000
--- a/services/net/java/android/net/shared/NetworkMonitorUtils.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 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.net.shared;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-
-import android.net.NetworkCapabilities;
-
-/** @hide */
-public class NetworkMonitorUtils {
-
- // Network conditions broadcast constants
- public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
- "android.net.conn.NETWORK_CONDITIONS_MEASURED";
- public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type";
- public static final String EXTRA_NETWORK_TYPE = "extra_network_type";
- public static final String EXTRA_RESPONSE_RECEIVED = "extra_response_received";
- public static final String EXTRA_IS_CAPTIVE_PORTAL = "extra_is_captive_portal";
- public static final String EXTRA_CELL_ID = "extra_cellid";
- public static final String EXTRA_SSID = "extra_ssid";
- public static final String EXTRA_BSSID = "extra_bssid";
- /** real time since boot */
- public static final String EXTRA_REQUEST_TIMESTAMP_MS = "extra_request_timestamp_ms";
- public static final String EXTRA_RESPONSE_TIMESTAMP_MS = "extra_response_timestamp_ms";
- public static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
- "android.permission.ACCESS_NETWORK_CONDITIONS";
-
- /**
- * Return whether validation is required for private DNS in strict mode.
- * @param nc Network capabilities of the network to test.
- */
- public static boolean isPrivateDnsValidationRequired(NetworkCapabilities nc) {
- // TODO: Consider requiring validation for DUN networks.
- return nc != null
- && nc.hasCapability(NET_CAPABILITY_INTERNET)
- && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
- && nc.hasCapability(NET_CAPABILITY_TRUSTED);
- }
-
- /**
- * Return whether validation is required for a network.
- * @param nc Network capabilities of the network to test.
- */
- public static boolean isValidationRequired(NetworkCapabilities nc) {
- // TODO: Consider requiring validation for DUN networks.
- return isPrivateDnsValidationRequired(nc) && nc.hasCapability(NET_CAPABILITY_NOT_VPN);
- }
-}
diff --git a/services/net/java/android/net/shared/ParcelableUtil.java b/services/net/java/android/net/shared/ParcelableUtil.java
deleted file mode 100644
index 3f40300..0000000
--- a/services/net/java/android/net/shared/ParcelableUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import android.annotation.NonNull;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.function.Function;
-
-/**
- * Utility methods to help convert to/from stable parcelables.
- * @hide
- */
-public final class ParcelableUtil {
- // Below methods could be implemented easily with streams, but streams are frowned upon in
- // frameworks code.
-
- /**
- * Convert a list of BaseType items to an array of ParcelableType items using the specified
- * converter function.
- */
- public static <ParcelableType, BaseType> ParcelableType[] toParcelableArray(
- @NonNull Collection<BaseType> base,
- @NonNull Function<BaseType, ParcelableType> conv,
- @NonNull Class<ParcelableType> parcelClass) {
- final ParcelableType[] out = (ParcelableType[]) Array.newInstance(parcelClass, base.size());
- int i = 0;
- for (BaseType b : base) {
- out[i] = conv.apply(b);
- i++;
- }
- return out;
- }
-
- /**
- * Convert an array of ParcelableType items to a list of BaseType items using the specified
- * converter function.
- */
- public static <ParcelableType, BaseType> ArrayList<BaseType> fromParcelableArray(
- @NonNull ParcelableType[] parceled, @NonNull Function<ParcelableType, BaseType> conv) {
- final ArrayList<BaseType> out = new ArrayList<>(parceled.length);
- for (ParcelableType t : parceled) {
- out.add(conv.apply(t));
- }
- return out;
- }
-}
diff --git a/services/net/java/android/net/shared/PrivateDnsConfig.java b/services/net/java/android/net/shared/PrivateDnsConfig.java
deleted file mode 100644
index c7dc530..0000000
--- a/services/net/java/android/net/shared/PrivateDnsConfig.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 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.net.shared;
-
-import static android.net.shared.ParcelableUtil.fromParcelableArray;
-import static android.net.shared.ParcelableUtil.toParcelableArray;
-
-import android.net.PrivateDnsConfigParcel;
-import android.text.TextUtils;
-
-import java.net.InetAddress;
-import java.util.Arrays;
-
-/** @hide */
-public class PrivateDnsConfig {
- public final boolean useTls;
- public final String hostname;
- public final InetAddress[] ips;
-
- public PrivateDnsConfig() {
- this(false);
- }
-
- public PrivateDnsConfig(boolean useTls) {
- this.useTls = useTls;
- this.hostname = "";
- this.ips = new InetAddress[0];
- }
-
- public PrivateDnsConfig(String hostname, InetAddress[] ips) {
- this.useTls = !TextUtils.isEmpty(hostname);
- this.hostname = useTls ? hostname : "";
- this.ips = (ips != null) ? ips : new InetAddress[0];
- }
-
- public PrivateDnsConfig(PrivateDnsConfig cfg) {
- useTls = cfg.useTls;
- hostname = cfg.hostname;
- ips = cfg.ips;
- }
-
- /**
- * Indicates whether this is a strict mode private DNS configuration.
- */
- public boolean inStrictMode() {
- return useTls && !TextUtils.isEmpty(hostname);
- }
-
- @Override
- public String toString() {
- return PrivateDnsConfig.class.getSimpleName()
- + "{" + useTls + ":" + hostname + "/" + Arrays.toString(ips) + "}";
- }
-
- /**
- * Create a stable AIDL-compatible parcel from the current instance.
- */
- public PrivateDnsConfigParcel toParcel() {
- final PrivateDnsConfigParcel parcel = new PrivateDnsConfigParcel();
- parcel.hostname = hostname;
- parcel.ips = toParcelableArray(
- Arrays.asList(ips), IpConfigurationParcelableUtil::parcelAddress, String.class);
-
- return parcel;
- }
-
- /**
- * Build a configuration from a stable AIDL-compatible parcel.
- */
- public static PrivateDnsConfig fromParcel(PrivateDnsConfigParcel parcel) {
- InetAddress[] ips = new InetAddress[parcel.ips.length];
- ips = fromParcelableArray(parcel.ips, IpConfigurationParcelableUtil::unparcelAddress)
- .toArray(ips);
- return new PrivateDnsConfig(parcel.hostname, ips);
- }
-}
diff --git a/services/net/java/android/net/shared/ProvisioningConfiguration.java b/services/net/java/android/net/shared/ProvisioningConfiguration.java
deleted file mode 100644
index 6f9c294..0000000
--- a/services/net/java/android/net/shared/ProvisioningConfiguration.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import android.annotation.Nullable;
-import android.net.INetd;
-import android.net.Network;
-import android.net.ProvisioningConfigurationParcelable;
-import android.net.StaticIpConfiguration;
-import android.net.apf.ApfCapabilities;
-import android.net.ip.IIpClient;
-
-import java.util.Objects;
-import java.util.StringJoiner;
-
-/**
- * This class encapsulates parameters to be passed to
- * IpClient#startProvisioning(). A defensive copy is made by IpClient
- * and the values specified herein are in force until IpClient#stop()
- * is called.
- *
- * Example use:
- *
- * final ProvisioningConfiguration config =
- * new ProvisioningConfiguration.Builder()
- * .withPreDhcpAction()
- * .withProvisioningTimeoutMs(36 * 1000)
- * .build();
- * mIpClient.startProvisioning(config.toStableParcelable());
- * ...
- * mIpClient.stop();
- *
- * The specified provisioning configuration will only be active until
- * IIpClient#stop() is called. Future calls to IIpClient#startProvisioning()
- * must specify the configuration again.
- * @hide
- */
-public class ProvisioningConfiguration {
- // TODO: Delete this default timeout once those callers that care are
- // fixed to pass in their preferred timeout.
- //
- // We pick 36 seconds so we can send DHCP requests at
- //
- // t=0, t=2, t=6, t=14, t=30
- //
- // allowing for 10% jitter.
- private static final int DEFAULT_TIMEOUT_MS = 36 * 1000;
-
- /**
- * Builder to create a {@link ProvisioningConfiguration}.
- */
- public static class Builder {
- protected ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
-
- /**
- * Specify that the configuration should not enable IPv4. It is enabled by default.
- */
- public Builder withoutIPv4() {
- mConfig.mEnableIPv4 = false;
- return this;
- }
-
- /**
- * Specify that the configuration should not enable IPv6. It is enabled by default.
- */
- public Builder withoutIPv6() {
- mConfig.mEnableIPv6 = false;
- return this;
- }
-
- /**
- * Specify that the configuration should not use a MultinetworkPolicyTracker. It is used
- * by default.
- */
- public Builder withoutMultinetworkPolicyTracker() {
- mConfig.mUsingMultinetworkPolicyTracker = false;
- return this;
- }
-
- /**
- * Specify that the configuration should not use a IpReachabilityMonitor. It is used by
- * default.
- */
- public Builder withoutIpReachabilityMonitor() {
- mConfig.mUsingIpReachabilityMonitor = false;
- return this;
- }
-
- /**
- * Identical to {@link #withPreDhcpAction(int)}, using a default timeout.
- * @see #withPreDhcpAction(int)
- */
- public Builder withPreDhcpAction() {
- mConfig.mRequestedPreDhcpActionMs = DEFAULT_TIMEOUT_MS;
- return this;
- }
-
- /**
- * Specify that {@link IpClientCallbacks#onPreDhcpAction()} should be called. Clients must
- * call {@link IIpClient#completedPreDhcpAction()} when the callback called. This behavior
- * is disabled by default.
- * @param dhcpActionTimeoutMs Timeout for clients to call completedPreDhcpAction().
- */
- public Builder withPreDhcpAction(int dhcpActionTimeoutMs) {
- mConfig.mRequestedPreDhcpActionMs = dhcpActionTimeoutMs;
- return this;
- }
-
- /**
- * Specify the initial provisioning configuration.
- */
- public Builder withInitialConfiguration(InitialConfiguration initialConfig) {
- mConfig.mInitialConfig = initialConfig;
- return this;
- }
-
- /**
- * Specify a static configuration for provisioning.
- */
- public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
- mConfig.mStaticIpConfig = staticConfig;
- return this;
- }
-
- /**
- * Specify ApfCapabilities.
- */
- public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
- mConfig.mApfCapabilities = apfCapabilities;
- return this;
- }
-
- /**
- * Specify the timeout to use for provisioning.
- */
- public Builder withProvisioningTimeoutMs(int timeoutMs) {
- mConfig.mProvisioningTimeoutMs = timeoutMs;
- return this;
- }
-
- /**
- * Specify that IPv6 address generation should use a random MAC address.
- */
- public Builder withRandomMacAddress() {
- mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_EUI64;
- return this;
- }
-
- /**
- * Specify that IPv6 address generation should use a stable MAC address.
- */
- public Builder withStableMacAddress() {
- mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
- return this;
- }
-
- /**
- * Specify the network to use for provisioning.
- */
- public Builder withNetwork(Network network) {
- mConfig.mNetwork = network;
- return this;
- }
-
- /**
- * Specify the display name that the IpClient should use.
- */
- public Builder withDisplayName(String displayName) {
- mConfig.mDisplayName = displayName;
- return this;
- }
-
- /**
- * Build the configuration using previously specified parameters.
- */
- public ProvisioningConfiguration build() {
- return new ProvisioningConfiguration(mConfig);
- }
- }
-
- public boolean mEnableIPv4 = true;
- public boolean mEnableIPv6 = true;
- public boolean mUsingMultinetworkPolicyTracker = true;
- public boolean mUsingIpReachabilityMonitor = true;
- public int mRequestedPreDhcpActionMs;
- public InitialConfiguration mInitialConfig;
- public StaticIpConfiguration mStaticIpConfig;
- public ApfCapabilities mApfCapabilities;
- public int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
- public int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
- public Network mNetwork = null;
- public String mDisplayName = null;
-
- public ProvisioningConfiguration() {} // used by Builder
-
- public ProvisioningConfiguration(ProvisioningConfiguration other) {
- mEnableIPv4 = other.mEnableIPv4;
- mEnableIPv6 = other.mEnableIPv6;
- mUsingMultinetworkPolicyTracker = other.mUsingMultinetworkPolicyTracker;
- mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
- mRequestedPreDhcpActionMs = other.mRequestedPreDhcpActionMs;
- mInitialConfig = InitialConfiguration.copy(other.mInitialConfig);
- mStaticIpConfig = other.mStaticIpConfig == null
- ? null
- : new StaticIpConfiguration(other.mStaticIpConfig);
- mApfCapabilities = other.mApfCapabilities;
- mProvisioningTimeoutMs = other.mProvisioningTimeoutMs;
- mIPv6AddrGenMode = other.mIPv6AddrGenMode;
- mNetwork = other.mNetwork;
- mDisplayName = other.mDisplayName;
- }
-
- /**
- * Create a ProvisioningConfigurationParcelable from this ProvisioningConfiguration.
- */
- public ProvisioningConfigurationParcelable toStableParcelable() {
- final ProvisioningConfigurationParcelable p = new ProvisioningConfigurationParcelable();
- p.enableIPv4 = mEnableIPv4;
- p.enableIPv6 = mEnableIPv6;
- p.usingMultinetworkPolicyTracker = mUsingMultinetworkPolicyTracker;
- p.usingIpReachabilityMonitor = mUsingIpReachabilityMonitor;
- p.requestedPreDhcpActionMs = mRequestedPreDhcpActionMs;
- p.initialConfig = mInitialConfig == null ? null : mInitialConfig.toStableParcelable();
- p.staticIpConfig = mStaticIpConfig == null
- ? null
- : new StaticIpConfiguration(mStaticIpConfig);
- p.apfCapabilities = mApfCapabilities; // ApfCapabilities is immutable
- p.provisioningTimeoutMs = mProvisioningTimeoutMs;
- p.ipv6AddrGenMode = mIPv6AddrGenMode;
- p.network = mNetwork;
- p.displayName = mDisplayName;
- return p;
- }
-
- /**
- * Create a ProvisioningConfiguration from a ProvisioningConfigurationParcelable.
- */
- public static ProvisioningConfiguration fromStableParcelable(
- @Nullable ProvisioningConfigurationParcelable p) {
- if (p == null) return null;
- final ProvisioningConfiguration config = new ProvisioningConfiguration();
- config.mEnableIPv4 = p.enableIPv4;
- config.mEnableIPv6 = p.enableIPv6;
- config.mUsingMultinetworkPolicyTracker = p.usingMultinetworkPolicyTracker;
- config.mUsingIpReachabilityMonitor = p.usingIpReachabilityMonitor;
- config.mRequestedPreDhcpActionMs = p.requestedPreDhcpActionMs;
- config.mInitialConfig = InitialConfiguration.fromStableParcelable(p.initialConfig);
- config.mStaticIpConfig = p.staticIpConfig == null
- ? null
- : new StaticIpConfiguration(p.staticIpConfig);
- config.mApfCapabilities = p.apfCapabilities; // ApfCapabilities is immutable
- config.mProvisioningTimeoutMs = p.provisioningTimeoutMs;
- config.mIPv6AddrGenMode = p.ipv6AddrGenMode;
- config.mNetwork = p.network;
- config.mDisplayName = p.displayName;
- return config;
- }
-
- @Override
- public String toString() {
- return new StringJoiner(", ", getClass().getSimpleName() + "{", "}")
- .add("mEnableIPv4: " + mEnableIPv4)
- .add("mEnableIPv6: " + mEnableIPv6)
- .add("mUsingMultinetworkPolicyTracker: " + mUsingMultinetworkPolicyTracker)
- .add("mUsingIpReachabilityMonitor: " + mUsingIpReachabilityMonitor)
- .add("mRequestedPreDhcpActionMs: " + mRequestedPreDhcpActionMs)
- .add("mInitialConfig: " + mInitialConfig)
- .add("mStaticIpConfig: " + mStaticIpConfig)
- .add("mApfCapabilities: " + mApfCapabilities)
- .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
- .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
- .add("mNetwork: " + mNetwork)
- .add("mDisplayName: " + mDisplayName)
- .toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof ProvisioningConfiguration)) return false;
- final ProvisioningConfiguration other = (ProvisioningConfiguration) obj;
- return mEnableIPv4 == other.mEnableIPv4
- && mEnableIPv6 == other.mEnableIPv6
- && mUsingMultinetworkPolicyTracker == other.mUsingMultinetworkPolicyTracker
- && mUsingIpReachabilityMonitor == other.mUsingIpReachabilityMonitor
- && mRequestedPreDhcpActionMs == other.mRequestedPreDhcpActionMs
- && Objects.equals(mInitialConfig, other.mInitialConfig)
- && Objects.equals(mStaticIpConfig, other.mStaticIpConfig)
- && Objects.equals(mApfCapabilities, other.mApfCapabilities)
- && mProvisioningTimeoutMs == other.mProvisioningTimeoutMs
- && mIPv6AddrGenMode == other.mIPv6AddrGenMode
- && Objects.equals(mNetwork, other.mNetwork)
- && Objects.equals(mDisplayName, other.mDisplayName);
- }
-
- public boolean isValid() {
- return (mInitialConfig == null) || mInitialConfig.isValid();
- }
-}
diff --git a/services/net/java/android/net/util/InterfaceParams.java b/services/net/java/android/net/util/InterfaceParams.java
deleted file mode 100644
index f6bb873..0000000
--- a/services/net/java/android/net/util/InterfaceParams.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.net.MacAddress;
-import android.text.TextUtils;
-
-import java.net.NetworkInterface;
-import java.net.SocketException;
-
-
-/**
- * Encapsulate the interface parameters common to IpClient/IpServer components.
- *
- * Basically all java.net.NetworkInterface methods throw Exceptions. IpClient
- * and IpServer (sub)components need most or all of this information at some
- * point during their lifecycles, so pass only this simplified object around
- * which can be created once when IpClient/IpServer are told to start.
- *
- * @hide
- */
-public class InterfaceParams {
- public final String name;
- public final int index;
- public final MacAddress macAddr;
- public final int defaultMtu;
-
- // TODO: move the below to NetworkStackConstants when this class is moved to the NetworkStack.
- private static final int ETHER_MTU = 1500;
- private static final int IPV6_MIN_MTU = 1280;
-
-
- public static InterfaceParams getByName(String name) {
- final NetworkInterface netif = getNetworkInterfaceByName(name);
- if (netif == null) return null;
-
- // Not all interfaces have MAC addresses, e.g. rmnet_data0.
- final MacAddress macAddr = getMacAddress(netif);
-
- try {
- return new InterfaceParams(name, netif.getIndex(), macAddr, netif.getMTU());
- } catch (IllegalArgumentException|SocketException e) {
- return null;
- }
- }
-
- public InterfaceParams(String name, int index, MacAddress macAddr) {
- this(name, index, macAddr, ETHER_MTU);
- }
-
- public InterfaceParams(String name, int index, MacAddress macAddr, int defaultMtu) {
- checkArgument((!TextUtils.isEmpty(name)), "impossible interface name");
- checkArgument((index > 0), "invalid interface index");
- this.name = name;
- this.index = index;
- this.macAddr = (macAddr != null) ? macAddr : MacAddress.fromBytes(new byte[] {
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 });
- this.defaultMtu = (defaultMtu > IPV6_MIN_MTU) ? defaultMtu : IPV6_MIN_MTU;
- }
-
- @Override
- public String toString() {
- return String.format("%s/%d/%s/%d", name, index, macAddr, defaultMtu);
- }
-
- private static NetworkInterface getNetworkInterfaceByName(String name) {
- try {
- return NetworkInterface.getByName(name);
- } catch (NullPointerException|SocketException e) {
- return null;
- }
- }
-
- private static MacAddress getMacAddress(NetworkInterface netif) {
- try {
- return MacAddress.fromBytes(netif.getHardwareAddress());
- } catch (IllegalArgumentException|NullPointerException|SocketException e) {
- return null;
- }
- }
-}
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
deleted file mode 100644
index 2cdb2b0..0000000
--- a/services/net/java/android/net/util/SharedLog.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.StringJoiner;
-
-
-/**
- * Class to centralize logging functionality for tethering.
- *
- * All access to class methods other than dump() must be on the same thread.
- *
- * TODO: this is a copy of SharedLog in the NetworkStack. Remove after Tethering is migrated.
- * @hide
- */
-public class SharedLog {
- private static final int DEFAULT_MAX_RECORDS = 500;
- private static final String COMPONENT_DELIMITER = ".";
-
- private enum Category {
- NONE,
- ERROR,
- MARK,
- WARN,
- };
-
- private final LocalLog mLocalLog;
- // The tag to use for output to the system log. This is not output to the
- // LocalLog because that would be redundant.
- private final String mTag;
- // The component (or subcomponent) of a system that is sharing this log.
- // This can grow in depth if components call forSubComponent() to obtain
- // their SharedLog instance. The tag is not included in the component for
- // brevity.
- private final String mComponent;
-
- public SharedLog(String tag) {
- this(DEFAULT_MAX_RECORDS, tag);
- }
-
- public SharedLog(int maxRecords, String tag) {
- this(new LocalLog(maxRecords), tag, tag);
- }
-
- private SharedLog(LocalLog localLog, String tag, String component) {
- mLocalLog = localLog;
- mTag = tag;
- mComponent = component;
- }
-
- public String getTag() {
- return mTag;
- }
-
- /**
- * Create a SharedLog based on this log with an additional component prefix on each logged line.
- */
- public SharedLog forSubComponent(String component) {
- if (!isRootLogInstance()) {
- component = mComponent + COMPONENT_DELIMITER + component;
- }
- return new SharedLog(mLocalLog, mTag, component);
- }
-
- /**
- * Dump the contents of this log.
- *
- * <p>This method may be called on any thread.
- */
- public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mLocalLog.readOnlyLocalLog().dump(fd, writer, args);
- }
-
- //////
- // Methods that both log an entry and emit it to the system log.
- //////
-
- /**
- * Log an error due to an exception. This does not include the exception stacktrace.
- *
- * <p>The log entry will be also added to the system log.
- * @see #e(String, Throwable)
- */
- public void e(Exception e) {
- Log.e(mTag, record(Category.ERROR, e.toString()));
- }
-
- /**
- * Log an error message.
- *
- * <p>The log entry will be also added to the system log.
- */
- public void e(String msg) {
- Log.e(mTag, record(Category.ERROR, msg));
- }
-
- /**
- * Log an error due to an exception, with the exception stacktrace if provided.
- *
- * <p>The error and exception message appear in the shared log, but the stacktrace is only
- * logged in general log output (logcat). The log entry will be also added to the system log.
- */
- public void e(@NonNull String msg, @Nullable Throwable exception) {
- if (exception == null) {
- e(msg);
- return;
- }
- Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception);
- }
-
- /**
- * Log an informational message.
- *
- * <p>The log entry will be also added to the system log.
- */
- public void i(String msg) {
- Log.i(mTag, record(Category.NONE, msg));
- }
-
- /**
- * Log a warning message.
- *
- * <p>The log entry will be also added to the system log.
- */
- public void w(String msg) {
- Log.w(mTag, record(Category.WARN, msg));
- }
-
- //////
- // Methods that only log an entry (and do NOT emit to the system log).
- //////
-
- /**
- * Log a general message to be only included in the in-memory log.
- *
- * <p>The log entry will *not* be added to the system log.
- */
- public void log(String msg) {
- record(Category.NONE, msg);
- }
-
- /**
- * Log a general, formatted message to be only included in the in-memory log.
- *
- * <p>The log entry will *not* be added to the system log.
- * @see String#format(String, Object...)
- */
- public void logf(String fmt, Object... args) {
- log(String.format(fmt, args));
- }
-
- /**
- * Log a message with MARK level.
- *
- * <p>The log entry will *not* be added to the system log.
- */
- public void mark(String msg) {
- record(Category.MARK, msg);
- }
-
- private String record(Category category, String msg) {
- final String entry = logLine(category, msg);
- mLocalLog.log(entry);
- return entry;
- }
-
- private String logLine(Category category, String msg) {
- final StringJoiner sj = new StringJoiner(" ");
- if (!isRootLogInstance()) sj.add("[" + mComponent + "]");
- if (category != Category.NONE) sj.add(category.toString());
- return sj.add(msg).toString();
- }
-
- // Check whether this SharedLog instance is nominally the top level in
- // a potential hierarchy of shared logs (the root of a tree),
- // or is a subcomponent within the hierarchy.
- private boolean isRootLogInstance() {
- return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
index 0605d9e..50437b4 100644
--- a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
@@ -36,7 +36,7 @@
public void test1() {
assertTrue("dynamic_system service available", mService != null);
try {
- mService.startInstallation("userdata", 8L << 30, false);
+ mService.startInstallation();
fail("DynamicSystemService did not throw SecurityException as expected");
} catch (SecurityException e) {
// expected
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e9e96c9..8fd8d04 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -56,6 +56,7 @@
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.os.Binder;
import android.os.Handler;
@@ -719,7 +720,7 @@
@Test
public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_noneSsid() throws Exception {
- when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE);
+ when(mWifiInfo.getSSID()).thenReturn(WifiManager.UNKNOWN_SSID);
NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter =
new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo);
@@ -793,7 +794,7 @@
List<ScanResult> invalidScanResults = Lists.newArrayList(
new ScanResult(),
createScanResult("", SCORED_NETWORK.networkKey.wifiKey.bssid),
- createScanResult(WifiSsid.NONE, SCORED_NETWORK.networkKey.wifiKey.bssid),
+ createScanResult(WifiManager.UNKNOWN_SSID, SCORED_NETWORK.networkKey.wifiKey.bssid),
createScanResult(SSID, null),
createScanResult(SSID, INVALID_BSSID)
);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
new file mode 100644
index 0000000..470d4fa
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 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.pm;
+
+import android.content.pm.PackageParser;
+
+import com.android.internal.util.ArrayUtils;
+
+class PackageBuilder {
+ final PackageParser.Package mPkg;
+
+ PackageBuilder(String packageName) {
+ mPkg = new PackageParser.Package(packageName);
+ }
+
+ PackageBuilder setApplicationInfoCodePath(String codePath) {
+ mPkg.applicationInfo.setCodePath(codePath);
+ return this;
+ }
+
+ PackageBuilder setApplicationInfoResourcePath(String resourcePath) {
+ mPkg.applicationInfo.setResourcePath(resourcePath);
+ return this;
+ }
+
+ PackageBuilder setCodePath(String codePath) {
+ mPkg.codePath = codePath;
+ return this;
+ }
+
+ PackageBuilder setBaseCodePath(String baseCodePath) {
+ mPkg.baseCodePath = baseCodePath;
+ return this;
+ }
+
+ PackageBuilder addUsesStaticLibrary(String name, long version) {
+ mPkg.usesStaticLibraries = ArrayUtils.add(mPkg.usesStaticLibraries, name);
+ mPkg.usesStaticLibrariesVersions =
+ ArrayUtils.appendLong(mPkg.usesStaticLibrariesVersions, version);
+ return this;
+ }
+
+ PackageBuilder setApplicationInfoNativeLibraryRootDir(String dir) {
+ mPkg.applicationInfo.nativeLibraryRootDir = dir;
+ return this;
+ }
+
+ PackageBuilder setStaticSharedLib(String staticSharedLibName, long staticSharedLibVersion) {
+ mPkg.staticSharedLibVersion = staticSharedLibVersion;
+ mPkg.staticSharedLibName = staticSharedLibName;
+ return this;
+ }
+
+ PackageBuilder setManifestPackageName(String manifestPackageName) {
+ mPkg.manifestPackageName = manifestPackageName;
+ return this;
+ }
+
+ PackageBuilder setVersionCodeMajor(int versionCodeMajor) {
+ mPkg.mVersionCodeMajor = versionCodeMajor;
+ return this;
+ }
+
+ PackageBuilder setVersionCode(int versionCode) {
+ mPkg.mVersionCode = versionCode;
+ return this;
+ }
+
+ PackageBuilder addSplitCodePath(String splitCodePath) {
+ mPkg.splitCodePaths =
+ ArrayUtils.appendElement(String.class, mPkg.splitCodePaths, splitCodePath);
+ return this;
+ }
+
+ PackageBuilder setApplicationInfoVolumeUuid(String volumeUuid) {
+ mPkg.applicationInfo.volumeUuid = volumeUuid;
+ return this;
+ }
+
+ PackageBuilder addLibraryName(String libraryName) {
+ mPkg.libraryNames = ArrayUtils.add(mPkg.libraryNames, libraryName);
+ return this;
+ }
+
+ PackageBuilder setRealPackageName(String realPackageName) {
+ mPkg.mRealPackage = realPackageName;
+ return this;
+ }
+
+ PackageBuilder setCpuAbiOVerride(String cpuAbiOverride) {
+ mPkg.cpuAbiOverride = cpuAbiOverride;
+ return this;
+ }
+
+ PackageBuilder addPermissionRequest(String permissionName) {
+ mPkg.requestedPermissions.add(permissionName);
+ return this;
+ }
+
+ PackageParser.Package build() {
+ return mPkg;
+ }
+
+ public PackageBuilder addApplicationInfoFlag(int flag) {
+ mPkg.applicationInfo.flags |= flag;
+ return this;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
new file mode 100644
index 0000000..b42cfd8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 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.pm;
+
+import android.content.pm.PackageUserState;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.util.List;
+
+class PackageSettingBuilder {
+ private String mName;
+ private String mRealName;
+ private String mCodePath;
+ private String mResourcePath;
+ private String mLegacyNativeLibraryPathString;
+ private String mPrimaryCpuAbiString;
+ private String mSecondaryCpuAbiString;
+ private String mCpuAbiOverrideString;
+ private long mPVersionCode;
+ private int mPkgFlags;
+ private int mPrivateFlags;
+ private String mParentPackageName;
+ private List<String> mChildPackageNames;
+ private int mSharedUserId;
+ private String[] mUsesStaticLibraries;
+ private long[] mUsesStaticLibrariesVersions;
+ private String mVolumeUuid;
+ private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
+
+ public PackageSettingBuilder setName(String name) {
+ this.mName = name;
+ return this;
+ }
+
+ public PackageSettingBuilder setRealName(String realName) {
+ this.mRealName = realName;
+ return this;
+ }
+
+ public PackageSettingBuilder setCodePath(String codePath) {
+ this.mCodePath = codePath;
+ return this;
+ }
+
+ public PackageSettingBuilder setResourcePath(String resourcePath) {
+ this.mResourcePath = resourcePath;
+ return this;
+ }
+
+ public PackageSettingBuilder setLegacyNativeLibraryPathString(
+ String legacyNativeLibraryPathString) {
+ this.mLegacyNativeLibraryPathString = legacyNativeLibraryPathString;
+ return this;
+ }
+
+ public PackageSettingBuilder setPrimaryCpuAbiString(String primaryCpuAbiString) {
+ this.mPrimaryCpuAbiString = primaryCpuAbiString;
+ return this;
+ }
+
+ public PackageSettingBuilder setSecondaryCpuAbiString(String secondaryCpuAbiString) {
+ this.mSecondaryCpuAbiString = secondaryCpuAbiString;
+ return this;
+ }
+
+ public PackageSettingBuilder setCpuAbiOverrideString(String cpuAbiOverrideString) {
+ this.mCpuAbiOverrideString = cpuAbiOverrideString;
+ return this;
+ }
+
+ public PackageSettingBuilder setPVersionCode(long pVersionCode) {
+ this.mPVersionCode = pVersionCode;
+ return this;
+ }
+
+ public PackageSettingBuilder setPkgFlags(int pkgFlags) {
+ this.mPkgFlags = pkgFlags;
+ return this;
+ }
+
+ public PackageSettingBuilder setPrivateFlags(int privateFlags) {
+ this.mPrivateFlags = privateFlags;
+ return this;
+ }
+
+ public PackageSettingBuilder setParentPackageName(String parentPackageName) {
+ this.mParentPackageName = parentPackageName;
+ return this;
+ }
+
+ public PackageSettingBuilder setChildPackageNames(List<String> childPackageNames) {
+ this.mChildPackageNames = childPackageNames;
+ return this;
+ }
+
+ public PackageSettingBuilder setSharedUserId(int sharedUserId) {
+ this.mSharedUserId = sharedUserId;
+ return this;
+ }
+
+ public PackageSettingBuilder setUsesStaticLibraries(String[] usesStaticLibraries) {
+ this.mUsesStaticLibraries = usesStaticLibraries;
+ return this;
+ }
+
+ public PackageSettingBuilder setUsesStaticLibrariesVersions(
+ long[] usesStaticLibrariesVersions) {
+ this.mUsesStaticLibrariesVersions = usesStaticLibrariesVersions;
+ return this;
+ }
+
+ public PackageSettingBuilder setVolumeUuid(String volumeUuid) {
+ this.mVolumeUuid = volumeUuid;
+ return this;
+ }
+
+ public PackageSettingBuilder setInstantAppUserState(int userId, boolean isInstant) {
+ if (mUserStates.indexOfKey(userId) < 0) {
+ mUserStates.put(userId, new PackageUserState());
+ }
+ mUserStates.get(userId).instantApp = isInstant;
+ return this;
+ }
+
+ public PackageSetting build() {
+ final PackageSetting packageSetting = new PackageSetting(mName, mRealName,
+ new File(mCodePath), new File(mResourcePath),
+ mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString,
+ mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mParentPackageName,
+ mChildPackageNames, mSharedUserId, mUsesStaticLibraries,
+ mUsesStaticLibrariesVersions);
+ packageSetting.volumeUuid = this.mVolumeUuid;
+ for (int i = 0; i < mUserStates.size(); i++) {
+ packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i));
+ }
+ return packageSetting;
+
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
new file mode 100644
index 0000000..34a3f86
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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.pm;
+
+import android.content.pm.PackageParser;
+import android.os.UserHandle;
+
+class ScanRequestBuilder {
+ private final PackageParser.Package mPkg;
+ private PackageParser.Package mOldPkg;
+ private SharedUserSetting mSharedUserSetting;
+ private PackageSetting mPkgSetting;
+ private PackageSetting mDisabledPkgSetting;
+ private PackageSetting mOriginalPkgSetting;
+ private String mRealPkgName;
+ private int mParseFlags;
+ private int mScanFlags;
+ private UserHandle mUser;
+ private boolean mIsPlatformPackage;
+
+ ScanRequestBuilder(PackageParser.Package pkg) {
+ this.mPkg = pkg;
+ }
+
+ public ScanRequestBuilder setOldPkg(PackageParser.Package oldPkg) {
+ this.mOldPkg = oldPkg;
+ return this;
+ }
+
+ public ScanRequestBuilder setSharedUserSetting(SharedUserSetting sharedUserSetting) {
+ this.mSharedUserSetting = sharedUserSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setPkgSetting(PackageSetting pkgSetting) {
+ this.mPkgSetting = pkgSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setDisabledPkgSetting(PackageSetting disabledPkgSetting) {
+ this.mDisabledPkgSetting = disabledPkgSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setOriginalPkgSetting(PackageSetting originalPkgSetting) {
+ this.mOriginalPkgSetting = originalPkgSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setRealPkgName(String realPkgName) {
+ this.mRealPkgName = realPkgName;
+ return this;
+ }
+
+ public ScanRequestBuilder setParseFlags(int parseFlags) {
+ this.mParseFlags = parseFlags;
+ return this;
+ }
+
+ public ScanRequestBuilder addParseFlag(int parseFlag) {
+ this.mParseFlags |= parseFlag;
+ return this;
+ }
+
+ public ScanRequestBuilder setScanFlags(int scanFlags) {
+ this.mScanFlags = scanFlags;
+ return this;
+ }
+
+ public ScanRequestBuilder addScanFlag(int scanFlag) {
+ this.mScanFlags |= scanFlag;
+ return this;
+ }
+
+ public ScanRequestBuilder setUser(UserHandle user) {
+ this.mUser = user;
+ return this;
+ }
+
+ public ScanRequestBuilder setIsPlatformPackage(boolean isPlatformPackage) {
+ this.mIsPlatformPackage = isPlatformPackage;
+ return this;
+ }
+
+ PackageManagerService.ScanRequest build() {
+ return new PackageManagerService.ScanRequest(
+ mPkg, mSharedUserSetting, mOldPkg, mPkgSetting, mDisabledPkgSetting,
+ mOriginalPkgSetting, mRealPkgName, mParseFlags, mScanFlags, mIsPlatformPackage,
+ mUser);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
new file mode 100644
index 0000000..dd3d8b9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2019 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.pm;
+
+import static android.content.pm.SharedLibraryInfo.TYPE_DYNAMIC;
+import static android.content.pm.SharedLibraryInfo.TYPE_STATIC;
+import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED;
+
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
+import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE;
+import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.SharedLibraryInfo;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManagerInternal;
+import android.platform.test.annotations.Presubmit;
+import android.util.Pair;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.File;
+
+@RunWith(MockitoJUnitRunner.class)
+@Presubmit
+// TODO: shared user tests
+public class ScanTests {
+
+ private static final String DUMMY_PACKAGE_NAME = "some.app.to.test";
+
+ @Mock
+ PackageAbiHelper mMockPackageAbiHelper;
+ @Mock
+ UserManagerInternal mMockUserManager;
+
+ @Before
+ public void setupDefaultUser() {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+ }
+
+ @Before
+ public void setupDefaultAbiBehavior() throws Exception {
+ when(mMockPackageAbiHelper.derivePackageAbi(
+ any(PackageParser.Package.class), nullable(String.class), anyBoolean()))
+ .thenReturn(new Pair<>(
+ new PackageAbiHelper.Abis("derivedPrimary", "derivedSecondary"),
+ new PackageAbiHelper.NativeLibraryPaths(
+ "derivedRootDir", true, "derivedNativeDir", "derivedNativeDir2")));
+ when(mMockPackageAbiHelper.getNativeLibraryPaths(
+ any(PackageParser.Package.class), any(File.class)))
+ .thenReturn(new PackageAbiHelper.NativeLibraryPaths(
+ "getRootDir", true, "getNativeDir", "getNativeDir2"
+ ));
+ when(mMockPackageAbiHelper.getBundledAppAbis(
+ any(PackageParser.Package.class)))
+ .thenReturn(new PackageAbiHelper.Abis("bundledPrimary", "bundledSecondary"));
+ }
+
+ @Test
+ public void newInstallSimpleAllNominal() throws Exception {
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
+ .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+ assertThat(scanResult.existingSettingCopied, is(false));
+ assertPathsNotDerived(scanResult);
+ }
+
+ @Test
+ public void newInstallForAllUsers() throws Exception {
+ final int[] userIds = {0, 10, 11};
+ when(mMockUserManager.getUserIds()).thenReturn(userIds);
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setRealPkgName(null)
+ .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
+ .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+ .build();
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ for (int uid : userIds) {
+ assertThat(scanResult.pkgSetting.readUserState(uid).installed, is(true));
+ }
+ }
+
+ @Test
+ public void installRealPackageName() throws Exception {
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setRealPkgName("com.package.real")
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.pkgSetting.realName, is("com.package.real"));
+
+ final PackageManagerService.ScanRequest scanRequestNoRealPkg =
+ createBasicScanRequestBuilder(
+ createBasicPackage(DUMMY_PACKAGE_NAME)
+ .setRealPackageName("com.package.real").build())
+ .build();
+
+ final PackageManagerService.ScanResult scanResultNoReal = executeScan(scanRequestNoRealPkg);
+ assertThat(scanResultNoReal.pkgSetting.realName, nullValue());
+ }
+
+ @Test
+ public void updateSimpleNominal() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting pkgSetting = createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setPrimaryCpuAbiString("primaryCpuAbi")
+ .setSecondaryCpuAbiString("secondaryCpuAbi")
+ .build();
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+ .setPkgSetting(pkgSetting)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.existingSettingCopied, is(true));
+
+ // ensure we don't overwrite the existing pkgSetting, in case something post-scan fails
+ assertNotSame(pkgSetting, scanResult.pkgSetting);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+
+ assertThat(scanResult.pkgSetting.primaryCpuAbiString, is("primaryCpuAbi"));
+ assertThat(scanResult.pkgSetting.secondaryCpuAbiString, is("secondaryCpuAbi"));
+ assertThat(scanResult.pkgSetting.cpuAbiOverrideString, nullValue());
+
+ assertPathsNotDerived(scanResult);
+ }
+
+ @Test
+ public void updateInstantSimpleNominal() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setInstantAppUserState(0, true)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/);
+ }
+
+ @Test
+ public void installStaticSharedLibrary() throws Exception {
+ final PackageParser.Package pkg = createBasicPackage("static.lib.pkg.123")
+ .setStaticSharedLib("static.lib", 123L)
+ .setManifestPackageName("static.lib.pkg")
+ .setVersionCodeMajor(1)
+ .setVersionCode(234)
+ .setBaseCodePath("/some/path.apk")
+ .addSplitCodePath("/some/other/path.apk")
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(
+ pkg).setUser(UserHandle.of(0)).build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.staticSharedLibraryInfo.getPackageName(), is("static.lib.pkg.123"));
+ assertThat(scanResult.staticSharedLibraryInfo.getName(), is("static.lib"));
+ assertThat(scanResult.staticSharedLibraryInfo.getLongVersion(), is(123L));
+ assertThat(scanResult.staticSharedLibraryInfo.getType(), is(TYPE_STATIC));
+ assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getPackageName(),
+ is("static.lib.pkg"));
+ assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getLongVersionCode(),
+ is(pkg.getLongVersionCode()));
+ assertThat(scanResult.staticSharedLibraryInfo.getAllCodePaths(),
+ hasItems("/some/path.apk", "/some/other/path.apk"));
+ assertThat(scanResult.staticSharedLibraryInfo.getDependencies(), nullValue());
+ assertThat(scanResult.staticSharedLibraryInfo.getDependentPackages(), empty());
+ }
+
+ @Test
+ public void installDynamicLibraries() throws Exception {
+ final PackageParser.Package pkg = createBasicPackage("dynamic.lib.pkg")
+ .setManifestPackageName("dynamic.lib.pkg")
+ .addLibraryName("liba")
+ .addLibraryName("libb")
+ .setVersionCodeMajor(1)
+ .setVersionCode(234)
+ .setBaseCodePath("/some/path.apk")
+ .addSplitCodePath("/some/other/path.apk")
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ new ScanRequestBuilder(pkg).setUser(UserHandle.of(0)).build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ final SharedLibraryInfo dynamicLib0 = scanResult.dynamicSharedLibraryInfos.get(0);
+ assertThat(dynamicLib0.getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib0.getName(), is("liba"));
+ assertThat(dynamicLib0.getLongVersion(), is((long) VERSION_UNDEFINED));
+ assertThat(dynamicLib0.getType(), is(TYPE_DYNAMIC));
+ assertThat(dynamicLib0.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib0.getDeclaringPackage().getLongVersionCode(),
+ is(pkg.getLongVersionCode()));
+ assertThat(dynamicLib0.getAllCodePaths(),
+ hasItems("/some/path.apk", "/some/other/path.apk"));
+ assertThat(dynamicLib0.getDependencies(), nullValue());
+ assertThat(dynamicLib0.getDependentPackages(), empty());
+
+ final SharedLibraryInfo dynamicLib1 = scanResult.dynamicSharedLibraryInfos.get(1);
+ assertThat(dynamicLib1.getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib1.getName(), is("libb"));
+ assertThat(dynamicLib1.getLongVersion(), is((long) VERSION_UNDEFINED));
+ assertThat(dynamicLib1.getType(), is(TYPE_DYNAMIC));
+ assertThat(dynamicLib1.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib1.getDeclaringPackage().getLongVersionCode(),
+ is(pkg.getLongVersionCode()));
+ assertThat(dynamicLib1.getAllCodePaths(),
+ hasItems("/some/path.apk", "/some/other/path.apk"));
+ assertThat(dynamicLib1.getDependencies(), nullValue());
+ assertThat(dynamicLib1.getDependentPackages(), empty());
+ }
+
+ @Test
+ public void volumeUuidChangesOnUpdate() throws Exception {
+ final PackageSetting pkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setVolumeUuid("someUuid")
+ .build();
+
+ final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .setApplicationInfoVolumeUuid("someNewUuid")
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(
+ new ScanRequestBuilder(basicPackage).setPkgSetting(pkgSetting).build());
+
+ assertThat(scanResult.pkgSetting.volumeUuid, is("someNewUuid"));
+ }
+
+ @Test
+ public void scanFirstBoot_derivesAbis() throws Exception {
+ final PackageSetting pkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build();
+
+ final PackageParser.Package basicPackage =
+ createBasicPackage(DUMMY_PACKAGE_NAME)
+ .setCpuAbiOVerride("testOverride")
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(new ScanRequestBuilder(
+ basicPackage)
+ .setPkgSetting(pkgSetting)
+ .addScanFlag(SCAN_FIRST_BOOT_OR_UPGRADE)
+ .build());
+
+ assertAbiAndPathssDerived(scanResult);
+ }
+
+ @Test
+ public void scanWithOriginalPkgSetting_packageNameChanges() throws Exception {
+ final PackageSetting originalPkgSetting =
+ createBasicPackageSettingBuilder("original.package").build();
+
+ final PackageParser.Package basicPackage =
+ createBasicPackage(DUMMY_PACKAGE_NAME)
+ .build();
+
+
+ final PackageManagerService.ScanResult result =
+ executeScan(new ScanRequestBuilder(basicPackage)
+ .setOriginalPkgSetting(originalPkgSetting)
+ .build());
+
+ assertThat(result.request.pkg.packageName, is("original.package"));
+ }
+
+ @Test
+ public void updateInstant_changeToFull() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setInstantAppUserState(0, true)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .addScanFlag(SCAN_AS_FULL_APP)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+ }
+
+ @Test
+ public void updateFull_changeToInstant() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setInstantAppUserState(0, false)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .addScanFlag(SCAN_AS_INSTANT_APP)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/);
+ }
+
+ @Test
+ public void updateSystemApp_applicationInfoFlagSet() throws Exception {
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .setDisabledPkgSetting(existingPkgSetting)
+ .addScanFlag(SCAN_NEW_INSTALL)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.request.pkg.applicationInfo.flags,
+ hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP));
+ }
+
+ @Test
+ public void factoryTestFlagSet() throws Exception {
+ final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .addPermissionRequest(Manifest.permission.FACTORY_TEST)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = PackageManagerService.scanPackageOnlyLI(
+ createBasicScanRequestBuilder(basicPackage).build(),
+ new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper),
+ true /*isUnderFactoryTest*/,
+ System.currentTimeMillis());
+
+ assertThat(scanResult.request.pkg.applicationInfo.flags,
+ hasFlag(ApplicationInfo.FLAG_FACTORY_TEST));
+ }
+
+ @Test
+ public void scanSystemApp_isOrphanedTrue() throws Exception {
+ final PackageParser.Package pkg = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .addApplicationInfoFlag(ApplicationInfo.FLAG_SYSTEM)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(pkg)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.pkgSetting.isOrphaned, is(true));
+ }
+
+ private static Matcher<Integer> hasFlag(final int flag) {
+ return new BaseMatcher<Integer>() {
+ @Override public void describeTo(Description description) {
+ description.appendText("flags ");
+ }
+
+ @Override public boolean matches(Object item) {
+ return ((int) item & flag) != 0;
+ }
+
+ @Override
+ public void describeMismatch(Object item, Description mismatchDescription) {
+ mismatchDescription
+ .appendValue(item)
+ .appendText(" does not contain flag ")
+ .appendValue(flag);
+ }
+ };
+ }
+
+ private PackageManagerService.ScanResult executeScan(
+ PackageManagerService.ScanRequest scanRequest) throws PackageManagerException {
+ return PackageManagerService.scanPackageOnlyLI(
+ scanRequest,
+ new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper),
+ false /*isUnderFactoryTest*/,
+ System.currentTimeMillis());
+ }
+
+ private static String createResourcePath(String packageName) {
+ return "/data/app/" + packageName + "-randompath/base.apk";
+ }
+
+ private static String createCodePath(String packageName) {
+ return "/data/app/" + packageName + "-randompath";
+ }
+
+ private static PackageSettingBuilder createBasicPackageSettingBuilder(String packageName) {
+ return new PackageSettingBuilder()
+ .setName(packageName)
+ .setCodePath(createCodePath(packageName))
+ .setResourcePath(createResourcePath(packageName));
+ }
+
+ private static ScanRequestBuilder createBasicScanRequestBuilder(PackageParser.Package pkg) {
+ return new ScanRequestBuilder(pkg)
+ .setUser(UserHandle.of(0));
+ }
+
+
+ private static PackageBuilder createBasicPackage(String packageName) {
+ return new PackageBuilder(packageName)
+ .setCodePath("/data/tmp/randompath")
+ .setApplicationInfoCodePath(createCodePath(packageName))
+ .setApplicationInfoResourcePath(createResourcePath(packageName))
+ .setApplicationInfoVolumeUuid("volumeUuid")
+ .setBaseCodePath("/data/tmp/randompath/base.apk")
+ .addUsesStaticLibrary("some.static.library", 234L)
+ .addUsesStaticLibrary("some.other.static.library", 456L)
+ .setApplicationInfoNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib")
+ .setVersionCodeMajor(1)
+ .setVersionCode(2345);
+ }
+
+ private static void assertBasicPackageScanResult(
+ PackageManagerService.ScanResult scanResult, String packageName, boolean isInstant) {
+ assertThat(scanResult.success, is(true));
+
+ final PackageSetting pkgSetting = scanResult.pkgSetting;
+ assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);
+
+ final ApplicationInfo applicationInfo = pkgSetting.pkg.applicationInfo;
+ assertBasicApplicationInfo(scanResult, applicationInfo);
+
+ }
+
+ private static void assertBasicPackageSetting(PackageManagerService.ScanResult scanResult,
+ String packageName, boolean isInstant, PackageSetting pkgSetting) {
+ assertThat(pkgSetting.pkg.packageName, is(packageName));
+ assertThat(pkgSetting.getInstantApp(0), is(isInstant));
+ assertThat(pkgSetting.usesStaticLibraries,
+ arrayContaining("some.static.library", "some.other.static.library"));
+ assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L}));
+ assertThat(pkgSetting.pkg, is(scanResult.request.pkg));
+ assertThat(pkgSetting.pkg.mExtras, is(pkgSetting));
+ assertThat(pkgSetting.codePath, is(new File(createCodePath(packageName))));
+ assertThat(pkgSetting.resourcePath, is(new File(createResourcePath(packageName))));
+ assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345)));
+ }
+
+ private static void assertBasicApplicationInfo(PackageManagerService.ScanResult scanResult,
+ ApplicationInfo applicationInfo) {
+ assertThat(applicationInfo.processName, is(scanResult.request.pkg.packageName));
+
+ final int uid = applicationInfo.uid;
+ assertThat(UserHandle.getUserId(uid), is(UserHandle.USER_SYSTEM));
+
+ final String calculatedCredentialId = Environment.getDataUserCePackageDirectory(
+ applicationInfo.volumeUuid, UserHandle.USER_SYSTEM,
+ scanResult.request.pkg.packageName).getAbsolutePath();
+ assertThat(applicationInfo.credentialProtectedDataDir, is(calculatedCredentialId));
+ assertThat(applicationInfo.dataDir, is(applicationInfo.credentialProtectedDataDir));
+ }
+
+ private static void assertAbiAndPathssDerived(PackageManagerService.ScanResult scanResult) {
+ final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo;
+ assertThat(applicationInfo.primaryCpuAbi, is("derivedPrimary"));
+ assertThat(applicationInfo.secondaryCpuAbi, is("derivedSecondary"));
+
+ assertThat(applicationInfo.nativeLibraryRootDir, is("derivedRootDir"));
+ assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("derivedRootDir"));
+ assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true));
+ assertThat(applicationInfo.nativeLibraryDir, is("derivedNativeDir"));
+ assertThat(applicationInfo.secondaryNativeLibraryDir, is("derivedNativeDir2"));
+ }
+
+ private static void assertPathsNotDerived(PackageManagerService.ScanResult scanResult) {
+ final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo;
+ assertThat(applicationInfo.nativeLibraryRootDir, is("getRootDir"));
+ assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("getRootDir"));
+ assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true));
+ assertThat(applicationInfo.nativeLibraryDir, is("getNativeDir"));
+ assertThat(applicationInfo.secondaryNativeLibraryDir, is("getNativeDir2"));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
new file mode 100644
index 0000000..1f312bf
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2019 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.recoverysystem;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IRecoverySystemProgressListener;
+import android.os.Looper;
+import android.os.PowerManager;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileWriter;
+
+/**
+ * atest FrameworksServicesTests:RecoverySystemServiceTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RecoverySystemServiceTest {
+ private RecoverySystemService mRecoverySystemService;
+ private RecoverySystemServiceTestable.FakeSystemProperties mSystemProperties;
+ private RecoverySystemService.UncryptSocket mUncryptSocket;
+ private Context mContext;
+ private IPowerManager mIPowerManager;
+ private FileWriter mUncryptUpdateFileWriter;
+
+ @Before
+ public void setup() {
+ mContext = mock(Context.class);
+ mSystemProperties = new RecoverySystemServiceTestable.FakeSystemProperties();
+ mUncryptSocket = mock(RecoverySystemService.UncryptSocket.class);
+ mUncryptUpdateFileWriter = mock(FileWriter.class);
+
+ Looper looper = InstrumentationRegistry.getContext().getMainLooper();
+ mIPowerManager = mock(IPowerManager.class);
+ PowerManager powerManager = new PowerManager(mock(Context.class), mIPowerManager,
+ new Handler(looper));
+
+ mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
+ powerManager, mUncryptUpdateFileWriter, mUncryptSocket);
+ }
+
+ @Test
+ public void clearBcb_success() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+ assertThat(mRecoverySystemService.clearBcb(), is(true));
+
+ assertThat(mSystemProperties.getCtlStart(), is("clear-bcb"));
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ }
+
+ @Test
+ public void clearBcb_uncrypt_failure() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+ assertThat(mRecoverySystemService.clearBcb(), is(false));
+
+ assertThat(mSystemProperties.getCtlStart(), is("clear-bcb"));
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ }
+
+ @Test(expected = SecurityException.class)
+ public void clearBcb_noPerm() {
+ doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ mRecoverySystemService.clearBcb();
+ }
+
+ @Test
+ public void setupBcb_success() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+ assertThat(mRecoverySystemService.setupBcb("foo"), is(true));
+
+ assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+ verify(mUncryptSocket).sendCommand("foo");
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ }
+
+ @Test
+ public void setupBcb_uncrypt_failure() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+ assertThat(mRecoverySystemService.setupBcb("foo"), is(false));
+
+ assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+ verify(mUncryptSocket).sendCommand("foo");
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ }
+
+ @Test(expected = SecurityException.class)
+ public void setupBcb_noPerm() {
+ doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ mRecoverySystemService.setupBcb("foo");
+ }
+
+ @Test
+ public void rebootRecoveryWithCommand_success() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+ mRecoverySystemService.rebootRecoveryWithCommand("foo");
+
+ assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+ verify(mUncryptSocket).sendCommand("foo");
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ verify(mIPowerManager).reboot(anyBoolean(), eq("recovery"), anyBoolean());
+ }
+
+ @Test
+ public void rebootRecoveryWithCommand_failure() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+ mRecoverySystemService.rebootRecoveryWithCommand("foo");
+
+ assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+ verify(mUncryptSocket).sendCommand("foo");
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ verifyNoMoreInteractions(mIPowerManager);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void rebootRecoveryWithCommand_noPerm() {
+ doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ mRecoverySystemService.rebootRecoveryWithCommand("foo");
+ }
+
+ @Test
+ public void uncrypt_success() throws Exception {
+ doNothing().when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.RECOVERY), any());
+ when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0, 5, 25, 50, 90, 99, 100);
+
+ IRecoverySystemProgressListener listener = mock(IRecoverySystemProgressListener.class);
+ assertThat(mRecoverySystemService.uncrypt("foo.zip", listener), is(true));
+
+ assertThat(mSystemProperties.getCtlStart(), is("uncrypt"));
+ verify(mUncryptSocket, times(7)).getPercentageUncrypted();
+ verify(mUncryptSocket).sendAck();
+ verify(mUncryptSocket).close();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
new file mode 100644
index 0000000..a986b71
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 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.recoverysystem;
+
+import android.content.Context;
+import android.os.PowerManager;
+
+import java.io.FileWriter;
+
+public class RecoverySystemServiceTestable extends RecoverySystemService {
+ private static class MockInjector extends RecoverySystemService.Injector {
+ private final FakeSystemProperties mSystemProperties;
+ private final PowerManager mPowerManager;
+ private final FileWriter mUncryptPackageFileWriter;
+ private final UncryptSocket mUncryptSocket;
+
+ MockInjector(Context context, FakeSystemProperties systemProperties,
+ PowerManager powerManager, FileWriter uncryptPackageFileWriter,
+ UncryptSocket uncryptSocket) {
+ super(context);
+ mSystemProperties = systemProperties;
+ mPowerManager = powerManager;
+ mUncryptPackageFileWriter = uncryptPackageFileWriter;
+ mUncryptSocket = uncryptSocket;
+ }
+
+ @Override
+ public PowerManager getPowerManager() {
+ return mPowerManager;
+ }
+
+ @Override
+ public String systemPropertiesGet(String key) {
+ return mSystemProperties.get(key);
+ }
+
+ @Override
+ public void systemPropertiesSet(String key, String value) {
+ mSystemProperties.set(key, value);
+ }
+
+ @Override
+ public boolean uncryptPackageFileDelete() {
+ return true;
+ }
+
+ @Override
+ public String getUncryptPackageFileName() {
+ return "mock-file.txt";
+ }
+
+ @Override
+ public FileWriter getUncryptPackageFileWriter() {
+ return mUncryptPackageFileWriter;
+ }
+
+ @Override
+ public UncryptSocket connectService() {
+ return mUncryptSocket;
+ }
+
+ @Override
+ public void threadSleep(long millis) {
+ }
+ }
+
+ RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
+ PowerManager powerManager, FileWriter uncryptPackageFileWriter,
+ UncryptSocket uncryptSocket) {
+ super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
+ uncryptSocket));
+ }
+
+ public static class FakeSystemProperties {
+ private String mCtlStart = null;
+
+ public String get(String key) {
+ if (RecoverySystemService.INIT_SERVICE_UNCRYPT.equals(key)
+ || RecoverySystemService.INIT_SERVICE_SETUP_BCB.equals(key)
+ || RecoverySystemService.INIT_SERVICE_CLEAR_BCB.equals(key)) {
+ return null;
+ } else {
+ throw new IllegalArgumentException("unexpected test key: " + key);
+ }
+ }
+
+ public void set(String key, String value) {
+ if ("ctl.start".equals(key)) {
+ mCtlStart = value;
+ } else {
+ throw new IllegalArgumentException("unexpected test key: " + key);
+ }
+ }
+
+ public String getCtlStart() {
+ return mCtlStart;
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
index 7986055..8cb5197 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
@@ -16,6 +16,7 @@
package com.android.server.rollback;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -58,8 +59,8 @@
// All users are unlocked so we should snapshot data for them.
doReturn(true).when(helper).isUserCredentialLocked(eq(10));
doReturn(true).when(helper).isUserCredentialLocked(eq(11));
- PackageRollbackInfo info = createPackageRollbackInfo("com.foo.bar", new int[]{10, 11});
- helper.snapshotAppData(5, info);
+ PackageRollbackInfo info = createPackageRollbackInfo("com.foo.bar");
+ helper.snapshotAppData(5, info, new int[]{10, 11});
assertEquals(2, info.getPendingBackups().size());
assertEquals(10, info.getPendingBackups().get(0));
@@ -79,8 +80,8 @@
doReturn(true).when(helper).isUserCredentialLocked(eq(11));
when(installer.snapshotAppData(anyString(), anyInt(), anyInt(), anyInt())).thenReturn(239L);
- PackageRollbackInfo info2 = createPackageRollbackInfo("com.foo.bar", new int[]{10, 11});
- helper.snapshotAppData(7, info2);
+ PackageRollbackInfo info2 = createPackageRollbackInfo("com.foo.bar");
+ helper.snapshotAppData(7, info2, new int[]{10, 11});
assertEquals(1, info2.getPendingBackups().size());
assertEquals(11, info2.getPendingBackups().get(0));
@@ -234,22 +235,22 @@
wasRecentlyRestored.getPendingRestores().add(
new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo"));
- RollbackData dataWithPendingBackup = new RollbackData(101, new File("/does/not/exist"), -1);
+ Rollback dataWithPendingBackup = new Rollback(101, new File("/does/not/exist"), -1);
dataWithPendingBackup.info.getPackages().add(pendingBackup);
- RollbackData dataWithRecentRestore = new RollbackData(17239, new File("/does/not/exist"),
+ Rollback dataWithRecentRestore = new Rollback(17239, new File("/does/not/exist"),
-1);
dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored);
- RollbackData dataForDifferentUser = new RollbackData(17239, new File("/does/not/exist"),
+ Rollback dataForDifferentUser = new Rollback(17239, new File("/does/not/exist"),
-1);
dataForDifferentUser.info.getPackages().add(ignoredInfo);
- RollbackData dataForRestore = new RollbackData(17239, new File("/does/not/exist"), -1);
+ Rollback dataForRestore = new Rollback(17239, new File("/does/not/exist"), -1);
dataForRestore.info.getPackages().add(pendingRestore);
dataForRestore.info.getPackages().add(wasRecentlyRestored);
- Set<RollbackData> changed = helper.commitPendingBackupAndRestoreForUser(37,
+ Set<Rollback> changed = helper.commitPendingBackupAndRestoreForUser(37,
Arrays.asList(dataWithPendingBackup, dataWithRecentRestore, dataForDifferentUser,
dataForRestore));
InOrder inOrder = Mockito.inOrder(installer);
@@ -264,7 +265,7 @@
assertEquals(-1, pendingBackup.getPendingBackups().indexOf(37));
assertEquals(53, pendingBackup.getCeSnapshotInodes().get(37));
- // Check that changed returns correct RollbackData.
+ // Check that changed returns correct Rollback.
assertEquals(3, changed.size());
assertTrue(changed.contains(dataWithPendingBackup));
assertTrue(changed.contains(dataWithRecentRestore));
@@ -278,4 +279,15 @@
inOrder.verifyNoMoreInteractions();
}
+
+ @Test
+ public void snapshotAddDataSavesSnapshottedUsersToInfo() {
+ Installer installer = mock(Installer.class);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+
+ PackageRollbackInfo info = createPackageRollbackInfo("com.foo.bar");
+ helper.snapshotAppData(5, info, new int[]{10, 11});
+
+ assertArrayEquals(info.getSnapshottedUsers().toArray(), new int[]{10, 11});
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index dcab78e..8cd6ef9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -98,7 +98,7 @@
suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
- priorityMessageSenders, suppressedVisualEffects);
+ priorityMessageSenders, suppressedVisualEffects, 0);
assertEquals(expectedPolicy, config.toNotificationPolicy(zenPolicy));
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 24b4046..3ecf8d7 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -25,8 +25,11 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import com.android.internal.telecom.IVideoProvider;
+
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
@@ -2132,13 +2135,22 @@
cannedTextResponsesChanged = true;
}
- VideoCallImpl newVideoCallImpl = parcelableCall.getVideoCallImpl(mCallingPackage,
- mTargetSdkVersion);
- boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
- !Objects.equals(mVideoCallImpl, newVideoCallImpl);
+ IVideoProvider previousVideoProvider = mVideoCallImpl == null ? null :
+ mVideoCallImpl.getVideoProvider();
+ IVideoProvider newVideoProvider = parcelableCall.getVideoProvider();
+
+ // parcelableCall.isVideoCallProviderChanged is only true when we have a video provider
+ // specified; so we should check if the actual IVideoProvider changes as well.
+ boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged()
+ && !Objects.equals(previousVideoProvider, newVideoProvider);
if (videoCallChanged) {
- mVideoCallImpl = newVideoCallImpl;
+ if (mVideoCallImpl != null) {
+ mVideoCallImpl.destroy();
+ }
+ mVideoCallImpl = parcelableCall.isVideoCallProviderChanged() ?
+ parcelableCall.getVideoCallImpl(mCallingPackage, mTargetSdkVersion) : null;
}
+
if (mVideoCallImpl != null) {
mVideoCallImpl.setVideoState(getDetails().getVideoState());
}
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index ef1c790..b91787c 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -106,8 +106,14 @@
SomeArgs args = (SomeArgs) msg.obj;
try {
mCallScreeningAdapter = (ICallScreeningAdapter) args.arg1;
- onScreenCall(
- Call.Details.createFromParcelableCall((ParcelableCall) args.arg2));
+ Call.Details callDetails = Call.Details
+ .createFromParcelableCall((ParcelableCall) args.arg2);
+ onScreenCall(callDetails);
+ if (callDetails.getCallDirection() == Call.Details.DIRECTION_OUTGOING) {
+ mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId());
+ }
+ } catch (RemoteException e) {
+ Log.w(this, "Exception when screening call: " + e);
} finally {
args.recycle();
}
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index d669e905..58abf00 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.SystemClock;
import android.telecom.Connection.VideoProvider;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index e2f5d0bb..4c22ba9 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -35,6 +35,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index ae92464..bebbbd0 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -97,6 +97,14 @@
*/
public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL";
+ /**
+ * This reason is set when a call is ended in order to place an emergency call when a
+ * {@link PhoneAccount} doesn't support holding an ongoing call to place an emergency call. This
+ * reason string should only be associated with the {@link #LOCAL} disconnect code returned from
+ * {@link #getCode()}.
+ */
+ public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED";
+
private int mDisconnectCode;
private CharSequence mDisconnectLabel;
private CharSequence mDisconnectDescription;
diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java
index 95a47e1..d82e93f 100644
--- a/telecomm/java/android/telecom/Logging/Session.java
+++ b/telecomm/java/android/telecom/Logging/Session.java
@@ -237,7 +237,10 @@
// keep track of calls and bail if we hit the recursion limit
private String getFullSessionId(int parentCount) {
if (parentCount >= SESSION_RECURSION_LIMIT) {
- Log.w(LOG_TAG, "getFullSessionId: Hit recursion limit!");
+ // Don't use Telecom's Log.w here or it will cause infinite recursion because it will
+ // try to add session information to this logging statement, which will cause it to hit
+ // this condition again and so on...
+ android.util.Slog.w(LOG_TAG, "getFullSessionId: Hit recursion limit!");
return TRUNCATE_STRING + mSessionId;
}
// Cache mParentSession locally to prevent a concurrency problem where
@@ -265,7 +268,11 @@
Session topNode = this;
while (topNode.getParentSession() != null) {
if (currParentCount >= SESSION_RECURSION_LIMIT) {
- Log.w(LOG_TAG, "getRootSession: Hit recursion limit from " + callingMethod);
+ // Don't use Telecom's Log.w here or it will cause infinite recursion because it
+ // will try to add session information to this logging statement, which will cause
+ // it to hit this condition again and so on...
+ android.util.Slog.w(LOG_TAG, "getRootSession: Hit recursion limit from "
+ + callingMethod);
break;
}
topNode = topNode.getParentSession();
@@ -289,7 +296,10 @@
private void printSessionTree(int tabI, StringBuilder sb, int currChildCount) {
// Prevent infinite recursion.
if (currChildCount >= SESSION_RECURSION_LIMIT) {
- Log.w(LOG_TAG, "printSessionTree: Hit recursion limit!");
+ // Don't use Telecom's Log.w here or it will cause infinite recursion because it will
+ // try to add session information to this logging statement, which will cause it to hit
+ // this condition again and so on...
+ android.util.Slog.w(LOG_TAG, "printSessionTree: Hit recursion limit!");
sb.append(TRUNCATE_STRING);
return;
}
@@ -315,7 +325,10 @@
private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath,
int parentCount) {
if (parentCount >= SESSION_RECURSION_LIMIT) {
- Log.w(LOG_TAG, "getFullMethodPath: Hit recursion limit!");
+ // Don't use Telecom's Log.w here or it will cause infinite recursion because it will
+ // try to add session information to this logging statement, which will cause it to hit
+ // this condition again and so on...
+ android.util.Slog.w(LOG_TAG, "getFullMethodPath: Hit recursion limit!");
sb.append(TRUNCATE_STRING);
return;
}
diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java
index 49c3a72..ac30058 100644
--- a/telecomm/java/android/telecom/Logging/SessionManager.java
+++ b/telecomm/java/android/telecom/Logging/SessionManager.java
@@ -202,7 +202,18 @@
return createSubsession(false);
}
- private synchronized Session createSubsession(boolean isStartedFromActiveSession) {
+ /**
+ * Creates a new subsession based on an existing session. Will not be started until
+ * {@link #continueSession(Session, String)} or {@link #cancelSubsession(Session)} is called.
+ * <p>
+ * Only public for testing!
+ * @param isStartedFromActiveSession true if this subsession is being created for a task on the
+ * same thread, false if it is being created for a related task on another thread.
+ * @return a new {@link Session}, call {@link #continueSession(Session, String)} to continue the
+ * session and {@link #endSession()} when done with this subsession.
+ */
+ @VisibleForTesting
+ public synchronized Session createSubsession(boolean isStartedFromActiveSession) {
int threadId = getCallingThreadId();
Session threadSession = mSessionMapper.get(threadId);
if (threadSession == null) {
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index aa50991..fdc3243 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -21,6 +21,7 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -225,6 +226,10 @@
return mVideoCall;
}
+ public IVideoProvider getVideoProvider() {
+ return mVideoCallProvider;
+ }
+
public boolean getIsRttCallChanged() {
return mIsRttCallChanged;
}
diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java
index cb74012..4a1aa0a 100644
--- a/telecomm/java/android/telecom/VideoCallImpl.java
+++ b/telecomm/java/android/telecom/VideoCallImpl.java
@@ -32,6 +32,8 @@
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
+import java.util.NoSuchElementException;
+
/**
* Implementation of a Video Call, which allows InCallUi to communicate commands to the underlying
* {@link Connection.VideoProvider}, and direct callbacks from the
@@ -53,7 +55,11 @@
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
- mVideoProvider.asBinder().unlinkToDeath(this, 0);
+ try {
+ mVideoProvider.asBinder().unlinkToDeath(this, 0);
+ } catch (NoSuchElementException nse) {
+ // Already unlinked in destroy below.
+ }
}
};
@@ -222,6 +228,11 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 127403196)
public void destroy() {
unregisterCallback(mCallback);
+ try {
+ mVideoProvider.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (NoSuchElementException nse) {
+ // Already unlinked in binderDied above.
+ }
}
/** {@inheritDoc} */
@@ -353,4 +364,12 @@
public void setVideoState(int videoState) {
mVideoState = videoState;
}
+
+ /**
+ * Get the video provider binder.
+ * @return the video provider binder.
+ */
+ public IVideoProvider getVideoProvider() {
+ return mVideoProvider;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
similarity index 100%
rename from telephony/java/com/android/internal/telephony/GsmAlphabet.java
rename to telephony/common/com/android/internal/telephony/GsmAlphabet.java
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index f79aef3..9da45da 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -195,7 +195,7 @@
* @return
*/
private static int getIncomingUserId(Context context) {
- int contextUserId = context.getUserId();
+ int contextUserId = UserHandle.myUserId();
final int callingUid = Binder.getCallingUid();
if (DEBUG_MULTIUSER) {
Log.i(LOG_TAG, "getIncomingUserHandle caller=" + callingUid + ", myuid="
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index d3728a6..087937d 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -16,6 +16,7 @@
package android.provider;
+import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
@@ -1126,8 +1127,9 @@
* values:</p>
*
* <ul>
- * <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message
- * data, including ETWS or CMAS warning notification info if present.</li>
+ * <li><em>"message"</em> - An {@link android.telephony.SmsCbMessage} object
+ * containing the broadcast message data, including ETWS or CMAS warning notification
+ * info if present.</li>
* </ul>
*
* <p>The extra values can be extracted using
@@ -1138,11 +1140,12 @@
*
* <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST} to
* receive.</p>
- * @removed
+ * @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
- "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
+ @SystemApi
+ public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED =
+ "android.provider.action.SMS_EMERGENCY_CB_RECEIVED";
/**
* Broadcast Action: A new CDMA SMS has been received containing Service Category
@@ -3944,10 +3947,11 @@
}
/**
- * Contains received SMS cell broadcast messages. More details are available in 3GPP TS 23.041.
+ * Contains received cell broadcast messages. More details are available in 3GPP TS 23.041.
* @hide
*/
@SystemApi
+ @TestApi
public static final class CellBroadcasts implements BaseColumns {
/**
@@ -3958,11 +3962,44 @@
/**
* The {@code content://} URI for this table.
+ * Only privileged framework components running on phone or network stack uid can
+ * query or modify this table.
*/
@NonNull
public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
/**
+ * The {@code content://} URI for query cellbroadcast message history.
+ * query results include following entries
+ * <ul>
+ * <li>{@link #_ID}</li>
+ * <li>{@link #SLOT_INDEX}</li>
+ * <li>{@link #GEOGRAPHICAL_SCOPE}</li>
+ * <li>{@link #PLMN}</li>
+ * <li>{@link #LAC}</li>
+ * <li>{@link #CID}</li>
+ * <li>{@link #SERIAL_NUMBER}</li>
+ * <li>{@link #SERVICE_CATEGORY}</li>
+ * <li>{@link #LANGUAGE_CODE}</li>
+ * <li>{@link #MESSAGE_BODY}</li>
+ * <li>{@link #DELIVERY_TIME}</li>
+ * <li>{@link #MESSAGE_READ}</li>
+ * <li>{@link #MESSAGE_FORMAT}</li>
+ * <li>{@link #MESSAGE_PRIORITY}</li>
+ * <li>{@link #ETWS_WARNING_TYPE}</li>
+ * <li>{@link #CMAS_MESSAGE_CLASS}</li>
+ * <li>{@link #CMAS_CATEGORY}</li>
+ * <li>{@link #CMAS_RESPONSE_TYPE}</li>
+ * <li>{@link #CMAS_SEVERITY}</li>
+ * <li>{@link #CMAS_URGENCY}</li>
+ * <li>{@link #CMAS_CERTAINTY}</li>
+ * </ul>
+ */
+ @RequiresPermission(Manifest.permission.READ_CELL_BROADCASTS)
+ @NonNull
+ public static final Uri MESSAGE_HISTORY_URI = Uri.parse("content://cellbroadcasts/history");
+
+ /**
* The subscription which received this cell broadcast message.
* @deprecated use {@link #SLOT_INDEX} instead.
* <P>Type: INTEGER</P>
@@ -3973,7 +4010,6 @@
/**
* The slot which received this cell broadcast message.
* <P>Type: INTEGER</P>
- * @hide
*/
public static final String SLOT_INDEX = "slot_index";
@@ -4151,14 +4187,12 @@
/**
* The timestamp in millisecond of when the device received the message.
* <P>Type: BIGINT</P>
- * @hide
*/
public static final String RECEIVED_TIME = "received_time";
/**
* Indicates that whether the message has been broadcasted to the application.
* <P>Type: BOOLEAN</P>
- * @hide
*/
public static final String MESSAGE_BROADCASTED = "message_broadcasted";
@@ -4194,7 +4228,6 @@
* "circle|0,0|100;polygon|0,0|0,1.5|1,1|1,0;circle|100.123,100|200.123"
*
* <P>Type: TEXT</P>
- * @hide
*/
public static final String GEOMETRIES = "geometries";
@@ -4206,7 +4239,6 @@
* for the alert.
*
* <P>Type: INTEGER</P>
- * @hide
*/
public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index afa35b4..a0aa60b 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -45,6 +45,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static final int TRANSPORT_TYPE_INVALID = -1;
/**
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index a884a70..72f758e 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -469,4 +469,44 @@
@Retention(RetentionPolicy.SOURCE)
public @interface DataFailureCause {
}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"PRECISE_CALL_STATE_"},
+ value = {
+ PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ PreciseCallState.PRECISE_CALL_STATE_IDLE,
+ PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+ PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+ PreciseCallState.PRECISE_CALL_STATE_DIALING,
+ PreciseCallState.PRECISE_CALL_STATE_ALERTING,
+ PreciseCallState. PRECISE_CALL_STATE_INCOMING,
+ PreciseCallState.PRECISE_CALL_STATE_WAITING,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
+ public @interface PreciseCallStates {}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = {
+ ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN,
+ ServiceState.RIL_RADIO_TECHNOLOGY_GPRS,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EDGE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_UMTS,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IS95A,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IS95B,
+ ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP,
+ ServiceState.RIL_RADIO_TECHNOLOGY_GSM,
+ ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_NR})
+ public @interface RilRadioTechnology {}
}
diff --git a/telephony/java/android/telephony/CallQuality.java b/telephony/java/android/telephony/CallQuality.java
index 028280c..e01deb2 100644
--- a/telephony/java/android/telephony/CallQuality.java
+++ b/telephony/java/android/telephony/CallQuality.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,6 +41,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class CallQuality implements Parcelable {
// Constants representing the call quality level (see #CallQuality);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e9249df2..a0aa892 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -809,7 +809,9 @@
/**
* The default flag specifying whether ETWS/CMAS test setting is forcibly disabled in
* Settings->More->Emergency broadcasts menu even though developer options is turned on.
+ * @deprecated moved to cellbroadcastreceiver resource show_test_settings
*/
+ @Deprecated
public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL =
"carrier_force_disable_etws_cmas_test_bool";
@@ -828,13 +830,6 @@
"disable_severe_when_extreme_disabled_bool";
/**
- * The message expiration time in milliseconds for duplicate detection purposes.
- * @hide
- */
- public static final String KEY_MESSAGE_EXPIRATION_TIME_LONG =
- "message_expiration_time_long";
-
- /**
* The data call retry configuration for different types of APN.
* @hide
*/
@@ -1750,6 +1745,15 @@
"allow_emergency_video_calls_bool";
/**
+ * Flag indicating whether or not an ongoing call will be held when an outgoing emergency call
+ * is placed. If true, ongoing calls will be put on hold when an emergency call is placed. If
+ * false, placing an emergency call will trigger the disconnect of all ongoing calls before
+ * the emergency call is placed.
+ */
+ public static final String KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL =
+ "allow_hold_call_during_emergency_bool";
+
+ /**
* Flag indicating whether the carrier supports RCS presence indication for
* User Capability Exchange (UCE). When presence is supported, the device should use the
* {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} bit mask and set the
@@ -2287,6 +2291,77 @@
"use_only_rsrp_for_lte_signal_bar_bool";
/**
+ * List of 4 customized 5G SS reference signal received power (SSRSRP) thresholds.
+ *
+ * Reference: 3GPP TS 38.215
+ *
+ * 4 threshold integers must be within the boundaries [-140 dB, -44 dB], and the levels are:
+ * "NONE: [-140, threshold1]"
+ * "POOR: (threshold1, threshold2]"
+ * "MODERATE: (threshold2, threshold3]"
+ * "GOOD: (threshold3, threshold4]"
+ * "EXCELLENT: (threshold4, -44]"
+ *
+ * This key is considered invalid if the format is violated. If the key is invalid or
+ * not configured, a default value set will apply.
+ */
+ public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY =
+ "5g_nr_ssrsrp_thresholds_int_array";
+
+ /**
+ * List of 4 customized 5G SS reference signal received quality (SSRSRQ) thresholds.
+ *
+ * Reference: 3GPP TS 38.215
+ *
+ * 4 threshold integers must be within the boundaries [-20 dB, -3 dB], and the levels are:
+ * "NONE: [-23, threshold1]"
+ * "POOR: (threshold1, threshold2]"
+ * "MODERATE: (threshold2, threshold3]"
+ * "GOOD: (threshold3, threshold4]"
+ * "EXCELLENT: (threshold4, -3]"
+ *
+ * This key is considered invalid if the format is violated. If the key is invalid or
+ * not configured, a default value set will apply.
+ */
+ public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY =
+ "5g_nr_ssrsrq_thresholds_int_array";
+
+ /**
+ * List of 4 customized 5G SS signal-to-noise and interference ratio (SSSINR) thresholds.
+ *
+ * Reference: 3GPP TS 38.215,
+ * 3GPP TS 38.133 10.1.16.1
+ *
+ * 4 threshold integers must be within the boundaries [-23 dB, 40 dB], and the levels are:
+ * "NONE: [-23, threshold1]"
+ * "POOR: (threshold1, threshold2]"
+ * "MODERATE: (threshold2, threshold3]"
+ * "GOOD: (threshold3, threshold4]"
+ * "EXCELLENT: (threshold4, 40]"
+ *
+ * This key is considered invalid if the format is violated. If the key is invalid or
+ * not configured, a default value set will apply.
+ */
+ public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY =
+ "5g_nr_sssinr_thresholds_int_array";
+
+ /**
+ * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
+ * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
+ * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
+ * parameter whose value is smallest is used to indicate the signal bar.
+ *
+ * SSRSRP = 1 << 0,
+ * SSRSRQ = 1 << 1,
+ * SSSINR = 1 << 2,
+ *
+ * Reference: 3GPP TS 38.215,
+ * 3GPP TS 38.133 10.1.16.1
+ */
+ public static final String KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT =
+ "parameters_use_for_5g_nr_signal_bar_int";
+
+ /**
* Key identifying if voice call barring notification is required to be shown to the user.
* @hide
*/
@@ -3316,7 +3391,6 @@
sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
- sDefaults.putLong(KEY_MESSAGE_EXPIRATION_TIME_LONG, 86400000L);
sDefaults.putStringArray(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS, new String[]{
"default:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
+ "320000:5000,640000:5000,1280000:5000,1800000:5000",
@@ -3436,6 +3510,7 @@
sDefaults.putString(KEY_MMS_USER_AGENT_STRING, "");
sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true);
sDefaults.putInt(KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0);
+ sDefaults.putBoolean(KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL, true);
sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false);
sDefaults.putBoolean(KEY_USE_RCS_SIP_OPTIONS_BOOL, false);
sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false);
diff --git a/telephony/java/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java
similarity index 94%
rename from telephony/java/com/android/internal/telephony/CbGeoUtils.java
rename to telephony/java/android/telephony/CbGeoUtils.java
index 0b73252..f4ce6e7 100644
--- a/telephony/java/com/android/internal/telephony/CbGeoUtils.java
+++ b/telephony/java/android/telephony/CbGeoUtils.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package android.telephony;
import android.annotation.NonNull;
-import android.telephony.Rlog;
+import android.annotation.SystemApi;
import android.text.TextUtils;
import java.util.ArrayList;
@@ -30,8 +30,17 @@
* The coordinates used by this utils class are latitude and longitude, but some algorithms in this
* class only use them as coordinates on plane, so the calculation will be inaccurate. So don't use
* this class for anything other then geo-targeting of cellbroadcast messages.
+ * @hide
*/
+@SystemApi
public class CbGeoUtils {
+
+ /**
+ * This class is never instantiated
+ * @hide
+ */
+ private CbGeoUtils() {}
+
/** Geometric interface. */
public interface Geometry {
/**
@@ -39,27 +48,36 @@
* @param p point in latitude, longitude format.
* @return {@code True} if the given point is inside the geometry.
*/
- boolean contains(LatLng p);
+ boolean contains(@NonNull LatLng p);
}
/**
* Tolerance for determining if the value is 0. If the absolute value of a value is less than
* this tolerance, it will be treated as 0.
+ * @hide
*/
public static final double EPS = 1e-7;
- /** The radius of earth. */
+ /**
+ * The radius of earth.
+ * @hide
+ */
public static final int EARTH_RADIUS_METER = 6371 * 1000;
private static final String TAG = "CbGeoUtils";
- /** The TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding. */
+ // The TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding.
+ /** @hide */
public static final int GEO_FENCING_MAXIMUM_WAIT_TIME = 0x01;
+ /** @hide */
public static final int GEOMETRY_TYPE_POLYGON = 0x02;
+ /** @hide */
public static final int GEOMETRY_TYPE_CIRCLE = 0x03;
- /** The identifier of geometry in the encoded string. */
+ // The identifier of geometry in the encoded string.
+ /** @hide */
private static final String CIRCLE_SYMBOL = "circle";
+ /** @hide */
private static final String POLYGON_SYMBOL = "polygon";
/** Point represent by (latitude, longitude). */
@@ -81,7 +99,8 @@
* @param p the point use to calculate the subtraction result.
* @return the result of this point subtract the given point {@code p}.
*/
- public LatLng subtract(LatLng p) {
+ @NonNull
+ public LatLng subtract(@NonNull LatLng p) {
return new LatLng(lat - p.lat, lng - p.lng);
}
@@ -90,7 +109,7 @@
* @param p the point use to calculate the distance.
* @return the distance in meter.
*/
- public double distance(LatLng p) {
+ public double distance(@NonNull LatLng p) {
double dlat = Math.sin(0.5 * Math.toRadians(lat - p.lat));
double dlng = Math.sin(0.5 * Math.toRadians(lng - p.lng));
double x = dlat * dlat
@@ -106,6 +125,7 @@
/**
* The class represents a simple polygon with at least 3 points.
+ * @hide
*/
public static class Polygon implements Geometry {
/**
@@ -239,7 +259,10 @@
}
}
- /** The class represents a circle. */
+ /**
+ * The class represents a circle.
+ * @hide
+ */
public static class Circle implements Geometry {
private final LatLng mCenter;
private final double mRadiusMeter;
@@ -266,6 +289,7 @@
/**
* Parse the geometries from the encoded string {@code str}. The string must follow the
* geometry encoding specified by {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+ * @hide
*/
@NonNull
public static List<Geometry> parseGeometriesFromString(@NonNull String str) {
@@ -297,6 +321,7 @@
*
* @param geometries the list of geometry objects need to be encoded.
* @return the encoded string.
+ * @hide
*/
@NonNull
public static String encodeGeometriesToString(List<Geometry> geometries) {
@@ -313,6 +338,7 @@
* {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
* @param geometry the geometry object need to be encoded.
* @return the encoded string.
+ * @hide
*/
@NonNull
private static String encodeGeometryToString(@NonNull Geometry geometry) {
@@ -351,6 +377,7 @@
*
* @param str encoded lat/lng string.
* @Return {@link LatLng} object.
+ * @hide
*/
@NonNull
public static LatLng parseLatLngFromString(@NonNull String str) {
@@ -361,6 +388,7 @@
/**
* @Return the sign of the given value {@code value} with the specified tolerance. Return 1
* means the sign is positive, -1 means negative, 0 means the value will be treated as 0.
+ * @hide
*/
public static int sign(double value) {
if (value > EPS) return 1;
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index 6df60ba..edc838c 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -62,6 +62,12 @@
}
/** @hide */
+ public CellIdentityNr(android.hardware.radio.V1_4.CellIdentityNr cid) {
+ this(cid.pci, cid.tac, cid.nrarfcn, cid.mcc, cid.mnc, cid.nci, cid.operatorNames.alphaLong,
+ cid.operatorNames.alphaShort);
+ }
+
+ /** @hide */
public CellIdentityNr sanitizeLocationInfo() {
return new CellIdentityNr(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
mMccStr, mMncStr, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort);
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index 18687d4..ae45307 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -374,6 +374,7 @@
case Info.hidl_discriminator.lte: return new CellInfoLte(ci, timeStamp);
case Info.hidl_discriminator.wcdma: return new CellInfoWcdma(ci, timeStamp);
case Info.hidl_discriminator.tdscdma: return new CellInfoTdscdma(ci, timeStamp);
+ case Info.hidl_discriminator.nr: return new CellInfoNr(ci, timeStamp);
default: return null;
}
}
diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java
index cea8323..8b41b8b 100644
--- a/telephony/java/android/telephony/CellInfoNr.java
+++ b/telephony/java/android/telephony/CellInfoNr.java
@@ -45,6 +45,14 @@
mCellSignalStrength = other.mCellSignalStrength;
}
+ /** @hide */
+ public CellInfoNr(android.hardware.radio.V1_4.CellInfo ci, long timeStamp) {
+ super(ci, timeStamp);
+ final android.hardware.radio.V1_4.CellInfoNr cil = ci.info.nr();
+ mCellIdentity = new CellIdentityNr(cil.cellidentity);
+ mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrength);
+ }
+
/**
* @return a {@link CellIdentityNr} instance.
*/
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 407ced7..270eafe 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -203,9 +203,12 @@
}
/**
+ * Get whether network has configured carrier aggregation or not.
+ *
* @return {@code true} if using carrier aggregation.
* @hide
*/
+ @SystemApi
public boolean isUsingCarrierAggregation() {
return mIsUsingCarrierAggregation;
}
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 85110c2..04ec4b6 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -354,6 +354,12 @@
*/
public static final int WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79;
+ /**
+ * Indicates that an emergency call was placed, which caused the existing connection to be
+ * hung up.
+ */
+ public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80;
+
//*********************************************************************************************
// When adding a disconnect type:
// 1) Update toString() with the newly added disconnect type.
@@ -528,6 +534,8 @@
return "EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE";
case WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
return "WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION";
+ case OUTGOING_EMERGENCY_CALL_PLACED:
+ return "OUTGOING_EMERGENCY_CALL_PLACED";
default:
return "INVALID: " + cause;
}
diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java
index ef2f121..75a79d6 100644
--- a/telephony/java/android/telephony/ImsiEncryptionInfo.java
+++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java
@@ -15,9 +15,11 @@
*/
package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.Date;
import android.util.Log;
import java.security.KeyFactory;
@@ -25,18 +27,18 @@
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
/**
* Class to represent information sent by the carrier, which will be used to encrypt
* the IMSI + IMPI. The ecryption is being done by WLAN, and the modem.
- *
* @hide
*/
+@SystemApi
public final class ImsiEncryptionInfo implements Parcelable {
private static final String LOG_TAG = "ImsiEncryptionInfo";
-
private final String mcc;
private final String mnc;
private final PublicKey publicKey;
@@ -45,11 +47,13 @@
//Date-Time in UTC when the key will expire.
private final Date expirationTime;
+ /** @hide */
public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
byte[] key, Date expirationTime) {
this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime);
}
+ /** @hide */
public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
PublicKey publicKey, Date expirationTime) {
// todo need to validate that ImsiEncryptionInfo is being created with the correct params.
@@ -63,6 +67,7 @@
this.expirationTime = expirationTime;
}
+ /** @hide */
public ImsiEncryptionInfo(Parcel in) {
int length = in.readInt();
byte b[] = new byte[length];
@@ -75,26 +80,40 @@
expirationTime = new Date(in.readLong());
}
+ /** @hide */
public String getMnc() {
return this.mnc;
}
+ /** @hide */
public String getMcc() {
return this.mcc;
}
+ /**
+ * Returns key identifier, a string that helps the authentication server to locate the
+ * private key to decrypt the permanent identity, or {@code null} when uavailable.
+ */
+ @Nullable
public String getKeyIdentifier() {
return this.keyIdentifier;
}
+ /** @hide */
public int getKeyType() {
return this.keyType;
}
+ /**
+ * Returns the carrier public key that is used for the IMSI encryption,
+ * or {@code null} when uavailable.
+ */
+ @Nullable
public PublicKey getPublicKey() {
return this.publicKey;
}
+ /** @hide */
public Date getExpirationTime() {
return this.expirationTime;
}
@@ -115,7 +134,7 @@
return 0;
}
- public static final @android.annotation.NonNull Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
+ public static final @NonNull Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
new Parcelable.Creator<ImsiEncryptionInfo>() {
@Override
public ImsiEncryptionInfo createFromParcel(Parcel in) {
@@ -129,7 +148,7 @@
};
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
byte[] b = publicKey.getEncoded();
dest.writeInt(b.length);
dest.writeByteArray(b);
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 3e02871..bbf746fc 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -323,9 +323,12 @@
public @Domain int getDomain() { return mDomain; }
/**
+ * Get the 5G NR connection state.
+ *
* @return the 5G NR connection state.
* @hide
*/
+ @SystemApi
public @NRState int getNrState() {
return mNrState;
}
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index f929649..9f75332 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -23,6 +23,7 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.PreciseCallStates;
import android.telephony.DisconnectCause;
import android.telephony.PreciseDisconnectCause;
@@ -48,22 +49,6 @@
@SystemApi
public final class PreciseCallState implements Parcelable {
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"PRECISE_CALL_STATE_"},
- value = {
- PRECISE_CALL_STATE_NOT_VALID,
- PRECISE_CALL_STATE_IDLE,
- PRECISE_CALL_STATE_ACTIVE,
- PRECISE_CALL_STATE_HOLDING,
- PRECISE_CALL_STATE_DIALING,
- PRECISE_CALL_STATE_ALERTING,
- PRECISE_CALL_STATE_INCOMING,
- PRECISE_CALL_STATE_WAITING,
- PRECISE_CALL_STATE_DISCONNECTED,
- PRECISE_CALL_STATE_DISCONNECTING})
- public @interface State {}
-
/** Call state is not valid (Not received a call state). */
public static final int PRECISE_CALL_STATE_NOT_VALID = -1;
/** Call state: No activity. */
@@ -85,9 +70,9 @@
/** Call state: Disconnecting. */
public static final int PRECISE_CALL_STATE_DISCONNECTING = 8;
- private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
- private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
- private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
private int mDisconnectCause = DisconnectCause.NOT_VALID;
private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
@@ -97,8 +82,9 @@
* @hide
*/
@UnsupportedAppUsage
- public PreciseCallState(@State int ringingCall, @State int foregroundCall,
- @State int backgroundCall, int disconnectCause,
+ public PreciseCallState(@PreciseCallStates int ringingCall,
+ @PreciseCallStates int foregroundCall,
+ @PreciseCallStates int backgroundCall, int disconnectCause,
int preciseDisconnectCause) {
mRingingCallState = ringingCall;
mForegroundCallState = foregroundCall;
@@ -131,21 +117,21 @@
/**
* Returns the precise ringing call state.
*/
- public @State int getRingingCallState() {
+ public @PreciseCallStates int getRingingCallState() {
return mRingingCallState;
}
/**
* Returns the precise foreground call state.
*/
- public @State int getForegroundCallState() {
+ public @PreciseCallStates int getForegroundCallState() {
return mForegroundCallState;
}
/**
* Returns the precise background call state.
*/
- public @State int getBackgroundCallState() {
+ public @PreciseCallStates int getBackgroundCallState() {
return mBackgroundCallState;
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index c575129..1e601cf 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -30,6 +30,7 @@
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.NetworkRegistrationInfo.Domain;
import android.telephony.NetworkRegistrationInfo.NRState;
import android.text.TextUtils;
@@ -155,32 +156,6 @@
*/
public static final int DUPLEX_MODE_TDD = 2;
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" },
- value = {
- RIL_RADIO_TECHNOLOGY_UNKNOWN,
- RIL_RADIO_TECHNOLOGY_GPRS,
- RIL_RADIO_TECHNOLOGY_EDGE,
- RIL_RADIO_TECHNOLOGY_UMTS,
- RIL_RADIO_TECHNOLOGY_IS95A,
- RIL_RADIO_TECHNOLOGY_IS95B,
- RIL_RADIO_TECHNOLOGY_1xRTT,
- RIL_RADIO_TECHNOLOGY_EVDO_0,
- RIL_RADIO_TECHNOLOGY_EVDO_A,
- RIL_RADIO_TECHNOLOGY_HSDPA,
- RIL_RADIO_TECHNOLOGY_HSUPA,
- RIL_RADIO_TECHNOLOGY_HSPA,
- RIL_RADIO_TECHNOLOGY_EVDO_B,
- RIL_RADIO_TECHNOLOGY_EHRPD,
- RIL_RADIO_TECHNOLOGY_LTE,
- RIL_RADIO_TECHNOLOGY_HSPAP,
- RIL_RADIO_TECHNOLOGY_GSM,
- RIL_RADIO_TECHNOLOGY_TD_SCDMA,
- RIL_RADIO_TECHNOLOGY_IWLAN,
- RIL_RADIO_TECHNOLOGY_LTE_CA,
- RIL_RADIO_TECHNOLOGY_NR})
- public @interface RilRadioTechnology {}
/**
* Available radio technologies for GSM, UMTS and CDMA.
* Duplicates the constants from hardware/radio/include/ril.h
@@ -988,6 +963,9 @@
case RIL_RADIO_TECHNOLOGY_LTE_CA:
rtString = "LTE_CA";
break;
+ case RIL_RADIO_TECHNOLOGY_NR:
+ rtString = "LTE_NR";
+ break;
default:
rtString = "Unexpected";
Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1406,9 +1384,12 @@
}
/**
+ * Get the 5G NR frequency range the device is currently registered.
+ *
* @return the frequency range of 5G NR.
* @hide
*/
+ @SystemApi
public @FrequencyRange int getNrFrequencyRange() {
return mNrFrequencyRange;
}
@@ -1486,44 +1467,44 @@
/** @hide */
public static int rilRadioTechnologyToNetworkType(@RilRadioTechnology int rat) {
switch(rat) {
- case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
+ case RIL_RADIO_TECHNOLOGY_GPRS:
return TelephonyManager.NETWORK_TYPE_GPRS;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
+ case RIL_RADIO_TECHNOLOGY_EDGE:
return TelephonyManager.NETWORK_TYPE_EDGE;
- case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
+ case RIL_RADIO_TECHNOLOGY_UMTS:
return TelephonyManager.NETWORK_TYPE_UMTS;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
+ case RIL_RADIO_TECHNOLOGY_HSDPA:
return TelephonyManager.NETWORK_TYPE_HSDPA;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
+ case RIL_RADIO_TECHNOLOGY_HSUPA:
return TelephonyManager.NETWORK_TYPE_HSUPA;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
+ case RIL_RADIO_TECHNOLOGY_HSPA:
return TelephonyManager.NETWORK_TYPE_HSPA;
- case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A:
- case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B:
+ case RIL_RADIO_TECHNOLOGY_IS95A:
+ case RIL_RADIO_TECHNOLOGY_IS95B:
return TelephonyManager.NETWORK_TYPE_CDMA;
- case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
+ case RIL_RADIO_TECHNOLOGY_1xRTT:
return TelephonyManager.NETWORK_TYPE_1xRTT;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
+ case RIL_RADIO_TECHNOLOGY_EVDO_0:
return TelephonyManager.NETWORK_TYPE_EVDO_0;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
+ case RIL_RADIO_TECHNOLOGY_EVDO_A:
return TelephonyManager.NETWORK_TYPE_EVDO_A;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
+ case RIL_RADIO_TECHNOLOGY_EVDO_B:
return TelephonyManager.NETWORK_TYPE_EVDO_B;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
+ case RIL_RADIO_TECHNOLOGY_EHRPD:
return TelephonyManager.NETWORK_TYPE_EHRPD;
- case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
+ case RIL_RADIO_TECHNOLOGY_LTE:
return TelephonyManager.NETWORK_TYPE_LTE;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
+ case RIL_RADIO_TECHNOLOGY_HSPAP:
return TelephonyManager.NETWORK_TYPE_HSPAP;
- case ServiceState.RIL_RADIO_TECHNOLOGY_GSM:
+ case RIL_RADIO_TECHNOLOGY_GSM:
return TelephonyManager.NETWORK_TYPE_GSM;
- case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+ case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
- case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN:
+ case RIL_RADIO_TECHNOLOGY_IWLAN:
return TelephonyManager.NETWORK_TYPE_IWLAN;
- case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
+ case RIL_RADIO_TECHNOLOGY_LTE_CA:
return TelephonyManager.NETWORK_TYPE_LTE_CA;
- case ServiceState.RIL_RADIO_TECHNOLOGY_NR:
+ case RIL_RADIO_TECHNOLOGY_NR:
return TelephonyManager.NETWORK_TYPE_NR;
default:
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
@@ -1554,6 +1535,7 @@
return AccessNetworkType.CDMA2000;
case RIL_RADIO_TECHNOLOGY_LTE:
case RIL_RADIO_TECHNOLOGY_LTE_CA:
+ case RIL_RADIO_TECHNOLOGY_NR:
return AccessNetworkType.EUTRAN;
case RIL_RADIO_TECHNOLOGY_IWLAN:
return AccessNetworkType.IWLAN;
@@ -1567,43 +1549,45 @@
public static int networkTypeToRilRadioTechnology(int networkType) {
switch(networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
- return ServiceState.RIL_RADIO_TECHNOLOGY_GPRS;
+ return RIL_RADIO_TECHNOLOGY_GPRS;
case TelephonyManager.NETWORK_TYPE_EDGE:
- return ServiceState.RIL_RADIO_TECHNOLOGY_EDGE;
+ return RIL_RADIO_TECHNOLOGY_EDGE;
case TelephonyManager.NETWORK_TYPE_UMTS:
- return ServiceState.RIL_RADIO_TECHNOLOGY_UMTS;
+ return RIL_RADIO_TECHNOLOGY_UMTS;
case TelephonyManager.NETWORK_TYPE_HSDPA:
- return ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA;
+ return RIL_RADIO_TECHNOLOGY_HSDPA;
case TelephonyManager.NETWORK_TYPE_HSUPA:
- return ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA;
+ return RIL_RADIO_TECHNOLOGY_HSUPA;
case TelephonyManager.NETWORK_TYPE_HSPA:
- return ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
+ return RIL_RADIO_TECHNOLOGY_HSPA;
case TelephonyManager.NETWORK_TYPE_CDMA:
- return ServiceState.RIL_RADIO_TECHNOLOGY_IS95A;
+ return RIL_RADIO_TECHNOLOGY_IS95A;
case TelephonyManager.NETWORK_TYPE_1xRTT:
- return ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT;
+ return RIL_RADIO_TECHNOLOGY_1xRTT;
case TelephonyManager.NETWORK_TYPE_EVDO_0:
- return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0;
+ return RIL_RADIO_TECHNOLOGY_EVDO_0;
case TelephonyManager.NETWORK_TYPE_EVDO_A:
- return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A;
+ return RIL_RADIO_TECHNOLOGY_EVDO_A;
case TelephonyManager.NETWORK_TYPE_EVDO_B:
- return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B;
+ return RIL_RADIO_TECHNOLOGY_EVDO_B;
case TelephonyManager.NETWORK_TYPE_EHRPD:
- return ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD;
+ return RIL_RADIO_TECHNOLOGY_EHRPD;
case TelephonyManager.NETWORK_TYPE_LTE:
- return ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+ return RIL_RADIO_TECHNOLOGY_LTE;
case TelephonyManager.NETWORK_TYPE_HSPAP:
- return ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP;
+ return RIL_RADIO_TECHNOLOGY_HSPAP;
case TelephonyManager.NETWORK_TYPE_GSM:
- return ServiceState.RIL_RADIO_TECHNOLOGY_GSM;
+ return RIL_RADIO_TECHNOLOGY_GSM;
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
- return ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA;
+ return RIL_RADIO_TECHNOLOGY_TD_SCDMA;
case TelephonyManager.NETWORK_TYPE_IWLAN:
- return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
+ return RIL_RADIO_TECHNOLOGY_IWLAN;
case TelephonyManager.NETWORK_TYPE_LTE_CA:
- return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
+ return RIL_RADIO_TECHNOLOGY_LTE_CA;
+ case TelephonyManager.NETWORK_TYPE_NR:
+ return RIL_RADIO_TECHNOLOGY_NR;
default:
- return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
+ return RIL_RADIO_TECHNOLOGY_UNKNOWN;
}
}
@@ -1692,7 +1676,8 @@
|| radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
|| radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
|| radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
- || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
}
@@ -1968,8 +1953,11 @@
/**
* The current registered raw data network operator name in long alphanumeric format.
*
+ * @return long raw name of operator, null if unregistered or unknown
* @hide
*/
+ @Nullable
+ @SystemApi
public String getOperatorAlphaLongRaw() {
return mOperatorAlphaLongRaw;
}
@@ -1984,8 +1972,11 @@
/**
* The current registered raw data network operator name in short alphanumeric format.
*
+ * @return short raw name of operator, null if unregistered or unknown
* @hide
*/
+ @Nullable
+ @SystemApi
public String getOperatorAlphaShortRaw() {
return mOperatorAlphaShortRaw;
}
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
index adf7154..663e8e2 100644
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ b/telephony/java/android/telephony/SmsCbLocation.java
@@ -65,9 +65,12 @@
/**
* Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
* the same object can be reused for multiple broadcasts.
- * @hide
+ *
+ * @param plmn the MCC/MNC of the network
+ * @param lac the GSM location area code, or UMTS service area code
+ * @param cid the GSM or UMTS cell ID
*/
- public SmsCbLocation(String plmn, int lac, int cid) {
+ public SmsCbLocation(@NonNull String plmn, int lac, int cid) {
mPlmn = plmn;
mLac = lac;
mCid = cid;
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
index dc991b9..737ead1 100644
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ b/telephony/java/android/telephony/SmsCbMessage.java
@@ -25,9 +25,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Telephony.CellBroadcasts;
-
-import com.android.internal.telephony.CbGeoUtils;
-import com.android.internal.telephony.CbGeoUtils.Geometry;
+import android.telephony.CbGeoUtils.Geometry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -140,8 +138,8 @@
public @interface MessagePriority {}
/**
- * ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12.
- * @hide
+ * Integer indicating that the maximum wait time is not set.
+ * Based on ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12.
*/
public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255;
@@ -211,6 +209,7 @@
/**
* Create a new SmsCbMessage with the specified data.
+ * @hide
*/
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
@NonNull SmsCbLocation location, int serviceCategory, @Nullable String language,
@@ -223,14 +222,14 @@
}
/**
- * Create a new {@link SmsCbMessage} with the warning area coordinates information.
- * @hide
+ * Create a new {@link SmsCbMessage} with the specified data, including warning area
+ * coordinates information.
*/
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
- SmsCbLocation location, int serviceCategory, String language, String body,
- int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo,
- int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis,
- int slotIndex) {
+ @NonNull SmsCbLocation location, int serviceCategory, @Nullable String language,
+ @Nullable String body, int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo,
+ @Nullable SmsCbCmasInfo cmasWarningInfo, int maximumWaitTimeSec,
+ @Nullable List<Geometry> geometries, long receivedTimeMillis, int slotIndex) {
mMessageFormat = messageFormat;
mGeographicalScope = geographicalScope;
mSerialNumber = serialNumber;
@@ -414,9 +413,8 @@
/**
* Get the Geo-Fencing Maximum Wait Time.
* @return the time in second.
- * @hide
*/
- public int getMaximumWaitingTime() {
+ public int getMaximumWaitingDuration() {
return mMaximumWaitTimeSec;
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 54e87af..daeacf8 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -520,7 +520,6 @@
throw new IllegalArgumentException("Invalid message body");
}
- final Context context = ActivityThread.currentApplication().getApplicationContext();
// We will only show the SMS disambiguation dialog in the case that the message is being
// persisted. This is for two reasons:
// 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
@@ -629,7 +628,6 @@
final int finalPriority = priority;
final int finalValidity = validityPeriod;
- final Context context = ActivityThread.currentApplication().getApplicationContext();
// We will only show the SMS disambiguation dialog in the case that the message is being
// persisted. This is for two reasons:
// 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
@@ -933,7 +931,6 @@
}
if (parts.size() > 1) {
- final Context context = ActivityThread.currentApplication().getApplicationContext();
// We will only show the SMS disambiguation dialog in the case that the message is being
// persisted. This is for two reasons:
// 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
@@ -1174,7 +1171,6 @@
if (parts.size() > 1) {
final int finalPriority = priority;
final int finalValidity = validityPeriod;
- final Context context = ActivityThread.currentApplication().getApplicationContext();
if (persistMessage) {
resolveSubscriptionForOperation(new SubscriptionResolverResult() {
@Override
@@ -1331,7 +1327,6 @@
throw new IllegalArgumentException("Invalid message data");
}
- final Context context = ActivityThread.currentApplication().getApplicationContext();
resolveSubscriptionForOperation(new SubscriptionResolverResult() {
@Override
public void onSuccess(int subId) {
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 36e8123..58f2858 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -551,7 +551,6 @@
*
* @param context Context of the application to check.
* @return whether the app is authorized to manage this subscription per its metadata.
- * @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
* @deprecated - Do not use.
*/
@@ -567,15 +566,11 @@
* @param context Any context.
* @param packageName Package name of the app to check.
* @return whether the app is authorized to manage this subscription per its metadata.
- * @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
* @deprecated - Do not use.
*/
@Deprecated
public boolean canManageSubscription(Context context, String packageName) {
- if (!isEmbedded()) {
- throw new UnsupportedOperationException("Not an embedded subscription");
- }
List<UiccAccessRule> allAccessRules = getAllAccessRules();
if (allAccessRules == null) {
return false;
@@ -585,7 +580,8 @@
try {
packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException("Unknown package: " + packageName, e);
+ Log.d("SubscriptionInfo", "canManageSubscription: Unknown package: " + packageName, e);
+ return false;
}
for (UiccAccessRule rule : allAccessRules) {
if (rule.getCarrierPrivilegeStatus(packageInfo)
@@ -606,9 +602,6 @@
*/
@SystemApi
public @Nullable List<UiccAccessRule> getAccessRules() {
- if (!isEmbedded()) {
- throw new UnsupportedOperationException("Not an embedded subscription");
- }
if (mNativeAccessRules == null) return null;
return Arrays.asList(mNativeAccessRules);
}
@@ -619,11 +612,10 @@
* @hide
*/
public @Nullable List<UiccAccessRule> getAllAccessRules() {
- if (!isEmbedded()) {
- throw new UnsupportedOperationException("Not an embedded subscription");
- }
List<UiccAccessRule> merged = new ArrayList<>();
- if (mNativeAccessRules != null) merged.addAll(getAccessRules());
+ if (mNativeAccessRules != null) {
+ merged.addAll(getAccessRules());
+ }
if (mCarrierConfigAccessRules != null) {
merged.addAll(Arrays.asList(mCarrierConfigAccessRules));
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index b35549e..3c890a1 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -49,6 +49,7 @@
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
@@ -60,11 +61,10 @@
import android.telephony.ims.ImsMmTelManager;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
-import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ISub;
-import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.Preconditions;
@@ -77,6 +77,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@@ -159,6 +160,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
/**
@@ -178,6 +180,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "advanced_calling");
@@ -196,6 +199,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
/**
@@ -213,6 +217,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "wfc_roaming_mode");
@@ -232,6 +237,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "vt_enabled");
@@ -250,6 +256,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "wfc_roaming_enabled");
@@ -905,6 +912,11 @@
private final Context mContext;
private volatile INetworkPolicyManager mNetworkPolicy;
+ // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
+ // the Context and subId.
+ private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
+ new ConcurrentHashMap<>();
+
/**
* A listener class for monitoring changes to {@link SubscriptionInfo} records.
* <p>
@@ -925,20 +937,24 @@
OnSubscriptionsChangedListenerHandler(Looper looper) {
super(looper);
}
-
- @Override
- public void handleMessage(Message msg) {
- if (DBG) {
- log("handleMessage: invoke the overriden onSubscriptionsChanged()");
- }
- OnSubscriptionsChangedListener.this.onSubscriptionsChanged();
- }
}
- private final Handler mHandler;
+ /**
+ * Posted executor callback on the handler associated with a given looper.
+ * The looper can be the calling thread's looper or the looper passed from the
+ * constructor {@link #OnSubscriptionsChangedListener(Looper)}.
+ */
+ private final HandlerExecutor mExecutor;
+
+ /**
+ * @hide
+ */
+ public HandlerExecutor getHandlerExecutor() {
+ return mExecutor;
+ }
public OnSubscriptionsChangedListener() {
- mHandler = new OnSubscriptionsChangedListenerHandler();
+ mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler());
}
/**
@@ -947,7 +963,7 @@
* @hide
*/
public OnSubscriptionsChangedListener(Looper looper) {
- mHandler = new OnSubscriptionsChangedListenerHandler(looper);
+ mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper));
}
/**
@@ -959,18 +975,6 @@
if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
}
- /**
- * The callback methods need to be called on the handler thread where
- * this object was created. If the binder did that for us it'd be nice.
- */
- IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
- @Override
- public void onSubscriptionsChanged() {
- if (DBG) log("callback: received, sendEmptyMessage(0) to handler");
- mHandler.sendEmptyMessage(0);
- }
- };
-
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
@@ -1012,21 +1016,19 @@
* onSubscriptionsChanged overridden.
*/
public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ if (listener == null) return;
String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {
logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
+ " listener=" + listener);
}
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available. Where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.addOnSubscriptionsChangedListener(pkgName, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available. Where as SubscriptionController could crash and not be available
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
+ listener.mExecutor);
}
}
@@ -1038,21 +1040,18 @@
* @param listener that is to be unregistered.
*/
public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ if (listener == null) return;
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {
logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
+ " listener=" + listener);
}
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available where as SubscriptionController could crash and not be available
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
}
}
@@ -1071,7 +1070,6 @@
* for #onOpportunisticSubscriptionsChanged to be invoked.
*/
public static class OnOpportunisticSubscriptionsChangedListener {
- private Executor mExecutor;
/**
* Callback invoked when there is any change to any SubscriptionInfo. Typically
* this method would invoke {@link #getActiveSubscriptionInfoList}
@@ -1080,27 +1078,6 @@
if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
}
- private void setExecutor(Executor executor) {
- mExecutor = executor;
- }
-
- /**
- * The callback methods need to be called on the handler thread where
- * this object was created. If the binder did that for us it'd be nice.
- */
- IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
- @Override
- public void onSubscriptionsChanged() {
- final long identity = Binder.clearCallingIdentity();
- try {
- if (DBG) log("onOpportunisticSubscriptionsChanged callback received.");
- mExecutor.execute(() -> onOpportunisticSubscriptionsChanged());
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- };
-
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
@@ -1127,18 +1104,13 @@
+ " listener=" + listener);
}
- listener.setExecutor(executor);
-
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available. Where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available where as SubscriptionController could crash and not be available
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
+ listener, executor);
}
}
@@ -1158,16 +1130,10 @@
logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
+ pkgForDebug + " listener=" + listener);
}
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
}
}
@@ -2345,8 +2311,20 @@
* @return Resources associated with Subscription.
* @hide
*/
+ @NonNull
public static Resources getResourcesForSubId(Context context, int subId,
boolean useRootLocale) {
+ // Check if resources for this context and subId already exist in the resource cache.
+ // Resources that use the root locale are not cached.
+ Pair<Context, Integer> cacheKey = null;
+ if (isValidSubscriptionId(subId) && !useRootLocale) {
+ cacheKey = Pair.create(context, subId);
+ if (sResourcesCache.containsKey(cacheKey)) {
+ // Cache hit. Use cached Resources.
+ return sResourcesCache.get(cacheKey);
+ }
+ }
+
final SubscriptionInfo subInfo =
SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
@@ -2366,7 +2344,13 @@
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
DisplayMetrics newMetrics = new DisplayMetrics();
newMetrics.setTo(metrics);
- return new Resources(context.getResources().getAssets(), newMetrics, newConfig);
+ Resources res = new Resources(context.getResources().getAssets(), newMetrics, newConfig);
+
+ if (cacheKey != null) {
+ // Save the newly created Resources in the resource cache.
+ sResourcesCache.put(cacheKey, res);
+ }
+ return res;
}
/**
@@ -2624,7 +2608,6 @@
*
* @param info The subscription to check.
* @return whether the app is authorized to manage this subscription per its metadata.
- * @throws IllegalArgumentException if this subscription is not embedded.
*/
public boolean canManageSubscription(SubscriptionInfo info) {
return canManageSubscription(info, mContext.getPackageName());
@@ -2640,14 +2623,10 @@
* @param info The subscription to check.
* @param packageName Package name of the app to check.
* @return whether the app is authorized to manage this subscription per its access rules.
- * @throws IllegalArgumentException if this subscription is not embedded.
* @hide
*/
public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
- if (!info.isEmbedded()) {
- throw new IllegalArgumentException("Not an embedded subscription");
- }
- if (info.getAllAccessRules() == null) {
+ if (info == null || info.getAllAccessRules() == null) {
return false;
}
PackageManager packageManager = mContext.getPackageManager();
@@ -2655,7 +2634,8 @@
try {
packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException("Unknown package: " + packageName, e);
+ logd("Unknown package: " + packageName);
+ return false;
}
for (UiccAccessRule rule : info.getAllAccessRules()) {
if (rule.getCarrierPrivilegeStatus(packageInfo)
@@ -3048,7 +3028,7 @@
// to the caller.
boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
.hasCarrierPrivileges(info.getSubscriptionId())
- || (info.isEmbedded() && canManageSubscription(info));
+ || canManageSubscription(info);
return hasCarrierPrivilegePermission;
}
@@ -3226,13 +3206,14 @@
}
/**
- * Get active data subscription id.
+ * Get active data subscription id. Active data subscription refers to the subscription
+ * currently chosen to provide cellular internet connection to the user. This may be
+ * different from getDefaultDataSubscriptionId(). Eg. Opportunistics data
+ *
* See {@link PhoneStateListener#onActiveDataSubscriptionIdChanged(int)} for the details.
*
- * @return Active data subscription id
- *
- * //TODO: Refactor this API in b/134702460
- * @hide
+ * @return Active data subscription id if any is chosen, or
+ * SubscriptionManager.INVALID_SUBSCRIPTION_ID if not.
*/
public static int getActiveDataSubscriptionId() {
try {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 17ef4bc..e99465d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -200,12 +200,29 @@
/** @hide */
static public final int OTASP_SIM_UNPROVISIONED = 5;
- /** @hide */
+ /**
+ * Used in carrier Wi-Fi for IMSI + IMPI encryption, this indicates a public key that's
+ * available for use in ePDG links.
+ *
+ * @hide
+ */
+ @SystemApi
static public final int KEY_TYPE_EPDG = 1;
- /** @hide */
+ /**
+ * Used in carrier Wi-Fi for IMSI + IMPI encryption, this indicates a public key that's
+ * available for use in WLAN links.
+ *
+ * @hide
+ */
+ @SystemApi
static public final int KEY_TYPE_WLAN = 2;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"KEY_TYPE_"}, value = {KEY_TYPE_EPDG, KEY_TYPE_WLAN})
+ public @interface KeyType {}
+
/**
* No Single Radio Voice Call Continuity (SRVCC) handover is active.
* See TS 23.216 for more information.
@@ -1633,12 +1650,11 @@
* Returns the software version number for the device, for example,
* the IMEI/SV for GSM phones. Return null if the software version is
* not available.
- *
- * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+ * <p>
+ * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}.
*/
- @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @Nullable
public String getDeviceSoftwareVersion() {
return getDeviceSoftwareVersion(getSlotIndex());
}
@@ -1647,12 +1663,16 @@
* Returns the software version number for the device, for example,
* the IMEI/SV for GSM phones. Return null if the software version is
* not available.
+ * <p>
+ * Requires Permission: READ_PRIVILEGED_PHONE_STATE.
*
* @param slotIndex of which deviceID is returned
+ *
+ * @hide
*/
- /** {@hide} */
- @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
- @UnsupportedAppUsage
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @Nullable
public String getDeviceSoftwareVersion(int slotIndex) {
ITelephony telephony = getITelephony();
if (telephony == null) return null;
@@ -2781,6 +2801,8 @@
/** Class of broadly defined "4G" networks. {@hide} */
@UnsupportedAppUsage
public static final int NETWORK_CLASS_4_G = 3;
+ /** Class of broadly defined "5G" networks. {@hide} */
+ public static final int NETWORK_CLASS_5_G = 4;
/**
* Return general class of network type, such as "3G" or "4G". In cases
@@ -2813,6 +2835,8 @@
case NETWORK_TYPE_IWLAN:
case NETWORK_TYPE_LTE_CA:
return NETWORK_CLASS_4_G;
+ case NETWORK_TYPE_NR:
+ return NETWORK_CLASS_5_G;
default:
return NETWORK_CLASS_UNKNOWN;
}
@@ -3807,25 +3831,27 @@
}
/**
- * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
- * This includes the public key and the key identifier. For multi-sim devices, if no subId
- * has been specified, we will return the value for the dafault data sim.
- * Return null if it is unavailable.
+ * Returns carrier specific information that will be used to encrypt the IMSI and IMPI,
+ * including the public key and the key identifier; or {@code null} if not available.
* <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- * @param keyType whether the key is being used for wlan or epdg. Valid key types are
- * {@link TelephonyManager#KEY_TYPE_EPDG} or
- * {@link TelephonyManager#KEY_TYPE_WLAN}.
+ * For a multi-sim device, the dafault data sim is used if not specified.
+ * <p>
+ * Requires Permission: READ_PRIVILEGED_PHONE_STATE.
+ *
+ * @param keyType whether the key is being used for EPDG or WLAN. Valid values are
+ * {@link #KEY_TYPE_EPDG} or {@link #KEY_TYPE_WLAN}.
* @return ImsiEncryptionInfo Carrier specific information that will be used to encrypt the
* IMSI and IMPI. This includes the public key and the key identifier. This information
- * will be stored in the device keystore. The system will return a null when no key was
- * found, and the carrier does not require a key. The system will throw
- * IllegalArgumentException when an invalid key is sent or when key is required but
+ * will be stored in the device keystore. {@code null} will be returned when no key is
+ * found, and the carrier does not require a key.
+ * @throws IllegalArgumentException when an invalid key is found or when key is required but
* not found.
* @hide
*/
- public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @SystemApi
+ @Nullable
+ public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(@KeyType int keyType) {
try {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null) {
@@ -3853,14 +3879,21 @@
}
/**
- * Resets the Carrier Keys in the database. This involves 2 steps:
+ * Resets the carrier keys used to encrypt the IMSI and IMPI.
+ * <p>
+ * This involves 2 steps:
* 1. Delete the keys from the database.
* 2. Send an intent to download new Certificates.
* <p>
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ * For a multi-sim device, the dafault data sim is used if not specified.
+ * <p>
+ * Requires Permission: MODIFY_PHONE_STATE.
+ *
+ * @see #getCarrierInfoForImsiEncryption
* @hide
*/
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @SystemApi
public void resetCarrierKeysForImsiEncryption() {
try {
IPhoneSubInfo info = getSubscriberInfo();
@@ -3887,7 +3920,7 @@
* @return true if the digit at position keyType is 1, else false.
* @hide
*/
- private static boolean isKeyEnabled(int keyAvailability, int keyType) {
+ private static boolean isKeyEnabled(int keyAvailability, @KeyType int keyType) {
int returnValue = (keyAvailability >> (keyType - 1)) & 1;
return (returnValue == 1) ? true : false;
}
@@ -3896,7 +3929,7 @@
* If Carrier requires Imsi to be encrypted.
* @hide
*/
- private boolean isImsiEncryptionRequired(int subId, int keyType) {
+ private boolean isImsiEncryptionRequired(int subId, @KeyType int keyType) {
CarrierConfigManager configManager =
(CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager == null) {
@@ -4095,6 +4128,7 @@
* @hide
* nobody seems to call this.
*/
+ @UnsupportedAppUsage
@TestApi
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
public String getLine1AlphaTag() {
@@ -7665,8 +7699,8 @@
*/
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@SystemApi
- public boolean isTetherApnRequired() {
- return isTetherApnRequired(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
+ public boolean isTetheringApnRequired() {
+ return isTetheringApnRequired(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
}
/**
@@ -7676,11 +7710,11 @@
* @return {@code true} if DUN APN is required for tethering.
* @hide
*/
- public boolean isTetherApnRequired(int subId) {
+ public boolean isTetheringApnRequired(int subId) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.isTetherApnRequiredForSubscriber(subId);
+ return telephony.isTetheringApnRequiredForSubscriber(subId);
} catch (RemoteException ex) {
Rlog.e(TAG, "hasMatchedTetherApnSetting RemoteException", ex);
} catch (NullPointerException ex) {
@@ -7934,6 +7968,7 @@
/** @hide */
@SystemApi
+ @TestApi
public List<String> getCarrierPackageNamesForIntent(Intent intent) {
return getCarrierPackageNamesForIntentAndPhone(intent, getPhoneId());
}
@@ -8797,7 +8832,10 @@
@Deprecated
public boolean isTtyModeSupported() {
try {
- TelecomManager telecomManager = TelecomManager.from(mContext);
+ TelecomManager telecomManager = null;
+ if (mContext != null) {
+ telecomManager = mContext.getSystemService(TelecomManager.class);
+ }
if (telecomManager != null) {
return telecomManager.isTtySupported();
}
@@ -10602,6 +10640,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public int getCarrierIdListVersion() {
try {
@@ -11490,6 +11529,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
@TestApi
public Pair<Integer, Integer> getRadioHalVersion() {
try {
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 0025c7a..cb66a96 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -189,6 +189,29 @@
"android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED";
/**
+ * Intent action sent by a carrier app to launch the eSIM activation flow provided by the LPA UI
+ * (LUI). The carrier app must send this intent with one of the following:
+ *
+ * <p>{@link #EXTRA_USE_QR_SCANNER} not set or set to false: The LPA should try to get an
+ * activation code from the carrier app by binding to the carrier app service implementing
+ * {@link android.service.euicc.EuiccService#ACTION_BIND_CARRIER_PROVISIONING_SERVICE}.
+ * <p>{@link #EXTRA_USE_QR_SCANNER} set to true: The LPA should launch a QR scanner for the user
+ * to scan an eSIM profile QR code.
+ *
+ * <p>Upon completion, the LPA should return one of the following results to the carrier app:
+ *
+ * <p>{@code Activity.RESULT_OK}: The LPA has succeeded in downloading the new eSIM profile.
+ * <p>{@code Activity.RESULT_CANCELED}: The carrier app should treat this as if the user pressed
+ * the back button.
+ * <p>Anything else: The carrier app should treat this as an error.
+ *
+ * <p>LPA needs to check if caller's package name is allowed to perform this action.
+ **/
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_START_EUICC_ACTIVATION =
+ "android.telephony.euicc.action.START_EUICC_ACTIVATION";
+
+ /**
* Result code for an operation indicating that the operation succeeded.
*/
public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0;
@@ -342,10 +365,20 @@
*
* @hide
*/
- // TODO: Make this a @SystemApi.
+ @SystemApi
public static final String EXTRA_PHYSICAL_SLOT_ID =
"android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
+
+ /**
+ * Key for an extra set on actions {@link #ACTION_START_EUICC_ACTIVATION} providing a boolean
+ * value of whether to start eSIM activation with QR scanner.
+ *
+ * <p>Expected type of the extra data: boolean
+ **/
+ public static final String EXTRA_USE_QR_SCANNER =
+ "android.telephony.euicc.extra.USE_QR_SCANNER";
+
/**
* Optional meta-data attribute for a carrier app providing an icon to use to represent the
* carrier. If not provided, the app's launcher icon will be used as a fallback.
@@ -830,7 +863,7 @@
* @param callbackIntent a PendingIntent to launch when the operation completes.
*
* @deprecated From R, callers should specify a flag for specific set of subscriptions to erase
- * and use {@link #eraseSubscriptionsWithOptions(int, PendingIntent)} instead
+ * and use {@link #eraseSubscriptions(int, PendingIntent)} instead
*
* @hide
*/
@@ -862,7 +895,7 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
- public void eraseSubscriptionsWithOptions(
+ public void eraseSubscriptions(
@ResetOption int options, @NonNull PendingIntent callbackIntent) {
if (!isEnabled()) {
sendUnavailableError(callbackIntent);
diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
index 79cdfef..9f09d7a 100644
--- a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
+++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsCallForwardInfo implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 4ddeb90..b0ff5dc 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.Parcel;
@@ -45,6 +46,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsCallProfile implements Parcelable {
private static final String TAG = "ImsCallProfile";
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index a09844d..e11886f 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.RemoteException;
import android.telephony.CallQuality;
import android.telephony.ims.aidl.IImsCallSessionListener;
@@ -36,6 +37,7 @@
// TODO: APIs in here do not conform to API guidelines yet. This can be changed if
// ImsCallSessionListenerConverter is also changed.
@SystemApi
+@TestApi
public class ImsCallSessionListener {
private final IImsCallSessionListener mListener;
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index df0cc3a..8d2049b 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,6 +38,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsConferenceState implements Parcelable {
private static final String TAG = "ImsConferenceState";
/**
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index 6187e67..39af2e7 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.pm.PackageManager;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
@@ -32,6 +33,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsException extends Exception {
/**
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 8d83257..dcb9c9d 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,6 +34,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsExternalCallState implements Parcelable {
private static final String TAG = "ImsExternalCallState";
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 9fc8e75..5fd0af5 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -24,6 +24,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.Binder;
import android.os.RemoteException;
@@ -58,6 +59,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsMmTelManager implements RegistrationManager {
/**
@@ -977,25 +979,25 @@
/**
* Get the status of the MmTel Feature registered on this subscription.
+ * @param executor The executor that will be used to call the callback.
* @param callback A callback containing an Integer describing the current state of the
* MmTel feature, Which will be one of the following:
* {@link ImsFeature#STATE_UNAVAILABLE},
* {@link ImsFeature#STATE_INITIALIZING},
* {@link ImsFeature#STATE_READY}. Will be called using the executor
* specified when the service state has been retrieved from the IMS service.
- * @param executor The executor that will be used to call the callback.
* @throws ImsException if the IMS service associated with this subscription is not available or
* the IMS service is not available.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void getFeatureState(@NonNull @ImsFeature.ImsState Consumer<Integer> callback,
- @NonNull @CallbackExecutor Executor executor) throws ImsException {
- if (callback == null) {
- throw new IllegalArgumentException("Must include a non-null Consumer.");
- }
+ public void getFeatureState(@NonNull @CallbackExecutor Executor executor,
+ @NonNull @ImsFeature.ImsState Consumer<Integer> callback) throws ImsException {
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
+ if (callback == null) {
+ throw new IllegalArgumentException("Must include a non-null Consumer.");
+ }
try {
getITelephony().getImsMmTelFeatureState(mSubId, new IIntegerConsumer.Stub() {
@Override
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 1e0d9a78..9f7ec22 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsReasonInfo implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index e6777c17..62bc2ae 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -17,6 +17,7 @@
package android.telephony.ims;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
@@ -90,6 +91,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsService extends Service {
private static final String LOG_TAG = "ImsService";
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index ec2ff6c..6b72859 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Rlog;
@@ -35,6 +36,7 @@
* {@hide}
*/
@SystemApi
+@TestApi
public final class ImsSsData implements Parcelable {
private static final String TAG = ImsSsData.class.getCanonicalName();
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index 0510a00..77bd984 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,6 +38,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsSsInfo implements Parcelable {
/**@hide*/
diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
index c1f059e..b7ab0a0 100644
--- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,6 +30,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsStreamMediaProfile implements Parcelable {
private static final String TAG = "ImsStreamMediaProfile";
diff --git a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
index 1630368..f67f68e 100644
--- a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
+++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,6 +32,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsSuppServiceNotification implements Parcelable {
private static final String TAG = "ImsSuppServiceNotification";
diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java
index 1a21d0a..bc124044 100644
--- a/telephony/java/android/telephony/ims/ImsUtListener.java
+++ b/telephony/java/android/telephony/ims/ImsUtListener.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.ims.stub.ImsUtImplBase;
@@ -33,6 +34,7 @@
// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
// will break other implementations of ImsUt maintained by other ImsServices.
@SystemApi
+@TestApi
public class ImsUtListener {
/**
diff --git a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java
index 1772401..270e693 100644
--- a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java
+++ b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java
@@ -17,6 +17,7 @@
package android.telephony.ims;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Handler;
@@ -36,6 +37,7 @@
* @hide
*/
@SystemApi
+@TestApi
public abstract class ImsVideoCallProvider {
private static final int MSG_SET_CALLBACK = 1;
private static final int MSG_SET_CAMERA = 2;
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index effdf48..e16085e 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -23,6 +23,7 @@
import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.WorkerThread;
import android.content.Context;
import android.content.pm.IPackageManager;
@@ -59,6 +60,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ProvisioningManager {
/**@hide*/
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 23402b8..99bb259 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.net.Uri;
import android.os.Binder;
import android.telephony.AccessNetworkConstants;
@@ -43,6 +44,7 @@
* @hide
*/
@SystemApi
+@TestApi
public interface RegistrationManager {
/**
diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
index 87a5094..1918bcb 100644
--- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
+++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -33,6 +34,7 @@
* {@hide}
*/
@SystemApi
+@TestApi
public final class CapabilityChangeRequest implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 3562880..72390d0 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.IInterface;
import android.os.RemoteCallbackList;
@@ -43,6 +44,7 @@
* @hide
*/
@SystemApi
+@TestApi
public abstract class ImsFeature {
private static final String LOG_TAG = "ImsFeature";
@@ -212,6 +214,7 @@
// Not Actually deprecated, but we need to remove it from the @SystemApi surface.
@Deprecated
@SystemApi // SystemApi only because it was leaked through type usage in a previous release.
+ @TestApi
public static class Capabilities {
/** @deprecated Use getters and accessors instead. */
// Not actually deprecated, but we need to remove it from the @SystemApi surface eventually.
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 8b27b6f..56c8771 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
@@ -54,6 +55,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class MmTelFeature extends ImsFeature {
private static final String LOG_TAG = "MmTelFeature";
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index f69b434..e96d082 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -20,6 +20,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
@@ -49,6 +50,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class RcsFeature extends ImsFeature {
private static final String LOG_TAG = "RcsFeature";
@@ -197,12 +199,19 @@
/** @hide*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = {
+ CAPABILITY_TYPE_NONE,
CAPABILITY_TYPE_OPTIONS_UCE,
CAPABILITY_TYPE_PRESENCE_UCE
})
public @interface RcsImsCapabilityFlag {}
/**
+ * Undefined capability type for initialization
+ * @hide
+ */
+ public static final int CAPABILITY_TYPE_NONE = 0;
+
+ /**
* This carrier supports User Capability Exchange using SIP OPTIONS as defined by the
* framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS.
* If not set, this RcsFeature should not service capability requests.
diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
index da6a7a6..f4367da 100644
--- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
@@ -17,19 +17,19 @@
package android.telephony.ims.stub;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Message;
import android.os.RemoteException;
-import android.telephony.ims.ImsCallSessionListener;
-import android.telephony.ims.aidl.IImsCallSessionListener;
-
import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallSession;
+import android.telephony.ims.ImsCallSessionListener;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
-import android.telephony.ims.ImsCallSession;
+import android.telephony.ims.ImsVideoCallProvider;
+import android.telephony.ims.aidl.IImsCallSessionListener;
+
import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsVideoCallProvider;
-import android.telephony.ims.ImsVideoCallProvider;
-
/**
* Base implementation of IImsCallSession, which implements stub versions of the methods available.
*
@@ -38,6 +38,7 @@
* @hide
*/
@SystemApi
+@TestApi
// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
// will break other implementations of ImsCallSession maintained by other ImsServices.
public class ImsCallSessionImplBase implements AutoCloseable {
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 3e135cc..4c0de7f 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.PersistableBundle;
import android.os.RemoteCallbackList;
@@ -48,6 +49,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsConfigImplBase {
private static final String TAG = "ImsConfigImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
index 06c35ea..4a3a2ea 100644
--- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java
@@ -17,6 +17,7 @@
package android.telephony.ims.stub;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.RemoteException;
import android.util.Log;
@@ -33,6 +34,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsEcbmImplBase {
private static final String TAG = "ImsEcbmImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index cd9ebbf..4e7307e 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.ims.feature.ImsFeature;
@@ -35,6 +36,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsFeatureConfiguration implements Parcelable {
public static final class FeatureSlotPair {
diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
index ce2d89a..0ae5bba 100644
--- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java
@@ -17,10 +17,11 @@
package android.telephony.ims.stub;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.RemoteException;
+import android.telephony.ims.ImsExternalCallState;
import android.util.Log;
-import android.telephony.ims.ImsExternalCallState;
import com.android.ims.internal.IImsExternalCallStateListener;
import com.android.ims.internal.IImsMultiEndpoint;
@@ -37,6 +38,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsMultiEndpointImplBase {
private static final String TAG = "MultiEndpointImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index b455c2e..c0f16e5 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.net.Uri;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -38,6 +39,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsRegistrationImplBase {
private static final String LOG_TAG = "ImsRegistrationImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index 36ece95..ce9a73a 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.RemoteException;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
@@ -37,6 +38,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class ImsSmsImplBase {
private static final String LOG_TAG = "SmsImplBase";
diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
index fcd7faf..feac3c2 100644
--- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
@@ -17,6 +17,7 @@
package android.telephony.ims.stub;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.ims.ImsUtListener;
@@ -33,6 +34,7 @@
// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
// will break other implementations of ImsUt maintained by other ImsServices.
@SystemApi
+@TestApi
public class ImsUtImplBase {
private IImsUt.Stub mServiceImpl = new IImsUt.Stub() {
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index b502ee7..2f18049e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -819,7 +819,7 @@
* @return {@code true} if DUN APN is required for tethering.
* @hide
*/
- boolean isTetherApnRequiredForSubscriber(int subId);
+ boolean isTetheringApnRequiredForSubscriber(int subId);
/**
* Enables framework IMS and triggers IMS Registration.
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index d29ef35..d36d95b 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -20,7 +20,6 @@
import android.os.Build;
import android.provider.Telephony;
import android.telephony.SmsMessage;
-import android.text.Emoji;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
@@ -404,9 +403,9 @@
if (!breakIterator.isBoundary(nextPos)) {
int breakPos = breakIterator.preceding(nextPos);
while (breakPos + 4 <= nextPos
- && Emoji.isRegionalIndicatorSymbol(
+ && isRegionalIndicatorSymbol(
Character.codePointAt(msgBody, breakPos))
- && Emoji.isRegionalIndicatorSymbol(
+ && isRegionalIndicatorSymbol(
Character.codePointAt(msgBody, breakPos + 2))) {
// skip forward over flags (pairs of Regional Indicator Symbol)
breakPos += 4;
@@ -422,6 +421,11 @@
return nextPos;
}
+ private static boolean isRegionalIndicatorSymbol(int codePoint) {
+ /** Based on http://unicode.org/Public/emoji/3.0/emoji-sequences.txt */
+ return 0x1F1E6 <= codePoint && codePoint <= 0x1F1FF;
+ }
+
/**
* Calculate the TextEncodingDetails of a message encoded in Unicode.
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index c3d490a..5766287 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -25,17 +25,17 @@
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
+import android.telephony.CbGeoUtils;
+import android.telephony.CbGeoUtils.Circle;
+import android.telephony.CbGeoUtils.Geometry;
+import android.telephony.CbGeoUtils.LatLng;
+import android.telephony.CbGeoUtils.Polygon;
import android.telephony.SmsCbLocation;
import android.telephony.SmsCbMessage;
import android.util.Pair;
import android.util.Slog;
import com.android.internal.R;
-import com.android.internal.telephony.CbGeoUtils;
-import com.android.internal.telephony.CbGeoUtils.Circle;
-import com.android.internal.telephony.CbGeoUtils.Geometry;
-import com.android.internal.telephony.CbGeoUtils.LatLng;
-import com.android.internal.telephony.CbGeoUtils.Polygon;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.SmsConstants;
import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
index d85cf15..11bc5de 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
@@ -33,7 +33,7 @@
* All relevant header information is now sent as a Parcelable
* {@link android.telephony.SmsCbMessage} object in the "message" extra of the
* {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or
- * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent.
+ * {@link android.provider.Telephony.Sms.Intents#ACTION_SMS_EMERGENCY_CB_RECEIVED} intent.
* The raw PDU is no longer sent to SMS CB applications.
*/
public class SmsCbHeader {
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 0b5d446..aa4174a 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -27,7 +27,10 @@
":framework-core-sources-for-test-mock",
":framework_native_aidl",
],
- libs: ["framework-all"],
+ libs: [
+ "framework-all",
+ "app-compat-annotations",
+ ],
api_packages: [
"android.test.mock",
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 727684e..1de6260 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -765,6 +765,12 @@
/** {@hide} */
@Override
+ public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@hide} */
+ @Override
public int getUserId() {
throw new UnsupportedOperationException();
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
index fd31aa5..e033d0a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
@@ -78,6 +78,7 @@
return TransitionRunner.newBuilder()
.withTag("OpenAppWarm_" + testApp.getLauncherName()
+ rotationToString(beginRotation))
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBeforeAll(() -> setRotation(device, beginRotation))
.runBeforeAll(testApp::open)
@@ -94,6 +95,7 @@
device) {
return TransitionRunner.newBuilder()
.withTag("closeAppWithBackKey_" + testApp.getLauncherName())
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(testApp::open)
.runBefore(device::waitForIdle)
@@ -108,6 +110,7 @@
device) {
return TransitionRunner.newBuilder()
.withTag("closeAppWithHomeKey_" + testApp.getLauncherName())
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(testApp::open)
.runBefore(device::waitForIdle)
@@ -123,6 +126,7 @@
return TransitionRunner.newBuilder()
.withTag("OpenAppCold_" + testApp.getLauncherName()
+ rotationToString(beginRotation))
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(device::pressHome)
.runBeforeAll(() -> setRotation(device, beginRotation))
@@ -140,6 +144,7 @@
.withTag("changeAppRotation_" + testApp.getLauncherName()
+ rotationToString(beginRotation) + "_" +
rotationToString(endRotation))
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBeforeAll(testApp::open)
.runBefore(() -> setRotation(device, beginRotation))
@@ -156,6 +161,7 @@
rotationToString(beginRotation) + "_" + rotationToString(endRotation);
return TransitionRunner.newBuilder()
.withTag(testTag)
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBeforeAll(() -> {
context.startActivity(intent);
@@ -173,6 +179,7 @@
static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device) {
return TransitionRunner.newBuilder()
.withTag("appToSplitScreen_" + testApp.getLauncherName())
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(testApp::open)
.runBefore(device::waitForIdle)
@@ -186,6 +193,7 @@
static TransitionBuilder splitScreenToLauncher(IAppHelper testApp, UiDevice device) {
return TransitionRunner.newBuilder()
.withTag("splitScreenToLauncher_" + testApp.getLauncherName())
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(testApp::open)
.runBefore(device::waitForIdle)
@@ -200,6 +208,7 @@
return TransitionRunner.newBuilder()
.withTag("editTextSetFocus_" + testApp.getLauncherName()
+ rotationToString(beginRotation))
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(device::pressHome)
.runBefore(() -> setRotation(device, beginRotation))
@@ -218,6 +227,7 @@
+ rotationToString(beginRotation);
return TransitionRunner.newBuilder()
.withTag(testTag)
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBeforeAll(() -> setRotation(device, beginRotation))
.runBeforeAll(() -> clearRecents(device))
@@ -246,6 +256,7 @@
return TransitionRunner.newBuilder()
.withTag("editTextLoseFocusToHome_" + testApp.getLauncherName()
+ rotationToString(beginRotation))
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(device::pressHome)
.runBefore(() -> setRotation(device, beginRotation))
@@ -262,6 +273,7 @@
return TransitionRunner.newBuilder()
.withTag("editTextLoseFocusToApp_" + testApp.getLauncherName()
+ rotationToString(beginRotation))
+ .recordAllRuns()
.runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
.runBefore(device::pressHome)
.runBefore(() -> setRotation(device, beginRotation))
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
new file mode 100644
index 0000000..5e9ef8e
--- /dev/null
+++ b/tests/PlatformCompatGating/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test {
+ name: "PlatformCompatGating",
+ // Only compile source java files in this apk.
+ srcs: ["src/**/*.java"],
+ certificate: "platform",
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ ],
+ static_libs: [
+ "junit",
+ "android-support-test",
+ "mockito-target-minus-junit4",
+ "truth-prebuilt",
+ "platform-compat-test-rules"
+ ],
+}
diff --git a/tests/PlatformCompatGating/AndroidManifest.xml b/tests/PlatformCompatGating/AndroidManifest.xml
new file mode 100644
index 0000000..7f14b83
--- /dev/null
+++ b/tests/PlatformCompatGating/AndroidManifest.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.tests.gating">
+ <application android:label="GatingTest">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.tests.gating"/>
+</manifest>
diff --git a/tests/PlatformCompatGating/AndroidTest.xml b/tests/PlatformCompatGating/AndroidTest.xml
new file mode 100644
index 0000000..c626848
--- /dev/null
+++ b/tests/PlatformCompatGating/AndroidTest.xml
@@ -0,0 +1,30 @@
+<!-- Copyright (C) 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.
+-->
+<configuration description="Test compatibility change gating.">
+ <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="PlatformCompatGating.apk"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
+ <option name="test-suite-tag" value="apct"/>
+ <option name="test-tag" value="Gating"/>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="com.android.tests.gating"/>
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/tests/PlatformCompatGating/src/com/android/compat/testing/DummyApi.java b/tests/PlatformCompatGating/src/com/android/compat/testing/DummyApi.java
new file mode 100644
index 0000000..731be8e
--- /dev/null
+++ b/tests/PlatformCompatGating/src/com/android/compat/testing/DummyApi.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You 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.compat.testing;
+
+import android.compat.Compatibility;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.compat.IPlatformCompat;
+
+/**
+ * This is a dummy API to test gating
+ *
+ * @hide
+ */
+public class DummyApi {
+
+ public static final long CHANGE_ID = 666013;
+ public static final long CHANGE_ID_1 = 666014;
+ public static final long CHANGE_ID_2 = 666015;
+ public static final long CHANGE_SYSTEM_SERVER = 666016;
+
+ /**
+ * Dummy method
+ * @return "A" if change is enabled, "B" otherwise.
+ */
+ public static String dummyFunc() {
+ if (Compatibility.isChangeEnabled(CHANGE_ID)) {
+ return "A";
+ }
+ return "B";
+ }
+
+ /**
+ * Dummy combined method
+ * @return "0" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is disabled,
+ "1" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is enabled,
+ "2" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is disabled,
+ "3" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is enabled.
+ */
+ public static String dummyCombinedFunc() {
+ if (!Compatibility.isChangeEnabled(CHANGE_ID_1)
+ && !Compatibility.isChangeEnabled(CHANGE_ID_2)) {
+ return "0";
+ } else if (!Compatibility.isChangeEnabled(CHANGE_ID_1)
+ && Compatibility.isChangeEnabled(CHANGE_ID_2)) {
+ return "1";
+ } else if (Compatibility.isChangeEnabled(CHANGE_ID_1)
+ && !Compatibility.isChangeEnabled(CHANGE_ID_2)) {
+ return "2";
+ }
+ return "3";
+ }
+
+ /**
+ * Dummy api using system server API.
+ */
+ public static boolean dummySystemServer(Context context) {
+ IPlatformCompat platformCompat = IPlatformCompat.Stub
+ .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+ if (platformCompat == null) {
+ throw new RuntimeException("Could not obtain IPlatformCompat instance!");
+ }
+ String packageName = context.getPackageName();
+ try {
+ return platformCompat.isChangeEnabledByPackageName(CHANGE_SYSTEM_SERVER, packageName,
+ context.getUserId());
+ } catch (RemoteException e) {
+ throw new RuntimeException("Could not get change value!", e);
+ }
+ }
+}
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
new file mode 100644
index 0000000..dc317f19
--- /dev/null
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 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 com.android.tests.gating;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.compat.testing.DummyApi;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for platform compatibility change gating.
+ */
+@RunWith(AndroidJUnit4.class)
+public class PlatformCompatGatingTest {
+
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+ @Test
+ @EnableCompatChanges({DummyApi.CHANGE_ID})
+ public void testDummyGatingPositive() {
+ assertThat(DummyApi.dummyFunc()).isEqualTo("A");
+ }
+
+ @Test
+ @DisableCompatChanges({DummyApi.CHANGE_ID})
+ public void testDummyGatingNegative() {
+ assertThat(DummyApi.dummyFunc()).isEqualTo("B");
+ }
+
+ @Test
+ @DisableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2})
+ public void testDummyGatingCombined0() {
+ assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("0");
+ }
+
+ @Test
+ @DisableCompatChanges({DummyApi.CHANGE_ID_1})
+ @EnableCompatChanges({DummyApi.CHANGE_ID_2})
+ public void testDummyGatingCombined1() {
+ assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("1");
+ }
+
+ @Test
+ @EnableCompatChanges({DummyApi.CHANGE_ID_1})
+ @DisableCompatChanges({DummyApi.CHANGE_ID_2})
+ public void testDummyGatingCombined2() {
+ assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("2");
+ }
+
+ @Test
+ @EnableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2})
+ public void testDummyGatingCombined3() {
+ assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("3");
+ }
+
+ @Test
+ @EnableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
+ public void testDummyGatingPositiveSystemServer() {
+ assertThat(
+ DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isTrue();
+ }
+
+ @Test
+ @DisableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
+ public void testDummyGatingNegativeSystemServer() {
+ assertThat(
+ DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isFalse();
+ }
+}
diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp
new file mode 100644
index 0000000..8211ef5
--- /dev/null
+++ b/tests/PlatformCompatGating/test-rules/Android.bp
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2019 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.
+//
+
+java_library {
+ name: "platform-compat-test-rules",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "junit",
+ "android-support-test",
+ "truth-prebuilt",
+ "core-compat-test-rules"
+ ],
+}
\ No newline at end of file
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
new file mode 100644
index 0000000..932ec64
--- /dev/null
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 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.compat.testing;
+
+import android.app.Instrumentation;
+import android.compat.Compatibility;
+import android.compat.Compatibility.ChangeConfig;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.support.test.InstrumentationRegistry;
+
+import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.IPlatformCompat;
+
+import libcore.junit.util.compat.CoreCompatChangeRule;
+
+import org.junit.runners.model.Statement;
+
+/**
+ * Allows tests to specify the which change to disable.
+ *
+ * <p>To use add the following to the test class. It will only change the behavior of a test method
+ * if it is annotated with
+ * {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or
+ * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges}.
+ * </p>
+ * <pre>
+ * @Rule
+ * public TestRule compatChangeRule = new PlatformCompatChangeRule();
+ * </pre>
+ *
+ * <p>Each test method that needs to disable a specific change needs to be annotated
+ * with {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or
+ * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} specifying the change
+ * id. e.g.:
+ * </p>
+ * <pre>
+ * @Test
+ * @DisableCompatChanges({42})
+ * public void testAsIfChange42Disabled() {
+ * // check behavior
+ * }
+ *
+ * @Test
+ * @EnableCompatChanges({42})
+ * public void testAsIfChange42Enabled() {
+ * // check behavior
+ *
+ * </pre>
+ */
+public class PlatformCompatChangeRule extends CoreCompatChangeRule {
+
+ @Override
+ protected Statement createStatementForConfig(final Statement statement, ChangeConfig config) {
+ return new CompatChangeStatement(statement, config);
+ }
+
+
+ private static class CompatChangeStatement extends Statement {
+ private final Statement mTestStatement;
+ private final ChangeConfig mConfig;
+
+ private CompatChangeStatement(Statement testStatement, ChangeConfig config) {
+ this.mTestStatement = testStatement;
+ this.mConfig = config;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ String packageName = instrumentation.getTargetContext().getPackageName();
+ IPlatformCompat platformCompat = IPlatformCompat.Stub
+ .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+ if (platformCompat == null) {
+ throw new IllegalStateException("Could not get IPlatformCompat service!");
+ }
+ Compatibility.setOverrides(mConfig);
+ try {
+ platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
+ packageName);
+ try {
+ mTestStatement.evaluate();
+ } finally {
+ platformCompat.clearOverridesForTest(packageName);
+ }
+ } catch (RemoteException e) {
+ throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
+ } finally {
+ Compatibility.clearOverrides();
+ }
+ }
+ }
+}
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index aec4055..231d045b 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -12,88 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-android_test_helper_app {
- name: "RollbackTestAppAv1",
- manifest: "TestApp/Av1.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v1"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppAv2",
- manifest: "TestApp/Av2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v2"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppAv3",
- manifest: "TestApp/Av3.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v3"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppACrashingV2",
- manifest: "TestApp/ACrashingV2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v2"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppBv1",
- manifest: "TestApp/Bv1.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v1"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppBv2",
- manifest: "TestApp/Bv2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v2"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppASplitV1",
- manifest: "TestApp/Av1.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v1"],
- package_splits: ["anydpi"],
-}
-
-android_test_helper_app {
- name: "RollbackTestAppASplitV2",
- manifest: "TestApp/Av2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
- resource_dirs: ["TestApp/res_v2"],
- package_splits: ["anydpi"],
-}
-
android_test {
name: "RollbackTest",
manifest: "RollbackTest/AndroidManifest.xml",
srcs: ["RollbackTest/src/**/*.java"],
- static_libs: ["androidx.test.rules"],
+ static_libs: ["androidx.test.rules", "cts-rollback-lib", "cts-install-lib"],
test_suites: ["general-tests"],
- java_resources: [
- ":RollbackTestAppAv1",
- ":RollbackTestAppAv2",
- ":RollbackTestAppAv3",
- ":RollbackTestAppACrashingV2",
- ":RollbackTestAppBv1",
- ":RollbackTestAppBv2",
- ":RollbackTestAppASplitV1",
- ":RollbackTestAppASplitV2",
- ],
test_config: "RollbackTest.xml",
// TODO: sdk_version: "test_current" when Intent#resolveSystemservice is TestApi
}
@@ -105,3 +29,11 @@
test_suites: ["general-tests"],
test_config: "StagedRollbackTest.xml",
}
+
+java_test_host {
+ name: "MultiUserRollbackTest",
+ srcs: ["MultiUserRollbackTest/src/**/*.java"],
+ libs: ["tradefed"],
+ test_suites: ["general-tests"],
+ test_config: "MultiUserRollbackTest.xml",
+}
diff --git a/tests/RollbackTest/MultiUserRollbackTest.xml b/tests/RollbackTest/MultiUserRollbackTest.xml
new file mode 100644
index 0000000..41cec46
--- /dev/null
+++ b/tests/RollbackTest/MultiUserRollbackTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs rollback tests for multiple users">
+ <option name="test-suite-tag" value="MultiUserRollbackTest" />
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="pm uninstall com.android.cts.install.lib.testapp.A" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.HostTest" >
+ <option name="class" value="com.android.tests.rollback.host.MultiUserRollbackTest" />
+ </test>
+</configuration>
diff --git a/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java b/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java
new file mode 100644
index 0000000..52f6eba
--- /dev/null
+++ b/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 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.tests.rollback.host;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Runs rollback tests for multiple users.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class MultiUserRollbackTest extends BaseHostJUnit4Test {
+ // The user that was running originally when the test starts.
+ private int mOriginalUserId;
+ private int mSecondaryUserId = -1;
+ private static final long SWITCH_USER_COMPLETED_NUMBER_OF_POLLS = 60;
+ private static final long SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS = 1000;
+
+
+ @After
+ public void tearDown() throws Exception {
+ getDevice().switchUser(mOriginalUserId);
+ getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.A");
+ removeSecondaryUserIfNecessary();
+ }
+
+ @Before
+ public void setup() throws Exception {
+ mOriginalUserId = getDevice().getCurrentUser();
+ installPackageAsUser("RollbackTest.apk", true, mOriginalUserId);
+ createAndSwitchToSecondaryUserIfNecessary();
+ installPackageAsUser("RollbackTest.apk", true, mSecondaryUserId);
+ }
+
+ @Test
+ public void testBasicForSecondaryUser() throws Exception {
+ runPhaseForUsers("testBasic", mSecondaryUserId);
+ }
+
+ @Test
+ public void testMultipleUsers() throws Exception {
+ runPhaseForUsers("testMultipleUsersInstallV1", mOriginalUserId, mSecondaryUserId);
+ runPhaseForUsers("testMultipleUsersUpgradeToV2", mOriginalUserId);
+ runPhaseForUsers("testMultipleUsersUpdateUserData", mOriginalUserId, mSecondaryUserId);
+ switchToUser(mOriginalUserId);
+ getDevice().executeShellCommand("pm rollback-app com.android.cts.install.lib.testapp.A");
+ runPhaseForUsers("testMultipleUsersVerifyUserdataRollback", mOriginalUserId,
+ mSecondaryUserId);
+ }
+
+ /**
+ * Run the phase for the given user ids, in the order they are given.
+ */
+ private void runPhaseForUsers(String phase, int... userIds) throws Exception {
+ for (int userId: userIds) {
+ switchToUser(userId);
+ assertTrue(runDeviceTests("com.android.tests.rollback",
+ "com.android.tests.rollback.MultiUserRollbackTest",
+ phase));
+ }
+ }
+
+ private void removeSecondaryUserIfNecessary() throws Exception {
+ if (mSecondaryUserId != -1) {
+ getDevice().removeUser(mSecondaryUserId);
+ mSecondaryUserId = -1;
+ }
+ }
+
+ private void createAndSwitchToSecondaryUserIfNecessary() throws Exception {
+ if (mSecondaryUserId == -1) {
+ mOriginalUserId = getDevice().getCurrentUser();
+ mSecondaryUserId = getDevice().createUser("MultiUserRollbackTest_User"
+ + System.currentTimeMillis());
+ switchToUser(mSecondaryUserId);
+ }
+ }
+
+ private void switchToUser(int userId) throws Exception {
+ if (getDevice().getCurrentUser() == userId) {
+ return;
+ }
+
+ assertTrue(getDevice().switchUser(userId));
+ for (int i = 0; i < SWITCH_USER_COMPLETED_NUMBER_OF_POLLS; ++i) {
+ String userState = getDevice().executeShellCommand("am get-started-user-state "
+ + userId);
+ if (userState.contains("RUNNING_UNLOCKED")) {
+ return;
+ }
+ Thread.sleep(SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS);
+ }
+ fail("User switch to user " + userId + " timed out");
+ }
+}
diff --git a/tests/RollbackTest/RollbackTest.xml b/tests/RollbackTest/RollbackTest.xml
index 70cd867..a14b01c 100644
--- a/tests/RollbackTest/RollbackTest.xml
+++ b/tests/RollbackTest/RollbackTest.xml
@@ -22,8 +22,9 @@
<option name="package" value="com.android.tests.rollback" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- <!-- Exclude the StagedRollbackTest tests, which needs to be specially
- driven from the StagedRollbackTest host test -->
+ <!-- Exclude the StagedRollbackTest and MultiUserRollbackTest tests, which need to be
+ specially driven from the StagedRollbackTest and MultiUserRollbackTest host test -->
<option name="exclude-filter" value="com.android.tests.rollback.StagedRollbackTest" />
+ <option name="exclude-filter" value="com.android.tests.rollback.MultiUserRollbackTest" />
</test>
</configuration>
diff --git a/tests/RollbackTest/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
index 5380dc9..2b8c964 100644
--- a/tests/RollbackTest/RollbackTest/AndroidManifest.xml
+++ b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
package="com.android.tests.rollback" >
<application>
- <receiver android:name="com.android.tests.rollback.LocalIntentSender"
+ <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
android:exported="true" />
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
deleted file mode 100644
index 267ef73..0000000
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 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 com.android.tests.rollback;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * Make IntentSender that sends intent locally.
- */
-public class LocalIntentSender extends BroadcastReceiver {
-
- private static final String TAG = "RollbackTest";
-
- private static final BlockingQueue<Intent> sIntentSenderResults = new LinkedBlockingQueue<>();
-
- @Override
- public void onReceive(Context context, Intent intent) {
- sIntentSenderResults.add(intent);
- }
-
- /**
- * Get a LocalIntentSender.
- */
- static IntentSender getIntentSender() {
- Context context = InstrumentationRegistry.getContext();
- Intent intent = new Intent(context, LocalIntentSender.class);
- PendingIntent pending = PendingIntent.getBroadcast(context, 0, intent, 0);
- return pending.getIntentSender();
- }
-
- /**
- * Returns the most recent Intent sent by a LocalIntentSender.
- */
- static Intent getIntentSenderResult() throws InterruptedException {
- return sIntentSenderResults.take();
- }
-}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java
new file mode 100644
index 0000000..0ffe041
--- /dev/null
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2019 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.tests.rollback;
+
+import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
+import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.Manifest;
+import android.content.rollback.RollbackInfo;
+import android.content.rollback.RollbackManager;
+
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.TestApp;
+import com.android.cts.rollback.lib.Rollback;
+import com.android.cts.rollback.lib.RollbackUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+@RunWith(JUnit4.class)
+public class MultiUserRollbackTest {
+
+ @Before
+ public void adoptShellPermissions() {
+ InstallUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ Manifest.permission.TEST_MANAGE_ROLLBACKS,
+ Manifest.permission.MANAGE_ROLLBACKS);
+ }
+
+ @After
+ public void dropShellPermissions() {
+ InstallUtils.dropShellPermissionIdentity();
+ }
+
+ @Test
+ public void testBasic() throws Exception {
+ new RollbackTest().testBasic();
+ }
+
+ /**
+ * Install version 1 of the test app. This method is run for both users.
+ */
+ @Test
+ public void testMultipleUsersInstallV1() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ InstallUtils.processUserData(TestApp.A);
+ }
+
+ /**
+ * Upgrade the test app to version 2. This method should only run once as the system user,
+ * and will update the app for both users.
+ */
+ @Test
+ public void testMultipleUsersUpgradeToV2() throws Exception {
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.A);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
+ }
+
+ /**
+ * This method is run for both users. Assert that the test app has upgraded for both users, and
+ * update their userdata to reflect this new version.
+ */
+ @Test
+ public void testMultipleUsersUpdateUserData() {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ InstallUtils.processUserData(TestApp.A);
+ }
+
+ /**
+ * The system will have rolled back the test app at this stage. Verify that the rollback has
+ * taken place, and that the userdata has been correctly rolled back. This method is run for
+ * both users.
+ */
+ @Test
+ public void testMultipleUsersVerifyUserdataRollback() {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ InstallUtils.processUserData(TestApp.A);
+ }
+}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
deleted file mode 100644
index ebe5418..0000000
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 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 com.android.tests.rollback;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A broadcast receiver that can be used to get
- * ACTION_ROLLBACK_COMMITTED broadcasts.
- */
-class RollbackBroadcastReceiver extends BroadcastReceiver {
-
- private static final String TAG = "RollbackTest";
-
- private final BlockingQueue<Intent> mRollbackBroadcasts = new LinkedBlockingQueue<>();
-
- /**
- * Creates a RollbackBroadcastReceiver and registers it with the given
- * context.
- */
- RollbackBroadcastReceiver() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_ROLLBACK_COMMITTED);
- InstrumentationRegistry.getContext().registerReceiver(this, filter);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.i(TAG, "Received rollback broadcast intent");
- mRollbackBroadcasts.add(intent);
- }
-
- /**
- * Polls for at most the given amount of time for the next rollback
- * broadcast.
- */
- Intent poll(long timeout, TimeUnit unit) throws InterruptedException {
- return mRollbackBroadcasts.poll(timeout, unit);
- }
-
- /**
- * Waits forever for the next rollback broadcast.
- */
- Intent take() throws InterruptedException {
- return mRollbackBroadcasts.take();
- }
-
- /**
- * Unregisters this broadcast receiver.
- */
- void unregister() {
- InstrumentationRegistry.getContext().unregisterReceiver(this);
- }
-}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 1b002ca..277c04f 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -16,14 +16,14 @@
package com.android.tests.rollback;
-import static com.android.tests.rollback.RollbackTestUtils.assertPackageRollbackInfoEquals;
-import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals;
-import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
-import static com.android.tests.rollback.RollbackTestUtils.processUserData;
+import static com.android.cts.install.lib.InstallUtils.processUserData;
+import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
+import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
+import static com.android.cts.rollback.lib.RollbackUtils.waitForAvailableRollback;
+import static com.android.cts.rollback.lib.RollbackUtils.waitForUnavailableRollback;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.fail;
import android.Manifest;
@@ -31,15 +31,21 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.VersionedPackage;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.provider.DeviceConfig;
-import android.provider.Settings;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.TestApp;
+import com.android.cts.install.lib.Uninstall;
+import com.android.cts.rollback.lib.Rollback;
+import com.android.cts.rollback.lib.RollbackBroadcastReceiver;
+import com.android.cts.rollback.lib.RollbackUtils;
+
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,8 +63,6 @@
private static final String TAG = "RollbackTest";
- private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
- private static final String TEST_APP_B = "com.android.tests.rollback.testapp.B";
private static final String INSTRUMENTED_APP = "com.android.tests.rollback";
// copied from PackageManagerService#PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS
@@ -88,7 +92,7 @@
context.registerReceiver(enableRollbackReceiver, enableRollbackFilter);
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -97,18 +101,18 @@
// Register a broadcast receiver for notification when the
// rollback has been committed.
RollbackBroadcastReceiver broadcastReceiver = new RollbackBroadcastReceiver();
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- // Uninstall TEST_APP_A
- RollbackTestUtils.uninstall(TEST_APP_A);
- assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ // Uninstall TestApp.A
+ Uninstall.packages(TestApp.A);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
// TODO: There is currently a race condition between when the app is
// uninstalled and when rollback manager deletes the rollback. Fix it
// so that's not the case!
for (int i = 0; i < 5; ++i) {
RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
if (rollback != null) {
Log.i(TAG, "Sleeping 1 second to wait for uninstall to take effect.");
Thread.sleep(1000);
@@ -116,50 +120,55 @@
}
// The app should not be available for rollback.
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+ waitForUnavailableRollback(TestApp.A);
// There should be no recently committed rollbacks for this package.
- assertNull(getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A));
+ assertThat(getUniqueRollbackInfoForPackage(
+ rm.getRecentlyCommittedRollbacks(), TestApp.A)).isNull();
// Install v1 of the app (without rollbacks enabled).
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
// Upgrade from v1 to v2, with rollbacks enabled.
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ RollbackInfo available = waitForAvailableRollback(TestApp.A);
+ assertThat(available).isNotStaged();
+ assertThat(available).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
// We should not have received any rollback requests yet.
// TODO: Possibly flaky if, by chance, some other app on device
// happens to be rolled back at the same time?
- assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS));
+ assertThat(broadcastReceiver.poll(0, TimeUnit.SECONDS)).isNull();
// Roll back the app.
- RollbackTestUtils.rollback(rollback.getRollbackId());
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ RollbackUtils.rollback(available.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
// Verify we received a broadcast for the rollback.
// TODO: Race condition between the timeout and when the broadcast is
// received could lead to test flakiness.
Intent broadcast = broadcastReceiver.poll(5, TimeUnit.SECONDS);
- assertNotNull(broadcast);
- assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS));
+ assertThat(broadcast).isNotNull();
+ assertThat(broadcastReceiver.poll(0, TimeUnit.SECONDS)).isNull();
// Verify the recent rollback has been recorded.
- rollback = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ RollbackInfo committed = getUniqueRollbackInfoForPackage(
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(committed).isNotNull();
+ assertThat(committed).isNotStaged();
+ assertThat(committed).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
+ assertThat(committed).hasRollbackId(available.getRollbackId());
broadcastReceiver.unregister();
context.unregisterReceiver(enableRollbackReceiver);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -169,50 +178,54 @@
@Test
public void testAvailableRollbackPersistence() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ Uninstall.packages(TestApp.B);
+ Install.single(TestApp.B1).commit();
+ Install.single(TestApp.B2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// Both test apps should now be available for rollback.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+ RollbackInfo rollbackA = waitForAvailableRollback(TestApp.A);
+ assertThat(rollbackA).isNotNull();
+ assertThat(rollbackA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+ RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
+ assertThat(rollbackB).isNotNull();
+ assertThat(rollbackB).packagesContainsExactly(
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Reload the persisted data.
rm.reloadPersistedData();
// The apps should still be available for rollback.
- rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+ rollbackA = waitForAvailableRollback(TestApp.A);
+ assertThat(rollbackA).isNotNull();
+ assertThat(rollbackA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
- rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+ rollbackB = waitForAvailableRollback(TestApp.B);
+ assertThat(rollbackB).isNotNull();
+ assertThat(rollbackB).packagesContainsExactly(
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Rollback of B should not rollback A
- RollbackTestUtils.rollback(rollbackB.getRollbackId());
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ RollbackUtils.rollback(rollbackB.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -222,49 +235,76 @@
@Test
public void testAvailableMultiPackageRollbackPersistence() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.installMultiPackage(false,
- "RollbackTestAppAv1.apk",
- "RollbackTestAppBv1.apk");
- RollbackTestUtils.installMultiPackage(true,
- "RollbackTestAppAv2.apk",
- "RollbackTestAppBv2.apk");
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ Uninstall.packages(TestApp.A, TestApp.B);
+ Install.multi(TestApp.A1, TestApp.B1).commit();
+ Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
+
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoForAandB(rollbackA);
+ RollbackInfo availableA = waitForAvailableRollback(TestApp.A);
+ assertThat(availableA).isNotNull();
+ assertThat(availableA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoForAandB(rollbackB);
+ RollbackInfo availableB = waitForAvailableRollback(TestApp.B);
+ assertThat(availableB).isNotNull();
+ assertThat(availableB).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
+
+ // Assert they're both the same rollback
+ assertThat(availableA).hasRollbackId(availableB.getRollbackId());
// Reload the persisted data.
rm.reloadPersistedData();
// The apps should still be available for rollback.
- rollbackA = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoForAandB(rollbackA);
+ availableA = waitForAvailableRollback(TestApp.A);
+ assertThat(availableA).isNotNull();
+ assertThat(availableA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
- rollbackB = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoForAandB(rollbackB);
+ availableB = waitForAvailableRollback(TestApp.B);
+ assertThat(availableB).isNotNull();
+ assertThat(availableB).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Rollback of B should rollback A as well
- RollbackTestUtils.rollback(rollbackB.getRollbackId());
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ RollbackUtils.rollback(availableB.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
+
+ RollbackInfo committedA = getUniqueRollbackInfoForPackage(
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(committedA).isNotNull();
+ assertThat(committedA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
+
+ RollbackInfo committedB = getUniqueRollbackInfoForPackage(
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(committedB).isNotNull();
+ assertThat(committedB).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
+
+ // Assert they're both the same rollback
+ assertThat(committedA).hasRollbackId(committedB.getRollbackId());
+ assertThat(committedA).hasRollbackId(availableA.getRollbackId());
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -274,42 +314,49 @@
@Test
public void testRecentlyCommittedRollbackPersistence() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
+ RollbackInfo available = waitForAvailableRollback(TestApp.A);
+ assertThat(available).isNotNull();
// Roll back the app.
- VersionedPackage cause = new VersionedPackage(
- "com.android.tests.rollback.testapp.Foo", 42);
- RollbackTestUtils.rollback(rollback.getRollbackId(), cause);
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ TestApp cause = new TestApp("Foo", "com.android.tests.rollback.testapp.Foo",
+ /*versionCode*/ 42, /*isApex*/ false);
+ RollbackUtils.rollback(available.getRollbackId(), cause);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
// Verify the recent rollback has been recorded.
- rollback = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, cause);
+ RollbackInfo committed = getUniqueRollbackInfoForPackage(
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(committed).isNotNull();
+ assertThat(committed).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
+ assertThat(committed).causePackagesContainsExactly(cause);
// Reload the persisted data.
rm.reloadPersistedData();
// Verify the recent rollback is still recorded.
- rollback = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, cause);
+ committed = getUniqueRollbackInfoForPackage(
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(committed).isNotNull();
+ assertThat(committed).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
+ assertThat(committed).causePackagesContainsExactly(cause);
+ assertThat(committed).hasRollbackId(available.getRollbackId());
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -320,10 +367,10 @@
public void testRollbackExpiresAfterLifetime() throws Exception {
long expirationTime = TimeUnit.SECONDS.toMillis(30);
long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -336,39 +383,43 @@
// Pull the new expiration time from DeviceConfig
rm.reloadPersistedData();
- // Uninstall TEST_APP_A
- RollbackTestUtils.uninstall(TEST_APP_A);
- assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ // Uninstall TestApp.A
+ Uninstall.packages(TestApp.A);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
// Install v1 of the app (without rollbacks enabled).
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
// Upgrade from v1 to v2, with rollbacks enabled.
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// Check that the rollback data has not expired
Thread.sleep(1000);
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
- // Give it a little more time, but still not the long enough to expire
+ // Give it a little more time, but still not long enough to expire
Thread.sleep(expirationTime / 2);
rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ rm.getAvailableRollbacks(), TestApp.A);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
// Check that the data has expired after the expiration time (with a buffer of 1 second)
Thread.sleep(expirationTime / 2);
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+ rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.A);
+ assertThat(rollback).isNull();
} finally {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
Long.toString(defaultExpirationTime), false /* makeDefault*/);
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -380,10 +431,10 @@
public void testTimeChangeDoesNotAffectLifetime() throws Exception {
long expirationTime = TimeUnit.SECONDS.toMillis(30);
long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -398,24 +449,25 @@
rm.reloadPersistedData();
// Install app A with rollback enabled
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
Thread.sleep(expirationTime / 2);
// Install app B with rollback enabled
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ Uninstall.packages(TestApp.B);
+ Install.single(TestApp.B1).commit();
+ Install.single(TestApp.B2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
+
// 1 second buffer
Thread.sleep(1000);
try {
// Change the time
- RollbackTestUtils.forwardTimeBy(expirationTime);
+ RollbackUtils.forwardTimeBy(expirationTime);
// 1 second buffer to allow Rollback Manager to handle time change before loading
// persisted data
@@ -427,24 +479,31 @@
// Wait until rollback for app A has expired
// This will trigger an expiration run that should expire app A but not B
Thread.sleep(expirationTime / 2);
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+ RollbackInfo rollback =
+ getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A);
+ assertThat(rollback).isNull();
// Rollback for app B should not be expired
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollback);
+ rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.B);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Wait until rollback for app B has expired
Thread.sleep(expirationTime / 2);
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_B));
+ rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.B);
+ // Rollback should be expired by now
+ assertThat(rollback).isNull();
} finally {
- RollbackTestUtils.forwardTimeBy(-expirationTime);
+ RollbackUtils.forwardTimeBy(-expirationTime);
}
} finally {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
Long.toString(defaultExpirationTime), false /* makeDefault*/);
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -455,30 +514,30 @@
@Test
public void testRollbackExpiration() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
// Expire the rollback.
- rm.expireRollbackForPackage(TEST_APP_A);
+ rm.expireRollbackForPackage(TestApp.A);
// The rollback should no longer be available.
- assertNull(getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A));
+ assertThat(getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.A)).isNull();
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -488,24 +547,22 @@
@Test
public void testUserDataRollback() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- processUserData(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- processUserData(TEST_APP_A);
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ processUserData(TestApp.A);
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ processUserData(TestApp.A);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- RollbackTestUtils.rollback(rollback.getRollbackId());
- processUserData(TEST_APP_A);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
+ RollbackUtils.rollback(rollback.getRollbackId());
+ processUserData(TestApp.A);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -515,30 +572,23 @@
@Test
public void testRollbackWithSplits() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.installSplit(false,
- "RollbackTestAppASplitV1.apk",
- "RollbackTestAppASplitV1_anydpi.apk");
- processUserData(TEST_APP_A);
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.ASplit1).commit();
+ processUserData(TestApp.A);
- RollbackTestUtils.installSplit(true,
- "RollbackTestAppASplitV2.apk",
- "RollbackTestAppASplitV2_anydpi.apk");
- processUserData(TEST_APP_A);
+ Install.single(TestApp.ASplit2).setEnableRollback().commit();
+ processUserData(TestApp.A);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertNotNull(rollback);
- RollbackTestUtils.rollback(rollback.getRollbackId());
- processUserData(TEST_APP_A);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
+ RollbackUtils.rollback(rollback.getRollbackId());
+ processUserData(TestApp.A);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -559,7 +609,7 @@
// Confirm that we really haven't received the broadcast.
// TODO: How long to wait for the expected timeout?
- assertNull(broadcastReceiver.poll(5, TimeUnit.SECONDS));
+ assertThat(broadcastReceiver.poll(5, TimeUnit.SECONDS)).isNull();
// TODO: Do we need to do this? Do we need to ensure this is always
// called, even when the test fails?
@@ -573,48 +623,47 @@
@Test
public void testMultipleRollbackAvailable() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
// Prep installation of the test apps.
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ Uninstall.packages(TestApp.B);
+ Install.single(TestApp.B1).commit();
+ Install.single(TestApp.B2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// Both test apps should now be available for rollback, and the
// RollbackInfo returned for the rollbacks should be correct.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+ RollbackInfo rollbackA = waitForAvailableRollback(TestApp.A);
+ assertThat(rollbackA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+ RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
+ assertThat(rollbackB).packagesContainsExactly(
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Executing rollback should roll back the correct package.
- RollbackTestUtils.rollback(rollbackA.getRollbackId());
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ RollbackUtils.rollback(rollbackA.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackTestUtils.rollback(rollbackB.getRollbackId());
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ RollbackUtils.rollback(rollbackB.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -626,7 +675,7 @@
public void testManageRollbacksPermission() throws Exception {
// We shouldn't be allowed to call any of the RollbackManager APIs
// without the MANAGE_ROLLBACKS permission.
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
try {
rm.getAvailableRollbacks();
@@ -659,7 +708,7 @@
}
try {
- rm.expireRollbackForPackage(TEST_APP_A);
+ rm.expireRollbackForPackage(TestApp.A);
fail("expected SecurityException");
} catch (SecurityException e) {
// Expected.
@@ -673,26 +722,27 @@
@Test
public void testEnableRollbackPermission() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES);
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", /* enableRollback */ false);
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", /* enableRollback */ true);
+ Install.single(TestApp.A2).setEnableRollback().commit();
// We expect v2 of the app was installed, but rollback has not
// been enabled.
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(
+ getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -703,25 +753,26 @@
@Test
public void testNonModuleEnableRollback() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.MANAGE_ROLLBACKS);
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", /* enableRollback */ false);
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", /* enableRollback */ true);
+ Install.single(TestApp.A2).setEnableRollback().commit();
// We expect v2 of the app was installed, but rollback has not
// been enabled because the test app is not a module.
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(
+ getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -731,54 +782,53 @@
@Test
public void testMultiPackage() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
// Prep installation of the test apps.
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.installMultiPackage(false,
- "RollbackTestAppAv1.apk",
- "RollbackTestAppBv1.apk");
- processUserData(TEST_APP_A);
- processUserData(TEST_APP_B);
- RollbackTestUtils.installMultiPackage(true,
- "RollbackTestAppAv2.apk",
- "RollbackTestAppBv2.apk");
- processUserData(TEST_APP_A);
- processUserData(TEST_APP_B);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ Uninstall.packages(TestApp.A, TestApp.B);
+ Install.multi(TestApp.A1, TestApp.B1).commit();
+ processUserData(TestApp.A);
+ processUserData(TestApp.B);
+ Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
+ processUserData(TestApp.A);
+ processUserData(TestApp.B);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
- // TEST_APP_A should now be available for rollback.
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoForAandB(rollback);
+ // TestApp.A should now be available for rollback.
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Rollback the app. It should cause both test apps to be rolled
// back.
- RollbackTestUtils.rollback(rollback.getRollbackId());
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ RollbackUtils.rollback(rollback.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
// We should see recent rollbacks listed for both A and B.
Thread.sleep(1000);
RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_B);
- assertRollbackInfoForAandB(rollbackB);
+ rm.getRecentlyCommittedRollbacks(), TestApp.B);
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1),
+ Rollback.from(TestApp.B2).to(TestApp.B1));
- assertEquals(rollbackA.getRollbackId(), rollbackB.getRollbackId());
+ assertThat(rollbackA).hasRollbackId(rollbackB.getRollbackId());
- processUserData(TEST_APP_A);
- processUserData(TEST_APP_B);
+ processUserData(TestApp.A);
+ processUserData(TestApp.B);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -790,31 +840,27 @@
@Test
public void testMultiPackageEnableFail() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-
+ Uninstall.packages(TestApp.A, TestApp.B);
+ Install.single(TestApp.A1).commit();
// We should fail to enable rollback here because TestApp B is not
// already installed.
- RollbackTestUtils.installMultiPackage(true,
- "RollbackTestAppAv2.apk",
- "RollbackTestAppBv2.apk");
+ Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
- assertNull(getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A));
- assertNull(getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B));
+ assertThat(getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.A)).isNull();
+ assertThat(getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.B)).isNull();
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -825,30 +871,33 @@
*/
public void testSameVersionUpdate() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- RollbackTestUtils.install("RollbackTestAppACrashingV2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ Install.single(TestApp.ACrashing2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 2, rollback);
+ rm.getAvailableRollbacks(), TestApp.A);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A2));
- RollbackTestUtils.rollback(rollback.getRollbackId());
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ RollbackUtils.rollback(rollback.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
rollback = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 2, rollback);
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A2));
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -857,60 +906,54 @@
*/
@Test
public void testBadUpdateRollback() throws Exception {
- BroadcastReceiver crashCountReceiver = null;
Context context = InstrumentationRegistry.getContext();
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.MANAGE_ROLLBACKS,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
- Manifest.permission.KILL_BACKGROUND_PROCESSES,
+ Manifest.permission.FORCE_STOP_PACKAGES,
Manifest.permission.RESTART_PACKAGES);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
// Prep installation of the test apps.
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppACrashingV2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A, TestApp.B);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.ACrashing2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackTestUtils.uninstall(TEST_APP_B);
- RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ Install.single(TestApp.B1).commit();
+ Install.single(TestApp.B2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// Both test apps should now be available for rollback, and the
// targetPackage returned for rollback should be correct.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+ RollbackInfo rollbackA = waitForAvailableRollback(TestApp.A);
+ assertThat(rollbackA).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_B);
- assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+ RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
+ assertThat(rollbackB).packagesContainsExactly(
+ Rollback.from(TestApp.B2).to(TestApp.B1));
// Register rollback committed receiver
RollbackBroadcastReceiver rollbackReceiver = new RollbackBroadcastReceiver();
- // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
- crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5);
+ // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
+ RollbackUtils.sendCrashBroadcast(TestApp.A, 5);
// Verify we received a broadcast for the rollback.
rollbackReceiver.take();
- // TEST_APP_A is automatically rolled back by the RollbackPackageHealthObserver
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ // TestApp.A is automatically rolled back by the RollbackPackageHealthObserver
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
// Instrumented app is still the package installer
- String installer = context.getPackageManager().getInstallerPackageName(TEST_APP_A);
- assertEquals(INSTRUMENTED_APP, installer);
- // TEST_APP_B is untouched
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ String installer = context.getPackageManager().getInstallerPackageName(TestApp.A);
+ assertThat(installer).isEqualTo(INSTRUMENTED_APP);
+ // TestApp.B is untouched
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
- if (crashCountReceiver != null) {
- context.unregisterReceiver(crashCountReceiver);
- }
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -920,31 +963,31 @@
@Test
public void testRollForwardRace() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
Manifest.permission.MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ Install.single(TestApp.A2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
// Install a new version of package A, then immediately rollback
// the previous version. We expect the rollback to fail, because
// it is no longer available.
// There are a couple different ways this could fail depending on
// thread interleaving, so don't ignore flaky failures.
- RollbackTestUtils.install("RollbackTestAppAv3.apk", false);
+ Install.single(TestApp.A3).commit();
try {
- RollbackTestUtils.rollback(rollback.getRollbackId());
+ RollbackUtils.rollback(rollback.getRollbackId());
// Note: Don't ignore flaky failures here.
fail("Expected rollback to fail, but it did not.");
} catch (AssertionError e) {
@@ -953,9 +996,9 @@
}
// Note: Don't ignore flaky failures here.
- assertEquals(3, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(3);
} finally {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
}
@@ -963,7 +1006,7 @@
@Ignore("b/136605788")
public void testEnableRollbackTimeoutFailsRollback() throws Exception {
try {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -973,36 +1016,32 @@
//setting the timeout to a very short amount that will definitely be triggered
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
- Long.toString(1), false /* makeDefault*/);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ Long.toString(0), false /* makeDefault*/);
+ RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackTestUtils.uninstall(TEST_APP_A);
- RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
- RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ waitForUnavailableRollback(TestApp.A);
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ // Block the RollbackManager to make extra sure it will not be
+ // able to enable the rollback in time.
+ rm.blockRollbackManager(TimeUnit.SECONDS.toMillis(1));
+ Install.single(TestApp.A2).setEnableRollback().commit();
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+
+ // Give plenty of time for RollbackManager to unblock and attempt
+ // to make the rollback available before asserting that the
+ // rollback was not made available.
+ Thread.sleep(TimeUnit.SECONDS.toMillis(2));
+ assertThat(
+ getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
} finally {
//setting the timeout back to default
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
null, false /* makeDefault*/);
- RollbackTestUtils.dropShellPermissionIdentity();
- }
- }
-
- // Helper function to test that the given rollback info is a rollback for
- // the atomic set {A2, B2} -> {A1, B1}.
- private void assertRollbackInfoForAandB(RollbackInfo rollback) {
- assertNotNull(rollback);
- assertEquals(2, rollback.getPackages().size());
- if (TEST_APP_A.equals(rollback.getPackages().get(0).getPackageName())) {
- assertPackageRollbackInfoEquals(TEST_APP_A, 2, 1, rollback.getPackages().get(0));
- assertPackageRollbackInfoEquals(TEST_APP_B, 2, 1, rollback.getPackages().get(1));
- } else {
- assertPackageRollbackInfoEquals(TEST_APP_B, 2, 1, rollback.getPackages().get(0));
- assertPackageRollbackInfoEquals(TEST_APP_A, 2, 1, rollback.getPackages().get(1));
+ InstallUtils.dropShellPermissionIdentity();
}
}
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
deleted file mode 100644
index a9e20cd..0000000
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 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 com.android.tests.rollback;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import android.app.ActivityManager;
-import android.app.AlarmManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.content.rollback.PackageRollbackInfo;
-import android.content.rollback.RollbackInfo;
-import android.content.rollback.RollbackManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.SynchronousQueue;
-
-/**
- * Utilities to facilitate testing rollbacks.
- */
-class RollbackTestUtils {
-
- private static final String TAG = "RollbackTest";
-
- static RollbackManager getRollbackManager() {
- Context context = InstrumentationRegistry.getContext();
- RollbackManager rm = (RollbackManager) context.getSystemService(Context.ROLLBACK_SERVICE);
- if (rm == null) {
- throw new AssertionError("Failed to get RollbackManager");
- }
- return rm;
- }
-
- private static void setTime(long millis) {
- Context context = InstrumentationRegistry.getContext();
- AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- am.setTime(millis);
- }
-
- static void forwardTimeBy(long offsetMillis) {
- setTime(System.currentTimeMillis() + offsetMillis);
- Log.i(TAG, "Forwarded time on device by " + offsetMillis + " millis");
- }
-
- /**
- * Returns the version of the given package installed on device.
- * Returns -1 if the package is not currently installed.
- */
- static long getInstalledVersion(String packageName) {
- PackageInfo pi = getPackageInfo(packageName);
- if (pi == null) {
- return -1;
- } else {
- return pi.getLongVersionCode();
- }
- }
-
- private static boolean isSystemAppWithoutUpdate(String packageName) {
- PackageInfo pi = getPackageInfo(packageName);
- if (pi == null) {
- return false;
- } else {
- return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
- && ((pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0);
- }
- }
-
- private static PackageInfo getPackageInfo(String packageName) {
- Context context = InstrumentationRegistry.getContext();
- PackageManager pm = context.getPackageManager();
- try {
- return pm.getPackageInfo(packageName, PackageManager.MATCH_APEX);
- } catch (PackageManager.NameNotFoundException e) {
- return null;
- }
- }
-
- private static void assertStatusSuccess(Intent result) {
- int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
- PackageInstaller.STATUS_FAILURE);
- if (status == -1) {
- throw new AssertionError("PENDING USER ACTION");
- } else if (status > 0) {
- String message = result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
- throw new AssertionError(message == null ? "UNKNOWN FAILURE" : message);
- }
- }
-
- /**
- * Uninstalls the given package.
- * Does nothing if the package is not installed.
- * @throws AssertionError if package can't be uninstalled.
- */
- static void uninstall(String packageName) throws InterruptedException, IOException {
- // No need to uninstall if the package isn't installed or is installed on /system.
- if (getInstalledVersion(packageName) == -1 || isSystemAppWithoutUpdate(packageName)) {
- return;
- }
-
- Context context = InstrumentationRegistry.getContext();
- PackageManager packageManager = context.getPackageManager();
- PackageInstaller packageInstaller = packageManager.getPackageInstaller();
- packageInstaller.uninstall(packageName, LocalIntentSender.getIntentSender());
- assertStatusSuccess(LocalIntentSender.getIntentSenderResult());
- }
-
- /**
- * Commit the given rollback.
- * @throws AssertionError if the rollback fails.
- */
- static void rollback(int rollbackId, VersionedPackage... causePackages)
- throws InterruptedException {
- RollbackManager rm = getRollbackManager();
- rm.commitRollback(rollbackId, Arrays.asList(causePackages),
- LocalIntentSender.getIntentSender());
- Intent result = LocalIntentSender.getIntentSenderResult();
- int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
- RollbackManager.STATUS_FAILURE);
- if (status != RollbackManager.STATUS_SUCCESS) {
- String message = result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE);
- throw new AssertionError(message);
- }
- }
-
- /**
- * Installs the apk with the given name.
- *
- * @param resourceName name of class loader resource for the apk to
- * install.
- * @param enableRollback if rollback should be enabled.
- * @throws AssertionError if the installation fails.
- */
- static void install(String resourceName, boolean enableRollback)
- throws InterruptedException, IOException {
- installSplit(enableRollback, resourceName);
- }
-
- /**
- * Installs the apk with the given name and its splits.
- *
- * @param enableRollback if rollback should be enabled.
- * @param resourceNames names of class loader resources for the apk and
- * its splits to install.
- * @throws AssertionError if the installation fails.
- */
- static void installSplit(boolean enableRollback, String... resourceNames)
- throws InterruptedException, IOException {
- Context context = InstrumentationRegistry.getContext();
- PackageInstaller.Session session = null;
- PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
- PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- params.setEnableRollback(enableRollback);
- int sessionId = packageInstaller.createSession(params);
- session = packageInstaller.openSession(sessionId);
-
- ClassLoader loader = RollbackTest.class.getClassLoader();
- for (String resourceName : resourceNames) {
- try (OutputStream packageInSession = session.openWrite(resourceName, 0, -1);
- InputStream is = loader.getResourceAsStream(resourceName);) {
- byte[] buffer = new byte[4096];
- int n;
- while ((n = is.read(buffer)) >= 0) {
- packageInSession.write(buffer, 0, n);
- }
- }
- }
-
- // Commit the session (this will start the installation workflow).
- session.commit(LocalIntentSender.getIntentSender());
- assertStatusSuccess(LocalIntentSender.getIntentSenderResult());
- }
-
- /** Launches {@code packageName} with {@link Intent#ACTION_MAIN}. */
- private static void launchPackage(String packageName)
- throws InterruptedException, IOException {
- Context context = InstrumentationRegistry.getContext();
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setPackage(packageName);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- context.startActivity(intent);
- }
-
- /**
- * Installs the APKs or APEXs with the given resource names as an atomic
- * set. A resource is assumed to be an APEX if it has the .apex extension.
- * <p>
- * In case of staged installs, this function will return succesfully after
- * the staged install has been committed and is ready for the device to
- * reboot.
- *
- * @param staged if the rollback should be staged.
- * @param enableRollback if rollback should be enabled.
- * @param resourceNames names of the class loader resource for the apks to
- * install.
- * @throws AssertionError if the installation fails.
- */
- private static void install(boolean staged, boolean enableRollback,
- String... resourceNames) throws InterruptedException, IOException {
- Context context = InstrumentationRegistry.getContext();
- PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
-
- PackageInstaller.SessionParams multiPackageParams = new PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- multiPackageParams.setMultiPackage();
- if (staged) {
- multiPackageParams.setStaged();
- }
- // TODO: Do we set this on the parent params, the child params, or
- // both?
- multiPackageParams.setEnableRollback(enableRollback);
- int multiPackageId = packageInstaller.createSession(multiPackageParams);
- PackageInstaller.Session multiPackage = packageInstaller.openSession(multiPackageId);
-
- for (String resourceName : resourceNames) {
- PackageInstaller.Session session = null;
- PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- if (staged) {
- params.setStaged();
- }
- if (resourceName.endsWith(".apex")) {
- params.setInstallAsApex();
- }
- params.setEnableRollback(enableRollback);
- int sessionId = packageInstaller.createSession(params);
- session = packageInstaller.openSession(sessionId);
-
- ClassLoader loader = RollbackTest.class.getClassLoader();
- try (OutputStream packageInSession = session.openWrite(resourceName, 0, -1);
- InputStream is = loader.getResourceAsStream(resourceName);) {
- byte[] buffer = new byte[4096];
- int n;
- while ((n = is.read(buffer)) >= 0) {
- packageInSession.write(buffer, 0, n);
- }
- }
- multiPackage.addChildSessionId(sessionId);
- }
-
- // Commit the session (this will start the installation workflow).
- multiPackage.commit(LocalIntentSender.getIntentSender());
- assertStatusSuccess(LocalIntentSender.getIntentSenderResult());
-
- if (staged) {
- waitForSessionReady(multiPackageId);
- }
- }
-
- /**
- * Installs the apks with the given resource names as an atomic set.
- *
- * @param enableRollback if rollback should be enabled.
- * @param resourceNames names of the class loader resource for the apks to
- * install.
- * @throws AssertionError if the installation fails.
- */
- static void installMultiPackage(boolean enableRollback, String... resourceNames)
- throws InterruptedException, IOException {
- install(false, enableRollback, resourceNames);
- }
-
- /**
- * Installs the APKs or APEXs with the given resource names as a staged
- * atomic set. A resource is assumed to be an APEX if it has the .apex
- * extension.
- *
- * @param enableRollback if rollback should be enabled.
- * @param resourceNames names of the class loader resource for the apks to
- * install.
- * @throws AssertionError if the installation fails.
- */
- static void installStaged(boolean enableRollback, String... resourceNames)
- throws InterruptedException, IOException {
- install(true, enableRollback, resourceNames);
- }
-
- static void adoptShellPermissionIdentity(String... permissions) {
- InstrumentationRegistry
- .getInstrumentation()
- .getUiAutomation()
- .adoptShellPermissionIdentity(permissions);
- }
-
- static void dropShellPermissionIdentity() {
- InstrumentationRegistry
- .getInstrumentation()
- .getUiAutomation()
- .dropShellPermissionIdentity();
- }
-
- /**
- * Returns the RollbackInfo with a given package in the list of rollbacks.
- * Throws an assertion failure if there is more than one such rollback
- * info. Returns null if there are no such rollback infos.
- */
- static RollbackInfo getUniqueRollbackInfoForPackage(List<RollbackInfo> rollbacks,
- String packageName) {
- RollbackInfo found = null;
- for (RollbackInfo rollback : rollbacks) {
- for (PackageRollbackInfo info : rollback.getPackages()) {
- if (packageName.equals(info.getPackageName())) {
- assertNull(found);
- found = rollback;
- break;
- }
- }
- }
- return found;
- }
-
- /**
- * Asserts that the given PackageRollbackInfo has the expected package
- * name and versions.
- */
- static void assertPackageRollbackInfoEquals(String packageName,
- long versionRolledBackFrom, long versionRolledBackTo,
- PackageRollbackInfo info) {
- assertEquals(packageName, info.getPackageName());
- assertEquals(packageName, info.getVersionRolledBackFrom().getPackageName());
- assertEquals(versionRolledBackFrom, info.getVersionRolledBackFrom().getLongVersionCode());
- assertEquals(packageName, info.getVersionRolledBackTo().getPackageName());
- assertEquals(versionRolledBackTo, info.getVersionRolledBackTo().getLongVersionCode());
- }
-
- /**
- * Asserts that the given RollbackInfo has the given packages with expected
- * package names and all are rolled to and from the same given versions.
- */
- static void assertRollbackInfoEquals(String[] packageNames,
- long versionRolledBackFrom, long versionRolledBackTo,
- RollbackInfo info, VersionedPackage... causePackages) {
- assertNotNull(info);
- assertEquals(packageNames.length, info.getPackages().size());
- int foundPackages = 0;
- for (String packageName : packageNames) {
- for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
- if (packageName.equals(pkgRollbackInfo.getPackageName())) {
- foundPackages++;
- assertPackageRollbackInfoEquals(packageName, versionRolledBackFrom,
- versionRolledBackTo, pkgRollbackInfo);
- break;
- }
- }
- }
- assertEquals(packageNames.length, foundPackages);
- assertEquals(causePackages.length, info.getCausePackages().size());
- for (int i = 0; i < causePackages.length; ++i) {
- assertEquals(causePackages[i].getPackageName(),
- info.getCausePackages().get(i).getPackageName());
- assertEquals(causePackages[i].getLongVersionCode(),
- info.getCausePackages().get(i).getLongVersionCode());
- }
- }
-
- /**
- * Asserts that the given RollbackInfo has a single package with expected
- * package name and versions.
- */
- static void assertRollbackInfoEquals(String packageName,
- long versionRolledBackFrom, long versionRolledBackTo,
- RollbackInfo info, VersionedPackage... causePackages) {
- String[] packageNames = {packageName};
- assertRollbackInfoEquals(packageNames, versionRolledBackFrom, versionRolledBackTo, info,
- causePackages);
- }
-
- /**
- * Waits for the given session to be marked as ready.
- * Throws an assertion if the session fails.
- */
- static void waitForSessionReady(int sessionId) {
- BlockingQueue<PackageInstaller.SessionInfo> sessionStatus = new LinkedBlockingQueue<>();
- BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- PackageInstaller.SessionInfo info =
- intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
- if (info != null && info.getSessionId() == sessionId) {
- if (info.isStagedSessionReady() || info.isStagedSessionFailed()) {
- try {
- sessionStatus.put(info);
- } catch (InterruptedException e) {
- Log.e(TAG, "Failed to put session info.", e);
- }
- }
- }
- }
- };
- IntentFilter sessionUpdatedFilter =
- new IntentFilter(PackageInstaller.ACTION_SESSION_UPDATED);
-
- Context context = InstrumentationRegistry.getContext();
- context.registerReceiver(sessionUpdatedReceiver, sessionUpdatedFilter);
-
- PackageInstaller installer = context.getPackageManager().getPackageInstaller();
- PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId);
-
- try {
- if (info.isStagedSessionReady() || info.isStagedSessionFailed()) {
- sessionStatus.put(info);
- }
-
- info = sessionStatus.take();
- context.unregisterReceiver(sessionUpdatedReceiver);
- if (info.isStagedSessionFailed()) {
- throw new AssertionError(info.getStagedSessionErrorMessage());
- }
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- }
- }
-
- private static final String NO_RESPONSE = "NO RESPONSE";
-
- /**
- * Calls into the test app to process user data.
- * Asserts if the user data could not be processed or was version
- * incompatible with the previously processed user data.
- */
- static void processUserData(String packageName) {
- Intent intent = new Intent();
- intent.setComponent(new ComponentName(packageName,
- "com.android.tests.rollback.testapp.ProcessUserData"));
- Context context = InstrumentationRegistry.getContext();
-
- HandlerThread handlerThread = new HandlerThread("RollbackTestHandlerThread");
- handlerThread.start();
-
- // It can sometimes take a while after rollback before the app will
- // receive this broadcast, so try a few times in a loop.
- String result = NO_RESPONSE;
- for (int i = 0; result.equals(NO_RESPONSE) && i < 5; ++i) {
- BlockingQueue<String> resultQueue = new LinkedBlockingQueue<>();
- context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (getResultCode() == 1) {
- resultQueue.add("OK");
- } else {
- // If the test app doesn't receive the broadcast or
- // fails to set the result data, then getResultData
- // here returns the initial NO_RESPONSE data passed to
- // the sendOrderedBroadcast call.
- resultQueue.add(getResultData());
- }
- }
- }, new Handler(handlerThread.getLooper()), 0, NO_RESPONSE, null);
-
- try {
- result = resultQueue.take();
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- }
- }
-
- handlerThread.quit();
- if (!"OK".equals(result)) {
- fail(result);
- }
- }
-
- /**
- * Return the rollback info for a recently committed rollback, by matching the rollback id, or
- * return null if no matching rollback is found.
- */
- static RollbackInfo getRecentlyCommittedRollbackInfoById(int getRollbackId) {
- for (RollbackInfo info : getRollbackManager().getRecentlyCommittedRollbacks()) {
- if (info.getRollbackId() == getRollbackId) {
- return info;
- }
- }
- return null;
- }
-
- /**
- * Send broadcast to crash {@code packageName} {@code count} times. If {@code count} is at least
- * {@link PackageWatchdog#TRIGGER_FAILURE_COUNT}, watchdog crash detection will be triggered.
- */
- static BroadcastReceiver sendCrashBroadcast(Context context, String packageName, int count)
- throws InterruptedException, IOException {
- BlockingQueue<Integer> crashQueue = new SynchronousQueue<>();
- IntentFilter crashCountFilter = new IntentFilter();
- crashCountFilter.addAction("com.android.tests.rollback.CRASH");
- crashCountFilter.addCategory(Intent.CATEGORY_DEFAULT);
-
- BroadcastReceiver crashCountReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- try {
- // Sleep long enough for packagewatchdog to be notified of crash
- Thread.sleep(1000);
- // Kill app and close AppErrorDialog
- ActivityManager am = context.getSystemService(ActivityManager.class);
- am.killBackgroundProcesses(packageName);
- // Allow another package launch
- crashQueue.put(intent.getIntExtra("count", 0));
- } catch (InterruptedException e) {
- fail("Failed to communicate with test app");
- }
- }
- };
- context.registerReceiver(crashCountReceiver, crashCountFilter);
-
- do {
- launchPackage(packageName);
- } while(crashQueue.take() < count);
- return crashCountReceiver;
- }
-}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 1a29c4c..9e6ac8e 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -16,26 +16,34 @@
package com.android.tests.rollback;
-import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals;
-import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
+import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
+import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
import android.Manifest;
-import android.content.BroadcastReceiver;
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.VersionedPackage;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
+import android.text.TextUtils;
import androidx.test.InstrumentationRegistry;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.LocalIntentSender;
+import com.android.cts.install.lib.TestApp;
+import com.android.cts.install.lib.Uninstall;
+import com.android.cts.rollback.lib.Rollback;
+import com.android.cts.rollback.lib.RollbackUtils;
+import com.android.internal.R;
import org.junit.After;
import org.junit.Before;
@@ -54,23 +62,21 @@
@RunWith(JUnit4.class)
public class StagedRollbackTest {
- private static final String TAG = "RollbackTest";
- private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
- private static final String TEST_APP_A_V1 = "RollbackTestAppAv1.apk";
- private static final String TEST_APP_A_CRASHING_V2 = "RollbackTestAppACrashingV2.apk";
private static final String NETWORK_STACK_CONNECTOR_CLASS =
"android.net.INetworkStackConnector";
+ private static final String MODULE_META_DATA_PACKAGE = getModuleMetadataPackageName();
+
/**
* Adopts common shell permissions needed for rollback tests.
*/
@Before
public void adoptShellPermissions() {
- RollbackTestUtils.adoptShellPermissionIdentity(
+ InstallUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
- Manifest.permission.KILL_BACKGROUND_PROCESSES);
+ Manifest.permission.FORCE_STOP_PACKAGES);
}
/**
@@ -78,7 +84,7 @@
*/
@After
public void dropShellPermissions() {
- RollbackTestUtils.dropShellPermissionIdentity();
+ InstallUtils.dropShellPermissionIdentity();
}
/**
@@ -87,14 +93,14 @@
*/
@Test
public void testBadApkOnlyEnableRollback() throws Exception {
- RollbackTestUtils.uninstall(TEST_APP_A);
- assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ Uninstall.packages(TestApp.A);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
- RollbackTestUtils.install(TEST_APP_A_V1, false);
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- RollbackTestUtils.processUserData(TEST_APP_A);
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ InstallUtils.processUserData(TestApp.A);
- RollbackTestUtils.installStaged(true, TEST_APP_A_CRASHING_V2);
+ Install.single(TestApp.ACrashing2).setEnableRollback().setStaged().commit();
// At this point, the host test driver will reboot the device and run
// testBadApkOnlyConfirmEnableRollback().
@@ -106,14 +112,16 @@
*/
@Test
public void testBadApkOnlyConfirmEnableRollback() throws Exception {
- assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- RollbackTestUtils.processUserData(TEST_APP_A);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ InstallUtils.processUserData(TestApp.A);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
- assertTrue(rollback.isStaged());
+ rm.getAvailableRollbacks(), TestApp.A);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
+ assertThat(rollback.isStaged()).isTrue();
// At this point, the host test driver will run
// testBadApkOnlyTriggerRollback().
@@ -126,18 +134,8 @@
*/
@Test
public void testBadApkOnlyTriggerRollback() throws Exception {
- BroadcastReceiver crashCountReceiver = null;
- Context context = InstrumentationRegistry.getContext();
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
-
- try {
- // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
- crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5);
- } finally {
- if (crashCountReceiver != null) {
- context.unregisterReceiver(crashCountReceiver);
- }
- }
+ // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
+ RollbackUtils.sendCrashBroadcast(TestApp.A, 5);
// We expect the device to be rebooted automatically. Wait for that to
// happen. At that point, the host test driver will wait for the
@@ -153,48 +151,80 @@
*/
@Test
public void testBadApkOnlyConfirmRollback() throws Exception {
- assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
- RollbackTestUtils.processUserData(TEST_APP_A);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ InstallUtils.processUserData(TestApp.A);
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, new VersionedPackage(TEST_APP_A, 2));
- assertTrue(rollback.isStaged());
- assertNotEquals(-1, rollback.getCommittedSessionId());
+ rm.getRecentlyCommittedRollbacks(), TestApp.A);
+ assertThat(rollback).isNotNull();
+ assertThat(rollback).packagesContainsExactly(
+ Rollback.from(TestApp.A2).to(TestApp.A1));
+ assertThat(rollback).causePackagesContainsExactly(TestApp.ACrashing2);
+ assertThat(rollback).isStaged();
+ assertThat(rollback.getCommittedSessionId()).isNotEqualTo(-1);
}
@Test
public void resetNetworkStack() throws Exception {
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackManager rm = RollbackUtils.getRollbackManager();
String networkStack = getNetworkStackPackageName();
rm.expireRollbackForPackage(networkStack);
- RollbackTestUtils.uninstall(networkStack);
+ Uninstall.packages(networkStack);
- assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
- networkStack));
+ assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+ networkStack)).isNull();
+ }
+
+ @Test
+ public void installModuleMetadataPackage() throws Exception {
+ resetModuleMetadataPackage();
+ Context context = InstrumentationRegistry.getContext();
+ PackageInfo metadataPackageInfo = context.getPackageManager().getPackageInfo(
+ MODULE_META_DATA_PACKAGE, 0);
+ String metadataApkPath = metadataPackageInfo.applicationInfo.sourceDir;
+ assertThat(metadataApkPath).isNotNull();
+ assertThat(metadataApkPath).isNotEqualTo("");
+
+ runShellCommand("pm install "
+ + "-r --enable-rollback --staged --wait "
+ + metadataApkPath);
}
@Test
public void assertNetworkStackRollbackAvailable() throws Exception {
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- assertNotNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
- getNetworkStackPackageName()));
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+ getNetworkStackPackageName())).isNotNull();
}
@Test
public void assertNetworkStackRollbackCommitted() throws Exception {
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- assertNotNull(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
- getNetworkStackPackageName()));
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+ getNetworkStackPackageName())).isNotNull();
}
@Test
public void assertNoNetworkStackRollbackCommitted() throws Exception {
- RollbackManager rm = RollbackTestUtils.getRollbackManager();
- assertNull(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
- getNetworkStackPackageName()));
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+ getNetworkStackPackageName())).isNull();
+ }
+
+ @Test
+ public void assertModuleMetadataRollbackAvailable() throws Exception {
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+ MODULE_META_DATA_PACKAGE)).isNotNull();
+ }
+
+ @Test
+ public void assertModuleMetadataRollbackCommitted() throws Exception {
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+ MODULE_META_DATA_PACKAGE)).isNotNull();
}
private String getNetworkStackPackageName() {
@@ -203,4 +233,65 @@
InstrumentationRegistry.getContext().getPackageManager(), 0);
return comp.getPackageName();
}
+
+ @Test
+ public void testPreviouslyAbandonedRollbacksEnableRollback() throws Exception {
+ Uninstall.packages(TestApp.A);
+ Install.single(TestApp.A1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+
+ int sessionId = Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
+ PackageInstaller pi = InstrumentationRegistry.getContext().getPackageManager()
+ .getPackageInstaller();
+ pi.abandonSession(sessionId);
+
+ // Remove the first intent sender result, so that the next staged install session does not
+ // erroneously think that it has itself been abandoned.
+ // TODO(b/136260017): Restructure LocalIntentSender to negate the need for this step.
+ LocalIntentSender.getIntentSenderResult();
+ Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
+ }
+
+ @Test
+ public void testPreviouslyAbandonedRollbacksCommitRollback() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ InstallUtils.processUserData(TestApp.A);
+
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TestApp.A);
+ RollbackUtils.rollback(rollback.getRollbackId());
+ }
+
+ @Test
+ public void testPreviouslyAbandonedRollbacksCheckUserdataRollback() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ InstallUtils.processUserData(TestApp.A);
+ Uninstall.packages(TestApp.A);
+ }
+
+ @Nullable
+ private static String getModuleMetadataPackageName() {
+ String packageName = InstrumentationRegistry.getContext().getResources().getString(
+ R.string.config_defaultModuleMetadataProvider);
+ if (TextUtils.isEmpty(packageName)) {
+ return null;
+ }
+ return packageName;
+ }
+
+ private void resetModuleMetadataPackage() {
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+
+ assertThat(MODULE_META_DATA_PACKAGE).isNotNull();
+ rm.expireRollbackForPackage(MODULE_META_DATA_PACKAGE);
+
+ assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+ MODULE_META_DATA_PACKAGE)).isNull();
+ }
+
+ private void runShellCommand(String cmd) {
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .executeShellCommand(cmd);
+ }
}
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index b767b08..f74aaf3 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -29,11 +29,15 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.TimeUnit;
+
/**
* Runs the staged rollback tests.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedRollbackTest extends BaseHostJUnit4Test {
+ private static final int NATIVE_CRASHES_THRESHOLD = 5;
+
/**
* Runs the given phase of a test by calling into the device.
* Throws an exception if the test phase fails.
@@ -84,6 +88,35 @@
runPhase("testBadApkOnlyConfirmRollback");
}
+ @Test
+ public void testNativeWatchdogTriggersRollback() throws Exception {
+ //Stage install ModuleMetadata package - this simulates a Mainline module update
+ runPhase("installModuleMetadataPackage");
+
+ // Reboot device to activate staged package
+ getDevice().reboot();
+ getDevice().waitForDeviceAvailable();
+
+ runPhase("assertModuleMetadataRollbackAvailable");
+
+ // crash system_server enough times to trigger a rollback
+ crashProcess("system_server", NATIVE_CRASHES_THRESHOLD);
+
+ // Rollback should be committed automatically now.
+ // Give time for rollback to be committed. This could take a while,
+ // because we need all of the following to happen:
+ // 1. system_server comes back up and boot completes.
+ // 2. Rollback health observer detects updatable crashing signal.
+ // 3. Staged rollback session becomes ready.
+ // 4. Device actually reboots.
+ // So we give a generous timeout here.
+ assertTrue(getDevice().waitForDeviceNotAvailable(TimeUnit.MINUTES.toMillis(5)));
+ getDevice().waitForDeviceAvailable();
+
+ // verify rollback committed
+ runPhase("assertModuleMetadataRollbackCommitted");
+ }
+
/**
* Tests failed network health check triggers watchdog staged rollbacks.
*/
@@ -167,6 +200,32 @@
runPhase("assertNoNetworkStackRollbackCommitted");
}
+ /**
+ * Tests rolling back user data where there are multiple rollbacks for that package.
+ */
+ @Test
+ public void testPreviouslyAbandonedRollbacks() throws Exception {
+ runPhase("testPreviouslyAbandonedRollbacksEnableRollback");
+ getDevice().reboot();
+ runPhase("testPreviouslyAbandonedRollbacksCommitRollback");
+ getDevice().reboot();
+ runPhase("testPreviouslyAbandonedRollbacksCheckUserdataRollback");
+ }
+
+ private void crashProcess(String processName, int numberOfCrashes) throws Exception {
+ String pid = "";
+ String lastPid = "invalid";
+ for (int i = 0; i < numberOfCrashes; ++i) {
+ // This condition makes sure before we kill the process, the process is running AND
+ // the last crash was finished.
+ while ("".equals(pid) || lastPid.equals(pid)) {
+ pid = getDevice().executeShellCommand("pidof " + processName);
+ }
+ getDevice().executeShellCommand("kill " + pid);
+ lastPid = pid;
+ }
+ }
+
private String getNetworkStackPath() throws DeviceNotAvailableException {
// Find the NetworkStack path (can be NetworkStack.apk or NetworkStackNext.apk)
return getDevice().executeShellCommand("ls /system/priv-app/NetworkStack*/*.apk");
diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING
index 6be93a0..fefde5b 100644
--- a/tests/RollbackTest/TEST_MAPPING
+++ b/tests/RollbackTest/TEST_MAPPING
@@ -5,6 +5,9 @@
},
{
"name": "StagedRollbackTest"
+ },
+ {
+ "name": "MultiUserRollbackTest"
}
]
}
diff --git a/tests/RollbackTest/TestApp/ACrashingV2.xml b/tests/RollbackTest/TestApp/ACrashingV2.xml
deleted file mode 100644
index 77bfd4e..0000000
--- a/tests/RollbackTest/TestApp/ACrashingV2.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tests.rollback.testapp.A"
- android:versionCode="2"
- android:versionName="2.0" >
-
-
- <uses-sdk android:minSdkVersion="19" />
-
- <application android:label="Rollback Test App A v2">
- <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
- android:exported="true" />
- <activity android:name="com.android.tests.rollback.testapp.CrashingMainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Av1.xml b/tests/RollbackTest/TestApp/Av1.xml
deleted file mode 100644
index 63729fb..0000000
--- a/tests/RollbackTest/TestApp/Av1.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tests.rollback.testapp.A"
- android:versionCode="1"
- android:versionName="1.0" >
-
-
- <uses-sdk android:minSdkVersion="19" />
-
- <application android:label="Rollback Test App A v1">
- <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
- android:exported="true" />
- <activity android:name="com.android.tests.rollback.testapp.MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Av2.xml b/tests/RollbackTest/TestApp/Av2.xml
deleted file mode 100644
index f0e909f..0000000
--- a/tests/RollbackTest/TestApp/Av2.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tests.rollback.testapp.A"
- android:versionCode="2"
- android:versionName="2.0" >
-
-
- <uses-sdk android:minSdkVersion="19" />
-
- <application android:label="Rollback Test App A v2">
- <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
- android:exported="true" />
- <activity android:name="com.android.tests.rollback.testapp.MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Av3.xml b/tests/RollbackTest/TestApp/Av3.xml
deleted file mode 100644
index 9725c9f7..0000000
--- a/tests/RollbackTest/TestApp/Av3.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tests.rollback.testapp.A"
- android:versionCode="3"
- android:versionName="3.0" >
-
-
- <uses-sdk android:minSdkVersion="19" />
-
- <application android:label="Rollback Test App A v3">
- <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
- android:exported="true" />
- <activity android:name="com.android.tests.rollback.testapp.MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Bv1.xml b/tests/RollbackTest/TestApp/Bv1.xml
deleted file mode 100644
index ca9c2ec..0000000
--- a/tests/RollbackTest/TestApp/Bv1.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tests.rollback.testapp.B"
- android:versionCode="1"
- android:versionName="1.0" >
-
-
- <uses-sdk android:minSdkVersion="19" />
-
- <application android:label="Rollback Test App B v1">
- <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
- android:exported="true" />
- <activity android:name="com.android.tests.rollback.testapp.MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Bv2.xml b/tests/RollbackTest/TestApp/Bv2.xml
deleted file mode 100644
index bd3e613..0000000
--- a/tests/RollbackTest/TestApp/Bv2.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tests.rollback.testapp.B"
- android:versionCode="2"
- android:versionName="2.0" >
-
-
- <uses-sdk android:minSdkVersion="19" />
-
- <application android:label="Rollback Test App B v2">
- <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
- android:exported="true" />
- <activity android:name="com.android.tests.rollback.testapp.MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/res_v1/values-anydpi/values.xml b/tests/RollbackTest/TestApp/res_v1/values-anydpi/values.xml
deleted file mode 100644
index 90d3da2..0000000
--- a/tests/RollbackTest/TestApp/res_v1/values-anydpi/values.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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>
- <integer name="split_version">1</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v1/values/values.xml b/tests/RollbackTest/TestApp/res_v1/values/values.xml
deleted file mode 100644
index 0447c74..0000000
--- a/tests/RollbackTest/TestApp/res_v1/values/values.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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>
- <integer name="app_version">1</integer>
- <integer name="split_version">0</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v2/values-anydpi/values.xml b/tests/RollbackTest/TestApp/res_v2/values-anydpi/values.xml
deleted file mode 100644
index 9a1aa7f..0000000
--- a/tests/RollbackTest/TestApp/res_v2/values-anydpi/values.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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>
- <integer name="split_version">2</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v2/values/values.xml b/tests/RollbackTest/TestApp/res_v2/values/values.xml
deleted file mode 100644
index fd988f5..0000000
--- a/tests/RollbackTest/TestApp/res_v2/values/values.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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>
- <integer name="app_version">2</integer>
- <integer name="split_version">0</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v3/values-anydpi/values.xml b/tests/RollbackTest/TestApp/res_v3/values-anydpi/values.xml
deleted file mode 100644
index f2d8992..0000000
--- a/tests/RollbackTest/TestApp/res_v3/values-anydpi/values.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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>
- <integer name="split_version">3</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v3/values/values.xml b/tests/RollbackTest/TestApp/res_v3/values/values.xml
deleted file mode 100644
index 968168a..0000000
--- a/tests/RollbackTest/TestApp/res_v3/values/values.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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>
- <integer name="app_version">3</integer>
- <integer name="split_version">0</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/CrashingMainActivity.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/CrashingMainActivity.java
deleted file mode 100644
index 97958ac..0000000
--- a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/CrashingMainActivity.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 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.tests.rollback.testapp;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-
-/**
- * A crashing test app for testing apk rollback support.
- */
-public class CrashingMainActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- incrementCountAndBroadcast();
- throw new RuntimeException("Intended force crash");
- }
-
- private void incrementCountAndBroadcast() {
- SharedPreferences preferences = getSharedPreferences("prefs", Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = preferences.edit();
- int count = preferences.getInt("crash_count", 0);
- editor.putInt("crash_count", ++count).commit();
-
- Intent intent = new Intent("com.android.tests.rollback.CRASH");
- intent.putExtra("count", count);
- sendBroadcast(intent);
- }
-}
diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java
deleted file mode 100644
index 9f1a060..0000000
--- a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 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 com.android.tests.rollback.testapp;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-/**
- * A test app for testing apk rollback support.
- */
-public class MainActivity extends Activity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- try {
- new ProcessUserData().processUserData(this);
- } catch (ProcessUserData.UserDataException e) {
- throw new AssertionError("Failed to process app user data", e);
- }
- }
-}
diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/ProcessUserData.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/ProcessUserData.java
deleted file mode 100644
index 38c658e..0000000
--- a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/ProcessUserData.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 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 com.android.tests.rollback.testapp;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Scanner;
-
-/**
- * A broadcast reciever to check for and update user app data version
- * compatibility.
- */
-public class ProcessUserData extends BroadcastReceiver {
-
- private static final String TAG = "RollbackTestApp";
-
- /**
- * Exception thrown in case of issue with user data.
- */
- public static class UserDataException extends Exception {
- public UserDataException(String message) {
- super(message);
- }
-
- public UserDataException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- try {
- processUserData(context);
- setResultCode(1);
- } catch (UserDataException e) {
- setResultCode(0);
- setResultData(e.getMessage());
- }
- }
-
- /**
- * Update the app's user data version to match the app version.
- *
- * @param context The application context.
- * @throws UserDataException in case of problems with app user data.
- */
- public void processUserData(Context context) throws UserDataException {
- Resources res = context.getResources();
- String packageName = context.getPackageName();
-
- int appVersionId = res.getIdentifier("app_version", "integer", packageName);
- int appVersion = res.getInteger(appVersionId);
-
- int splitVersionId = res.getIdentifier("split_version", "integer", packageName);
- int splitVersion = res.getInteger(splitVersionId);
-
- // Make sure the app version and split versions are compatible.
- if (appVersion != splitVersion) {
- throw new UserDataException("Split version " + splitVersion
- + " does not match app version " + appVersion);
- }
-
- // Read the version of the app's user data and ensure it is compatible
- // with our version of the application.
- File versionFile = new File(context.getFilesDir(), "version.txt");
- try {
- Scanner s = new Scanner(versionFile);
- int userDataVersion = s.nextInt();
- s.close();
-
- if (userDataVersion > appVersion) {
- throw new UserDataException("User data is from version " + userDataVersion
- + ", which is not compatible with this version " + appVersion
- + " of the RollbackTestApp");
- }
- } catch (FileNotFoundException e) {
- // No problem. This is a fresh install of the app or the user data
- // has been wiped.
- }
-
- // Record the current version of the app in the user data.
- try {
- PrintWriter pw = new PrintWriter(versionFile);
- pw.println(appVersion);
- pw.close();
- } catch (IOException e) {
- throw new UserDataException("Unable to write user data.", e);
- }
- }
-}
diff --git a/tests/net/java/android/net/ip/InterfaceControllerTest.java b/tests/net/java/android/net/ip/InterfaceControllerTest.java
deleted file mode 100644
index 7a56b3a..0000000
--- a/tests/net/java/android/net/ip/InterfaceControllerTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.ip;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.INetd;
-import android.net.InetAddresses;
-import android.net.InterfaceConfigurationParcel;
-import android.net.LinkAddress;
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class InterfaceControllerTest {
- private static final String TEST_IFACE = "testif";
- private static final String TEST_IPV4_ADDR = "192.168.123.28";
- private static final int TEST_PREFIXLENGTH = 31;
-
- @Mock private INetd mNetd;
- @Mock private SharedLog mLog;
- @Captor private ArgumentCaptor<InterfaceConfigurationParcel> mConfigCaptor;
-
- private InterfaceController mController;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mController = new InterfaceController(TEST_IFACE, mNetd, mLog);
-
- doNothing().when(mNetd).interfaceSetCfg(mConfigCaptor.capture());
- }
-
- @Test
- public void testSetIPv4Address() throws Exception {
- mController.setIPv4Address(
- new LinkAddress(InetAddresses.parseNumericAddress(TEST_IPV4_ADDR),
- TEST_PREFIXLENGTH));
- verify(mNetd, times(1)).interfaceSetCfg(any());
- final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue();
- assertEquals(TEST_IFACE, parcel.ifName);
- assertEquals(TEST_IPV4_ADDR, parcel.ipv4Addr);
- assertEquals(TEST_PREFIXLENGTH, parcel.prefixLength);
- assertEquals("", parcel.hwAddr);
- assertArrayEquals(new String[0], parcel.flags);
- }
-
- @Test
- public void testClearIPv4Address() throws Exception {
- mController.clearIPv4Address();
- verify(mNetd, times(1)).interfaceSetCfg(any());
- final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue();
- assertEquals(TEST_IFACE, parcel.ifName);
- assertEquals("0.0.0.0", parcel.ipv4Addr);
- assertEquals(0, parcel.prefixLength);
- assertEquals("", parcel.hwAddr);
- assertArrayEquals(new String[0], parcel.flags);
- }
-}
diff --git a/tests/net/java/android/net/netlink/ConntrackMessageTest.java b/tests/net/java/android/net/netlink/ConntrackMessageTest.java
deleted file mode 100644
index 5c86757..0000000
--- a/tests/net/java/android/net/netlink/ConntrackMessageTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netlink;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assume.assumeTrue;
-
-import android.system.OsConstants;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteOrder;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ConntrackMessageTest {
- private static final boolean USING_LE = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
-
- // Example 1: TCP (192.168.43.209, 44333) -> (23.211.13.26, 443)
- public static final String CT_V4UPDATE_TCP_HEX =
- // struct nlmsghdr
- "50000000" + // length = 80
- "0001" + // type = (1 << 8) | 0
- "0501" + // flags
- "01000000" + // seqno = 1
- "00000000" + // pid = 0
- // struct nfgenmsg
- "02" + // nfgen_family = AF_INET
- "00" + // version = NFNETLINK_V0
- "0000" + // res_id
- // struct nlattr
- "3400" + // nla_len = 52
- "0180" + // nla_type = nested CTA_TUPLE_ORIG
- // struct nlattr
- "1400" + // nla_len = 20
- "0180" + // nla_type = nested CTA_TUPLE_IP
- "0800 0100 C0A82BD1" + // nla_type=CTA_IP_V4_SRC, ip=192.168.43.209
- "0800 0200 17D30D1A" + // nla_type=CTA_IP_V4_DST, ip=23.211.13.26
- // struct nlattr
- "1C00" + // nla_len = 28
- "0280" + // nla_type = nested CTA_TUPLE_PROTO
- "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=6
- "0600 0200 AD2D 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=44333 (big endian)
- "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
- // struct nlattr
- "0800" + // nla_len = 8
- "0700" + // nla_type = CTA_TIMEOUT
- "00069780"; // nla_value = 432000 (big endian)
- public static final byte[] CT_V4UPDATE_TCP_BYTES =
- HexEncoding.decode(CT_V4UPDATE_TCP_HEX.replaceAll(" ", "").toCharArray(), false);
-
- // Example 2: UDP (100.96.167.146, 37069) -> (216.58.197.10, 443)
- public static final String CT_V4UPDATE_UDP_HEX =
- // struct nlmsghdr
- "50000000" + // length = 80
- "0001" + // type = (1 << 8) | 0
- "0501" + // flags
- "01000000" + // seqno = 1
- "00000000" + // pid = 0
- // struct nfgenmsg
- "02" + // nfgen_family = AF_INET
- "00" + // version = NFNETLINK_V0
- "0000" + // res_id
- // struct nlattr
- "3400" + // nla_len = 52
- "0180" + // nla_type = nested CTA_TUPLE_ORIG
- // struct nlattr
- "1400" + // nla_len = 20
- "0180" + // nla_type = nested CTA_TUPLE_IP
- "0800 0100 6460A792" + // nla_type=CTA_IP_V4_SRC, ip=100.96.167.146
- "0800 0200 D83AC50A" + // nla_type=CTA_IP_V4_DST, ip=216.58.197.10
- // struct nlattr
- "1C00" + // nla_len = 28
- "0280" + // nla_type = nested CTA_TUPLE_PROTO
- "0500 0100 11 000000" + // nla_type=CTA_PROTO_NUM, proto=17
- "0600 0200 90CD 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=37069 (big endian)
- "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
- // struct nlattr
- "0800" + // nla_len = 8
- "0700" + // nla_type = CTA_TIMEOUT
- "000000B4"; // nla_value = 180 (big endian)
- public static final byte[] CT_V4UPDATE_UDP_BYTES =
- HexEncoding.decode(CT_V4UPDATE_UDP_HEX.replaceAll(" ", "").toCharArray(), false);
-
- @Test
- public void testConntrackIPv4TcpTimeoutUpdate() throws Exception {
- assumeTrue(USING_LE);
-
- final byte[] tcp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
- OsConstants.IPPROTO_TCP,
- (Inet4Address) InetAddress.getByName("192.168.43.209"), 44333,
- (Inet4Address) InetAddress.getByName("23.211.13.26"), 443,
- 432000);
- assertArrayEquals(CT_V4UPDATE_TCP_BYTES, tcp);
- }
-
- @Test
- public void testConntrackIPv4UdpTimeoutUpdate() throws Exception {
- assumeTrue(USING_LE);
-
- final byte[] udp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
- OsConstants.IPPROTO_UDP,
- (Inet4Address) InetAddress.getByName("100.96.167.146"), 37069,
- (Inet4Address) InetAddress.getByName("216.58.197.10"), 443,
- 180);
- assertArrayEquals(CT_V4UPDATE_UDP_BYTES, udp);
- }
-}
diff --git a/tests/net/java/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
deleted file mode 100644
index 1f2bb0a..0000000
--- a/tests/net/java/android/net/netlink/InetDiagSocketTest.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (C) 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.net.netlink;
-
-import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_STREAM;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.netlink.StructNlMsgHdr;
-import android.os.Process;
-import android.system.Os;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.FileDescriptor;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class InetDiagSocketTest {
- private final String TAG = "InetDiagSocketTest";
- private ConnectivityManager mCm;
- private Context mContext;
- private final static int SOCKET_TIMEOUT_MS = 100;
-
- @Before
- public void setUp() throws Exception {
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- mContext = instrumentation.getTargetContext();
- mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- }
-
- private class Connection {
- public int socketDomain;
- public int socketType;
- public InetAddress localAddress;
- public InetAddress remoteAddress;
- public InetAddress localhostAddress;
- public InetSocketAddress local;
- public InetSocketAddress remote;
- public int protocol;
- public FileDescriptor localFd;
- public FileDescriptor remoteFd;
-
- public FileDescriptor createSocket() throws Exception {
- return Os.socket(socketDomain, socketType, protocol);
- }
-
- public Connection(String to, String from) throws Exception {
- remoteAddress = InetAddress.getByName(to);
- if (from != null) {
- localAddress = InetAddress.getByName(from);
- } else {
- localAddress = (remoteAddress instanceof Inet4Address) ?
- Inet4Address.getByName("localhost") : Inet6Address.getByName("::");
- }
- if ((localAddress instanceof Inet4Address) && (remoteAddress instanceof Inet4Address)) {
- socketDomain = AF_INET;
- localhostAddress = Inet4Address.getByName("localhost");
- } else {
- socketDomain = AF_INET6;
- localhostAddress = Inet6Address.getByName("::");
- }
- }
-
- public void close() throws Exception {
- Os.close(localFd);
- }
- }
-
- private class TcpConnection extends Connection {
- public TcpConnection(String to, String from) throws Exception {
- super(to, from);
- protocol = IPPROTO_TCP;
- socketType = SOCK_STREAM;
-
- remoteFd = createSocket();
- Os.bind(remoteFd, remoteAddress, 0);
- Os.listen(remoteFd, 10);
- int remotePort = ((InetSocketAddress) Os.getsockname(remoteFd)).getPort();
-
- localFd = createSocket();
- Os.bind(localFd, localAddress, 0);
- Os.connect(localFd, remoteAddress, remotePort);
-
- local = (InetSocketAddress) Os.getsockname(localFd);
- remote = (InetSocketAddress) Os.getpeername(localFd);
- }
-
- public void close() throws Exception {
- super.close();
- Os.close(remoteFd);
- }
- }
- private class UdpConnection extends Connection {
- public UdpConnection(String to, String from) throws Exception {
- super(to, from);
- protocol = IPPROTO_UDP;
- socketType = SOCK_DGRAM;
-
- remoteFd = null;
- localFd = createSocket();
- Os.bind(localFd, localAddress, 0);
-
- Os.connect(localFd, remoteAddress, 7);
- local = (InetSocketAddress) Os.getsockname(localFd);
- remote = new InetSocketAddress(remoteAddress, 7);
- }
- }
-
- private void checkConnectionOwnerUid(int protocol, InetSocketAddress local,
- InetSocketAddress remote, boolean expectSuccess) {
- final int uid = mCm.getConnectionOwnerUid(protocol, local, remote);
-
- if (expectSuccess) {
- assertEquals(Process.myUid(), uid);
- } else {
- assertNotEquals(Process.myUid(), uid);
- }
- }
-
- private int findLikelyFreeUdpPort(UdpConnection conn) throws Exception {
- UdpConnection udp = new UdpConnection(conn.remoteAddress.getHostAddress(),
- conn.localAddress.getHostAddress());
- final int localPort = udp.local.getPort();
- udp.close();
- return localPort;
- }
-
- /**
- * Create a test connection for UDP and TCP sockets and verify that this
- * {protocol, local, remote} socket result in receiving a valid UID.
- */
- public void checkGetConnectionOwnerUid(String to, String from) throws Exception {
- TcpConnection tcp = new TcpConnection(to, from);
- checkConnectionOwnerUid(tcp.protocol, tcp.local, tcp.remote, true);
- checkConnectionOwnerUid(IPPROTO_UDP, tcp.local, tcp.remote, false);
- checkConnectionOwnerUid(tcp.protocol, new InetSocketAddress(0), tcp.remote, false);
- checkConnectionOwnerUid(tcp.protocol, tcp.local, new InetSocketAddress(0), false);
- tcp.close();
-
- UdpConnection udp = new UdpConnection(to,from);
- checkConnectionOwnerUid(udp.protocol, udp.local, udp.remote, true);
- checkConnectionOwnerUid(IPPROTO_TCP, udp.local, udp.remote, false);
- checkConnectionOwnerUid(udp.protocol, new InetSocketAddress(findLikelyFreeUdpPort(udp)),
- udp.remote, false);
- udp.close();
- }
-
- @Test
- public void testGetConnectionOwnerUid() throws Exception {
- checkGetConnectionOwnerUid("::", null);
- checkGetConnectionOwnerUid("::", "::");
- checkGetConnectionOwnerUid("0.0.0.0", null);
- checkGetConnectionOwnerUid("0.0.0.0", "0.0.0.0");
- checkGetConnectionOwnerUid("127.0.0.1", null);
- checkGetConnectionOwnerUid("127.0.0.1", "127.0.0.2");
- checkGetConnectionOwnerUid("::1", null);
- checkGetConnectionOwnerUid("::1", "::1");
- }
-
- @Ignore("Times out on Marlin/Sailfish")
- /* Verify fix for b/141603906 */
- @Test
- public void testB141603906() throws Exception {
- final InetSocketAddress src = new InetSocketAddress(0);
- final InetSocketAddress dst = new InetSocketAddress(0);
- for (int i = 1; i <= 100000; i++) {
- mCm.getConnectionOwnerUid(IPPROTO_TCP, src, dst);
- }
- }
-
- // Hexadecimal representation of InetDiagReqV2 request.
- private static final String INET_DIAG_REQ_V2_UDP_INET4_HEX =
- // struct nlmsghdr
- "48000000" + // length = 72
- "1400" + // type = SOCK_DIAG_BY_FAMILY
- "0103" + // flags = NLM_F_REQUEST | NLM_F_DUMP
- "00000000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct inet_diag_req_v2
- "02" + // family = AF_INET
- "11" + // protcol = IPPROTO_UDP
- "00" + // idiag_ext
- "00" + // pad
- "ffffffff" + // idiag_states
- // inet_diag_sockid
- "a5de" + // idiag_sport = 42462
- "b971" + // idiag_dport = 47473
- "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2
- "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8
- "00000000" + // idiag_if
- "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE
- private static final byte[] INET_DIAG_REQ_V2_UDP_INET4_BYTES =
- HexEncoding.decode(INET_DIAG_REQ_V2_UDP_INET4_HEX.toCharArray(), false);
-
- @Test
- public void testInetDiagReqV2UdpInet4() throws Exception {
- InetSocketAddress local = new InetSocketAddress(InetAddress.getByName("10.0.100.2"),
- 42462);
- InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"),
- 47473);
- final byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_UDP, local, remote, AF_INET,
- (short) (NLM_F_REQUEST | NLM_F_DUMP));
- assertArrayEquals(INET_DIAG_REQ_V2_UDP_INET4_BYTES, msg);
- }
-
- // Hexadecimal representation of InetDiagReqV2 request.
- private static final String INET_DIAG_REQ_V2_TCP_INET6_HEX =
- // struct nlmsghdr
- "48000000" + // length = 72
- "1400" + // type = SOCK_DIAG_BY_FAMILY
- "0100" + // flags = NLM_F_REQUEST
- "00000000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct inet_diag_req_v2
- "0a" + // family = AF_INET6
- "06" + // protcol = IPPROTO_TCP
- "00" + // idiag_ext
- "00" + // pad
- "ffffffff" + // idiag_states
- // inet_diag_sockid
- "a5de" + // idiag_sport = 42462
- "b971" + // idiag_dport = 47473
- "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b
- "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8
- "00000000" + // idiag_if
- "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE
- private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_BYTES =
- HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_HEX.toCharArray(), false);
-
- @Test
- public void testInetDiagReqV2TcpInet6() throws Exception {
- InetSocketAddress local = new InetSocketAddress(
- InetAddress.getByName("fe80::86c9:b2ff:fe6a:ed4b"), 42462);
- InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"),
- 47473);
- byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET6,
- NLM_F_REQUEST);
-
- assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_BYTES, msg);
- }
-
- // Hexadecimal representation of InetDiagReqV2 request with extension, INET_DIAG_INFO.
- private static final String INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_HEX =
- // struct nlmsghdr
- "48000000" + // length = 72
- "1400" + // type = SOCK_DIAG_BY_FAMILY
- "0100" + // flags = NLM_F_REQUEST
- "00000000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct inet_diag_req_v2
- "02" + // family = AF_INET
- "06" + // protcol = IPPROTO_TCP
- "02" + // idiag_ext = INET_DIAG_INFO
- "00" + // pad
- "ffffffff" + // idiag_states
- // inet_diag_sockid
- "3039" + // idiag_sport = 12345
- "d431" + // idiag_dport = 54321
- "01020304000000000000000000000000" + // idiag_src = 1.2.3.4
- "08080404000000000000000000000000" + // idiag_dst = 8.8.4.4
- "00000000" + // idiag_if
- "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE
-
- private static final byte[] INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_BYTES =
- HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_HEX.toCharArray(), false);
- private static final int TCP_ALL_STATES = 0xffffffff;
- @Test
- public void testInetDiagReqV2TcpInetWithExt() throws Exception {
- InetSocketAddress local = new InetSocketAddress(
- InetAddress.getByName("1.2.3.4"), 12345);
- InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.4.4"),
- 54321);
- byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET,
- NLM_F_REQUEST, 0 /* pad */, 2 /* idiagExt */, TCP_ALL_STATES);
-
- assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET_INET_DIAG_BYTES, msg);
-
- local = new InetSocketAddress(
- InetAddress.getByName("fe80::86c9:b2ff:fe6a:ed4b"), 42462);
- remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"),
- 47473);
- msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET6,
- NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES);
-
- assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_BYTES, msg);
- }
-
- // Hexadecimal representation of InetDiagReqV2 request with no socket specified.
- private static final String INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_HEX =
- // struct nlmsghdr
- "48000000" + // length = 72
- "1400" + // type = SOCK_DIAG_BY_FAMILY
- "0100" + // flags = NLM_F_REQUEST
- "00000000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct inet_diag_req_v2
- "0a" + // family = AF_INET6
- "06" + // protcol = IPPROTO_TCP
- "00" + // idiag_ext
- "00" + // pad
- "ffffffff" + // idiag_states
- // inet_diag_sockid
- "0000" + // idiag_sport
- "0000" + // idiag_dport
- "00000000000000000000000000000000" + // idiag_src
- "00000000000000000000000000000000" + // idiag_dst
- "00000000" + // idiag_if
- "0000000000000000"; // idiag_cookie
-
- private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFED_BYTES =
- HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFIED_HEX.toCharArray(), false);
-
- @Test
- public void testInetDiagReqV2TcpInet6NoIdSpecified() throws Exception {
- InetSocketAddress local = new InetSocketAddress(
- InetAddress.getByName("fe80::fe6a:ed4b"), 12345);
- InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.4.4"),
- 54321);
- // Verify no socket specified if either local or remote socket address is null.
- byte[] msgExt = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, null, null, AF_INET6,
- NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES);
- byte[] msg;
- try {
- msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, null, remote, AF_INET6,
- NLM_F_REQUEST);
- fail("Both remote and local should be null, expected UnknownHostException");
- } catch (NullPointerException e) {
- }
-
- try {
- msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, local, null, AF_INET6,
- NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES);
- fail("Both remote and local should be null, expected UnknownHostException");
- } catch (NullPointerException e) {
- }
-
- msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, null, null, AF_INET6,
- NLM_F_REQUEST, 0 /* pad */, 0 /* idiagExt */, TCP_ALL_STATES);
- assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFED_BYTES, msg);
- assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_NO_ID_SPECIFED_BYTES, msgExt);
- }
-
- // Hexadecimal representation of InetDiagReqV2 request.
- private static final String INET_DIAG_MSG_HEX =
- // struct nlmsghdr
- "58000000" + // length = 88
- "1400" + // type = SOCK_DIAG_BY_FAMILY
- "0200" + // flags = NLM_F_MULTI
- "00000000" + // seqno
- "f5220000" + // pid (0 == kernel)
- // struct inet_diag_msg
- "0a" + // family = AF_INET6
- "01" + // idiag_state
- "00" + // idiag_timer
- "00" + // idiag_retrans
- // inet_diag_sockid
- "a817" + // idiag_sport = 43031
- "960f" + // idiag_dport = 38415
- "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b
- "00000000000000000000ffff08080808" + // idiag_dst = 8.8.8.8
- "00000000" + // idiag_if
- "ffffffffffffffff" + // idiag_cookie = INET_DIAG_NOCOOKIE
- "00000000" + // idiag_expires
- "00000000" + // idiag_rqueue
- "00000000" + // idiag_wqueue
- "a3270000" + // idiag_uid
- "A57E1900"; // idiag_inode
- private static final byte[] INET_DIAG_MSG_BYTES =
- HexEncoding.decode(INET_DIAG_MSG_HEX.toCharArray(), false);
-
- @Test
- public void testParseInetDiagResponse() throws Exception {
- final ByteBuffer byteBuffer = ByteBuffer.wrap(INET_DIAG_MSG_BYTES);
- byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
- final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
- assertNotNull(msg);
-
- assertTrue(msg instanceof InetDiagMessage);
- final InetDiagMessage inetDiagMsg = (InetDiagMessage) msg;
- assertEquals(10147, inetDiagMsg.mStructInetDiagMsg.idiag_uid);
-
- final StructNlMsgHdr hdr = inetDiagMsg.getHeader();
- assertNotNull(hdr);
- assertEquals(NetlinkConstants.SOCK_DIAG_BY_FAMILY, hdr.nlmsg_type);
- assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
- assertEquals(0, hdr.nlmsg_seq);
- assertEquals(8949, hdr.nlmsg_pid);
- }
-}
diff --git a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
deleted file mode 100644
index 44ab605..0000000
--- a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
-import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkErrorMessage;
-import android.net.netlink.NetlinkMessage;
-import android.net.netlink.StructNlMsgErr;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class NetlinkErrorMessageTest {
- private final String TAG = "NetlinkErrorMessageTest";
-
- // Hexadecimal representation of packet capture.
- public static final String NLM_ERROR_OK_HEX =
- // struct nlmsghdr
- "24000000" + // length = 36
- "0200" + // type = 2 (NLMSG_ERROR)
- "0000" + // flags
- "26350000" + // seqno
- "64100000" + // pid = userspace process
- // error integer
- "00000000" + // "errno" (0 == OK)
- // struct nlmsghdr
- "30000000" + // length (48) of original request
- "1C00" + // type = 28 (RTM_NEWNEIGH)
- "0501" + // flags (NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE)
- "26350000" + // seqno
- "00000000"; // pid = kernel
- public static final byte[] NLM_ERROR_OK =
- HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false);
-
- @Test
- public void testParseNlmErrorOk() {
- final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK);
- byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
- final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
- assertNotNull(msg);
- assertTrue(msg instanceof NetlinkErrorMessage);
- final NetlinkErrorMessage errorMsg = (NetlinkErrorMessage) msg;
-
- final StructNlMsgHdr hdr = errorMsg.getHeader();
- assertNotNull(hdr);
- assertEquals(36, hdr.nlmsg_len);
- assertEquals(NetlinkConstants.NLMSG_ERROR, hdr.nlmsg_type);
- assertEquals(0, hdr.nlmsg_flags);
- assertEquals(13606, hdr.nlmsg_seq);
- assertEquals(4196, hdr.nlmsg_pid);
-
- final StructNlMsgErr err = errorMsg.getNlMsgError();
- assertNotNull(err);
- assertEquals(0, err.error);
- assertNotNull(err.msg);
- assertEquals(48, err.msg.nlmsg_len);
- assertEquals(NetlinkConstants.RTM_NEWNEIGH, err.msg.nlmsg_type);
- assertEquals((NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE), err.msg.nlmsg_flags);
- assertEquals(13606, err.msg.nlmsg_seq);
- assertEquals(0, err.msg.nlmsg_pid);
- }
-}
diff --git a/tests/net/java/android/net/netlink/NetlinkSocketTest.java b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
deleted file mode 100644
index 3916578..0000000
--- a/tests/net/java/android/net/netlink/NetlinkSocketTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
-import static android.system.OsConstants.NETLINK_ROUTE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.netlink.NetlinkSocket;
-import android.net.netlink.RtNetlinkNeighborMessage;
-import android.net.netlink.StructNlMsgHdr;
-import android.system.NetlinkSocketAddress;
-import android.system.Os;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.io.IoUtils;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.FileDescriptor;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class NetlinkSocketTest {
- private final String TAG = "NetlinkSocketTest";
-
- @Test
- public void testBasicWorkingGetNeighborsQuery() throws Exception {
- final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_ROUTE);
- assertNotNull(fd);
-
- NetlinkSocket.connectToKernel(fd);
-
- final NetlinkSocketAddress localAddr = (NetlinkSocketAddress) Os.getsockname(fd);
- assertNotNull(localAddr);
- assertEquals(0, localAddr.getGroupsMask());
- assertTrue(0 != localAddr.getPortId());
-
- final int TEST_SEQNO = 5;
- final byte[] req = RtNetlinkNeighborMessage.newGetNeighborsRequest(TEST_SEQNO);
- assertNotNull(req);
-
- final long TIMEOUT = 500;
- assertEquals(req.length, NetlinkSocket.sendMessage(fd, req, 0, req.length, TIMEOUT));
-
- int neighMessageCount = 0;
- int doneMessageCount = 0;
-
- while (doneMessageCount == 0) {
- ByteBuffer response = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT);
- assertNotNull(response);
- assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit());
- assertEquals(0, response.position());
- assertEquals(ByteOrder.nativeOrder(), response.order());
-
- // Verify the messages at least appears minimally reasonable.
- while (response.remaining() > 0) {
- final NetlinkMessage msg = NetlinkMessage.parse(response);
- assertNotNull(msg);
- final StructNlMsgHdr hdr = msg.getHeader();
- assertNotNull(hdr);
-
- if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) {
- doneMessageCount++;
- continue;
- }
-
- assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
- assertTrue(msg instanceof RtNetlinkNeighborMessage);
- assertTrue((hdr.nlmsg_flags & StructNlMsgHdr.NLM_F_MULTI) != 0);
- assertEquals(TEST_SEQNO, hdr.nlmsg_seq);
- assertEquals(localAddr.getPortId(), hdr.nlmsg_pid);
-
- neighMessageCount++;
- }
- }
-
- assertEquals(1, doneMessageCount);
- // TODO: make sure this test passes sanely in airplane mode.
- assertTrue(neighMessageCount > 0);
-
- IoUtils.closeQuietly(fd);
- }
-}
diff --git a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
deleted file mode 100644
index 8162522..0000000
--- a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.netlink;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.netlink.NetlinkConstants;
-import android.net.netlink.NetlinkMessage;
-import android.net.netlink.RtNetlinkNeighborMessage;
-import android.net.netlink.StructNdMsg;
-import android.net.netlink.StructNlMsgHdr;
-import android.system.OsConstants;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RtNetlinkNeighborMessageTest {
- private final String TAG = "RtNetlinkNeighborMessageTest";
-
- // Hexadecimal representation of packet capture.
- public static final String RTM_DELNEIGH_HEX =
- // struct nlmsghdr
- "4c000000" + // length = 76
- "1d00" + // type = 29 (RTM_DELNEIGH)
- "0000" + // flags
- "00000000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct ndmsg
- "02" + // family
- "00" + // pad1
- "0000" + // pad2
- "15000000" + // interface index (21 == wlan0, on test device)
- "0400" + // NUD state (0x04 == NUD_STALE)
- "00" + // flags
- "01" + // type
- // struct nlattr: NDA_DST
- "0800" + // length = 8
- "0100" + // type (1 == NDA_DST, for neighbor messages)
- "c0a89ffe" + // IPv4 address (== 192.168.159.254)
- // struct nlattr: NDA_LLADDR
- "0a00" + // length = 10
- "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
- "00005e000164" + // MAC Address (== 00:00:5e:00:01:64)
- "0000" + // padding, for 4 byte alignment
- // struct nlattr: NDA_PROBES
- "0800" + // length = 8
- "0400" + // type (4 == NDA_PROBES, for neighbor messages)
- "01000000" + // number of probes
- // struct nlattr: NDA_CACHEINFO
- "1400" + // length = 20
- "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
- "05190000" + // ndm_used, as "clock ticks ago"
- "05190000" + // ndm_confirmed, as "clock ticks ago"
- "190d0000" + // ndm_updated, as "clock ticks ago"
- "00000000"; // ndm_refcnt
- public static final byte[] RTM_DELNEIGH =
- HexEncoding.decode(RTM_DELNEIGH_HEX.toCharArray(), false);
-
- // Hexadecimal representation of packet capture.
- public static final String RTM_NEWNEIGH_HEX =
- // struct nlmsghdr
- "58000000" + // length = 88
- "1c00" + // type = 28 (RTM_NEWNEIGH)
- "0000" + // flags
- "00000000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct ndmsg
- "0a" + // family
- "00" + // pad1
- "0000" + // pad2
- "15000000" + // interface index (21 == wlan0, on test device)
- "0400" + // NUD state (0x04 == NUD_STALE)
- "80" + // flags
- "01" + // type
- // struct nlattr: NDA_DST
- "1400" + // length = 20
- "0100" + // type (1 == NDA_DST, for neighbor messages)
- "fe8000000000000086c9b2fffe6aed4b" + // IPv6 address (== fe80::86c9:b2ff:fe6a:ed4b)
- // struct nlattr: NDA_LLADDR
- "0a00" + // length = 10
- "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
- "84c9b26aed4b" + // MAC Address (== 84:c9:b2:6a:ed:4b)
- "0000" + // padding, for 4 byte alignment
- // struct nlattr: NDA_PROBES
- "0800" + // length = 8
- "0400" + // type (4 == NDA_PROBES, for neighbor messages)
- "01000000" + // number of probes
- // struct nlattr: NDA_CACHEINFO
- "1400" + // length = 20
- "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
- "eb0e0000" + // ndm_used, as "clock ticks ago"
- "861f0000" + // ndm_confirmed, as "clock ticks ago"
- "00000000" + // ndm_updated, as "clock ticks ago"
- "05000000"; // ndm_refcnt
- public static final byte[] RTM_NEWNEIGH =
- HexEncoding.decode(RTM_NEWNEIGH_HEX.toCharArray(), false);
-
- // An example of the full response from an RTM_GETNEIGH query.
- private static final String RTM_GETNEIGH_RESPONSE_HEX =
- // <-- struct nlmsghr -->|<-- struct ndmsg -->|<-- struct nlattr: NDA_DST -->|<-- NDA_LLADDR -->|<-- NDA_PROBES -->|<-- NDA_CACHEINFO -->|
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000001 0a00 0200 333300000001 0000 0800 0400 00000000 1400 0300 a2280000 32110000 32110000 01000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff000001 0a00 0200 3333ff000001 0000 0800 0400 00000000 1400 0300 0d280000 9d100000 9d100000 00000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0400 80 01 1400 0100 20010db800040ca00000000000000001 0a00 0200 84c9b26aed4b 0000 0800 0400 04000000 1400 0300 90100000 90100000 90080000 01000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff47da19 0a00 0200 3333ff47da19 0000 0800 0400 00000000 1400 0300 a1280000 31110000 31110000 01000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 912a0000 21130000 21130000 00000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 922a0000 22130000 22130000 00000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff5c2a83 0a00 0200 3333ff5c2a83 0000 0800 0400 00000000 1400 0300 391c0000 c9040000 c9040000 01000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 01000000 4000 00 02 1400 0100 00000000000000000000000000000000 0a00 0200 000000000000 0000 0800 0400 00000000 1400 0300 cd180200 5d010200 5d010200 08000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 352a0000 c5120000 c5120000 00000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 982a0000 28130000 28130000 00000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0800 80 01 1400 0100 fe8000000000000086c9b2fffe6aed4b 0a00 0200 84c9b26aed4b 0000 0800 0400 00000000 1400 0300 23000000 24000000 57000000 13000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 992a0000 29130000 29130000 01000000" +
- "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 2e2a0000 be120000 be120000 00000000" +
- "44000000 1c00 0200 00000000 3e2b0000 02 00 0000 18000000 4000 00 03 0800 0100 00000000 0400 0200 0800 0400 00000000 1400 0300 75280000 05110000 05110000 22000000";
- public static final byte[] RTM_GETNEIGH_RESPONSE =
- HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
-
- @Test
- public void testParseRtmDelNeigh() {
- final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
- byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
- final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
- assertNotNull(msg);
- assertTrue(msg instanceof RtNetlinkNeighborMessage);
- final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
-
- final StructNlMsgHdr hdr = neighMsg.getHeader();
- assertNotNull(hdr);
- assertEquals(76, hdr.nlmsg_len);
- assertEquals(NetlinkConstants.RTM_DELNEIGH, hdr.nlmsg_type);
- assertEquals(0, hdr.nlmsg_flags);
- assertEquals(0, hdr.nlmsg_seq);
- assertEquals(0, hdr.nlmsg_pid);
-
- final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
- assertNotNull(ndmsgHdr);
- assertEquals((byte) OsConstants.AF_INET, ndmsgHdr.ndm_family);
- assertEquals(21, ndmsgHdr.ndm_ifindex);
- assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
- final InetAddress destination = neighMsg.getDestination();
- assertNotNull(destination);
- assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
- }
-
- @Test
- public void testParseRtmNewNeigh() {
- final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
- byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
- final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
- assertNotNull(msg);
- assertTrue(msg instanceof RtNetlinkNeighborMessage);
- final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
-
- final StructNlMsgHdr hdr = neighMsg.getHeader();
- assertNotNull(hdr);
- assertEquals(88, hdr.nlmsg_len);
- assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
- assertEquals(0, hdr.nlmsg_flags);
- assertEquals(0, hdr.nlmsg_seq);
- assertEquals(0, hdr.nlmsg_pid);
-
- final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
- assertNotNull(ndmsgHdr);
- assertEquals((byte) OsConstants.AF_INET6, ndmsgHdr.ndm_family);
- assertEquals(21, ndmsgHdr.ndm_ifindex);
- assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
- final InetAddress destination = neighMsg.getDestination();
- assertNotNull(destination);
- assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
- }
-
- @Test
- public void testParseRtmGetNeighResponse() {
- final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
- byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
-
- int messageCount = 0;
- while (byteBuffer.remaining() > 0) {
- final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
- assertNotNull(msg);
- assertTrue(msg instanceof RtNetlinkNeighborMessage);
- final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
-
- final StructNlMsgHdr hdr = neighMsg.getHeader();
- assertNotNull(hdr);
- assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
- assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
- assertEquals(0, hdr.nlmsg_seq);
- assertEquals(11070, hdr.nlmsg_pid);
-
- messageCount++;
- }
- // TODO: add more detailed spot checks.
- assertEquals(14, messageCount);
- }
-
- @Test
- public void testCreateRtmNewNeighMessage() {
- final int seqNo = 2635;
- final int ifIndex = 14;
- final byte[] llAddr =
- new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6 };
-
- // Hexadecimal representation of our created packet.
- final String expectedNewNeighHex =
- // struct nlmsghdr
- "30000000" + // length = 48
- "1c00" + // type = 28 (RTM_NEWNEIGH)
- "0501" + // flags (NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE)
- "4b0a0000" + // seqno
- "00000000" + // pid (0 == kernel)
- // struct ndmsg
- "02" + // family
- "00" + // pad1
- "0000" + // pad2
- "0e000000" + // interface index (14)
- "0800" + // NUD state (0x08 == NUD_DELAY)
- "00" + // flags
- "00" + // type
- // struct nlattr: NDA_DST
- "0800" + // length = 8
- "0100" + // type (1 == NDA_DST, for neighbor messages)
- "7f000001" + // IPv4 address (== 127.0.0.1)
- // struct nlattr: NDA_LLADDR
- "0a00" + // length = 10
- "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
- "010203040506" + // MAC Address (== 01:02:03:04:05:06)
- "0000"; // padding, for 4 byte alignment
- final byte[] expectedNewNeigh =
- HexEncoding.decode(expectedNewNeighHex.toCharArray(), false);
-
- final byte[] bytes = RtNetlinkNeighborMessage.newNewNeighborMessage(
- seqNo, Inet4Address.LOOPBACK, StructNdMsg.NUD_DELAY, ifIndex, llAddr);
- if (!Arrays.equals(expectedNewNeigh, bytes)) {
- assertEquals(expectedNewNeigh.length, bytes.length);
- for (int i = 0; i < Math.min(expectedNewNeigh.length, bytes.length); i++) {
- assertEquals(expectedNewNeigh[i], bytes[i]);
- }
- }
- }
-}
diff --git a/tests/net/java/android/net/shared/Inet4AddressUtilsTest.java b/tests/net/java/android/net/shared/Inet4AddressUtilsTest.java
deleted file mode 100644
index 35f8c79..0000000
--- a/tests/net/java/android/net/shared/Inet4AddressUtilsTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getImplicitNetmask;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTL;
-import static android.net.shared.Inet4AddressUtils.netmaskToPrefixLength;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTL;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.junit.Assert.fail;
-
-import android.net.InetAddresses;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class Inet4AddressUtilsTest {
-
- @Test
- public void testInet4AddressToIntHTL() {
- assertEquals(0, inet4AddressToIntHTL(ipv4Address("0.0.0.0")));
- assertEquals(0x000080ff, inet4AddressToIntHTL(ipv4Address("255.128.0.0")));
- assertEquals(0x0080ff0a, inet4AddressToIntHTL(ipv4Address("10.255.128.0")));
- assertEquals(0x00feff0a, inet4AddressToIntHTL(ipv4Address("10.255.254.0")));
- assertEquals(0xfeffa8c0, inet4AddressToIntHTL(ipv4Address("192.168.255.254")));
- assertEquals(0xffffa8c0, inet4AddressToIntHTL(ipv4Address("192.168.255.255")));
- }
-
- @Test
- public void testIntToInet4AddressHTL() {
- assertEquals(ipv4Address("0.0.0.0"), intToInet4AddressHTL(0));
- assertEquals(ipv4Address("255.128.0.0"), intToInet4AddressHTL(0x000080ff));
- assertEquals(ipv4Address("10.255.128.0"), intToInet4AddressHTL(0x0080ff0a));
- assertEquals(ipv4Address("10.255.254.0"), intToInet4AddressHTL(0x00feff0a));
- assertEquals(ipv4Address("192.168.255.254"), intToInet4AddressHTL(0xfeffa8c0));
- assertEquals(ipv4Address("192.168.255.255"), intToInet4AddressHTL(0xffffa8c0));
- }
-
- @Test
- public void testInet4AddressToIntHTH() {
- assertEquals(0, inet4AddressToIntHTH(ipv4Address("0.0.0.0")));
- assertEquals(0xff800000, inet4AddressToIntHTH(ipv4Address("255.128.0.0")));
- assertEquals(0x0aff8000, inet4AddressToIntHTH(ipv4Address("10.255.128.0")));
- assertEquals(0x0afffe00, inet4AddressToIntHTH(ipv4Address("10.255.254.0")));
- assertEquals(0xc0a8fffe, inet4AddressToIntHTH(ipv4Address("192.168.255.254")));
- assertEquals(0xc0a8ffff, inet4AddressToIntHTH(ipv4Address("192.168.255.255")));
- }
-
- @Test
- public void testIntToInet4AddressHTH() {
- assertEquals(ipv4Address("0.0.0.0"), intToInet4AddressHTH(0));
- assertEquals(ipv4Address("255.128.0.0"), intToInet4AddressHTH(0xff800000));
- assertEquals(ipv4Address("10.255.128.0"), intToInet4AddressHTH(0x0aff8000));
- assertEquals(ipv4Address("10.255.254.0"), intToInet4AddressHTH(0x0afffe00));
- assertEquals(ipv4Address("192.168.255.254"), intToInet4AddressHTH(0xc0a8fffe));
- assertEquals(ipv4Address("192.168.255.255"), intToInet4AddressHTH(0xc0a8ffff));
- }
-
-
- @Test
- public void testPrefixLengthToV4NetmaskIntHTL() {
- assertEquals(0, prefixLengthToV4NetmaskIntHTL(0));
- assertEquals(0x000080ff /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTL(9));
- assertEquals(0x0080ffff /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTL(17));
- assertEquals(0x00feffff /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTL(23));
- assertEquals(0xfeffffff /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTL(31));
- assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTL(32));
- }
-
- @Test
- public void testPrefixLengthToV4NetmaskIntHTH() {
- assertEquals(0, prefixLengthToV4NetmaskIntHTH(0));
- assertEquals(0xff800000 /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTH(9));
- assertEquals(0xffff8000 /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTH(17));
- assertEquals(0xfffffe00 /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTH(23));
- assertEquals(0xfffffffe /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTH(31));
- assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTH(32));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPrefixLengthToV4NetmaskIntHTH_NegativeLength() {
- prefixLengthToV4NetmaskIntHTH(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPrefixLengthToV4NetmaskIntHTH_LengthTooLarge() {
- prefixLengthToV4NetmaskIntHTH(33);
- }
-
- private void checkAddressMasking(String expectedAddr, String addr, int prefixLength) {
- final int prefix = prefixLengthToV4NetmaskIntHTH(prefixLength);
- final int addrInt = inet4AddressToIntHTH(ipv4Address(addr));
- assertEquals(ipv4Address(expectedAddr), intToInet4AddressHTH(prefix & addrInt));
- }
-
- @Test
- public void testPrefixLengthToV4NetmaskIntHTH_MaskAddr() {
- checkAddressMasking("192.168.0.0", "192.168.128.1", 16);
- checkAddressMasking("255.240.0.0", "255.255.255.255", 12);
- checkAddressMasking("255.255.255.255", "255.255.255.255", 32);
- checkAddressMasking("0.0.0.0", "255.255.255.255", 0);
- }
-
- @Test
- public void testGetImplicitNetmask() {
- assertEquals(8, getImplicitNetmask(ipv4Address("4.2.2.2")));
- assertEquals(8, getImplicitNetmask(ipv4Address("10.5.6.7")));
- assertEquals(16, getImplicitNetmask(ipv4Address("173.194.72.105")));
- assertEquals(16, getImplicitNetmask(ipv4Address("172.23.68.145")));
- assertEquals(24, getImplicitNetmask(ipv4Address("192.0.2.1")));
- assertEquals(24, getImplicitNetmask(ipv4Address("192.168.5.1")));
- assertEquals(32, getImplicitNetmask(ipv4Address("224.0.0.1")));
- assertEquals(32, getImplicitNetmask(ipv4Address("255.6.7.8")));
- }
-
- private void assertInvalidNetworkMask(Inet4Address addr) {
- try {
- netmaskToPrefixLength(addr);
- fail("Invalid netmask " + addr.getHostAddress() + " did not cause exception");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testNetmaskToPrefixLength() {
- assertEquals(0, netmaskToPrefixLength(ipv4Address("0.0.0.0")));
- assertEquals(9, netmaskToPrefixLength(ipv4Address("255.128.0.0")));
- assertEquals(17, netmaskToPrefixLength(ipv4Address("255.255.128.0")));
- assertEquals(23, netmaskToPrefixLength(ipv4Address("255.255.254.0")));
- assertEquals(31, netmaskToPrefixLength(ipv4Address("255.255.255.254")));
- assertEquals(32, netmaskToPrefixLength(ipv4Address("255.255.255.255")));
-
- assertInvalidNetworkMask(ipv4Address("0.0.0.1"));
- assertInvalidNetworkMask(ipv4Address("255.255.255.253"));
- assertInvalidNetworkMask(ipv4Address("255.255.0.255"));
- }
-
- @Test
- public void testGetPrefixMaskAsAddress() {
- assertEquals("255.255.240.0", getPrefixMaskAsInet4Address(20).getHostAddress());
- assertEquals("255.0.0.0", getPrefixMaskAsInet4Address(8).getHostAddress());
- assertEquals("0.0.0.0", getPrefixMaskAsInet4Address(0).getHostAddress());
- assertEquals("255.255.255.255", getPrefixMaskAsInet4Address(32).getHostAddress());
- }
-
- @Test
- public void testGetBroadcastAddress() {
- assertEquals("192.168.15.255",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 20).getHostAddress());
- assertEquals("192.255.255.255",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 8).getHostAddress());
- assertEquals("192.168.0.123",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 32).getHostAddress());
- assertEquals("255.255.255.255",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 0).getHostAddress());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetBroadcastAddress_PrefixTooLarge() {
- getBroadcastAddress(ipv4Address("192.168.0.123"), 33);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetBroadcastAddress_NegativePrefix() {
- getBroadcastAddress(ipv4Address("192.168.0.123"), -1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetPrefixMaskAsAddress_PrefixTooLarge() {
- getPrefixMaskAsInet4Address(33);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetPrefixMaskAsAddress_NegativePrefix() {
- getPrefixMaskAsInet4Address(-1);
- }
-
- private Inet4Address ipv4Address(String addr) {
- return (Inet4Address) InetAddresses.parseNumericAddress(addr);
- }
-}
diff --git a/tests/net/java/android/net/shared/InitialConfigurationTest.java b/tests/net/java/android/net/shared/InitialConfigurationTest.java
deleted file mode 100644
index 17f8324..0000000
--- a/tests/net/java/android/net/shared/InitialConfigurationTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import static android.net.InetAddresses.parseNumericAddress;
-
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.function.Consumer;
-
-/**
- * Tests for {@link InitialConfiguration}
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class InitialConfigurationTest {
- private InitialConfiguration mConfig;
-
- @Before
- public void setUp() {
- mConfig = new InitialConfiguration();
- mConfig.ipAddresses.addAll(Arrays.asList(
- new LinkAddress(parseNumericAddress("192.168.45.45"), 16),
- new LinkAddress(parseNumericAddress("2001:db8::45"), 33)));
- mConfig.directlyConnectedRoutes.addAll(Arrays.asList(
- new IpPrefix(parseNumericAddress("192.168.46.46"), 17),
- new IpPrefix(parseNumericAddress("2001:db8::46"), 34)));
- mConfig.dnsServers.addAll(Arrays.asList(
- parseNumericAddress("192.168.47.47"),
- parseNumericAddress("2001:db8::47")));
- // Any added InitialConfiguration field must be included in equals() to be tested properly
- assertFieldCountEquals(3, InitialConfiguration.class);
- }
-
- @Test
- public void testParcelUnparcelInitialConfiguration() {
- final InitialConfiguration unparceled =
- InitialConfiguration.fromStableParcelable(mConfig.toStableParcelable());
- assertEquals(mConfig, unparceled);
- }
-
- @Test
- public void testEquals() {
- assertEquals(mConfig, InitialConfiguration.copy(mConfig));
-
- assertNotEqualsAfterChange(c -> c.ipAddresses.add(
- new LinkAddress(parseNumericAddress("192.168.47.47"), 24)));
- assertNotEqualsAfterChange(c -> c.directlyConnectedRoutes.add(
- new IpPrefix(parseNumericAddress("192.168.46.46"), 32)));
- assertNotEqualsAfterChange(c -> c.dnsServers.add(parseNumericAddress("2001:db8::49")));
- assertFieldCountEquals(3, InitialConfiguration.class);
- }
-
- private void assertNotEqualsAfterChange(Consumer<InitialConfiguration> mutator) {
- final InitialConfiguration newConfig = InitialConfiguration.copy(mConfig);
- mutator.accept(newConfig);
- assertNotEquals(mConfig, newConfig);
- }
-}
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
deleted file mode 100644
index f987389..0000000
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;
-import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-
-import static org.junit.Assert.assertEquals;
-
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-
-/**
- * Tests for {@link IpConfigurationParcelableUtil}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpConfigurationParcelableUtilTest {
- private DhcpResults mDhcpResults;
-
- @Before
- public void setUp() {
- mDhcpResults = new DhcpResults();
- mDhcpResults.ipAddress = new LinkAddress(parseNumericAddress("2001:db8::42"), 64);
- mDhcpResults.gateway = parseNumericAddress("192.168.42.42");
- mDhcpResults.dnsServers.add(parseNumericAddress("2001:db8::43"));
- mDhcpResults.dnsServers.add(parseNumericAddress("192.168.43.43"));
- mDhcpResults.domains = "example.com";
- mDhcpResults.serverAddress = (Inet4Address) parseNumericAddress("192.168.44.44");
- mDhcpResults.vendorInfo = "TEST_VENDOR_INFO";
- mDhcpResults.leaseDuration = 3600;
- mDhcpResults.serverHostName = "dhcp.example.com";
- mDhcpResults.mtu = 1450;
- // Any added DhcpResults field must be included in equals() to be tested properly
- assertFieldCountEquals(9, DhcpResults.class);
- }
-
- @Test
- public void testParcelUnparcelDhcpResults() {
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_NullIpAddress() {
- mDhcpResults.ipAddress = null;
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_NullGateway() {
- mDhcpResults.gateway = null;
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_NullDomains() {
- mDhcpResults.domains = null;
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_EmptyDomains() {
- mDhcpResults.domains = "";
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_NullServerAddress() {
- mDhcpResults.serverAddress = null;
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_NullVendorInfo() {
- mDhcpResults.vendorInfo = null;
- doDhcpResultsParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelDhcpResults_NullServerHostName() {
- mDhcpResults.serverHostName = null;
- doDhcpResultsParcelUnparcelTest();
- }
-
- private void doDhcpResultsParcelUnparcelTest() {
- final DhcpResults unparceled = fromStableParcelable(toStableParcelable(mDhcpResults));
- assertEquals(mDhcpResults, unparceled);
- }
-}
diff --git a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
deleted file mode 100644
index 7079a28..0000000
--- a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 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.net.shared;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.shared.ProvisioningConfiguration.fromStableParcelable;
-
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.StaticIpConfiguration;
-import android.net.apf.ApfCapabilities;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.function.Consumer;
-
-/**
- * Tests for {@link ProvisioningConfiguration}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ProvisioningConfigurationTest {
- private ProvisioningConfiguration mConfig;
-
- @Before
- public void setUp() {
- mConfig = new ProvisioningConfiguration();
- mConfig.mEnableIPv4 = true;
- mConfig.mEnableIPv6 = true;
- mConfig.mUsingMultinetworkPolicyTracker = true;
- mConfig.mUsingIpReachabilityMonitor = true;
- mConfig.mRequestedPreDhcpActionMs = 42;
- mConfig.mInitialConfig = new InitialConfiguration();
- mConfig.mInitialConfig.ipAddresses.add(
- new LinkAddress(parseNumericAddress("192.168.42.42"), 24));
- mConfig.mStaticIpConfig = new StaticIpConfiguration();
- mConfig.mStaticIpConfig.ipAddress =
- new LinkAddress(parseNumericAddress("2001:db8::42"), 90);
- // Not testing other InitialConfig or StaticIpConfig members: they have their own unit tests
- mConfig.mApfCapabilities = new ApfCapabilities(1, 2, 3);
- mConfig.mProvisioningTimeoutMs = 4200;
- mConfig.mIPv6AddrGenMode = 123;
- mConfig.mNetwork = new Network(321);
- mConfig.mDisplayName = "test_config";
- // Any added field must be included in equals() to be tested properly
- assertFieldCountEquals(12, ProvisioningConfiguration.class);
- }
-
- @Test
- public void testParcelUnparcel() {
- doParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcel_NullInitialConfiguration() {
- mConfig.mInitialConfig = null;
- doParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcel_NullStaticConfiguration() {
- mConfig.mStaticIpConfig = null;
- doParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcel_NullApfCapabilities() {
- mConfig.mApfCapabilities = null;
- doParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcel_NullNetwork() {
- mConfig.mNetwork = null;
- doParcelUnparcelTest();
- }
-
- private void doParcelUnparcelTest() {
- final ProvisioningConfiguration unparceled =
- fromStableParcelable(mConfig.toStableParcelable());
- assertEquals(mConfig, unparceled);
- }
-
- @Test
- public void testEquals() {
- assertEquals(mConfig, new ProvisioningConfiguration(mConfig));
-
- assertNotEqualsAfterChange(c -> c.mEnableIPv4 = false);
- assertNotEqualsAfterChange(c -> c.mEnableIPv6 = false);
- assertNotEqualsAfterChange(c -> c.mUsingMultinetworkPolicyTracker = false);
- assertNotEqualsAfterChange(c -> c.mUsingIpReachabilityMonitor = false);
- assertNotEqualsAfterChange(c -> c.mRequestedPreDhcpActionMs++);
- assertNotEqualsAfterChange(c -> c.mInitialConfig.ipAddresses.add(
- new LinkAddress(parseNumericAddress("192.168.47.47"), 16)));
- assertNotEqualsAfterChange(c -> c.mInitialConfig = null);
- assertNotEqualsAfterChange(c -> c.mStaticIpConfig.ipAddress =
- new LinkAddress(parseNumericAddress("2001:db8::47"), 64));
- assertNotEqualsAfterChange(c -> c.mStaticIpConfig = null);
- assertNotEqualsAfterChange(c -> c.mApfCapabilities = new ApfCapabilities(4, 5, 6));
- assertNotEqualsAfterChange(c -> c.mApfCapabilities = null);
- assertNotEqualsAfterChange(c -> c.mProvisioningTimeoutMs++);
- assertNotEqualsAfterChange(c -> c.mIPv6AddrGenMode++);
- assertNotEqualsAfterChange(c -> c.mNetwork = new Network(123));
- assertNotEqualsAfterChange(c -> c.mNetwork = null);
- assertNotEqualsAfterChange(c -> c.mDisplayName = "other_test");
- assertNotEqualsAfterChange(c -> c.mDisplayName = null);
- assertFieldCountEquals(12, ProvisioningConfiguration.class);
- }
-
- private void assertNotEqualsAfterChange(Consumer<ProvisioningConfiguration> mutator) {
- final ProvisioningConfiguration newConfig = new ProvisioningConfiguration(mConfig);
- mutator.accept(newConfig);
- assertNotEquals(mConfig, newConfig);
- }
-}
diff --git a/tests/net/java/android/net/util/InterfaceParamsTest.java b/tests/net/java/android/net/util/InterfaceParamsTest.java
deleted file mode 100644
index 141455c..0000000
--- a/tests/net/java/android/net/util/InterfaceParamsTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class InterfaceParamsTest {
- @Test
- public void testNullInterfaceReturnsNull() {
- assertNull(InterfaceParams.getByName(null));
- }
-
- @Test
- public void testNonExistentInterfaceReturnsNull() {
- assertNull(InterfaceParams.getByName("doesnotexist0"));
- }
-
- @Test
- public void testLoopback() {
- final InterfaceParams ifParams = InterfaceParams.getByName("lo");
- assertNotNull(ifParams);
- assertEquals("lo", ifParams.name);
- assertTrue(ifParams.index > 0);
- assertNotNull(ifParams.macAddr);
- assertTrue(ifParams.defaultMtu >= NetworkConstants.ETHER_MTU);
- }
-}
diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java
deleted file mode 100644
index e1dba36..0000000
--- a/tests/net/java/android/net/util/SharedLogTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SharedLogTest {
- private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
- private static final String TIMESTAMP = "HH:MM:SS";
-
- @Test
- public void testBasicOperation() {
- final SharedLog logTop = new SharedLog("top");
- logTop.mark("first post!");
-
- final SharedLog logLevel2a = logTop.forSubComponent("twoA");
- final SharedLog logLevel2b = logTop.forSubComponent("twoB");
- logLevel2b.e("2b or not 2b");
- logLevel2b.e("No exception", null);
- logLevel2b.e("Wait, here's one", new Exception("Test"));
- logLevel2a.w("second post?");
-
- final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
- logTop.log("still logging");
- logLevel3.log("3 >> 2");
- logLevel2a.mark("ok: last post");
-
- final String[] expected = {
- " - MARK first post!",
- " - [twoB] ERROR 2b or not 2b",
- " - [twoB] ERROR No exception",
- // No stacktrace in shared log, only in logcat
- " - [twoB] ERROR Wait, here's one: Test",
- " - [twoA] WARN second post?",
- " - still logging",
- " - [twoA.three] 3 >> 2",
- " - [twoA] MARK ok: last post",
- };
- // Verify the logs are all there and in the correct order.
- verifyLogLines(expected, logTop);
-
- // In fact, because they all share the same underlying LocalLog,
- // every subcomponent SharedLog's dump() is identical.
- verifyLogLines(expected, logLevel2a);
- verifyLogLines(expected, logLevel2b);
- verifyLogLines(expected, logLevel3);
- }
-
- private static void verifyLogLines(String[] expected, SharedLog log) {
- final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
- final PrintWriter pw = new PrintWriter(ostream, true);
- log.dump(null, pw, null);
-
- final String dumpOutput = ostream.toString();
- assertTrue(dumpOutput != null);
- assertTrue(!"".equals(dumpOutput));
-
- final String[] lines = dumpOutput.split("\n");
- assertEquals(expected.length, lines.length);
-
- for (int i = 0; i < expected.length; i++) {
- String got = lines[i];
- String want = expected[i];
- assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
- assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP),
- got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
- }
- }
-}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 61f37fd..aad2f3d 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -20,6 +20,9 @@
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
+import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL;
+import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
+import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE;
import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
@@ -28,6 +31,7 @@
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
+import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
@@ -145,6 +149,7 @@
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
+import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
@@ -244,6 +249,7 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Predicate;
import kotlin.reflect.KClass;
@@ -330,6 +336,9 @@
private class MockContext extends BroadcastInterceptingContext {
private final MockContentResolver mContentResolver;
+ // Contains all registered receivers since this object was created. Useful to clear
+ // them when needed, as BroadcastInterceptingContext does not provide this facility.
+ private final List<BroadcastReceiver> mRegisteredReceivers = new ArrayList<>();
@Spy private Resources mResources;
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
@@ -343,6 +352,7 @@
"wifi,1,1,1,-1,true",
"mobile,0,0,0,-1,true",
"mobile_mms,2,0,2,60000,true",
+ "mobile_supl,3,0,2,60000,true",
});
when(mResources.getStringArray(
@@ -410,6 +420,19 @@
// make sure the code does not rely on unexpected permissions.
super.enforceCallingOrSelfPermission(permission, message);
}
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ mRegisteredReceivers.add(receiver);
+ return super.registerReceiver(receiver, filter);
+ }
+
+ public void clearRegisteredReceivers() {
+ // super.unregisterReceiver is a no-op for receivers that are not registered (because
+ // they haven't been registered or because they have already been unregistered).
+ // For the same reason, don't bother clearing mRegisteredReceivers.
+ for (final BroadcastReceiver rcv : mRegisteredReceivers) unregisterReceiver(rcv);
+ }
}
private void waitForIdle() {
@@ -438,7 +461,7 @@
}
// Bring up a network that we can use to send messages to ConnectivityService.
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
@@ -458,7 +481,7 @@
@Ignore
public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception {
// Bring up a network that we can use to send messages to ConnectivityService.
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
@@ -1227,17 +1250,26 @@
* Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION
* broadcasts are received.
*/
- private ConditionVariable waitForConnectivityBroadcasts(final int count) {
+ private ConditionVariable registerConnectivityBroadcast(final int count) {
+ return registerConnectivityBroadcastThat(count, intent -> true);
+ }
+
+ private ConditionVariable registerConnectivityBroadcastThat(final int count,
+ @NonNull final Predicate<Intent> filter) {
final ConditionVariable cv = new ConditionVariable();
- mServiceContext.registerReceiver(new BroadcastReceiver() {
+ final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION);
+ intentFilter.addAction(CONNECTIVITY_ACTION_SUPL);
+ final BroadcastReceiver receiver = new BroadcastReceiver() {
private int remaining = count;
public void onReceive(Context context, Intent intent) {
+ if (!filter.test(intent)) return;
if (--remaining == 0) {
cv.open();
mServiceContext.unregisterReceiver(this);
}
}
- }, new IntentFilter(CONNECTIVITY_ACTION));
+ };
+ mServiceContext.registerReceiver(receiver, intentFilter);
return cv;
}
@@ -1258,6 +1290,75 @@
}
@Test
+ public void testNetworkFeature() throws Exception {
+ // Connect the cell agent and wait for the connected broadcast.
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL);
+ final ConditionVariable cv1 = registerConnectivityBroadcastThat(1,
+ intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE);
+ mCellNetworkAgent.connect(true);
+ waitFor(cv1);
+
+ // Build legacy request for SUPL.
+ final NetworkCapabilities legacyCaps = new NetworkCapabilities();
+ legacyCaps.addTransportType(TRANSPORT_CELLULAR);
+ legacyCaps.addCapability(NET_CAPABILITY_SUPL);
+ final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL,
+ ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST);
+
+ // Send request and check that the legacy broadcast for SUPL is sent correctly.
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ final ConditionVariable cv2 = registerConnectivityBroadcastThat(1,
+ intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
+ mCm.requestNetwork(legacyRequest, callback);
+ callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ waitFor(cv2);
+
+ // File another request, withdraw it and make sure no broadcast is sent
+ final ConditionVariable cv3 = registerConnectivityBroadcast(1);
+ final TestNetworkCallback callback2 = new TestNetworkCallback();
+ mCm.requestNetwork(legacyRequest, callback2);
+ callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ mCm.unregisterNetworkCallback(callback2);
+ assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent
+ // As the broadcast did not fire, the receiver was not unregistered. Do this now.
+ mServiceContext.clearRegisteredReceivers();
+
+ // Withdraw the request and check that the broadcast for disconnection is sent.
+ final ConditionVariable cv4 = registerConnectivityBroadcastThat(1, intent ->
+ !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected()
+ && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
+ mCm.unregisterNetworkCallback(callback);
+ waitFor(cv4);
+
+ // Re-file the request and expect the connected broadcast again
+ final ConditionVariable cv5 = registerConnectivityBroadcastThat(1,
+ intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
+ final TestNetworkCallback callback3 = new TestNetworkCallback();
+ mCm.requestNetwork(legacyRequest, callback3);
+ callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ waitFor(cv5);
+
+ // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one
+ // for mobile. Use a small hack to check that both have been sent, but the order is
+ // not contractual.
+ final AtomicBoolean vanillaAction = new AtomicBoolean(false);
+ final AtomicBoolean suplAction = new AtomicBoolean(false);
+ final ConditionVariable cv6 = registerConnectivityBroadcastThat(2, intent -> {
+ if (intent.getAction().equals(CONNECTIVITY_ACTION)) {
+ vanillaAction.set(true);
+ } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) {
+ suplAction.set(true);
+ }
+ return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected();
+ });
+ mCellNetworkAgent.disconnect();
+ waitFor(cv6);
+ assertTrue(vanillaAction.get());
+ assertTrue(suplAction.get());
+ }
+
+ @Test
public void testLingering() throws Exception {
verifyNoNetwork();
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
@@ -1265,7 +1366,7 @@
assertNull(mCm.getActiveNetworkInfo());
assertNull(mCm.getActiveNetwork());
// Test bringing up validated cellular.
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
@@ -1275,7 +1376,7 @@
assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) ||
mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork()));
// Test bringing up validated WiFi.
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -1292,7 +1393,7 @@
assertLength(1, mCm.getAllNetworks());
assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
// Test WiFi disconnect.
- cv = waitForConnectivityBroadcasts(1);
+ cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.disconnect();
waitFor(cv);
verifyNoNetwork();
@@ -1302,7 +1403,7 @@
public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
// Test bringing up unvalidated WiFi
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -1317,17 +1418,17 @@
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up validated cellular
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mCellNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test cellular disconnect.
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mCellNetworkAgent.disconnect();
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi disconnect.
- cv = waitForConnectivityBroadcasts(1);
+ cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.disconnect();
waitFor(cv);
verifyNoNetwork();
@@ -1337,23 +1438,23 @@
public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
// Test bringing up unvalidated cellular.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.connect(false);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi disconnect.
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.disconnect();
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test cellular disconnect.
- cv = waitForConnectivityBroadcasts(1);
+ cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.disconnect();
waitFor(cv);
verifyNoNetwork();
@@ -1363,7 +1464,7 @@
public void testUnlingeringDoesNotValidate() throws Exception {
// Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -1371,14 +1472,14 @@
NET_CAPABILITY_VALIDATED));
// Test bringing up validated cellular.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mCellNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
NET_CAPABILITY_VALIDATED));
// Test cellular disconnect.
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mCellNetworkAgent.disconnect();
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -1391,23 +1492,23 @@
public void testCellularOutscoresWeakWifi() throws Exception {
// Test bringing up validated cellular.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test bringing up validated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi getting really weak.
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.adjustScore(-11);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test WiFi restoring signal strength.
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.adjustScore(11);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -1427,7 +1528,7 @@
mCellNetworkAgent.expectDisconnected();
// Test bringing up validated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- final ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ final ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -1446,18 +1547,18 @@
public void testCellularFallback() throws Exception {
// Test bringing up validated cellular.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test bringing up validated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Reevaluate WiFi (it'll instantly fail DNS).
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
NET_CAPABILITY_VALIDATED));
mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork());
@@ -1467,7 +1568,7 @@
NET_CAPABILITY_VALIDATED));
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Reevaluate cellular (it'll instantly fail DNS).
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
NET_CAPABILITY_VALIDATED));
mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
@@ -1484,18 +1585,18 @@
public void testWiFiFallback() throws Exception {
// Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up validated cellular.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mCellNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Reevaluate cellular (it'll instantly fail DNS).
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
NET_CAPABILITY_VALIDATED));
mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
@@ -1570,7 +1671,7 @@
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
// Test unvalidated networks
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(false);
genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
@@ -1585,7 +1686,7 @@
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
@@ -1594,7 +1695,7 @@
waitFor(cv);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
- cv = waitForConnectivityBroadcasts(2);
+ cv = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.disconnect();
genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
@@ -1602,7 +1703,7 @@
waitFor(cv);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
- cv = waitForConnectivityBroadcasts(1);
+ cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.disconnect();
genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
@@ -2192,7 +2293,7 @@
// Test bringing up validated WiFi.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- final ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ final ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -2220,7 +2321,7 @@
public void testMMSonCell() throws Exception {
// Test bringing up cellular without MMS
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.connect(false);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
@@ -3679,7 +3780,7 @@
}
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mWiFiNetworkAgent.connect(true);
waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
@@ -4212,7 +4313,7 @@
assertNotPinnedToWifi();
// Disconnect cell and wifi.
- ConditionVariable cv = waitForConnectivityBroadcasts(3); // cell down, wifi up, wifi down.
+ ConditionVariable cv = registerConnectivityBroadcast(3); // cell down, wifi up, wifi down.
mCellNetworkAgent.disconnect();
mWiFiNetworkAgent.disconnect();
waitFor(cv);
@@ -4225,7 +4326,7 @@
assertPinnedToWifiWithWifiDefault();
// ... and is maintained even when that network is no longer the default.
- cv = waitForConnectivityBroadcasts(1);
+ cv = registerConnectivityBroadcast(1);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mCellNetworkAgent.connect(true);
waitFor(cv);
@@ -4326,7 +4427,7 @@
@Test
public void testNetworkInfoOfTypeNone() throws Exception {
- ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1);
+ ConditionVariable broadcastCV = registerConnectivityBroadcast(1);
verifyNoNetwork();
TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE);
@@ -5778,7 +5879,7 @@
.destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId));
// Disconnect wifi
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ ConditionVariable cv = registerConnectivityBroadcast(1);
reset(mNetworkManagementService);
mWiFiNetworkAgent.disconnect();
waitFor(cv);
diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
index f0453694..42d4cf3 100644
--- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -18,6 +18,7 @@
import android.net.ConnectivityManager.TYPE_ETHERNET
import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_MOBILE_SUPL
import android.net.ConnectivityManager.TYPE_WIFI
import android.net.ConnectivityManager.TYPE_WIMAX
import android.net.NetworkInfo.DetailedState.CONNECTED
@@ -46,7 +47,7 @@
@RunWith(AndroidJUnit4::class)
@SmallTest
class LegacyTypeTrackerTest {
- private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET)
+ private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_SUPL)
private val mMockService = mock(ConnectivityService::class.java).apply {
doReturn(false).`when`(this).isDefaultNetwork(any())
@@ -70,6 +71,26 @@
}
@Test
+ fun testSupl() {
+ val mobileNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, mobileNai)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE)
+ reset(mMockService)
+ mTracker.add(TYPE_MOBILE_SUPL, mobileNai)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL)
+ reset(mMockService)
+ mTracker.remove(TYPE_MOBILE_SUPL, mobileNai, false /* wasDefault */)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL)
+ reset(mMockService)
+ mTracker.add(TYPE_MOBILE_SUPL, mobileNai)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL)
+ reset(mMockService)
+ mTracker.remove(mobileNai, false)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE)
+ }
+
+ @Test
fun testAddNetwork() {
val mobileNai = mock(NetworkAgentInfo::class.java)
val wifiNai = mock(NetworkAgentInfo::class.java)
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 5f62c08..9e5717b 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -208,6 +208,12 @@
if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
return super.getSystemService(name);
}
+
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
+ return super.getSystemServiceName(serviceClass);
+ }
}
public class MockIpServerDependencies extends IpServer.Dependencies {
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 1d29a82..4d42a61 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -192,8 +192,8 @@
mService = new NetworkStatsService(
mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
- TelephonyManager.getDefault(), mSettings, mStatsFactory,
- new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir));
+ mServiceContext.getSystemService(TelephonyManager.class), mSettings,
+ mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir));
mHandlerThread = new HandlerThread("HandlerThread");
mHandlerThread.start();
Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index 05ba8f0..806f4e3 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -404,12 +404,15 @@
for (const auto& entry : keep_set.conditional_class_set_) {
std::set<UsageLocation> locations;
- bool can_be_conditional = true;
- for (const UsageLocation& location : entry.second) {
- can_be_conditional &= CollectLocations(location, keep_set, &locations);
+ bool can_be_conditional = false;
+ if (keep_set.conditional_keep_rules_) {
+ can_be_conditional = true;
+ for (const UsageLocation& location : entry.second) {
+ can_be_conditional &= CollectLocations(location, keep_set, &locations);
+ }
}
- if (keep_set.conditional_keep_rules_ && can_be_conditional) {
+ if (can_be_conditional) {
for (const UsageLocation& location : locations) {
printer.Print("# Referenced at ").Println(location.source.to_string());
printer.Print("-if class **.R$layout { int ")
diff --git a/tools/genprotos.sh b/tools/genprotos.sh
deleted file mode 100755
index f901c9f..0000000
--- a/tools/genprotos.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can
-# end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to
-# the way sbox rewrites the command. See b/70221552.
-
-set -e
-
-location_aprotoc=$1
-location_protoc=$2
-location_soong_zip=$3
-genDir=$4
-depfile=$5
-in=$6
-out=$7
-
-mkdir -p ${genDir}/${in} && \
- ${location_aprotoc} --plugin=${location_protoc} \
- --dependency_out=${depfile} \
- --javastream_out=${genDir}/${in} \
- -Iexternal/protobuf/src \
- -I . \
- ${in} && \
- ${location_soong_zip} -jar -o ${out} -C ${genDir}/${in} -D ${genDir}/${in}
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index e883c6b..46105f4 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -241,8 +241,6 @@
flags = csv[1:]
if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
flags.append(FLAG_WHITELIST)
- elif FLAG_TEST_API in flags:
- flags.append(FLAG_GREYLIST)
self._dict[csv[0]].update(flags)
def assign_flag(self, flag, apis, source="<unknown>"):
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
index 4dc880b..55c3a7d 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py
@@ -53,14 +53,22 @@
# Test new additions.
flags.parse_and_merge_csv([
'A,' + FLAG_GREYLIST,
- 'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O ])
- self.assertEqual(flags.generate_csv(),
- [ 'A,' + FLAG_GREYLIST,
- 'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O ])
+ 'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O,
+ 'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
+ 'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
+ 'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
+ ])
+ self.assertEqual(flags.generate_csv(), [
+ 'A,' + FLAG_GREYLIST,
+ 'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O,
+ 'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
+ 'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
+ 'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
+ ])
# Test unknown flag.
with self.assertRaises(AssertionError):
- flags.parse_and_merge_csv([ 'C,foo' ])
+ flags.parse_and_merge_csv([ 'Z,foo' ])
def test_assign_flag(self):
flags = FlagsDict()
diff --git a/tools/processors/unsupportedappusage/Android.bp b/tools/processors/unsupportedappusage/Android.bp
index 0e33fdd..1e96234 100644
--- a/tools/processors/unsupportedappusage/Android.bp
+++ b/tools/processors/unsupportedappusage/Android.bp
@@ -1,11 +1,6 @@
-java_plugin {
- name: "unsupportedappusage-annotation-processor",
- processor_class: "android.processor.unsupportedappusage.UnsupportedAppUsageProcessor",
-
- java_resources: [
- "META-INF/**/*",
- ],
+java_library_host {
+ name: "unsupportedappusage-annotation-processor-lib",
srcs: [
"src/**/*.java",
],
@@ -22,6 +17,18 @@
"--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
],
},
+}
+
+java_plugin {
+ name: "unsupportedappusage-annotation-processor",
+ processor_class: "android.processor.unsupportedappusage.UnsupportedAppUsageProcessor",
+
+ java_resources: [
+ "META-INF/**/*",
+ ],
+ static_libs: [
+ "unsupportedappusage-annotation-processor-lib"
+ ],
use_tools_jar: true,
}
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
index 5a5703e..65fc733 100644
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
+++ b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
@@ -101,14 +101,20 @@
private String getClassSignature(TypeElement clazz) {
StringBuilder sb = new StringBuilder("L");
for (Element enclosing : getEnclosingElements(clazz)) {
- if (enclosing.getKind() == PACKAGE) {
- sb.append(((PackageElement) enclosing)
- .getQualifiedName()
- .toString()
- .replace('.', '/'));
- sb.append('/');
- } else {
- sb.append(enclosing.getSimpleName()).append('$');
+ switch (enclosing.getKind()) {
+ case MODULE:
+ // ignore this.
+ break;
+ case PACKAGE:
+ sb.append(((PackageElement) enclosing)
+ .getQualifiedName()
+ .toString()
+ .replace('.', '/'));
+ sb.append('/');
+ break;
+ default:
+ sb.append(enclosing.getSimpleName()).append('$');
+ break;
}
}
diff --git a/tools/processors/unsupportedappusage/test/Android.bp b/tools/processors/unsupportedappusage/test/Android.bp
new file mode 100644
index 0000000..49ea3d4
--- /dev/null
+++ b/tools/processors/unsupportedappusage/test/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 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.
+
+java_test_host {
+ name: "unsupportedappusage-processor-test",
+
+ srcs: ["src/**/*.java"],
+
+ static_libs: [
+ "libjavac",
+ "unsupportedappusage-annotation-processor-lib",
+ "truth-host-prebuilt",
+ "mockito-host",
+ "junit-host",
+ "objenesis",
+ ],
+}
diff --git a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java
new file mode 100644
index 0000000..23db99e
--- /dev/null
+++ b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.processor.unsupportedappusage;
+
+import com.google.common.base.Splitter;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CsvReader {
+
+ private final Splitter mSplitter;
+ private final List<String> mColumns;
+ private final List<Map<String, String>> mContents;
+
+ public CsvReader(InputStream in) throws IOException {
+ mSplitter = Splitter.on(",");
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ mColumns = mSplitter.splitToList(br.readLine());
+ mContents = new ArrayList<>();
+ String line = br.readLine();
+ while (line != null) {
+ List<String> contents = mSplitter.splitToList(line);
+ Map<String, String> contentMap = new HashMap<>();
+ for (int i = 0; i < Math.min(contents.size(), mColumns.size()); ++i) {
+ contentMap.put(mColumns.get(i), contents.get(i));
+ }
+ mContents.add(contentMap);
+ line = br.readLine();
+ }
+ br.close();
+ }
+
+ public List<String> getColumns() {
+ return mColumns;
+ }
+
+ public List<Map<String, String>> getContents() {
+ return mContents;
+ }
+}
diff --git a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java
new file mode 100644
index 0000000..012e88f
--- /dev/null
+++ b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 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.processor.unsupportedappusage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.javac.Javac;
+
+import com.google.common.base.Joiner;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class UnsupportedAppUsageProcessorTest {
+
+ private Javac mJavac;
+
+ @Before
+ public void setup() throws IOException {
+ mJavac = new Javac();
+ mJavac.addSource("dalvik.annotation.compat.UnsupportedAppUsage", Joiner.on('\n').join(
+ "package dalvik.annotation.compat;",
+ "public @interface UnsupportedAppUsage {",
+ " String expectedSignature() default \"\";\n",
+ " String someProperty() default \"\";",
+ "}"));
+ }
+
+ private CsvReader compileAndReadCsv() throws IOException {
+ mJavac.compileWithAnnotationProcessor(new UnsupportedAppUsageProcessor());
+ return new CsvReader(
+ mJavac.getOutputFile("unsupportedappusage/unsupportedappusage_index.csv"));
+ }
+
+ @Test
+ public void testSignatureFormat() throws Exception {
+ mJavac.addSource("a.b.Class", Joiner.on('\n').join(
+ "package a.b;",
+ "import dalvik.annotation.compat.UnsupportedAppUsage;",
+ "public class Class {",
+ " @UnsupportedAppUsage",
+ " public void method() {}",
+ "}"));
+ assertThat(compileAndReadCsv().getContents().get(0)).containsEntry(
+ "signature", "La/b/Class;->method()V"
+ );
+ }
+
+ @Test
+ public void testSourcePosition() throws Exception {
+ mJavac.addSource("a.b.Class", Joiner.on('\n').join(
+ "package a.b;", // 1
+ "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
+ "public class Class {", // 3
+ " @UnsupportedAppUsage", // 4
+ " public void method() {}", // 5
+ "}"));
+ Map<String, String> row = compileAndReadCsv().getContents().get(0);
+ assertThat(row).containsEntry("startline", "4");
+ assertThat(row).containsEntry("startcol", "3");
+ assertThat(row).containsEntry("endline", "4");
+ assertThat(row).containsEntry("endcol", "23");
+ }
+
+ @Test
+ public void testAnnotationProperties() throws Exception {
+ mJavac.addSource("a.b.Class", Joiner.on('\n').join(
+ "package a.b;", // 1
+ "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
+ "public class Class {", // 3
+ " @UnsupportedAppUsage(someProperty=\"value\")", // 4
+ " public void method() {}", // 5
+ "}"));
+ assertThat(compileAndReadCsv().getContents().get(0)).containsEntry(
+ "properties", "someProperty=%22value%22");
+ }
+
+
+}
diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl
index b8d2971..8a252dd 100644
--- a/wifi/java/android/net/wifi/ISoftApCallback.aidl
+++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl
@@ -16,6 +16,8 @@
package android.net.wifi;
+import android.net.wifi.WifiClient;
+
/**
* Interface for Soft AP callback.
*
@@ -36,9 +38,9 @@
void onStateChanged(int state, int failureReason);
/**
- * Service to manager callback providing number of connected clients.
+ * Service to manager callback providing connected client's information.
*
- * @param numClients number of connected clients
+ * @param clients the currently connected clients
*/
- void onNumClientsChanged(int numClients);
+ void onConnectedClientsChanged(in List<WifiClient> clients);
}
diff --git a/wifi/java/android/net/wifi/WifiClient.aidl b/wifi/java/android/net/wifi/WifiClient.aidl
new file mode 100644
index 0000000..accdadd
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiClient.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 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.net.wifi;
+
+@JavaOnlyStableParcelable parcelable WifiClient;
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiClient.java b/wifi/java/android/net/wifi/WifiClient.java
new file mode 100644
index 0000000..3e09580
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiClient.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 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.net.wifi;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.MacAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/** @hide */
+@SystemApi
+public final class WifiClient implements Parcelable {
+
+ private final MacAddress mMacAddress;
+
+ /**
+ * The mac address of this client.
+ */
+ @NonNull
+ public MacAddress getMacAddress() {
+ return mMacAddress;
+ }
+
+ private WifiClient(Parcel in) {
+ mMacAddress = in.readParcelable(null);
+ }
+
+ /** @hide */
+ public WifiClient(@NonNull MacAddress macAddress) {
+ Preconditions.checkNotNull(macAddress, "mMacAddress must not be null.");
+
+ this.mMacAddress = macAddress;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mMacAddress, flags);
+ }
+
+ @NonNull
+ public static final Creator<WifiClient> CREATOR = new Creator<WifiClient>() {
+ public WifiClient createFromParcel(Parcel in) {
+ return new WifiClient(in);
+ }
+
+ public WifiClient[] newArray(int size) {
+ return new WifiClient[size];
+ }
+ };
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "WifiClient{"
+ + "mMacAddress=" + mMacAddress
+ + '}';
+ }
+
+ @Override
+ public boolean equals(@NonNull Object o) {
+ if (this == o) return true;
+ if (!(o instanceof WifiClient)) return false;
+ WifiClient client = (WifiClient) o;
+ return mMacAddress.equals(client.mMacAddress);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mMacAddress);
+ }
+}
+
+
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 0d2e816..b53b2aa 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1128,6 +1128,9 @@
*/
private static final int MAX_ACTIVE_LOCKS = 50;
+ /** Indicates an invalid SSID. */
+ public static final String UNKNOWN_SSID = "<unknown ssid>";
+
/* Number of currently active WifiLocks and MulticastLocks */
@UnsupportedAppUsage
private int mActiveLockCount;
@@ -2326,7 +2329,7 @@
* <p>
* In the connected state, access to the SSID and BSSID requires
* the same permissions as {@link #getScanResults}. If such access is not allowed,
- * {@link WifiInfo#getSSID} will return {@code "<unknown ssid>"} and
+ * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and
* {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}.
*
* @return the Wi-Fi information, contained in {@link WifiInfo}.
@@ -3117,29 +3120,31 @@
/**
* Base class for soft AP callback. Should be extended by applications and set when calling
- * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}.
+ * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}.
*
* @hide
*/
+ @SystemApi
public interface SoftApCallback {
/**
* Called when soft AP state changes.
*
- * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
- * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
- * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
+ * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
+ * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
+ * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
* @param failureReason reason when in failed state. One of
- * {@link #SAP_START_FAILURE_GENERAL}, {@link #SAP_START_FAILURE_NO_CHANNEL}
+ * {@link #SAP_START_FAILURE_GENERAL},
+ * {@link #SAP_START_FAILURE_NO_CHANNEL}
*/
- public abstract void onStateChanged(@WifiApState int state,
+ void onStateChanged(@WifiApState int state,
@SapStartFailure int failureReason);
/**
- * Called when number of connected clients to soft AP changes.
+ * Called when the connected clients to soft AP changes.
*
- * @param numClients number of connected clients
+ * @param clients the currently connected clients
*/
- public abstract void onNumClientsChanged(int numClients);
+ void onConnectedClientsChanged(@NonNull List<WifiClient> clients);
}
/**
@@ -3148,11 +3153,11 @@
* @hide
*/
private class SoftApCallbackProxy extends ISoftApCallback.Stub {
- private final Handler mHandler;
+ private final Executor mExecutor;
private final SoftApCallback mCallback;
- SoftApCallbackProxy(Looper looper, SoftApCallback callback) {
- mHandler = new Handler(looper);
+ SoftApCallbackProxy(Executor executor, SoftApCallback callback) {
+ mExecutor = executor;
mCallback = callback;
}
@@ -3162,18 +3167,23 @@
Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state
+ ", failureReason=" + failureReason);
}
- mHandler.post(() -> {
+
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> {
mCallback.onStateChanged(state, failureReason);
});
}
@Override
- public void onNumClientsChanged(int numClients) {
+ public void onConnectedClientsChanged(List<WifiClient> clients) {
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy: onNumClientsChanged: numClients=" + numClients);
+ Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients="
+ + clients.size() + " clients");
}
- mHandler.post(() -> {
- mCallback.onNumClientsChanged(numClients);
+
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> {
+ mCallback.onConnectedClientsChanged(clients);
});
}
}
@@ -3190,22 +3200,23 @@
* without the permission will trigger a {@link java.lang.SecurityException}.
* <p>
*
+ * @param executor The executor to execute the callbacks of the {@code executor}
+ * object. If null, then the application's main executor will be used.
* @param callback Callback for soft AP events
- * @param handler The Handler on whose thread to execute the callbacks of the {@code callback}
- * object. If null, then the application's main thread will be used.
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void registerSoftApCallback(@NonNull SoftApCallback callback,
- @Nullable Handler handler) {
+ public void registerSoftApCallback(@Nullable @CallbackExecutor Executor executor,
+ @NonNull SoftApCallback callback) {
if (callback == null) throw new IllegalArgumentException("callback cannot be null");
- Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", handler=" + handler);
+ Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor);
- Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
+ executor = (executor == null) ? mContext.getMainExecutor() : executor;
Binder binder = new Binder();
try {
- mService.registerSoftApCallback(binder, new SoftApCallbackProxy(looper, callback),
+ mService.registerSoftApCallback(binder, new SoftApCallbackProxy(executor, callback),
callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
index b22ae070..5a212a8 100755
--- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
+++ b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.net.INetworkScoreCache;
import android.net.NetworkKey;
+import android.net.NetworkScoreManager;
import android.net.ScoredNetwork;
import android.os.Handler;
import android.os.Process;
@@ -40,7 +41,8 @@
*
* @hide
*/
-public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
+public class WifiNetworkScoreCache extends INetworkScoreCache.Stub
+ implements NetworkScoreManager.NetworkScoreCallback {
private static final String TAG = "WifiNetworkScoreCache";
private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
@@ -246,6 +248,17 @@
}
@Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ dumpWithLatestScanResults(fd, writer, args, wifiManager.getScanResults());
+ }
+
+ /**
+ * This is directly invoked from within Wifi-Service (on it's instance of this class), hence
+ * avoid making the WifiManager.getScanResults() call to avoid a deadlock.
+ */
+ public final void dumpWithLatestScanResults(
+ FileDescriptor fd, PrintWriter writer, String[] args,
+ List<ScanResult> latestScanResults) {
mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
String header = String.format("WifiNetworkScoreCache (%s/%d)",
mContext.getPackageName(), Process.myUid());
@@ -256,8 +269,7 @@
writer.println(" " + score);
}
writer.println(" Network scores for latest ScanResults:");
- WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- for (ScanResult scanResult : wifiManager.getScanResults()) {
+ for (ScanResult scanResult : latestScanResults) {
writer.println(
" " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
}
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index 70ca088..f187e10 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -48,7 +48,7 @@
private static final int HEX_RADIX = 16;
@UnsupportedAppUsage
- public static final String NONE = "<unknown ssid>";
+ public static final String NONE = WifiManager.UNKNOWN_SSID;
private WifiSsid() {
}
diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk
index 401b652..3453d6e 100644
--- a/wifi/tests/Android.mk
+++ b/wifi/tests/Android.mk
@@ -49,6 +49,7 @@
core-test-rules \
guava \
mockito-target-minus-junit4 \
+ net-tests-utils \
frameworks-base-testutils \
truth-prebuilt \
diff --git a/wifi/tests/src/android/net/wifi/WifiClientTest.java b/wifi/tests/src/android/net/wifi/WifiClientTest.java
new file mode 100644
index 0000000..42cab55
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiClientTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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.net.wifi;
+
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.net.MacAddress;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiClient}.
+ */
+@SmallTest
+public class WifiClientTest {
+ private static final String INTERFACE_NAME = "wlan0";
+ private static final String MAC_ADDRESS_STRING = "00:0a:95:9d:68:16";
+ private static final MacAddress MAC_ADDRESS = MacAddress.fromString(MAC_ADDRESS_STRING);
+
+ /**
+ * Verify parcel write/read with WifiClient.
+ */
+ @Test
+ public void testWifiClientParcelWriteRead() throws Exception {
+ WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
+
+ assertParcelSane(writeWifiClient, 1);
+ }
+
+ /**
+ * Verify equals with WifiClient.
+ */
+ @Test
+ public void testWifiClientEquals() throws Exception {
+ WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
+ WifiClient writeWifiClientEquals = new WifiClient(MAC_ADDRESS);
+
+ assertEquals(writeWifiClient, writeWifiClientEquals);
+ assertEquals(writeWifiClient.hashCode(), writeWifiClientEquals.hashCode());
+ assertFieldCountEquals(1, WifiClient.class);
+ }
+
+ /**
+ * Verify not-equals with WifiClient.
+ */
+ @Test
+ public void testWifiClientNotEquals() throws Exception {
+ final MacAddress macAddressNotEquals = MacAddress.fromString("00:00:00:00:00:00");
+ WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
+ WifiClient writeWifiClientNotEquals = new WifiClient(macAddressNotEquals);
+
+ assertNotEquals(writeWifiClient, writeWifiClientNotEquals);
+ assertNotEquals(writeWifiClient.hashCode(), writeWifiClientNotEquals.hashCode());
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index b75a1ac..4260c20 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -66,6 +66,7 @@
import android.net.wifi.WifiManager.TrafficStateCallback;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
@@ -101,8 +102,7 @@
private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
@Mock Context mContext;
- @Mock
- android.net.wifi.IWifiManager mWifiService;
+ @Mock android.net.wifi.IWifiManager mWifiService;
@Mock ApplicationInfo mApplicationInfo;
@Mock WifiConfiguration mApConfig;
@Mock IBinder mAppBinder;
@@ -118,7 +118,8 @@
private Messenger mWifiServiceMessenger;
final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class);
- @Before public void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
mHandler = spy(new Handler(mLooper.getLooper()));
@@ -214,7 +215,7 @@
@Test
public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
try (WifiManager.LocalOnlyHotspotSubscription sub =
- mWifiManager.new LocalOnlyHotspotSubscription()) {
+ mWifiManager.new LocalOnlyHotspotSubscription()) {
sub.close();
}
}
@@ -685,7 +686,7 @@
@Test
public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
try {
- mWifiManager.registerSoftApCallback(null, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
@@ -709,8 +710,8 @@
@Test
public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() {
when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
- mWifiManager.registerSoftApCallback(mSoftApCallback, null);
- verify(mContext).getMainLooper();
+ mWifiManager.registerSoftApCallback(null, mSoftApCallback);
+ verify(mContext).getMainExecutor();
}
/**
@@ -718,7 +719,7 @@
*/
@Test
public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
- mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(any(IBinder.class),
any(ISoftApCallback.Stub.class), anyInt());
}
@@ -729,7 +730,7 @@
@Test
public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
- mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(any(IBinder.class),
any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
@@ -744,7 +745,7 @@
public void softApCallbackProxyCallsOnStateChanged() throws Exception {
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
anyInt());
@@ -757,17 +758,17 @@
* Verify client-provided callback is being called through callback proxy
*/
@Test
- public void softApCallbackProxyCallsOnNumClientsChanged() throws Exception {
+ public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception {
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
anyInt());
- final int testNumClients = 3;
- callbackCaptor.getValue().onNumClientsChanged(testNumClients);
+ final List<WifiClient> testClients = new ArrayList();
+ callbackCaptor.getValue().onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mSoftApCallback).onConnectedClientsChanged(testClients);
}
/*
@@ -777,18 +778,18 @@
public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
- mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
anyInt());
- final int testNumClients = 5;
+ final List<WifiClient> testClients = new ArrayList();
callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
- callbackCaptor.getValue().onNumClientsChanged(testNumClients);
+ callbackCaptor.getValue().onConnectedClientsChanged(testClients);
callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
mLooper.dispatchAll();
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
- verify(mSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mSoftApCallback).onConnectedClientsChanged(testClients);
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
}
@@ -801,7 +802,7 @@
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
TestLooper altLooper = new TestLooper();
Handler altHandler = new Handler(altLooper.getLooper());
- mWifiManager.registerSoftApCallback(mSoftApCallback, altHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
anyInt());
@@ -815,7 +816,7 @@
*/
@Test
public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
- mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
mLooper.dispatchAll();
verify(mWifiService).registerSoftApCallback(any(IBinder.class),
any(ISoftApCallback.Stub.class), anyInt());
@@ -1047,8 +1048,8 @@
verifyNoMoreInteractions(mWifiService);
}
- /**
-i * Verify that a call to cancel WPS immediately returns a failure.
+ /**
+ * Verify that a call to cancel WPS immediately returns a failure.
*/
@Test
public void testCancelWpsImmediatelyFailsWithCallback() {
@@ -1343,7 +1344,6 @@
/**
* Verify getting the factory MAC address.
- * @throws Exception
*/
@Test
public void testGetFactoryMacAddress() throws Exception {
@@ -1390,7 +1390,6 @@
/**
* Test behavior of isEnhancedOpenSupported
- * @throws Exception
*/
@Test
public void testIsEnhancedOpenSupported() throws Exception {
@@ -1404,7 +1403,6 @@
/**
* Test behavior of isWpa3SaeSupported
- * @throws Exception
*/
@Test
public void testIsWpa3SaeSupported() throws Exception {
@@ -1418,7 +1416,6 @@
/**
* Test behavior of isWpa3SuiteBSupported
- * @throws Exception
*/
@Test
public void testIsWpa3SuiteBSupported() throws Exception {
@@ -1432,7 +1429,6 @@
/**
* Test behavior of isEasyConnectSupported
- * @throws Exception
*/
@Test
public void testIsEasyConnectSupported() throws Exception {
@@ -1446,7 +1442,6 @@
/**
* Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
- * @throws Exception
*/
@Test
public void testAddNetwork() throws Exception {
@@ -1463,7 +1458,6 @@
/**
* Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
- * @throws Exception
*/
@Test
public void testUpdateNetwork() throws Exception {
@@ -1485,7 +1479,6 @@
/**
* Test behavior of {@link WifiManager#enableNetwork(int, boolean)}
- * @throws Exception
*/
@Test
public void testEnableNetwork() throws Exception {
@@ -1497,7 +1490,6 @@
/**
* Test behavior of {@link WifiManager#disableNetwork(int)}
- * @throws Exception
*/
@Test
public void testDisableNetwork() throws Exception {
@@ -1509,7 +1501,6 @@
/**
* Test behavior of {@link WifiManager#disconnect()}
- * @throws Exception
*/
@Test
public void testDisconnect() throws Exception {
@@ -1520,7 +1511,6 @@
/**
* Test behavior of {@link WifiManager#reconnect()}
- * @throws Exception
*/
@Test
public void testReconnect() throws Exception {
@@ -1531,7 +1521,6 @@
/**
* Test behavior of {@link WifiManager#reassociate()}
- * @throws Exception
*/
@Test
public void testReassociate() throws Exception {
@@ -1542,7 +1531,6 @@
/**
* Test behavior of {@link WifiManager#getSupportedFeatures()}
- * @throws Exception
*/
@Test
public void testGetSupportedFeatures() throws Exception {
@@ -1569,7 +1557,6 @@
/**
* Test behavior of {@link WifiManager#getControllerActivityEnergyInfo()}
- * @throws Exception
*/
@Test
public void testGetControllerActivityEnergyInfo() throws Exception {
@@ -1582,7 +1569,6 @@
/**
* Test behavior of {@link WifiManager#getConnectionInfo()}
- * @throws Exception
*/
@Test
public void testGetConnectionInfo() throws Exception {
@@ -1594,7 +1580,6 @@
/**
* Test behavior of {@link WifiManager#isDualModeSupported()} ()}
- * @throws Exception
*/
@Test
public void testIsDualModeSupported() throws Exception {
@@ -1605,7 +1590,6 @@
/**
* Test behavior of {@link WifiManager#isDualBandSupported()}
- * @throws Exception
*/
@Test
public void testIsDualBandSupported() throws Exception {
@@ -1616,7 +1600,6 @@
/**
* Test behavior of {@link WifiManager#getDhcpInfo()}
- * @throws Exception
*/
@Test
public void testGetDhcpInfo() throws Exception {
@@ -1629,7 +1612,6 @@
/**
* Test behavior of {@link WifiManager#setWifiEnabled(boolean)}
- * @throws Exception
*/
@Test
public void testSetWifiEnabled() throws Exception {