Merge "Hook up TaskDescription into set bar color calls (6/N)"
diff --git a/Android.bp b/Android.bp
index d04eb17..3721947 100644
--- a/Android.bp
+++ b/Android.bp
@@ -958,8 +958,7 @@
metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
"--ignore-classes-on-classpath " +
- "--hide-package com.android.okhttp " +
- "--hide-package com.android.org.conscrypt --hide-package com.android.server " +
+ "--hide-package com.android.server " +
"--error UnhiddenSystemApi " +
"--hide RequiresPermission " +
"--hide CallbackInterface " +
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e731138..6831117 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,8 +1,6 @@
[Hook Scripts]
checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
-api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT}
-
strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
diff --git a/api/current.txt b/api/current.txt
index e5acc40..fdd30db 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30010,6 +30010,7 @@
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void addScanResultsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsListener);
+ method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
method public static int calculateSignalLevel(int, int);
method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -30046,6 +30047,7 @@
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", "android.permission.NETWORK_CARRIER_PROVISIONING"}) public void removePasspointConfiguration(String);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeScanResultsListener(@NonNull android.net.wifi.WifiManager.ScanResultsListener);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
method @Deprecated public boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(String, boolean);
@@ -30079,6 +30081,10 @@
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
+ field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
+ field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
+ field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
+ field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 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 @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
@@ -30125,6 +30131,10 @@
method public void onScanResultsAvailable();
}
+ public static interface WifiManager.SuggestionConnectionStatusListener {
+ method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
+ }
+
public class WifiManager.WifiLock {
method public void acquire();
method public boolean isHeld();
@@ -34183,31 +34193,31 @@
package android.os {
- public abstract class AsyncTask<Params, Progress, Result> {
- ctor public AsyncTask();
- method public final boolean cancel(boolean);
- method @WorkerThread protected abstract Result doInBackground(Params...);
- method @MainThread public final android.os.AsyncTask<Params,Progress,Result> execute(Params...);
- method @MainThread public static void execute(Runnable);
- method @MainThread public final android.os.AsyncTask<Params,Progress,Result> executeOnExecutor(java.util.concurrent.Executor, Params...);
- method public final Result get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
- method public final Result get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
- method public final android.os.AsyncTask.Status getStatus();
- method public final boolean isCancelled();
- method @MainThread protected void onCancelled(Result);
- method @MainThread protected void onCancelled();
- method @MainThread protected void onPostExecute(Result);
- method @MainThread protected void onPreExecute();
- method @MainThread protected void onProgressUpdate(Progress...);
- method @WorkerThread protected final void publishProgress(Progress...);
- field public static final java.util.concurrent.Executor SERIAL_EXECUTOR;
- field public static final java.util.concurrent.Executor THREAD_POOL_EXECUTOR;
+ @Deprecated public abstract class AsyncTask<Params, Progress, Result> {
+ ctor @Deprecated public AsyncTask();
+ method @Deprecated public final boolean cancel(boolean);
+ method @Deprecated @WorkerThread protected abstract Result doInBackground(Params...);
+ method @Deprecated @MainThread public final android.os.AsyncTask<Params,Progress,Result> execute(Params...);
+ method @Deprecated @MainThread public static void execute(Runnable);
+ method @Deprecated @MainThread public final android.os.AsyncTask<Params,Progress,Result> executeOnExecutor(java.util.concurrent.Executor, Params...);
+ method @Deprecated public final Result get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+ method @Deprecated public final Result get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+ method @Deprecated public final android.os.AsyncTask.Status getStatus();
+ method @Deprecated public final boolean isCancelled();
+ method @Deprecated @MainThread protected void onCancelled(Result);
+ method @Deprecated @MainThread protected void onCancelled();
+ method @Deprecated @MainThread protected void onPostExecute(Result);
+ method @Deprecated @MainThread protected void onPreExecute();
+ method @Deprecated @MainThread protected void onProgressUpdate(Progress...);
+ method @Deprecated @WorkerThread protected final void publishProgress(Progress...);
+ field @Deprecated public static final java.util.concurrent.Executor SERIAL_EXECUTOR;
+ field @Deprecated public static final java.util.concurrent.Executor THREAD_POOL_EXECUTOR;
}
- public enum AsyncTask.Status {
- enum_constant public static final android.os.AsyncTask.Status FINISHED;
- enum_constant public static final android.os.AsyncTask.Status PENDING;
- enum_constant public static final android.os.AsyncTask.Status RUNNING;
+ @Deprecated public enum AsyncTask.Status {
+ enum_constant @Deprecated public static final android.os.AsyncTask.Status FINISHED;
+ enum_constant @Deprecated public static final android.os.AsyncTask.Status PENDING;
+ enum_constant @Deprecated public static final android.os.AsyncTask.Status RUNNING;
}
public class BadParcelableException extends android.util.AndroidRuntimeException {
@@ -44280,6 +44290,9 @@
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";
@@ -44411,6 +44424,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";
@@ -52647,10 +52661,12 @@
field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
}
- public static final class AccessibilityNodeInfo.AccessibilityAction {
+ public static final class AccessibilityNodeInfo.AccessibilityAction implements android.os.Parcelable {
ctor public AccessibilityNodeInfo.AccessibilityAction(int, @Nullable CharSequence);
+ method public int describeContents();
method public int getId();
method public CharSequence getLabel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_ACCESSIBILITY_FOCUS;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_ACCESSIBILITY_FOCUS;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_FOCUS;
@@ -52688,6 +52704,7 @@
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_TOOLTIP;
+ field @NonNull public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> CREATOR;
}
public static final class AccessibilityNodeInfo.CollectionInfo {
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 2ca8cf4..4a37e67 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -534,7 +534,7 @@
MissingNullability: android.media.MediaMetadataRetriever#getFrameAtTime(long, int, android.media.MediaMetadataRetriever.BitmapParams):
MissingNullability: android.media.MediaMetadataRetriever#getScaledFrameAtTime(long, int, int, int, android.media.MediaMetadataRetriever.BitmapParams):
-
+
RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
@@ -1160,7 +1160,7 @@
SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener):
SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener):
-
+
StreamFiles: android.content.res.loader.DirectoryResourceLoader#DirectoryResourceLoader(java.io.File):
diff --git a/api/system-current.txt b/api/system-current.txt
index fd8fd88..5d3ecf5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -250,6 +250,7 @@
public static final class R.drawable {
field public static final int ic_info = 17301684; // 0x10800b4
+ field public static final int stat_notify_wifi_in_range = 17301685; // 0x10800b5
}
public static final class R.raw {
@@ -268,6 +269,9 @@
field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
+ field public static final int notification_channel_network_alerts = 17039398; // 0x1040026
+ field public static final int notification_channel_network_available = 17039399; // 0x1040027
+ field public static final int notification_channel_network_status = 17039397; // 0x1040025
}
public static final class R.style {
@@ -1278,9 +1282,13 @@
method public boolean disableBLE();
method public boolean enableBLE();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public long getDiscoveryEndMillis();
method public boolean isBleScanAlwaysAvailable();
method public boolean isLeEnabled();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setScanMode(int, int);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setScanMode(int);
field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
}
@@ -1371,6 +1379,14 @@
}
+package android.companion {
+
+ public final class CompanionDeviceManager {
+ method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociated(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
+ }
+
+}
+
package android.content {
public class ContentProviderClient implements java.lang.AutoCloseable {
@@ -4816,6 +4832,8 @@
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
+ method public boolean isApMacRandomizationSupported();
+ method public boolean isConnectedMacRandomizationSupported();
method @Deprecated public boolean isDeviceToDeviceRttSupported();
method public boolean isPortableHotspotSupported();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
@@ -5147,6 +5165,7 @@
field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
+ field public static final int PREAMBLE_HE = 3; // 0x3
field public static final int PREAMBLE_HT = 1; // 0x1
field public static final int PREAMBLE_LEGACY = 0; // 0x0
field public static final int PREAMBLE_VHT = 2; // 0x2
@@ -7471,13 +7490,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
}
- public class CallerInfo {
- method @Nullable public android.net.Uri getContactDisplayPhotoUri();
- method public long getContactId();
- method @Nullable public String getName();
- method @Nullable public String getPhoneNumber();
- }
-
public class CarrierConfigManager {
method @NonNull public static android.os.PersistableBundle getDefaultConfig();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
@@ -8109,6 +8121,12 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
}
+ public class PhoneNumberUtils {
+ method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
+ method public static boolean isUriNumber(@Nullable String);
+ method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
+ }
+
public class PhoneStateListener {
method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int);
@@ -8341,6 +8359,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();
@@ -8390,6 +8409,7 @@
public final class SmsManager {
method public boolean disableCellBroadcastRange(int, int, int);
method public boolean enableCellBroadcastRange(int, int, int);
+ method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
}
@@ -8407,6 +8427,7 @@
method public void requestEmbeddedSubscriptionInfoListRefresh(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
@@ -8476,11 +8497,13 @@
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
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();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
+ method public int getMaxNumberOfSimultaneouslyActiveSims();
method public static long getMaxNumberVerificationTimeoutMillis();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNetworkCountryIso(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
diff --git a/api/test-current.txt b/api/test-current.txt
index 495e57a..1f51c0f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -643,6 +643,14 @@
}
+package android.companion {
+
+ public final class CompanionDeviceManager {
+ method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociated(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
+ }
+
+}
+
package android.content {
public final class AutofillOptions implements android.os.Parcelable {
@@ -747,6 +755,7 @@
public abstract class PackageManager {
method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
method public abstract boolean arePermissionsIndividuallyControlled();
+ method @Nullable public String getContentCaptureServicePackageName();
method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
method @Nullable public String getIncidentReportApproverPackageName();
method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
@@ -2902,10 +2911,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);
}
@@ -2987,6 +3021,9 @@
public class PhoneNumberUtils {
method public static int getMinMatchForTest();
+ method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
+ method public static boolean isUriNumber(@Nullable String);
+ method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
method public static void setMinMatchForTest(int);
}
@@ -3010,6 +3047,7 @@
public final class SmsManager {
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+ method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
@@ -3017,9 +3055,21 @@
field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
}
+ 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 @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNetworkCountryIso(int);
method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
@@ -3043,6 +3093,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.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor) 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 9606413..ba85ae6 100644
--- a/api/test-lint-baseline.txt
+++ b/api/test-lint-baseline.txt
@@ -7,6 +7,36 @@
ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION:
+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:
@@ -69,6 +99,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():
@@ -229,6 +267,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:
@@ -297,6 +337,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):
@@ -413,6 +457,10 @@
+InternalField: android.telephony.ims.ImsConferenceState#mParticipants:
+ Internal field mParticipants must not be exposed
+
+
KotlinOperator: android.os.WorkSource#get(int):
@@ -423,6 +471,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:
@@ -441,6 +493,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.os.UserHandle#MIN_SECONDARY_USER_ID:
MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS:
@@ -1391,6 +1457,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:
@@ -1407,6 +1475,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():
@@ -1443,6 +1515,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:
@@ -1893,6 +2275,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[]):
@@ -1905,6 +2289,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):
@@ -2043,6 +2443,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):
@@ -2121,6 +2523,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/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 3cb2273..3d4eea5 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -793,7 +793,6 @@
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
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9b81f14..6182def 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2572,6 +2572,9 @@
* entirely drawn your UI and populated with all of the significant data. You
* can safely call this method any time after first launch as well, in which case
* it will simply be ignored.
+ * <p>If this method is called before the activity's window is <em>first</em> drawn
+ * and displayed as measured by the system, the reported time here will be shifted
+ * to the system measured time.
*/
public void reportFullyDrawn() {
if (mDoReportFullyDrawn) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1e78fc1..2e9b2af 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -17,6 +17,7 @@
package android.app;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import android.Manifest;
import android.annotation.DrawableRes;
@@ -31,6 +32,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.IPackageDataObserver;
@@ -981,6 +983,9 @@
private int mNavigationBarColor;
private boolean mEnsureStatusBarContrastWhenTransparent;
private boolean mEnsureNavigationBarContrastWhenTransparent;
+ private int mResizeMode;
+ private int mMinWidth;
+ private int mMinHeight;
/**
* Creates the TaskDescription to the specified values.
@@ -993,7 +998,8 @@
*/
@Deprecated
public TaskDescription(String label, Bitmap icon, int colorPrimary) {
- this(label, icon, 0, null, colorPrimary, 0, 0, 0, false, false);
+ this(label, icon, 0, null, colorPrimary, 0, 0, 0, false, false,
+ RESIZE_MODE_RESIZEABLE, -1, -1);
if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
throw new RuntimeException("A TaskDescription's primary color should be opaque");
}
@@ -1009,7 +1015,8 @@
* opaque.
*/
public TaskDescription(String label, @DrawableRes int iconRes, int colorPrimary) {
- this(label, null, iconRes, null, colorPrimary, 0, 0, 0, false, false);
+ this(label, null, iconRes, null, colorPrimary, 0, 0, 0, false, false,
+ RESIZE_MODE_RESIZEABLE, -1, -1);
if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
throw new RuntimeException("A TaskDescription's primary color should be opaque");
}
@@ -1024,7 +1031,7 @@
*/
@Deprecated
public TaskDescription(String label, Bitmap icon) {
- this(label, icon, 0, null, 0, 0, 0, 0, false, false);
+ this(label, icon, 0, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1);
}
/**
@@ -1035,7 +1042,8 @@
* activity.
*/
public TaskDescription(String label, @DrawableRes int iconRes) {
- this(label, null, iconRes, null, 0, 0, 0, 0, false, false);
+ this(label, null, iconRes, null, 0, 0, 0, 0, false, false,
+ RESIZE_MODE_RESIZEABLE, -1, -1);
}
/**
@@ -1044,21 +1052,22 @@
* @param label A label and description of the current state of this activity.
*/
public TaskDescription(String label) {
- this(label, null, 0, null, 0, 0, 0, 0, false, false);
+ this(label, null, 0, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1);
}
/**
* Creates an empty TaskDescription.
*/
public TaskDescription() {
- this(null, null, 0, null, 0, 0, 0, 0, false, false);
+ this(null, null, 0, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1);
}
/** @hide */
public TaskDescription(String label, Bitmap bitmap, int iconRes, String iconFilename,
int colorPrimary, int colorBackground, int statusBarColor, int navigationBarColor,
boolean ensureStatusBarContrastWhenTransparent,
- boolean ensureNavigationBarContrastWhenTransparent) {
+ boolean ensureNavigationBarContrastWhenTransparent, int resizeMode, int minWidth,
+ int minHeight) {
mLabel = label;
mIcon = bitmap;
mIconRes = iconRes;
@@ -1070,6 +1079,9 @@
mEnsureStatusBarContrastWhenTransparent = ensureStatusBarContrastWhenTransparent;
mEnsureNavigationBarContrastWhenTransparent =
ensureNavigationBarContrastWhenTransparent;
+ mResizeMode = resizeMode;
+ mMinWidth = minWidth;
+ mMinHeight = minHeight;
}
/**
@@ -1095,6 +1107,9 @@
mEnsureStatusBarContrastWhenTransparent = other.mEnsureStatusBarContrastWhenTransparent;
mEnsureNavigationBarContrastWhenTransparent =
other.mEnsureNavigationBarContrastWhenTransparent;
+ mResizeMode = other.mResizeMode;
+ mMinWidth = other.mMinWidth;
+ mMinHeight = other.mMinHeight;
}
/**
@@ -1120,6 +1135,9 @@
mEnsureStatusBarContrastWhenTransparent = other.mEnsureStatusBarContrastWhenTransparent;
mEnsureNavigationBarContrastWhenTransparent =
other.mEnsureNavigationBarContrastWhenTransparent;
+ mResizeMode = other.mResizeMode;
+ mMinWidth = other.mMinWidth;
+ mMinHeight = other.mMinHeight;
}
private TaskDescription(Parcel source) {
@@ -1200,6 +1218,33 @@
}
/**
+ * Sets the resize mode for this task description. Resize mode as in
+ * {@link android.content.pm.ActivityInfo}.
+ * @hide
+ */
+ public void setResizeMode(int resizeMode) {
+ mResizeMode = resizeMode;
+ }
+
+ /**
+ * The minimal width size to show the app content in freeform mode.
+ * @param minWidth minimal width, -1 for system default.
+ * @hide
+ */
+ public void setMinWidth(int minWidth) {
+ mMinWidth = minWidth;
+ }
+
+ /**
+ * The minimal height size to show the app content in freeform mode.
+ * @param minHeight minimal height, -1 for system default.
+ * @hide
+ */
+ public void setMinHeight(int minHeight) {
+ mMinHeight = minHeight;
+ }
+
+ /**
* @return The label and description of the current state of this task.
*/
public String getLabel() {
@@ -1309,6 +1354,27 @@
ensureNavigationBarContrastWhenTransparent;
}
+ /**
+ * @hide
+ */
+ public int getResizeMode() {
+ return mResizeMode;
+ }
+
+ /**
+ * @hide
+ */
+ public int getMinWidth() {
+ return mMinWidth;
+ }
+
+ /**
+ * @hide
+ */
+ public int getMinHeight() {
+ return mMinHeight;
+ }
+
/** @hide */
public void saveToXml(XmlSerializer out) throws IOException {
if (mLabel != null) {
@@ -1371,6 +1437,9 @@
dest.writeInt(mNavigationBarColor);
dest.writeBoolean(mEnsureStatusBarContrastWhenTransparent);
dest.writeBoolean(mEnsureNavigationBarContrastWhenTransparent);
+ dest.writeInt(mResizeMode);
+ dest.writeInt(mMinWidth);
+ dest.writeInt(mMinHeight);
if (mIconFilename == null) {
dest.writeInt(0);
} else {
@@ -1389,6 +1458,9 @@
mNavigationBarColor = source.readInt();
mEnsureStatusBarContrastWhenTransparent = source.readBoolean();
mEnsureNavigationBarContrastWhenTransparent = source.readBoolean();
+ mResizeMode = source.readInt();
+ mMinWidth = source.readInt();
+ mMinHeight = source.readInt();
mIconFilename = source.readInt() > 0 ? source.readString() : null;
}
@@ -1404,14 +1476,16 @@
@Override
public String toString() {
- return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
- " IconRes: " + mIconRes + " IconFilename: " + mIconFilename +
- " colorPrimary: " + mColorPrimary + " colorBackground: " + mColorBackground +
- " statusBarColor: " + mStatusBarColor + (
- mEnsureStatusBarContrastWhenTransparent ? " (contrast when transparent)"
- : "") + " navigationBarColor: " + mNavigationBarColor + (
- mEnsureNavigationBarContrastWhenTransparent
- ? " (contrast when transparent)" : "");
+ return "TaskDescription Label: " + mLabel + " Icon: " + mIcon
+ + " IconRes: " + mIconRes + " IconFilename: " + mIconFilename
+ + " colorPrimary: " + mColorPrimary + " colorBackground: " + mColorBackground
+ + " statusBarColor: " + mStatusBarColor
+ + (mEnsureStatusBarContrastWhenTransparent ? " (contrast when transparent)"
+ : "") + " navigationBarColor: " + mNavigationBarColor
+ + (mEnsureNavigationBarContrastWhenTransparent
+ ? " (contrast when transparent)" : "")
+ + " resizeMode: " + ActivityInfo.resizeModeToString(mResizeMode)
+ + " minWidth: " + mMinWidth + " minHeight: " + mMinHeight;
}
}
@@ -1523,6 +1597,9 @@
pw.print(" iconRes=" + (td.getIconResource() != 0));
pw.print(" iconBitmap=" + (td.getIconFilename() != null
|| td.getInMemoryIcon() != null));
+ pw.print(" resizeMode=" + ActivityInfo.resizeModeToString(td.getResizeMode()));
+ pw.print(" minWidth=" + td.getMinWidth());
+ pw.print(" minHeight=" + td.getMinHeight());
pw.println(" }");
}
}
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index fbf1f59..79ab67a 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -16,94 +16,58 @@
package android.app;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
-import static android.view.Display.INVALID_DISPLAY;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
-import android.app.ActivityManager.StackInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Insets;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.VirtualDisplay;
-import android.hardware.input.InputManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.IWindow;
import android.view.IWindowManager;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
-import android.view.SurfaceSession;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.inputmethod.InputMethodManager;
import dalvik.system.CloseGuard;
-import java.util.List;
-
/**
- * Activity container that allows launching activities into itself.
+ * Task container that allows launching activities into itself.
* <p>Activity launching into this container is restricted by the same rules that apply to launching
* on VirtualDisplays.
* @hide
*/
@TestApi
-public class ActivityView extends ViewGroup {
+public class ActivityView extends ViewGroup implements TaskEmbedder.Host {
- private static final String DISPLAY_NAME = "ActivityViewVirtualDisplay";
private static final String TAG = "ActivityView";
- private VirtualDisplay mVirtualDisplay;
+ private TaskEmbedder mTaskEmbedder;
+
private final SurfaceView mSurfaceView;
-
- /**
- * This is the root surface for the VirtualDisplay. The VirtualDisplay child surfaces will be
- * re-parented to this surface. This will also be a child of the SurfaceView's SurfaceControl.
- */
- private SurfaceControl mRootSurfaceControl;
-
private final SurfaceCallback mSurfaceCallback;
- private StateCallback mActivityViewCallback;
-
- private IActivityTaskManager mActivityTaskManager;
- // Temp container to store view coordinates in window.
- private final int[] mLocationInWindow = new int[2];
-
- // The latest tap exclude region that we've sent to WM.
- private final Region mTapExcludeRegion = new Region();
-
- private TaskStackListener mTaskStackListener;
private final CloseGuard mGuard = CloseGuard.get();
private boolean mOpened; // Protected by mGuard.
private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
- /** The ActivityView is only allowed to contain one task. */
- private final boolean mSingleTaskInstance;
-
- private Insets mForwardedInsets;
-
- private float mCornerRadius;
+ // For Host
+ private final Point mWindowPosition = new Point();
+ private final int[] mTmpArray = new int[2];
+ private final Matrix mScreenSurfaceMatrix = new Matrix();
+ private final Region mTapExcludeRegion = new Region();
public ActivityView(Context context) {
this(context, null /* attrs */);
@@ -120,9 +84,7 @@
public ActivityView(
Context context, AttributeSet attrs, int defStyle, boolean singleTaskInstance) {
super(context, attrs, defStyle);
- mSingleTaskInstance = singleTaskInstance;
-
- mActivityTaskManager = ActivityTaskManager.getService();
+ mTaskEmbedder = new TaskEmbedder(getContext(), this, singleTaskInstance);
mSurfaceView = new SurfaceView(context);
// Since ActivityView#getAlpha has been overridden, we should use parent class's alpha
// as master to synchronize surface view's alpha value.
@@ -189,11 +151,11 @@
* @see #startActivity(Intent)
*/
public void setCallback(StateCallback callback) {
- mActivityViewCallback = callback;
-
- if (mVirtualDisplay != null && mActivityViewCallback != null) {
- mActivityViewCallback.onActivityViewReady(this);
+ if (callback == null) {
+ mTaskEmbedder.setListener(null);
+ return;
}
+ mTaskEmbedder.setListener(new StateCallbackAdapter(callback));
}
/**
@@ -262,8 +224,7 @@
* @see #startActivity(PendingIntent)
*/
public void startActivity(@NonNull Intent intent) {
- final ActivityOptions options = prepareActivityOptions();
- getContext().startActivity(intent, options.toBundle());
+ mTaskEmbedder.startActivity(intent);
}
/**
@@ -284,8 +245,7 @@
* @see #startActivity(PendingIntent)
*/
public void startActivity(@NonNull Intent intent, UserHandle user) {
- final ActivityOptions options = prepareActivityOptions();
- getContext().startActivityAsUser(intent, options.toBundle(), user);
+ mTaskEmbedder.startActivity(intent, user);
}
/**
@@ -304,14 +264,7 @@
* @see #startActivity(Intent)
*/
public void startActivity(@NonNull PendingIntent pendingIntent) {
- final ActivityOptions options = prepareActivityOptions();
- try {
- pendingIntent.send(null /* context */, 0 /* code */, null /* intent */,
- null /* onFinished */, null /* handler */, null /* requiredPermission */,
- options.toBundle());
- } catch (PendingIntent.CanceledException e) {
- throw new RuntimeException(e);
- }
+ mTaskEmbedder.startActivity(pendingIntent);
}
/**
@@ -333,28 +286,7 @@
*/
public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
@NonNull ActivityOptions options) {
- options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
- try {
- pendingIntent.send(getContext(), 0 /* code */, fillInIntent,
- null /* onFinished */, null /* handler */, null /* requiredPermission */,
- options.toBundle());
- } catch (PendingIntent.CanceledException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Check if container is ready to launch and create {@link ActivityOptions} to target the
- * virtual display.
- */
- private ActivityOptions prepareActivityOptions() {
- if (mVirtualDisplay == null) {
- throw new IllegalStateException(
- "Trying to start activity before ActivityView is ready.");
- }
- final ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
- return options;
+ mTaskEmbedder.startActivity(pendingIntent, fillInIntent, options);
}
/**
@@ -366,7 +298,7 @@
* @see StateCallback
*/
public void release() {
- if (mVirtualDisplay == null) {
+ if (!mTaskEmbedder.isInitialized()) {
throw new IllegalStateException(
"Trying to release container that is not initialized.");
}
@@ -378,15 +310,7 @@
* regions and avoid focus switches by touches on this view.
*/
public void onLocationChanged() {
- updateLocationAndTapExcludeRegion();
- }
-
- private void clearActivityViewGeometryForIme() {
- if (mVirtualDisplay == null) {
- return;
- }
- final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
- mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null);
+ mTaskEmbedder.notifyBoundsChanged();
}
@Override
@@ -419,102 +343,31 @@
public boolean gatherTransparentRegion(Region region) {
// The tap exclude region may be affected by any view on top of it, so we detect the
// possible change by monitoring this function.
- updateLocationAndTapExcludeRegion();
+ mTaskEmbedder.notifyBoundsChanged();
return super.gatherTransparentRegion(region);
}
- /**
- * Sends current location in window and tap exclude region to WM for this view.
- */
- private void updateLocationAndTapExcludeRegion() {
- if (mVirtualDisplay == null || !isAttachedToWindow()) {
- return;
- }
- try {
- int x = mLocationInWindow[0];
- int y = mLocationInWindow[1];
- getLocationInWindow(mLocationInWindow);
- if (x != mLocationInWindow[0] || y != mLocationInWindow[1]) {
- x = mLocationInWindow[0];
- y = mLocationInWindow[1];
- final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
- WindowManagerGlobal.getWindowSession().updateDisplayContentLocation(
- getWindow(), x, y, displayId);
-
- // Also report this geometry information to InputMethodManagerService.
- // TODO(b/115693908): Unify this logic into the above WMS-based one.
- // TODO(b/138175283): Address the location update when the host of this view is
- // moving.
- final Matrix matrix = new Matrix();
- final int[] locationOnScreen = new int[2];
- getLocationOnScreen(locationOnScreen);
- final int dx = locationOnScreen[0];
- final int dy = locationOnScreen[1];
- matrix.set(getMatrix());
- matrix.postTranslate(dx, dy);
- mContext.getSystemService(InputMethodManager.class)
- .reportActivityView(displayId, matrix);
- }
- updateTapExcludeRegion(x, y);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /** Computes and sends current tap exclude region to WM for this view. */
- private void updateTapExcludeRegion(int x, int y) throws RemoteException {
- if (!canReceivePointerEvents()) {
- cleanTapExcludeRegion();
- return;
- }
- mTapExcludeRegion.set(x, y, x + getWidth(), y + getHeight());
-
- // There might be views on top of us. We need to subtract those areas from the tap
- // exclude region.
- final ViewParent parent = getParent();
- if (parent != null) {
- parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this);
- }
-
- WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
- mTapExcludeRegion);
- }
-
private class SurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
- if (mVirtualDisplay == null) {
- initVirtualDisplay(new SurfaceSession());
- if (mVirtualDisplay != null && mActivityViewCallback != null) {
- mActivityViewCallback.onActivityViewReady(ActivityView.this);
- }
+ if (!mTaskEmbedder.isInitialized()) {
+ initTaskEmbedder(mSurfaceView.getSurfaceControl());
} else {
- mTmpTransaction.reparent(mRootSurfaceControl,
+ mTmpTransaction.reparent(mTaskEmbedder.getSurfaceControl(),
mSurfaceView.getSurfaceControl()).apply();
}
-
- if (mVirtualDisplay != null) {
- mVirtualDisplay.setDisplayState(true);
- }
-
- updateLocationAndTapExcludeRegion();
+ mTaskEmbedder.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
- if (mVirtualDisplay != null) {
- mVirtualDisplay.resize(width, height, getBaseDisplayDensity());
- }
- updateLocationAndTapExcludeRegion();
+ mTaskEmbedder.resizeTask(width, height);
+ mTaskEmbedder.notifyBoundsChanged();
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
- if (mVirtualDisplay != null) {
- mVirtualDisplay.setDisplayState(false);
- }
- clearActivityViewGeometryForIme();
- cleanTapExcludeRegion();
+ mTaskEmbedder.stop();
}
}
@@ -528,10 +381,7 @@
* @return the display id of the virtual display.
*/
public int getVirtualDisplayId() {
- if (mVirtualDisplay != null) {
- return mVirtualDisplay.getDisplay().getDisplayId();
- }
- return INVALID_DISPLAY;
+ return mTaskEmbedder.getDisplayId();
}
/**
@@ -539,135 +389,36 @@
* virtual display.
*/
public void performBackPress() {
- if (mVirtualDisplay == null) {
- return;
- }
- final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
- final InputManager im = InputManager.getInstance();
- im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, displayId),
- InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
- im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, displayId),
- InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ mTaskEmbedder.performBackPress();
}
- private static KeyEvent createKeyEvent(int action, int code, int displayId) {
- long when = SystemClock.uptimeMillis();
- final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
- 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
- InputDevice.SOURCE_KEYBOARD);
- ev.setDisplayId(displayId);
- return ev;
- }
-
- private void initVirtualDisplay(SurfaceSession surfaceSession) {
- if (mVirtualDisplay != null) {
- throw new IllegalStateException("Trying to initialize for the second time.");
- }
-
- final int width = mSurfaceView.getWidth();
- final int height = mSurfaceView.getHeight();
- final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-
- mVirtualDisplay = displayManager.createVirtualDisplay(
- DISPLAY_NAME + "@" + System.identityHashCode(this), width, height,
- getBaseDisplayDensity(), null,
- VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
- | VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL);
- if (mVirtualDisplay == null) {
+ /**
+ * Initializes the task embedder.
+ *
+ * @param parent control for the surface to parent to
+ * @return true if the task embedder has been initialized
+ */
+ private boolean initTaskEmbedder(SurfaceControl parent) {
+ if (!mTaskEmbedder.initialize(parent)) {
Log.e(TAG, "Failed to initialize ActivityView");
- return;
+ return false;
}
-
- final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
- final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-
- mRootSurfaceControl = new SurfaceControl.Builder(surfaceSession)
- .setContainerLayer()
- .setParent(mSurfaceView.getSurfaceControl())
- .setName(DISPLAY_NAME)
- .build();
-
- try {
- // TODO: Find a way to consolidate these calls to the server.
- WindowManagerGlobal.getWindowSession().reparentDisplayContent(
- getWindow(), mRootSurfaceControl, displayId);
- wm.dontOverrideDisplayInfo(displayId);
- if (mSingleTaskInstance) {
- mActivityTaskManager.setDisplayToSingleTaskInstance(displayId);
- }
- wm.setForwardedInsets(displayId, mForwardedInsets);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
-
- mTmpTransaction.show(mRootSurfaceControl).apply();
- mTaskStackListener = new TaskStackListenerImpl();
- try {
- mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to register task stack listener", e);
- }
+ mTmpTransaction.show(mTaskEmbedder.getSurfaceControl()).apply();
+ return true;
}
private void performRelease() {
if (!mOpened) {
return;
}
-
mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
-
- cleanTapExcludeRegion();
-
- if (mTaskStackListener != null) {
- try {
- mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to unregister task stack listener", e);
- }
- mTaskStackListener = null;
- }
-
- final boolean displayReleased;
- if (mVirtualDisplay != null) {
- mVirtualDisplay.release();
- mVirtualDisplay = null;
- displayReleased = true;
- } else {
- displayReleased = false;
- }
-
- if (displayReleased && mActivityViewCallback != null) {
- mActivityViewCallback.onActivityViewDestroyed(this);
- }
+ mTaskEmbedder.setListener(null);
+ mTaskEmbedder.release();
mGuard.close();
mOpened = false;
}
- /** Report to server that tap exclude region on hosting display should be cleared. */
- private void cleanTapExcludeRegion() {
- if (!isAttachedToWindow() || mTapExcludeRegion.isEmpty()) {
- return;
- }
- // Update tap exclude region with a null region to clean the state on server.
- try {
- WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
- null /* region */);
- mTapExcludeRegion.setEmpty();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /** Get density of the hosting display. */
- private int getBaseDisplayDensity() {
- final WindowManager wm = mContext.getSystemService(WindowManager.class);
- final DisplayMetrics metrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(metrics);
- return metrics.densityDpi;
- }
-
@Override
protected void finalize() throws Throwable {
try {
@@ -686,108 +437,100 @@
* @see IWindowManager#setForwardedInsets
*/
public void setForwardedInsets(Insets insets) {
- mForwardedInsets = insets;
- if (mVirtualDisplay == null) {
- return;
- }
- try {
- final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
- wm.setForwardedInsets(mVirtualDisplay.getDisplay().getDisplayId(), mForwardedInsets);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
+ mTaskEmbedder.setForwardedInsets(insets);
+ }
+
+ // Host
+
+ /** @hide */
+ @Override
+ public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) {
+ if (mSurfaceView != null) {
+ mSurfaceView.setResizeBackgroundColor(bgColor);
}
}
- /**
- * A task change listener that detects background color change of the topmost stack on our
- * virtual display and updates the background of the surface view. This background will be shown
- * when surface view is resized, but the app hasn't drawn its content in new size yet.
- * It also calls StateCallback.onTaskMovedToFront to notify interested parties that the stack
- * associated with the {@link ActivityView} has had a Task moved to the front. This is useful
- * when needing to also bring the host Activity to the foreground at the same time.
- */
- private class TaskStackListenerImpl extends TaskStackListener {
+ /** @hide */
+ @Override
+ public Region getTapExcludeRegion() {
+ if (isAttachedToWindow() && canReceivePointerEvents()) {
+ Point windowPos = getPositionInWindow();
+ mTapExcludeRegion.set(
+ windowPos.x,
+ windowPos.y,
+ windowPos.x + getWidth(),
+ windowPos.y + getHeight());
+ // There might be views on top of us. We need to subtract those areas from the tap
+ // exclude region.
+ final ViewParent parent = getParent();
+ if (parent != null) {
+ parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this);
+ }
+ } else {
+ mTapExcludeRegion.setEmpty();
+ }
+ return mTapExcludeRegion;
+ }
- @Override
- public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
- throws RemoteException {
- if (mVirtualDisplay == null
- || taskInfo.displayId != mVirtualDisplay.getDisplay().getDisplayId()) {
- return;
- }
+ /** @hide */
+ @Override
+ public Matrix getScreenToTaskMatrix() {
+ getLocationOnScreen(mTmpArray);
+ mScreenSurfaceMatrix.set(getMatrix());
+ mScreenSurfaceMatrix.postTranslate(mTmpArray[0], mTmpArray[1]);
+ return mScreenSurfaceMatrix;
+ }
- StackInfo stackInfo = getTopMostStackInfo();
- if (stackInfo == null) {
- return;
- }
- // Found the topmost stack on target display. Now check if the topmost task's
- // description changed.
- if (taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
- mSurfaceView.setResizeBackgroundColor(
- taskInfo.taskDescription.getBackgroundColor());
- }
+ /** @hide */
+ @Override
+ public Point getPositionInWindow() {
+ getLocationInWindow(mTmpArray);
+ mWindowPosition.set(mTmpArray[0], mTmpArray[1]);
+ return mWindowPosition;
+ }
+
+ /** @hide */
+ @Override
+ public IWindow getWindow() {
+ return super.getWindow();
+ }
+
+ /** @hide */
+ @Override
+ public boolean canReceivePointerEvents() {
+ return super.canReceivePointerEvents();
+ }
+
+ private final class StateCallbackAdapter implements TaskEmbedder.Listener {
+ private final StateCallback mCallback;
+
+ private StateCallbackAdapter(ActivityView.StateCallback cb) {
+ mCallback = cb;
}
@Override
- public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
- throws RemoteException {
- if (mActivityViewCallback == null || mVirtualDisplay == null
- || taskInfo.displayId != mVirtualDisplay.getDisplay().getDisplayId()) {
- return;
- }
-
- StackInfo stackInfo = getTopMostStackInfo();
- // if StackInfo was null or unrelated to the "move to front" then there's no use
- // notifying the callback
- if (stackInfo != null
- && taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
- mActivityViewCallback.onTaskMovedToFront(taskInfo.taskId);
- }
+ public void onInitialized() {
+ mCallback.onActivityViewReady(ActivityView.this);
}
@Override
- public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
- if (mActivityViewCallback == null || mVirtualDisplay == null) {
- return;
- }
-
- StackInfo stackInfo = getTopMostStackInfo();
- // if StackInfo was null or unrelated to the task creation then there's no use
- // notifying the callback
- if (stackInfo != null
- && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
- mActivityViewCallback.onTaskCreated(taskId, componentName);
- }
+ public void onReleased() {
+ mCallback.onActivityViewDestroyed(ActivityView.this);
}
@Override
- public void onTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)
- throws RemoteException {
- if (mActivityViewCallback == null || mVirtualDisplay == null
- || taskInfo.displayId != mVirtualDisplay.getDisplay().getDisplayId()) {
- return;
- }
- mActivityViewCallback.onTaskRemovalStarted(taskInfo.taskId);
+ public void onTaskCreated(int taskId, ComponentName name) {
+ mCallback.onTaskCreated(taskId, name);
}
- private StackInfo getTopMostStackInfo() throws RemoteException {
- // Find the topmost task on our virtual display - it will define the background
- // color of the surface view during resizing.
- final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
- final List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfos();
+ @Override
+ public void onTaskMovedToFront(int taskId) {
+ mCallback.onTaskMovedToFront(taskId);
+ }
- // Iterate through stacks from top to bottom.
- final int stackCount = stackInfoList.size();
- for (int i = 0; i < stackCount; i++) {
- final StackInfo stackInfo = stackInfoList.get(i);
- // Only look for stacks on our virtual display.
- if (stackInfo.displayId != displayId) {
- continue;
- }
- // Found the topmost stack on target display.
- return stackInfo;
- }
- return null;
+ @Override
+ public void onTaskRemovalStarted(int taskId) {
+ mCallback.onTaskRemovalStarted(taskId);
}
}
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 03ef286..008c4c1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3196,6 +3196,15 @@
}
@Override
+ public String getContentCaptureServicePackageName() {
+ try {
+ return mPM.getContentCaptureServicePackageName();
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ @Override
public boolean isPackageStateProtected(String packageName, int userId) {
try {
return mPM.isPackageStateProtected(packageName, userId);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 629c2bb..36d899e 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -170,6 +170,7 @@
import android.telephony.TelephonyRegistryManager;
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;
@@ -631,6 +632,14 @@
}
});
+ 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
diff --git a/core/java/android/app/TaskEmbedder.java b/core/java/android/app/TaskEmbedder.java
new file mode 100644
index 0000000..a1389bd
--- /dev/null
+++ b/core/java/android/app/TaskEmbedder.java
@@ -0,0 +1,674 @@
+/*
+ * 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.app;
+
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Insets;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Region;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.hardware.input.InputManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWindow;
+import android.view.IWindowManager;
+import android.view.IWindowSession;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.inputmethod.InputMethodManager;
+
+import dalvik.system.CloseGuard;
+
+import java.util.List;
+
+/**
+ * A component which handles embedded display of tasks within another window. The embedded task can
+ * be presented using the SurfaceControl provided from {@link #getSurfaceControl()}.
+ *
+ * @hide
+ */
+public class TaskEmbedder {
+ private static final String TAG = "TaskEmbedder";
+ private static final String DISPLAY_NAME = "TaskVirtualDisplay";
+
+ /**
+ * A component which will host the task.
+ */
+ public interface Host {
+ /** @return the screen area where touches should be dispatched to the embedded Task */
+ Region getTapExcludeRegion();
+
+ /** @return a matrix which transforms from screen-space to the embedded task surface */
+ Matrix getScreenToTaskMatrix();
+
+ /** @return the window containing the parent surface, if attached and available */
+ @Nullable IWindow getWindow();
+
+ /** @return the x/y offset from the origin of the window to the surface */
+ Point getPositionInWindow();
+
+ /** @return whether this surface is able to receive pointer events */
+ boolean canReceivePointerEvents();
+
+ /** @return the width of the container for the embedded task */
+ int getWidth();
+
+ /** @return the height of the container for the embedded task */
+ int getHeight();
+
+ /**
+ * Called to inform the host of the task's background color. This can be used to
+ * fill unpainted areas if necessary.
+ */
+ void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor);
+ }
+
+ /**
+ * Describes changes to the state of the TaskEmbedder as well the tasks within.
+ */
+ public interface Listener {
+ /** Called when the container is ready for launching activities. */
+ default void onInitialized() {}
+
+ /** Called when the container can no longer launch activities. */
+ default void onReleased() {}
+
+ /** Called when a task is created inside the container. */
+ default void onTaskCreated(int taskId, ComponentName name) {}
+
+ /** Called when a task is moved to the front of the stack inside the container. */
+ default void onTaskMovedToFront(int taskId) {}
+
+ /** Called when a task is about to be removed from the stack inside the container. */
+ default void onTaskRemovalStarted(int taskId) {}
+ }
+
+ private IActivityTaskManager mActivityTaskManager = ActivityTaskManager.getService();
+
+ private final Context mContext;
+ private TaskEmbedder.Host mHost;
+ private int mDisplayDensityDpi;
+ private final boolean mSingleTaskInstance;
+ private SurfaceControl.Transaction mTransaction;
+ private SurfaceControl mSurfaceControl;
+ private VirtualDisplay mVirtualDisplay;
+ private Insets mForwardedInsets;
+ private TaskStackListener mTaskStackListener;
+ private Listener mListener;
+ private boolean mOpened; // Protected by mGuard.
+
+ private final CloseGuard mGuard = CloseGuard.get();
+
+
+ /**
+ * Constructs a new TaskEmbedder.
+ *
+ * @param context the context
+ * @param host the host for this embedded task
+ * @param singleTaskInstance whether to apply a single-task constraint to this container
+ */
+ public TaskEmbedder(Context context, TaskEmbedder.Host host, boolean singleTaskInstance) {
+ mContext = context;
+ mHost = host;
+ mSingleTaskInstance = singleTaskInstance;
+ }
+
+ /**
+ * Whether this container has been initialized.
+ *
+ * @return true if initialized
+ */
+ public boolean isInitialized() {
+ return mVirtualDisplay != null;
+ }
+
+ /**
+ * Initialize this container.
+ *
+ * @param parent the surface control for the parent surface
+ * @return true if initialized successfully
+ */
+ public boolean initialize(SurfaceControl parent) {
+ if (mVirtualDisplay != null) {
+ throw new IllegalStateException("Trying to initialize for the second time.");
+ }
+
+ mTransaction = new SurfaceControl.Transaction();
+
+ final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ mDisplayDensityDpi = getBaseDisplayDensity();
+
+ mVirtualDisplay = displayManager.createVirtualDisplay(
+ DISPLAY_NAME + "@" + System.identityHashCode(this), mHost.getWidth(),
+ mHost.getHeight(), mDisplayDensityDpi, null,
+ VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
+ | VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL);
+
+ if (mVirtualDisplay == null) {
+ Log.e(TAG, "Failed to initialize TaskEmbedder");
+ return false;
+ }
+
+ // Create a container surface to which the ActivityDisplay will be reparented
+ final String name = "TaskEmbedder - " + Integer.toHexString(System.identityHashCode(this));
+ mSurfaceControl = new SurfaceControl.Builder()
+ .setContainerLayer()
+ .setParent(parent)
+ .setName(name)
+ .build();
+
+ final int displayId = getDisplayId();
+
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ try {
+ // TODO: Find a way to consolidate these calls to the server.
+ WindowManagerGlobal.getWindowSession().reparentDisplayContent(
+ mHost.getWindow(), mSurfaceControl, displayId);
+ wm.dontOverrideDisplayInfo(displayId);
+ if (mSingleTaskInstance) {
+ mContext.getSystemService(ActivityTaskManager.class)
+ .setDisplayToSingleTaskInstance(displayId);
+ }
+ setForwardedInsets(mForwardedInsets);
+ if (mHost.getWindow() != null) {
+ updateLocationAndTapExcludeRegion();
+ }
+ mTaskStackListener = new TaskStackListenerImpl();
+ try {
+ mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register task stack listener", e);
+ }
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ if (mListener != null && mVirtualDisplay != null) {
+ mListener.onInitialized();
+ }
+ mOpened = true;
+ mGuard.open("release");
+ return true;
+ }
+
+ /**
+ * Returns the surface control for the task surface. This should be parented to a screen
+ * surface for display/embedding purposes.
+ *
+ * @return the surface control for the task
+ */
+ public SurfaceControl getSurfaceControl() {
+ return mSurfaceControl;
+ }
+
+ /**
+ * Set forwarded insets on the virtual display.
+ *
+ * @see IWindowManager#setForwardedInsets
+ */
+ public void setForwardedInsets(Insets insets) {
+ mForwardedInsets = insets;
+ if (mVirtualDisplay == null) {
+ return;
+ }
+ try {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ wm.setForwardedInsets(getDisplayId(), mForwardedInsets);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** An opaque unique identifier for this task surface among others being managed by the app. */
+ public int getId() {
+ return getDisplayId();
+ }
+
+ int getDisplayId() {
+ if (mVirtualDisplay != null) {
+ return mVirtualDisplay.getDisplay().getDisplayId();
+ }
+ return Display.INVALID_DISPLAY;
+ }
+
+ /**
+ * Set the callback to be notified about state changes.
+ * <p>This class must finish initializing before {@link #startActivity(Intent)} can be called.
+ * <p>Note: If the instance was ready prior to this call being made, then
+ * {@link Listener#onInitialized()} will be called from within this method call.
+ *
+ * @param listener The listener to report events to.
+ *
+ * @see ActivityView.StateCallback
+ * @see #startActivity(Intent)
+ */
+ void setListener(TaskEmbedder.Listener listener) {
+ mListener = listener;
+ if (mListener != null && isInitialized()) {
+ mListener.onInitialized();
+ }
+ }
+
+ /**
+ * Launch a new activity into this container.
+ *
+ * @param intent Intent used to launch an activity
+ *
+ * @see #startActivity(PendingIntent)
+ */
+ public void startActivity(@NonNull Intent intent) {
+ final ActivityOptions options = prepareActivityOptions();
+ mContext.startActivity(intent, options.toBundle());
+ }
+
+ /**
+ * Launch a new activity into this container.
+ *
+ * @param intent Intent used to launch an activity
+ * @param user The UserHandle of the user to start this activity for
+ *
+ * @see #startActivity(PendingIntent)
+ */
+ public void startActivity(@NonNull Intent intent, UserHandle user) {
+ final ActivityOptions options = prepareActivityOptions();
+ mContext.startActivityAsUser(intent, options.toBundle(), user);
+ }
+
+ /**
+ * Launch a new activity into this container.
+ *
+ * @param pendingIntent Intent used to launch an activity
+ *
+ * @see #startActivity(Intent)
+ */
+ public void startActivity(@NonNull PendingIntent pendingIntent) {
+ final ActivityOptions options = prepareActivityOptions();
+ try {
+ pendingIntent.send(null /* context */, 0 /* code */, null /* intent */,
+ null /* onFinished */, null /* handler */, null /* requiredPermission */,
+ options.toBundle());
+ } catch (PendingIntent.CanceledException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Launch a new activity into this container.
+ *
+ * @param pendingIntent Intent used to launch an activity
+ * @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()}
+ * @param options options for the activity
+ *
+ * @see #startActivity(Intent)
+ */
+ public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
+ @NonNull ActivityOptions options) {
+
+ options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
+ try {
+ pendingIntent.send(mContext, 0 /* code */, fillInIntent,
+ null /* onFinished */, null /* handler */, null /* requiredPermission */,
+ options.toBundle());
+ } catch (PendingIntent.CanceledException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Check if container is ready to launch and create {@link ActivityOptions} to target the
+ * virtual display.
+ */
+ private ActivityOptions prepareActivityOptions() {
+ if (mVirtualDisplay == null) {
+ throw new IllegalStateException(
+ "Trying to start activity before ActivityView is ready.");
+ }
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchDisplayId(getDisplayId());
+ return options;
+ }
+
+ /**
+ * Stops presentation of tasks in this container.
+ */
+ public void stop() {
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.setDisplayState(false);
+ clearActivityViewGeometryForIme();
+ clearTapExcludeRegion();
+ }
+ }
+
+ /**
+ * Starts presentation of tasks in this container.
+ */
+ public void start() {
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.setDisplayState(true);
+ updateLocationAndTapExcludeRegion();
+ }
+ }
+
+ /**
+ * This should be called whenever the position or size of the surface changes
+ * or if touchable areas above the surface are added or removed.
+ */
+ public void notifyBoundsChanged() {
+ updateLocationAndTapExcludeRegion();
+ }
+
+ /**
+ * Updates position and bounds information needed by WM and IME to manage window
+ * focus and touch events properly.
+ * <p>
+ * This should be called whenever the position or size of the surface changes
+ * or if touchable areas above the surface are added or removed.
+ */
+ private void updateLocationAndTapExcludeRegion() {
+ if (mVirtualDisplay == null || mHost.getWindow() == null) {
+ return;
+ }
+ reportLocation(mHost.getScreenToTaskMatrix(), mHost.getPositionInWindow());
+ applyTapExcludeRegion(mHost.getWindow(), hashCode(), mHost.getTapExcludeRegion());
+ }
+
+ /**
+ * Call to update the position and transform matrix for the embedded surface.
+ * <p>
+ * This should not normally be called directly, but through
+ * {@link #updateLocationAndTapExcludeRegion()}. This method
+ * is provided as an optimization when managing multiple TaskSurfaces within a view.
+ *
+ * @param screenToViewMatrix the matrix/transform from screen space to view space
+ * @param positionInWindow the window-relative position of the surface
+ *
+ * @see InputMethodManager#reportActivityView(int, Matrix)
+ */
+ private void reportLocation(Matrix screenToViewMatrix, Point positionInWindow) {
+ try {
+ final int displayId = getDisplayId();
+ mContext.getSystemService(InputMethodManager.class)
+ .reportActivityView(displayId, screenToViewMatrix);
+ IWindowSession session = WindowManagerGlobal.getWindowSession();
+ session.updateDisplayContentLocation(mHost.getWindow(), positionInWindow.x,
+ positionInWindow.y, displayId);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Call to update the tap exclude region for the window.
+ * <p>
+ * This should not normally be called directly, but through
+ * {@link #updateLocationAndTapExcludeRegion()}. This method
+ * is provided as an optimization when managing multiple TaskSurfaces within a view.
+ *
+ * @see IWindowSession#updateTapExcludeRegion(IWindow, int, Region)
+ */
+ private void applyTapExcludeRegion(IWindow window, int regionId,
+ @Nullable Region tapExcludeRegion) {
+ try {
+ IWindowSession session = WindowManagerGlobal.getWindowSession();
+ session.updateTapExcludeRegion(window, regionId, tapExcludeRegion);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * @see InputMethodManager#reportActivityView(int, Matrix)
+ */
+ private void clearActivityViewGeometryForIme() {
+ final int displayId = getDisplayId();
+ mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null);
+ }
+
+ /**
+ * Removes the tap exclude region set by {@link #updateLocationAndTapExcludeRegion()}.
+ */
+ private void clearTapExcludeRegion() {
+ if (mHost.getWindow() == null) {
+ Log.w(TAG, "clearTapExcludeRegion: not attached to window!");
+ return;
+ }
+ applyTapExcludeRegion(mHost.getWindow(), hashCode(), null);
+ }
+
+ /**
+ * Called to update the dimensions whenever the host size changes.
+ *
+ * @param width the new width of the surface
+ * @param height the new height of the surface
+ */
+ public void resizeTask(int width, int height) {
+ mDisplayDensityDpi = getBaseDisplayDensity();
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.resize(width, height, mDisplayDensityDpi);
+ }
+ }
+
+ /**
+ * Injects a pair of down/up key events with keycode {@link KeyEvent#KEYCODE_BACK} to the
+ * virtual display.
+ */
+ public void performBackPress() {
+ if (mVirtualDisplay == null) {
+ return;
+ }
+ final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
+ final InputManager im = InputManager.getInstance();
+ im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, displayId),
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, displayId),
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+
+ private static KeyEvent createKeyEvent(int action, int code, int displayId) {
+ long when = SystemClock.uptimeMillis();
+ final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
+ 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+ InputDevice.SOURCE_KEYBOARD);
+ ev.setDisplayId(displayId);
+ return ev;
+ }
+
+ /**
+ * Releases the resources for this TaskEmbedder. Tasks will no longer be launchable
+ * within this container.
+ *
+ * <p>Note: Calling this method is allowed after {@link Listener#onInitialized()} callback is
+ * triggered and before {@link Listener#onReleased()}.
+ */
+ public void release() {
+ if (mVirtualDisplay == null) {
+ throw new IllegalStateException(
+ "Trying to release container that is not initialized.");
+ }
+ performRelease();
+ }
+
+ private boolean performRelease() {
+ if (!mOpened) {
+ return false;
+ }
+ mTransaction.reparent(mSurfaceControl, null).apply();
+ mSurfaceControl.release();
+
+ // Clear activity view geometry for IME on this display
+ clearActivityViewGeometryForIme();
+
+ // Clear tap-exclude region (if any) for this window.
+ clearTapExcludeRegion();
+
+ if (mTaskStackListener != null) {
+ try {
+ mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to unregister task stack listener", e);
+ }
+ mTaskStackListener = null;
+ }
+
+ boolean reportReleased = false;
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.release();
+ mVirtualDisplay = null;
+ reportReleased = true;
+
+ }
+
+ if (mListener != null && reportReleased) {
+ mListener.onReleased();
+ }
+ mOpened = false;
+ mGuard.close();
+ return true;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mGuard != null) {
+ mGuard.warnIfOpen();
+ performRelease();
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /** Get density of the hosting display. */
+ private int getBaseDisplayDensity() {
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(metrics);
+ return metrics.densityDpi;
+ }
+
+ /**
+ * A task change listener that detects background color change of the topmost stack on our
+ * virtual display and updates the background of the surface view. This background will be shown
+ * when surface view is resized, but the app hasn't drawn its content in new size yet.
+ * It also calls StateCallback.onTaskMovedToFront to notify interested parties that the stack
+ * associated with the {@link ActivityView} has had a Task moved to the front. This is useful
+ * when needing to also bring the host Activity to the foreground at the same time.
+ */
+ private class TaskStackListenerImpl extends TaskStackListener {
+
+ @Override
+ public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
+ throws RemoteException {
+ if (!isInitialized()
+ || taskInfo.displayId != getDisplayId()) {
+ return;
+ }
+
+ ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
+ if (stackInfo == null) {
+ return;
+ }
+ // Found the topmost stack on target display. Now check if the topmost task's
+ // description changed.
+ if (taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+ mHost.onTaskBackgroundColorChanged(TaskEmbedder.this,
+ taskInfo.taskDescription.getBackgroundColor());
+ }
+ }
+
+ @Override
+ public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
+ throws RemoteException {
+ if (!isInitialized() || mListener == null
+ || taskInfo.displayId != getDisplayId()) {
+ return;
+ }
+
+ ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
+ // if StackInfo was null or unrelated to the "move to front" then there's no use
+ // notifying the callback
+ if (stackInfo != null
+ && taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+ mListener.onTaskMovedToFront(taskInfo.taskId);
+ }
+ }
+
+ @Override
+ public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
+ if (mListener == null || !isInitialized()) {
+ return;
+ }
+
+ ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
+ // if StackInfo was null or unrelated to the task creation then there's no use
+ // notifying the callback
+ if (stackInfo != null
+ && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+ mListener.onTaskCreated(taskId, componentName);
+ }
+ }
+
+ @Override
+ public void onTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)
+ throws RemoteException {
+ if (mListener == null || !isInitialized()
+ || taskInfo.displayId != getDisplayId()) {
+ return;
+ }
+ mListener.onTaskRemovalStarted(taskInfo.taskId);
+ }
+
+ private ActivityManager.StackInfo getTopMostStackInfo() throws RemoteException {
+ // Find the topmost task on our virtual display - it will define the background
+ // color of the surface view during resizing.
+ final int displayId = getDisplayId();
+ final List<ActivityManager.StackInfo> stackInfoList =
+ mActivityTaskManager.getAllStackInfos();
+
+ // Iterate through stacks from top to bottom.
+ final int stackCount = stackInfoList.size();
+ for (int i = 0; i < stackCount; i++) {
+ final ActivityManager.StackInfo stackInfo = stackInfoList.get(i);
+ // Only look for stacks on our virtual display.
+ if (stackInfo.displayId != displayId) {
+ continue;
+ }
+ // Found the topmost stack on target display.
+ return stackInfo;
+ }
+ return null;
+ }
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index e7ba85a..566b387 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1189,13 +1189,11 @@
/**
* Factory reset bluetooth settings.
*
- * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
- * permission
- *
* @return true to indicate that the config file was successfully cleared
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean factoryReset() {
try {
mServiceLock.readLock().lock();
@@ -1214,13 +1212,12 @@
/**
* Get the UUIDs supported by the local Bluetooth adapter.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
- *
* @return the UUIDs supported by the local Bluetooth Adapter.
* @hide
*/
@UnsupportedAppUsage
- public ParcelUuid[] getUuids() {
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public @NonNull ParcelUuid[] getUuids() {
if (getState() != STATE_ON) {
return null;
}
@@ -1476,7 +1473,6 @@
* will return false. After turning on Bluetooth,
* wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
* to get the updated value.
- * <p>Requires {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
* <p>Applications cannot set the scan mode. They should use
* <code>startActivityForResult(
* BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
@@ -1488,8 +1484,8 @@
* @return true if the scan mode was set, false otherwise
* @hide
*/
- @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which "
- + "shows UI that confirms the user wants to go into discoverable mode.")
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public boolean setScanMode(@ScanMode int mode, int duration) {
if (getState() != STATE_ON) {
return false;
@@ -1507,9 +1503,34 @@
return false;
}
- /** @hide */
- @UnsupportedAppUsage
- public boolean setScanMode(int mode) {
+ /**
+ * Set the Bluetooth scan mode of the local Bluetooth adapter.
+ * <p>The Bluetooth scan mode determines if the local adapter is
+ * connectable and/or discoverable from remote Bluetooth devices.
+ * <p>For privacy reasons, discoverable mode is automatically turned off
+ * after <code>duration</code> seconds. For example, 120 seconds should be
+ * enough for a remote device to initiate and complete its discovery
+ * process.
+ * <p>Valid scan mode values are:
+ * {@link #SCAN_MODE_NONE},
+ * {@link #SCAN_MODE_CONNECTABLE},
+ * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
+ * <p>If Bluetooth state is not {@link #STATE_ON}, this API
+ * will return false. After turning on Bluetooth,
+ * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
+ * to get the updated value.
+ * <p>Applications cannot set the scan mode. They should use
+ * <code>startActivityForResult(
+ * BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
+ * </code>instead.
+ *
+ * @param mode valid scan mode
+ * @return true if the scan mode was set, false otherwise
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public boolean setScanMode(@ScanMode int mode) {
if (getState() != STATE_ON) {
return false;
}
@@ -1562,6 +1583,8 @@
* been called recently.
* @hide
*/
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public long getDiscoveryEndMillis() {
try {
mServiceLock.readLock().lock();
@@ -2060,7 +2083,7 @@
* BluetoothProfile}.
* @hide
*/
- public List<Integer> getSupportedProfiles() {
+ public @NonNull List<Integer> getSupportedProfiles() {
final ArrayList<Integer> supportedProfiles = new ArrayList<Integer>();
try {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 9cb73f9..28cc1f8 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -21,7 +21,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.app.Activity;
import android.app.Application;
import android.app.PendingIntent;
@@ -29,9 +32,11 @@
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
+import android.net.MacAddress;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.util.Log;
@@ -252,6 +257,38 @@
}
}
+ /**
+ * Check if a given package was {@link #associate associated} with a device with given
+ * mac address by given user.
+ *
+ * @param packageName the package to check for
+ * @param macAddress the mac address or BSSID of the device to check for
+ * @param user the user to check for
+ * @return whether a corresponding association record exists
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
+ public boolean isDeviceAssociated(
+ @NonNull String packageName,
+ @NonNull MacAddress macAddress,
+ @NonNull UserHandle user) {
+ if (!checkFeaturePresent()) {
+ return false;
+ }
+ checkNotNull(packageName, "package name cannot be null");
+ checkNotNull(macAddress, "mac address cannot be null");
+ checkNotNull(user, "user cannot be null");
+ try {
+ return mService.isDeviceAssociated(
+ packageName, macAddress.toString(), user.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private boolean checkFeaturePresent() {
boolean featurePresent = mService != null;
if (!featurePresent && DEBUG) {
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 561342e..2e1ff0b 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -39,4 +39,6 @@
boolean hasNotificationAccess(in ComponentName component);
PendingIntent requestNotificationAccess(in ComponentName component);
+
+ boolean isDeviceAssociated(in String packageName, in String macAddress, int userId);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 862ec50..0b0fe79 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4762,6 +4762,13 @@
/**
* Use with {@link #getSystemService(String)} to retrieve an
+ * {@link android.telephony.ims.ImsManager}.
+ * @hide
+ */
+ public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve an
* {@link android.telephony.ims.RcsMessageManager}.
* @hide
*/
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6174018..714e9fb 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -929,6 +929,12 @@
return mBase.getUserId();
}
+ /** @hide */
+ @Override
+ public UserHandle getUser() {
+ return mBase.getUser();
+ }
+
@Override
public Context createConfigurationContext(Configuration overrideConfiguration) {
return mBase.createConfigurationContext(overrideConfiguration);
diff --git a/core/java/android/content/SyncStats.java b/core/java/android/content/SyncStats.java
index 03b2250e..9596a60 100644
--- a/core/java/android/content/SyncStats.java
+++ b/core/java/android/content/SyncStats.java
@@ -58,7 +58,7 @@
* attempted to update or delete a version of a resource on the server. This is expected
* to clear itself automatically once the new state is retrieved from the server,
* though it may remain until the user intervenes manually, perhaps by clearing the
- * local storage and starting over frmo scratch. This is considered a hard error.
+ * local storage and starting over from scratch. This is considered a hard error.
*/
public long numConflictDetectedExceptions;
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 1d78e2c..af0b357 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -692,6 +692,8 @@
String getIncidentReportApproverPackageName();
+ String getContentCaptureServicePackageName();
+
boolean isPackageStateProtected(String packageName, int userId);
void sendDeviceCustomizationReadyBroadcast();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7509065..51b9e24 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7458,6 +7458,18 @@
}
/**
+ * @return the system defined content capture package name, or null if there's none.
+ *
+ * @hide
+ */
+ @TestApi
+ @Nullable
+ public String getContentCaptureServicePackageName() {
+ throw new UnsupportedOperationException(
+ "getContentCaptureServicePackageName not implemented in subclass");
+ }
+
+ /**
* @return the incident report approver app package name, or null if it's not defined
* by the OEM.
*
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index b79cf65..38df3175 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -360,8 +360,9 @@
/**
* Retrieve the boolean value for the attribute at <var>index</var>.
* <p>
- * If the attribute is an integer value, this method will return whether
- * it is equal to zero. If the attribute is not a boolean or integer value,
+ * If the attribute is an integer value, this method returns false if the
+ * attribute is equal to zero, and true otherwise.
+ * If the attribute is not a boolean or integer value,
* this method will attempt to coerce it to an integer using
* {@link Integer#decode(String)} and return whether it is equal to zero.
*
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 43ea589..ff4bf2d 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
@@ -418,7 +419,16 @@
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
- queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0);
+ final NetworkScore ns = new NetworkScore();
+ ns.putIntExtension(NetworkScore.LEGACY_SCORE, score);
+ updateScore(ns);
+ }
+
+ /**
+ * Called by the bearer code when it has a new NetworkScore for this network.
+ */
+ public void updateScore(@NonNull NetworkScore ns) {
+ queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns));
}
/**
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
new file mode 100644
index 0000000..1ab6335
--- /dev/null
+++ b/core/java/android/net/NetworkScore.java
@@ -0,0 +1,157 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Object representing the quality of a network as perceived by the user.
+ *
+ * A NetworkScore object represents the characteristics of a network that affects how good the
+ * network is considered for a particular use.
+ * @hide
+ */
+public final class NetworkScore implements Parcelable {
+
+ // The key of bundle which is used to get the legacy network score of NetworkAgentInfo.
+ // TODO: Remove this when the transition to NetworkScore is over.
+ public static final String LEGACY_SCORE = "LEGACY_SCORE";
+ @NonNull
+ private final Bundle mExtensions;
+
+ public NetworkScore() {
+ mExtensions = new Bundle();
+ }
+
+ public NetworkScore(@NonNull NetworkScore source) {
+ mExtensions = new Bundle(source.mExtensions);
+ }
+
+ /**
+ * Put the value of parcelable inside the bundle by key.
+ */
+ public void putExtension(@Nullable String key, @Nullable Parcelable value) {
+ mExtensions.putParcelable(key, value);
+ }
+
+ /**
+ * Put the value of int inside the bundle by key.
+ */
+ public void putIntExtension(@Nullable String key, int value) {
+ mExtensions.putInt(key, value);
+ }
+
+ /**
+ * Get the value of non primitive type by key.
+ */
+ public <T extends Parcelable> T getExtension(@Nullable String key) {
+ return mExtensions.getParcelable(key);
+ }
+
+ /**
+ * Get the value of int by key.
+ */
+ public int getIntExtension(@Nullable String key) {
+ return mExtensions.getInt(key);
+ }
+
+ /**
+ * Remove the entry by given key.
+ */
+ public void removeExtension(@Nullable String key) {
+ mExtensions.remove(key);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ synchronized (this) {
+ dest.writeBundle(mExtensions);
+ }
+ }
+
+ public static final @NonNull Creator<NetworkScore> CREATOR = new Creator<NetworkScore>() {
+ @Override
+ public NetworkScore createFromParcel(@NonNull Parcel in) {
+ return new NetworkScore(in);
+ }
+
+ @Override
+ public NetworkScore[] newArray(int size) {
+ return new NetworkScore[size];
+ }
+ };
+
+ private NetworkScore(@NonNull Parcel in) {
+ mExtensions = in.readBundle();
+ }
+
+ // TODO: Modify this method once new fields are added into this class.
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ if (!(obj instanceof NetworkScore)) {
+ return false;
+ }
+ final NetworkScore other = (NetworkScore) obj;
+ return bundlesEqual(mExtensions, other.mExtensions);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 29;
+ for (String key : mExtensions.keySet()) {
+ final Object value = mExtensions.get(key);
+ // The key may be null, so call Objects.hash() is safer.
+ result += 31 * value.hashCode() + 37 * Objects.hash(key);
+ }
+ return result;
+ }
+
+ // mExtensions won't be null since the constructor will create it.
+ private boolean bundlesEqual(@NonNull Bundle bundle1, @NonNull Bundle bundle2) {
+ if (bundle1 == bundle2) {
+ return true;
+ }
+
+ // This is unlikely but it's fine to add this clause here.
+ if (null == bundle1 || null == bundle2) {
+ return false;
+ }
+
+ if (bundle1.size() != bundle2.size()) {
+ return false;
+ }
+
+ for (String key : bundle1.keySet()) {
+ final Object value1 = bundle1.get(key);
+ final Object value2 = bundle2.get(key);
+ if (!Objects.equals(value1, value2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 535bf67..64f20b8 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -49,8 +49,8 @@
* limited to a local network over Multicast DNS. DNS service discovery is described at
* http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
*
- * <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks on a seperate internal thread.
+ * <p> The API is asynchronous, and responses to requests from an application are on listener
+ * callbacks on a separate internal thread.
*
* <p> There are three main operations the API supports - registration, discovery and resolution.
* <pre>
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index d259f38..b37e176 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -38,9 +38,11 @@
import java.util.concurrent.atomic.AtomicInteger;
/**
- * <p>AsyncTask enables proper and easy use of the UI thread. This class allows you
- * to perform background operations and publish results on the UI thread without
- * having to manipulate threads and/or handlers.</p>
+ * <p>AsyncTask was intended to enable proper and easy use of the UI thread. However, the most
+ * common use case was for integrating into UI, and that would cause Context leaks, missed
+ * callbacks, or crashes on configuration changes. It also has inconsistent behavior on different
+ * versions of the platform, swallows exceptions from {@code doInBackground}, and does not provide
+ * much utility over using {@link Executor}s directly.</p>
*
* <p>AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler}
* and does not constitute a generic threading framework. AsyncTasks should ideally be
@@ -188,7 +190,12 @@
* <p>If you truly want parallel execution, you can invoke
* {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with
* {@link #THREAD_POOL_EXECUTOR}.</p>
+ *
+ * @deprecated Use the standard <code>java.util.concurrent</code> or
+ * <a href="https://developer.android.com/topic/libraries/architecture/coroutines">
+ * Kotlin concurrency utilities</a> instead.
*/
+@Deprecated
public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask";
@@ -240,7 +247,13 @@
/**
* An {@link Executor} that can be used to execute tasks in parallel.
+ *
+ * @deprecated Using a single thread pool for a general purpose results in suboptimal behavior
+ * for different tasks. Small, CPU-bound tasks benefit from a bounded pool and queueing, and
+ * long-running blocking tasks, such as network operations, benefit from many threads. Use or
+ * create an {@link Executor} configured for your use case.
*/
+ @Deprecated
public static final Executor THREAD_POOL_EXECUTOR;
static {
@@ -254,7 +267,10 @@
/**
* An {@link Executor} that executes tasks one at a time in serial
* order. This serialization is global to a particular process.
+ *
+ * @deprecated Globally serializing tasks results in excessive queuing for unrelated operations.
*/
+ @Deprecated
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static final int MESSAGE_POST_RESULT = 0x1;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 3476b18..b096049 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2486,6 +2486,8 @@
/**
* Return the number of users currently created on the device.
+ * <p>This API is not for use by third-party apps. It requires the {@code MANAGE_USERS}
+ * permission.</p>
*/
public int getUserCount() {
List<UserInfo> users = getUsers();
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 1643a21..c91d42b 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -35,10 +35,10 @@
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.DataUsageFeedback;
+import android.telecom.CallerInfo;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
-import android.telephony.CallerInfo;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b90ce87..412b0ca 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -493,7 +493,7 @@
*
* <p>
* To initiate a layout, call {@link #requestLayout}. This method is typically
- * called by a view on itself when it believes that is can no longer fit within
+ * called by a view on itself when it believes that it can no longer fit within
* its current bounds.
* </p>
*
@@ -2836,7 +2836,7 @@
/**
* Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL,
- * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction.
+ * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph's text direction.
*
* Use with {@link #setTextAlignment(int)}
*/
@@ -2864,7 +2864,7 @@
public static final int TEXT_ALIGNMENT_CENTER = 4;
/**
- * Align to the start of the view, which is ALIGN_LEFT if the view’s resolved
+ * Align to the start of the view, which is ALIGN_LEFT if the view's resolved
* layoutDirection is LTR, and ALIGN_RIGHT otherwise.
*
* Use with {@link #setTextAlignment(int)}
@@ -2872,7 +2872,7 @@
public static final int TEXT_ALIGNMENT_VIEW_START = 5;
/**
- * Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved
+ * Align to the end of the view, which is ALIGN_RIGHT if the view's resolved
* layoutDirection is LTR, and ALIGN_LEFT otherwise.
*
* Use with {@link #setTextAlignment(int)}
@@ -3675,7 +3675,7 @@
* if the user swipes from the top of the screen.
* <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
* system gestures, such as swiping from the top of the screen. These transient system bars
- * will overlay app’s content, may have some degree of transparency, and will automatically
+ * will overlay app's content, may have some degree of transparency, and will automatically
* hide after a short timeout.
* </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
@@ -10295,7 +10295,7 @@
}
/**
- * Gets the unique identifier of the window in which this View reseides.
+ * Gets the unique identifier of the window in which this View resides.
*
* @return The window accessibility id.
*
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 9e914d4..6a099d57 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Point;
import android.os.Build;
import android.os.RemoteException;
import android.provider.Settings;
@@ -398,11 +397,7 @@
mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
// Size of the screen in bytes, in ARGB_8888 format
- final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
- final Display display = win.getDefaultDisplay();
- final Point size = new Point();
- display.getRealSize(size);
- mMaximumDrawingCacheSize = 4 * size.x * size.y;
+ mMaximumDrawingCacheSize = 4 * metrics.heightPixels * metrics.widthPixels;
mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
@@ -842,6 +837,7 @@
* The maximum drawing cache size expressed in bytes.
*
* @return the maximum size of View's drawing cache expressed in bytes
+ *
*/
public int getScaledMaximumDrawingCacheSize() {
return mMaximumDrawingCacheSize;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl b/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl
index 59175ce..dbc9903 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl
@@ -17,3 +17,4 @@
package android.view.accessibility;
parcelable AccessibilityNodeInfo;
+parcelable AccessibilityNodeInfo.AccessibilityAction;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 06e9d0d..b33fdbb 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3570,8 +3570,7 @@
for (int i = 0; i < actionCount; i++) {
AccessibilityAction action = mActions.get(i);
if (!isDefaultStandardAction(action)) {
- parcel.writeInt(action.getId());
- parcel.writeCharSequence(action.getLabel());
+ action.writeToParcel(parcel, flags);
}
}
} else {
@@ -3777,8 +3776,8 @@
addStandardActions(standardActions);
final int nonStandardActionCount = parcel.readInt();
for (int i = 0; i < nonStandardActionCount; i++) {
- final AccessibilityAction action = new AccessibilityAction(
- parcel.readInt(), parcel.readCharSequence());
+ final AccessibilityAction action =
+ AccessibilityAction.CREATOR.createFromParcel(parcel);
addActionUnchecked(action);
}
}
@@ -4177,7 +4176,7 @@
* can discover the set of supported actions.
* </p>
*/
- public static final class AccessibilityAction {
+ public static final class AccessibilityAction implements Parcelable {
/** @hide */
public static final ArraySet<AccessibilityAction> sStandardActions = new ArraySet<>();
@@ -4654,6 +4653,38 @@
public String toString() {
return "AccessibilityAction: " + getActionSymbolicName(mActionId) + " - " + mLabel;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Write data into a parcel.
+ */
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mActionId);
+ out.writeCharSequence(mLabel);
+ }
+
+ public static final @NonNull Parcelable.Creator<AccessibilityAction> CREATOR =
+ new Parcelable.Creator<AccessibilityAction>() {
+ public AccessibilityAction createFromParcel(Parcel in) {
+ return new AccessibilityAction(in);
+ }
+
+ public AccessibilityAction[] newArray(int size) {
+ return new AccessibilityAction[size];
+ }
+ };
+
+ private AccessibilityAction(Parcel in) {
+ mActionId = in.readInt();
+ mLabel = in.readCharSequence();
+ }
}
/**
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index c877b9c..f5b0746 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -127,7 +127,7 @@
*
* @param context Application context used to access resources
* @param id The resource id of the animation to load
- * @return The animation object reference by the specified id
+ * @return The animation object referenced by the specified id
* @throws NotFoundException when the animation cannot be loaded
*/
public static Animation loadAnimation(Context context, @AnimRes int id)
@@ -208,7 +208,7 @@
*
* @param context Application context used to access resources
* @param id The resource id of the animation to load
- * @return The animation object reference by the specified id
+ * @return The animation controller object referenced by the specified id
* @throws NotFoundException when the layout animation controller cannot be loaded
*/
public static LayoutAnimationController loadLayoutAnimation(Context context, @AnimRes int id)
@@ -331,7 +331,7 @@
*
* @param context Application context used to access resources
* @param id The resource id of the animation to load
- * @return The animation object reference by the specified id
+ * @return The interpolator object referenced by the specified id
* @throws NotFoundException
*/
public static Interpolator loadInterpolator(Context context, @AnimRes @InterpolatorRes int id)
@@ -361,7 +361,7 @@
*
* @param res The resources
* @param id The resource id of the animation to load
- * @return The interpolator object reference by the specified id
+ * @return The interpolator object referenced by the specified id
* @throws NotFoundException
* @hide
*/
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 1cb1148..3a197e2 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -120,10 +120,6 @@
* <a href="{@docRoot}training/improving-layouts/smooth-scrolling.html">
* Making ListView Scrolling Smooth</a> for more ways to ensure a smooth user experience.</p>
*
- * <p>For a more complete example of creating a custom adapter, see the
- * <a href="{@docRoot}samples/CustomChoiceList/index.html">
- * Custom Choice List</a> sample app.</p>
- *
* <p>To specify an action when a user clicks or taps on a single list item, see
* <a href="{@docRoot}guide/topics/ui/declaring-layout.html#HandlingUserSelections">
* Handling click events</a>.</p>
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 6b324a5..167010b8 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -73,7 +73,7 @@
*
* <p>This behavior has been preserved for apps that set <code>android:targetSdkVersion="17"</code>
* or older in their manifest's <code>uses-sdk</code> tag for compatibility. Apps targeting SDK
- * version 18 or newer will receive the correct behavior</p>
+ * version 18 or newer will receive the correct behavior.</p>
*
* <p>See the <a href="{@docRoot}guide/topics/ui/layout/relative.html">Relative
* Layout</a> guide.</p>
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 3ab0b0d2..99bf93e 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -31,19 +31,19 @@
// be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h
// and not be reordered
int checkOperation(int code, int uid, String packageName);
- int noteOperation(int code, int uid, String packageName, String featureId);
- int startOperation(IBinder token, int code, int uid, String packageName, String featureId,
- boolean startIfModeDefault);
+ int noteOperation(int code, int uid, String packageName, @nullable String featureId);
+ int startOperation(IBinder token, int code, int uid, String packageName,
+ @nullable String featureId, boolean startIfModeDefault);
@UnsupportedAppUsage
void finishOperation(IBinder token, int code, int uid, String packageName,
- String featureId);
+ @nullable String featureId);
void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
void stopWatchingMode(IAppOpsCallback callback);
IBinder getToken(IBinder clientToken);
int permissionToOpCode(String permission);
int checkAudioOperation(int code, int usage, int uid, String packageName);
- void noteAsyncOp(String callingPackageName, int uid, String packageName, int opCode,
- String featureId, String message);
+ void noteAsyncOp(@nullable String callingPackageName, int uid, @nullable String packageName,
+ int opCode, @nullable String featureId, String message);
boolean shouldCollectNotes(int opCode);
void setCameraAudioRestriction(int mode);
// End of methods also called by native code.
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index a587936..0286aa6 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -634,8 +634,7 @@
subLabel = null;
}
- if (!TextUtils.equals(text2.getText(), subLabel)
- && !TextUtils.isEmpty(subLabel)) {
+ if (!TextUtils.equals(text2.getText(), subLabel)) {
text2.setVisibility(View.VISIBLE);
text2.setText(subLabel);
}
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 36a7a9c..58e80c7 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -47,6 +47,20 @@
*/
public static final String NAS_MAX_SUGGESTIONS = "nas_max_suggestions";
+ // Flags related to screenshot intelligence
+
+ /**
+ * (bool) Whether to enable smart actions in screenshot notifications.
+ */
+ public static final String ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS =
+ "enable_screenshot_notification_smart_actions";
+
+ /**
+ * (int) Timeout value in ms to get smart actions for screenshot notification.
+ */
+ public static final String SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS =
+ "screenshot_notification_smart_actions_timeout_ms";
+
// Flags related to controls
/**
diff --git a/core/java/com/android/internal/util/CollectionUtils.java b/core/java/com/android/internal/util/CollectionUtils.java
index f9cf23b..4165f20 100644
--- a/core/java/com/android/internal/util/CollectionUtils.java
+++ b/core/java/com/android/internal/util/CollectionUtils.java
@@ -231,6 +231,15 @@
}
/**
+ * Returns whether there exists at least one element in the set for which
+ * condition {@code predicate} is true
+ */
+ public static <T> boolean any(@Nullable Set<T> items,
+ java.util.function.Predicate<T> predicate) {
+ return find(items, predicate) != null;
+ }
+
+ /**
* Returns the first element from the list for which
* condition {@code predicate} is true, or null if there is no such element
*/
@@ -245,6 +254,37 @@
}
/**
+ * Returns the first element from the set for which
+ * condition {@code predicate} is true, or null if there is no such element
+ */
+ public static @Nullable <T> T find(@Nullable Set<T> cur,
+ java.util.function.Predicate<T> predicate) {
+ if (cur == null || predicate == null) return null;
+ int size = cur.size();
+ if (size == 0) return null;
+ try {
+ if (cur instanceof ArraySet) {
+ ArraySet<T> arraySet = (ArraySet<T>) cur;
+ for (int i = 0; i < size; i++) {
+ T item = arraySet.valueAt(i);
+ if (predicate.test(item)) {
+ return item;
+ }
+ }
+ } else {
+ for (T t : cur) {
+ if (predicate.test(t)) {
+ return t;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw ExceptionUtils.propagate(e);
+ }
+ return null;
+ }
+
+ /**
* Similar to {@link List#add}, but with support for list values of {@code null} and
* {@link Collections#emptyList}
*/
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index d9428c5..30edc37 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -246,6 +246,7 @@
"libmediametrics",
"libmeminfo",
"libaudioclient",
+ "libaudiofoundation",
"libaudiopolicy",
"libusbhost",
"libpdfium",
@@ -258,6 +259,7 @@
"libmemunreachable",
"libhidlbase",
"libvintf",
+ "libnativedisplay",
"libnativewindow",
"libdl",
"libdl_android",
@@ -437,6 +439,7 @@
],
shared_libs: [
"libandroidfw",
+ "libnativedisplay",
"libnativewindow",
"libgui",
"libpdfium",
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 686a919..6417b28 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -27,6 +27,7 @@
#include "core_jni_helpers.h"
#include <audiomanager/AudioManager.h>
+#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioSystem.h>
#include <media/AudioPolicy.h>
#include <media/MicrophoneInfo.h>
@@ -2015,9 +2016,10 @@
if (!env->IsInstanceOf(addrJobj, stringClass)) {
return (jint) AUDIO_JAVA_BAD_VALUE;
}
- String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL));
+ const char* address = env->GetStringUTFChars((jstring) addrJobj, NULL);
AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
deviceVector.add(dev);
+ env->ReleaseStringUTFChars((jstring) addrJobj, address);
}
env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 49c5cad..ee6e8c4 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -207,7 +207,7 @@
return;
}
- int res = SetTaskProfiles(tid, {get_sched_policy_name((SchedPolicy)grp)}, true) ? 0 : -1;
+ int res = SetTaskProfiles(tid, {get_sched_policy_profile_name((SchedPolicy)grp)}, true) ? 0 : -1;
if (res != NO_ERROR) {
signalExceptionForGroupError(env, -res, tid);
diff --git a/core/proto/android/server/appwindowthumbnail.proto b/core/proto/android/server/windowcontainerthumbnail.proto
similarity index 89%
rename from core/proto/android/server/appwindowthumbnail.proto
rename to core/proto/android/server/windowcontainerthumbnail.proto
index f22cdc5..9f8ea60 100644
--- a/core/proto/android/server/appwindowthumbnail.proto
+++ b/core/proto/android/server/windowcontainerthumbnail.proto
@@ -23,9 +23,9 @@
option java_multiple_files = true;
/**
- * Represents a {@link com.android.server.wm.AppWindowThumbnail} object.
+ * Represents a {@link com.android.server.wm.WindowContainerThumbnailProto} object.
*/
-message AppWindowThumbnailProto {
+message WindowContainerThumbnailProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional int32 width = 1;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 69e67d1..c9a1829 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -20,7 +20,7 @@
import "frameworks/base/core/proto/android/content/activityinfo.proto";
import "frameworks/base/core/proto/android/content/configuration.proto";
import "frameworks/base/core/proto/android/graphics/rect.proto";
-import "frameworks/base/core/proto/android/server/appwindowthumbnail.proto";
+import "frameworks/base/core/proto/android/server/windowcontainerthumbnail.proto";
import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
import "frameworks/base/core/proto/android/view/displaycutout.proto";
import "frameworks/base/core/proto/android/view/displayinfo.proto";
@@ -232,7 +232,7 @@
optional bool last_surface_showing = 3;
optional bool is_waiting_for_transition_start = 4;
optional bool is_animating = 5;
- optional AppWindowThumbnailProto thumbnail = 6;
+ optional WindowContainerThumbnailProto thumbnail = 6;
optional bool fills_parent = 7;
optional bool app_stopped = 8;
optional bool hidden_requested = 9;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 66e84dc..b357b3e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2280,7 +2280,7 @@
types of interactions
@hide -->
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
- android:protectionLevel="signature|installer|telephony" />
+ android:protectionLevel="signature|installer|telephony|wifi" />
<!-- @SystemApi Allows an application to start its own activities, but on a different profile
associated with the user. For example, an application running on the main profile of a user
@@ -3553,7 +3553,7 @@
<!-- Allows an application to manage the companion devices.
@hide -->
<permission android:name="android.permission.MANAGE_COMPANION_DEVICES"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|wifi" />
<!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
<p>Not for use by third-party applications.
diff --git a/core/res/res/drawable/ic_wifi_settings.xml b/core/res/res/drawable/ic_wifi_settings.xml
deleted file mode 100644
index c678ad4..0000000
--- a/core/res/res/drawable/ic_wifi_settings.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#000000"
- android:pathData="M12.584,15.93c0.026-0.194,0.044-0.397,0.044-0.608c0-0.211-0.018-0.405-0.044-0.608l1.304-1.022
-c0.115-0.088,0.15-0.256,0.071-0.397l-1.234-2.133c-0.071-0.132-0.238-0.185-0.379-0.132l-1.533,0.617
-c-0.317-0.247-0.67-0.449-1.04-0.608L9.535,9.4c-0.018-0.132-0.141-0.247-0.3-0.247H6.768c-0.15,0-0.282,0.115-0.3,0.256
-L6.23,11.048c-0.379,0.159-0.723,0.361-1.04,0.608l-1.533-0.617c-0.141-0.053-0.3,0-0.379,0.132l-1.234,2.133
-c-0.079,0.132-0.044,0.3,0.07,0.397l1.304,1.022c-0.026,0.194-0.044,0.405-0.044,0.608s0.018,0.405,0.044,0.608l-1.304,1.022
-c-0.115,0.088-0.15,0.256-0.07,0.397l1.234,2.133c0.07,0.132,0.238,0.185,0.379,0.132l1.533-0.617
-c0.317,0.247,0.67,0.449,1.04,0.608l0.238,1.639c0.018,0.15,0.15,0.256,0.3,0.256h2.467c0.159,0,0.282-0.115,0.3-0.256
-l0.238-1.639c0.379-0.15,0.723-0.361,1.04-0.608l1.533,0.617c0.141,0.053,0.3,0,0.379-0.132l1.234-2.133
-c0.071-0.132,0.044-0.3-0.07-0.397L12.584,15.93z
-M8.002,17.481c-1.19,0-2.159-0.969-2.159-2.159s0.969-2.159,2.159-2.159
-s2.159,0.969,2.159,2.159C10.161,16.512,9.191,17.481,8.002,17.481z" />
- <path
- android:fillColor="#000000"
- android:pathData="M16.003,12.026l5.995-7.474c-0.229-0.172-2.537-2.06-6-2.06s-5.771,1.889-6,2.06l5.995,7.469l0.005,0.01L16.003,12.026z" />
-</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/wifi_p2p_dialog.xml b/core/res/res/layout/wifi_p2p_dialog.xml
deleted file mode 100644
index 86dcbfa..0000000
--- a/core/res/res/layout/wifi_p2p_dialog.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <LinearLayout android:id="@+id/info"
- style="@style/wifi_section" />
-
- <LinearLayout android:id="@+id/enter_pin_section"
- style="@style/wifi_section"
- android:visibility="gone">
-
- <LinearLayout
- style="@style/wifi_item">
- <TextView
- android:text="@string/wifi_p2p_enter_pin_message"
- style="@style/wifi_item_label" />
-
- <EditText android:id="@+id/wifi_p2p_wps_pin"
- android:singleLine="true"
- android:maxLines="8"
- android:inputType="number"
- style="@style/wifi_item_content" />
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
-
-</ScrollView>
diff --git a/core/res/res/layout/wifi_p2p_dialog_row.xml b/core/res/res/layout/wifi_p2p_dialog_row.xml
deleted file mode 100644
index 2c88b10..0000000
--- a/core/res/res/layout/wifi_p2p_dialog_row.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/wifi_item">
- <TextView
- style="@style/wifi_item_label"
- android:id="@+id/name" />
-
- <TextView
- android:id="@+id/value"
- style="@style/wifi_item_content"
- android:textStyle="bold"
- android:textAlignment="viewStart" />
-</LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9ca98c5..b5e14d6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -570,209 +570,6 @@
<string-array translatable="false" name="config_cdma_dun_supported_types">
</string-array>
- <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
- <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
-
- <!-- Maximum number of concurrent WiFi interfaces in AP mode -->
- <integer translatable="false" name="config_wifi_max_ap_interfaces">1</integer>
-
- <!-- Boolean indicating whether the wifi chipset requires the softap band be -->
- <!-- converted from 5GHz to ANY due to hardware restrictions -->
- <bool translatable="false" name="config_wifi_convert_apband_5ghz_to_any">false</bool>
-
- <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
- <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
-
- <!-- Device type information conforming to Annex B format in WiFi Direct specification.
- The default represents a dual-mode smartphone -->
- <string translatable="false" name="config_wifi_p2p_device_type">10-0050F204-5</string>
-
- <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism.
- This mechanism allows the host to remain in suspend state and the dongle to actively
- scan and wake the host when a configured SSID is detected by the dongle. This chipset
- capability can provide power savings when wifi needs to be always kept on. -->
- <bool translatable="false" name="config_wifi_background_scan_support">false</bool>
-
- <!-- Boolean indicating we re-try re-associating once upon disconnection and RSSI is high failure -->
- <bool translatable="true" name="config_wifi_enable_disconnection_debounce">true</bool>
-
- <!-- Boolean indicating whether or not to revert to default country code when cellular
- radio is unable to find any MCC information to infer wifi country code from -->
- <bool translatable="false" name="config_wifi_revert_country_code_on_cellular_loss">false</bool>
-
- <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in default logging mode -->
- <integer translatable="false" name="config_wifi_logger_ring_buffer_default_size_limit_kb">32</integer>
-
- <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in verbose logging mode -->
- <integer translatable="false" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb">1024</integer>
-
- <!-- Array indicating wifi fatal firmware alert error code list from driver -->
- <integer-array translatable="false" name="config_wifi_fatal_firmware_alert_error_code_list">
- <!-- Example:
- <item>0</item>
- <item>1</item>
- <item>2</item>
- -->
- </integer-array>
-
- <!-- Boolean indicating whether or not wifi should turn off when emergency call is made -->
- <bool translatable="false" name="config_wifi_turn_off_during_emergency_call">false</bool>
-
- <!-- Integer specifying the basic autojoin parameters -->
- <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_threshold">-65</integer>
- <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_factor">40</integer>
- <integer translatable="false" name="config_wifi_framework_5GHz_preference_penalty_threshold">-75</integer>
- <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_OFFSET">85</integer>
- <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_SLOPE">4</integer>
- <integer translatable="false" name="config_wifi_framework_SAME_BSSID_AWARD">24</integer>
- <integer translatable="false" name="config_wifi_framework_LAST_SELECTION_AWARD">480</integer>
- <integer translatable="false" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD">40</integer>
- <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
- <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
- <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
- <!-- Integers specifying the max packet Tx/Rx rates for full scan -->
- <integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer>
- <integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer>
- <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network -->
- <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer>
- <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer>
- <!-- Integer parameters of the wifi to cellular handover feature
- wifi should not stick to bad networks -->
- <!-- Integer threshold for low network score, should be somewhat less than the entry threshhold -->
- <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-80</integer>
- <!-- Integer threshold, do not connect to APs with RSSI lower than the entry threshold -->
- <integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz">-77</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz">-70</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-57</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz">-83</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz">-80</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-73</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-60</integer>
-
- <!-- Integer delay in milliseconds before shutting down soft AP when there
- are no connected devices. Framework will enforce a minimum limit on
- this value and this setting will be overridden if the provided value is
- smaller than the limit. -->
- <integer translatable="false" name="config_wifi_framework_soft_ap_timeout_delay">600000</integer>
-
- <string translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string>
- <string translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string>
-
- <bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool>
-
- <!-- Integer packet threshold used to allow scan while associated -->
- <integer translatable="false" name="config_wifi_framework_associated_full_scan_tx_packet_threshold">5</integer>
- <integer translatable="false" name="config_wifi_framework_associated_full_scan_rx_packet_threshold">10</integer>
- <integer translatable="false" name="config_wifi_framework_associated_partial_scan_tx_packet_threshold">40</integer>
- <integer translatable="false" name="config_wifi_framework_associated_partial_scan_rx_packet_threshold">80</integer>
- <integer translatable="false" name="config_wifi_framework_network_switch_tx_packet_threshold">2</integer>
- <integer translatable="false" name="config_wifi_framework_network_switch_rx_packet_threshold">20</integer>
-
- <!-- Integer indicating wpa_supplicant scan interval in milliseconds -->
- <integer translatable="false" name="config_wifi_supplicant_scan_interval">15000</integer>
-
- <!-- Integer indicating amount of time failed networks areblacklisted for the purpose
- of network switching in milliseconds -->
- <integer translatable="false" name="config_wifi_network_switching_blacklist_time">172800000</integer>
-
- <!-- Integer indicating wpa_supplicant scan interval when p2p is connected in milliseconds -->
- <integer translatable="false" name="config_wifi_scan_interval_p2p_connected">60000</integer>
-
- <!-- Integer indicating disconnect mode short scan interval in milliseconds -->
- <integer translatable="false" name="config_wifi_disconnected_short_scan_interval">15000</integer>
-
- <!-- Integer indicating associated partial scan short interval in milliseconds -->
- <integer translatable="false" name="config_wifi_associated_short_scan_interval">20000</integer>
-
- <!-- Integer indicating associated full scan backoff, representing a fraction: xx/8 -->
- <integer translatable="false" name="config_wifi_framework_associated_full_scan_backoff">12</integer>
-
- <!-- Integer indicating associated full scan max interval in milliseconds -->
- <integer translatable="false" name="config_wifi_framework_associated_full_scan_max_interval">300000</integer>
-
- <!-- Integer indicating associated full scan max total dwell time in milliseconds -->
- <integer translatable="false" name="config_wifi_framework_associated_full_scan_max_total_dwell_time">500</integer>
-
- <!-- Integer indicating associated full scan max num active channels -->
- <integer translatable="false" name="config_wifi_framework_associated_partial_scan_max_num_active_channels">6</integer>
-
- <!-- Integer indicating RSSI boost given to current network -->
- <integer translatable="false" name="config_wifi_framework_current_network_boost">16</integer>
-
- <!-- Integer delay in milliseconds before set wlan interface up during watchdog recovery -->
- <integer translatable="false" name="config_wifi_framework_recovery_timeout_delay">2000</integer>
-
- <!-- Integer indicating how to handle beacons with uninitialized RSSI value of 0 -->
- <integer translatable="false" name="config_wifi_framework_scan_result_rssi_level_patchup_value">-85</integer>
-
- <!-- Boolean indicating associated network selection is allowed -->
- <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
-
- <!-- Boolean indicating whether single radio chain scan results are to be used for network selection -->
- <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">true</bool>
-
- <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
- <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
-
- <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements -->
- <bool translatable="false" name="config_wifi_framework_enable_sar_tx_power_limit">false</bool>
-
- <!-- Boolean indicating whether framework should use detection of softAP mode to set the tx
- power limit for meeting SAR requirements -->
- <bool translatable="false" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit">false</bool>
-
- <!-- Boolean indicating whether framework needs to use body proximity to set the tx power limit
- for meeting SAR requirements -->
- <bool translatable="false" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit">false</bool>
-
- <!-- String for the sensor type for body/head proximity for SAR -->
- <string translatable="false" name="config_wifi_sar_sensor_type"></string>
-
- <!-- Integer indicating event id by sar sensor for free space -->
- <integer translatable="false" name="config_wifi_framework_sar_free_space_event_id">1</integer>
-
- <!-- Integer indicating event id by sar sensor for near hand -->
- <integer translatable="false" name="config_wifi_framework_sar_near_hand_event_id">2</integer>
-
- <!-- Integer indicating event id by sar sensor for near head -->
- <integer translatable="false" name="config_wifi_framework_sar_near_head_event_id">3</integer>
-
- <!-- Integer indicating event id by sar sensor for near body -->
- <integer translatable="false" name="config_wifi_framework_sar_near_body_event_id">4</integer>
-
- <!-- Wifi driver supports batched scan -->
- <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
-
- <!-- Wifi driver supports Automatic channel selection (ACS) for softap -->
- <bool translatable="false" name="config_wifi_softap_acs_supported">false</bool>
-
- <!-- Channel list restriction to Automatic channel selection (ACS) for softap. If the device
- doesn't want to restrict channels this should be empty. Value is a comma separated channel
- string and/or channel range string like '1-6,11' -->
- <string translatable="false" name="config_wifi_softap_acs_supported_channel_list"></string>
-
- <!-- Wifi driver supports IEEE80211AC for softap -->
- <bool translatable="false" name="config_wifi_softap_ieee80211ac_supported">false</bool>
-
- <!-- Indicates that local-only hotspot should be brought up at 5GHz. This option is
- for automotive builds only (the one that have PackageManager#FEATURE_AUTOMOTIVE) -->
- <bool translatable="false" name="config_wifi_local_only_hotspot_5ghz">false</bool>
-
- <!-- Indicates that connected MAC randomization is supported on this device -->
- <bool translatable="false" name="config_wifi_connected_mac_randomization_supported">false</bool>
-
- <!-- Indicates that p2p MAC randomization is supported on this device -->
- <bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">false</bool>
-
- <!-- Indicates that AP mode MAC randomization is supported on this device -->
- <bool translatable="false" name="config_wifi_ap_mac_randomization_supported">true</bool>
-
- <!-- flag for activating paranoid MAC randomization on a limited set of SSIDs -->
- <bool translatable="false" name="config_wifi_aggressive_randomization_ssid_whitelist_enabled">false</bool>
-
- <!-- Indicates that wifi link probing is supported on this device -->
- <bool translatable="false" name="config_wifi_link_probing_supported">false</bool>
-
<!-- Flag indicating whether we should enable the automatic brightness.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
@@ -2613,10 +2410,6 @@
rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
<string name="config_ethernet_tcp_buffers" translatable="false">524288,1048576,3145728,524288,1048576,2097152</string>
- <!-- Configure wifi tcp buffersizes in the form:
- rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
- <string name="config_wifi_tcp_buffers" translatable="false">524288,1048576,2097152,262144,524288,1048576</string>
-
<!-- Whether WiFi display is supported by this device.
There are many prerequisites for this feature to work correctly.
Here are a few of them:
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9724c41..9b89eab 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3005,6 +3005,8 @@
</public-group>
<public-group type="drawable" first-id="0x010800b5">
+ <!-- @hide @SystemApi -->
+ <public name="stat_notify_wifi_in_range" />
</public-group>
<public-group type="style" first-id="0x010302e5">
@@ -3014,6 +3016,12 @@
</public-group>
<public-group type="string" first-id="0x01040025">
+ <!-- @hide @SystemApi -->
+ <public name="notification_channel_network_status" />
+ <!-- @hide @SystemApi -->
+ <public name="notification_channel_network_alerts" />
+ <!-- @hide @SystemApi -->
+ <public name="notification_channel_network_available" />
</public-group>
<public-group type="bool" first-id="0x01110005">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 585c4bb..5f2bbac 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3379,52 +3379,6 @@
<!-- If there is ever a ringtone set for some setting, but that ringtone can no longer be resolved, t his is shown instead. For example, if the ringtone was on a SD card and it had been removed, this woudl be shown for ringtones on that SD card. -->
<string name="ringtone_unknown">Unknown</string>
- <!-- A notification is shown when there are open wireless networks nearby. This is the notification's title. -->
- <plurals name="wifi_available">
- <item quantity="one">Wi-Fi network available</item>
- <item quantity="other">Wi-Fi networks available</item>
- </plurals>
- <!-- A notification is shown when there are open wireless networks nearby. This is the notification's message. -->
- <plurals name="wifi_available_detailed">
- <item quantity="one">Open Wi-Fi network available</item>
- <item quantity="other">Open Wi-Fi networks available</item>
- </plurals>
-
- <!-- Notification title for a nearby open wireless network.-->
- <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
- <!-- Notification title when the system is connecting to the specified network. The network name is specified in the notification content. -->
- <string name="wifi_available_title_connecting">Connecting to Wi\u2011Fi network</string>
- <!-- Notification title when the system has connected to the network. The network name is specified in the notification content. -->
- <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
- <!-- Notification title when the system failed to connect to the specified network. -->
- <string name="wifi_available_title_failed_to_connect">Could not connect to Wi\u2011Fi network</string>
- <!-- Notification content when the system failed to connect to the specified network. This informs the user that tapping on this notification will open the wifi picker. -->
- <string name="wifi_available_content_failed_to_connect">Tap to see all networks</string>
- <!-- Notification action name for connecting to the network specified in the notification body. -->
- <string name="wifi_available_action_connect">Connect</string>
- <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
- <string name="wifi_available_action_all_networks">All networks</string>
-
- <!-- Notification title for a connection to a app suggested wireless network.-->
- <string name="wifi_suggestion_title">Allow suggested Wi\u2011Fi networks?</string>
- <!-- Notification content for a connection to a app suggested wireless network.-->
- <string name="wifi_suggestion_content"><xliff:g id="name" example="App123">%s</xliff:g> suggested networks. Device may connect automatically. </string>
- <!-- Notification action for allowing app specified in the notification body.-->
- <string name="wifi_suggestion_action_allow_app">Allow</string>
- <!-- Notification action for disallowing app specified in the notification body.-->
- <string name="wifi_suggestion_action_disallow_app">No thanks</string>
-
- <!--Notification title for Wi-Fi Wake onboarding. This is displayed the first time a user disables Wi-Fi with the feature enabled. -->
- <string name="wifi_wakeup_onboarding_title">Wi\u2011Fi will turn on automatically</string>
- <!--Notification subtext for Wi-Fi Wake onboarding.-->
- <string name="wifi_wakeup_onboarding_subtext">When you\'re near a high quality saved network</string>
- <!--Notification action to disable Wi-Fi Wake during onboarding.-->
- <string name="wifi_wakeup_onboarding_action_disable">Don\'t turn back on</string>
- <!--Notification title for when Wi-Fi Wake enables Wi-Fi.-->
- <string name="wifi_wakeup_enabled_title">Wi\u2011Fi turned on automatically</string>
- <!--Notification content for when Wi-Fi Wake enables Wi-Fi. %1$s is the SSID of the nearby saved network that triggered the wakeup. -->
- <string name="wifi_wakeup_enabled_content">You\u0027re near a saved network: <xliff:g id="network_ssid">%1$s</xliff:g></string>
-
<!-- A notification is shown when a wifi captive portal network is detected. This is the notification's title. -->
<string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
@@ -3457,21 +3411,6 @@
<!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's message. [CHAR LIMIT=50] -->
<string name="network_partial_connectivity_detailed">Tap to connect anyway</string>
- <!-- A notification is shown when the user's softap config has been changed due to underlying
- hardware restrictions. This is the notifications's title.
- [CHAR_LIMIT=NONE] -->
- <string name="wifi_softap_config_change">Changes to your hotspot settings</string>
-
- <!-- A notification is shown when the user's softap config has been changed due to underlying
- hardware restrictions. This is the notification's summary message.
- [CHAR_LIMIT=NONE] -->
- <string name="wifi_softap_config_change_summary">Your hotspot band has changed.</string>
-
- <!-- A notification is shown when the user's softap config has been changed due to underlying
- hardware restrictions. This is the notification's full message.
- [CHAR_LIMIT=NONE] -->
- <string name="wifi_softap_config_change_detailed">This device doesn\u2019t support your preference for 5GHz only. Instead, this device will use the 5GHz band when available.</string>
-
<!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's title. %1$s is the network type that the device switched to, e.g., cellular data. It is one of the strings in the network_switch_type_name array. -->
<string name="network_switch_metered">Switched to <xliff:g id="network_type">%1$s</xliff:g></string>
@@ -3493,43 +3432,8 @@
<!-- Network type name displayed if one of the types is not found in network_switch_type_name. -->
<string name="network_switch_type_name_unknown">an unknown network type</string>
- <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems. This is the notification's title / ticker. -->
- <string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
- <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems. The complete alert msg is: <hotspot name> + this string, i.e. "Linksys has a poor internet connection" -->
- <string name="wifi_watchdog_network_disabled_detailed">\u0020has a poor internet connection.</string>
-
- <!-- Do not translate. Default access point SSID used for tethering -->
- <string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
- <!-- Do not translate. Default access point SSID used for local only hotspot -->
- <string name="wifi_localhotspot_configure_ssid_default" translatable="false">AndroidShare</string>
-
- <!-- A notification is shown the first time a connection is attempted on an app owned AP -->
- <!-- title for this message -->
- <string name="wifi_connect_alert_title">Allow connection?</string>
- <!-- message explaining who is connecting to what -->
- <string name="wifi_connect_alert_message">Application %1$s would like to connect to Wifi Network %2$s</string>
- <!-- default application in case name can not be found -->
- <string name="wifi_connect_default_application">An application</string>
-
- <string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
- <string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
- <string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
- <string name="wifi_p2p_enabled_notification_title">Wi-Fi Direct is on</string>
- <string name="wifi_p2p_enabled_notification_message">Tap for settings</string>
-
<string name="accept">Accept</string>
<string name="decline">Decline</string>
- <string name="wifi_p2p_invitation_sent_title">Invitation sent</string>
- <string name="wifi_p2p_invitation_to_connect_title">Invitation to connect</string>
-
- <string name="wifi_p2p_from_message">From: </string>
- <string name="wifi_p2p_to_message">To: </string>
- <string name="wifi_p2p_enter_pin_message">Type the required PIN: </string>
- <string name="wifi_p2p_show_pin_message">PIN: </string>
-
- <string name="wifi_p2p_frequency_conflict_message" product="tablet">The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv">Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
- <string name="wifi_p2p_frequency_conflict_message" product="default">The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
<!-- Name of the dialog that lets the user choose an accented character to insert -->
<string name="select_character">Insert character</string>
@@ -4869,10 +4773,10 @@
<string name="confirm_battery_saver">OK</string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
- <string name="battery_saver_description_with_learn_more">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. <annotation id="url">Learn More</annotation></string>
+ <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
- <string name="battery_saver_description">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life.</string>
+ <string name="battery_saver_description">To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</string>
<!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->
<string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 18f7e48..bcce1f0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1443,39 +1443,6 @@
<item name="drawableTintMode">src_atop</item>
</style>
- <!-- Wifi dialog styles -->
- <!-- @hide -->
- <style name="wifi_item">
- <item name="layout_width">200dip</item>
- <item name="layout_height">wrap_content</item>
- <item name="layout_marginTop">8dip</item>
- <item name="layout_marginStart">16dip</item>
- <item name="layout_marginEnd">16dip</item>
- <item name="orientation">vertical</item>
- <item name="gravity">start</item>
- </style>
-
- <!-- @hide -->
- <style name="wifi_item_label">
- <item name="layout_width">wrap_content</item>
- <item name="layout_height">wrap_content</item>
- <item name="textSize">14sp</item>
- </style>
-
- <!-- @hide -->
- <style name="wifi_item_content">
- <item name="layout_width">match_parent</item>
- <item name="layout_height">wrap_content</item>
- <item name="textSize">18sp</item>
- </style>
-
- <!-- @hide -->
- <style name="wifi_section">
- <item name="layout_width">match_parent</item>
- <item name="layout_height">wrap_content</item>
- <item name="orientation">vertical</item>
- </style>
-
<style name="Widget.FastScroll">
<item name="thumbDrawable">?attr/fastScrollThumbDrawable</item>
<item name="trackDrawable">?attr/fastScrollTrackDrawable</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1313912..8e10b00 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -82,7 +82,6 @@
<java-symbol type="id" name="divider" />
<java-symbol type="id" name="edit_query" />
<java-symbol type="id" name="edittext_container" />
- <java-symbol type="id" name="enter_pin_section" />
<java-symbol type="id" name="expand_activities_button" />
<java-symbol type="id" name="expires_on" />
<java-symbol type="id" name="find_next" />
@@ -100,7 +99,6 @@
<java-symbol type="id" name="image" />
<java-symbol type="id" name="increment" />
<java-symbol type="id" name="internalEmpty" />
- <java-symbol type="id" name="info" />
<java-symbol type="id" name="inputExtractAccessories" />
<java-symbol type="id" name="inputExtractAction" />
<java-symbol type="id" name="issued_on" />
@@ -117,7 +115,6 @@
<java-symbol type="id" name="mode_normal" />
<java-symbol type="id" name="month" />
<java-symbol type="id" name="month_name" />
- <java-symbol type="id" name="name" />
<java-symbol type="id" name="next" />
<java-symbol type="id" name="next_button" />
<java-symbol type="id" name="new_app_action" />
@@ -193,7 +190,6 @@
<java-symbol type="id" name="up" />
<java-symbol type="id" name="value" />
<java-symbol type="id" name="websearch" />
- <java-symbol type="id" name="wifi_p2p_wps_pin" />
<java-symbol type="id" name="year" />
<java-symbol type="id" name="zoomControls" />
<java-symbol type="id" name="zoomIn" />
@@ -356,10 +352,6 @@
<java-symbol type="bool" name="config_requireRadioPowerOffOnSimRefreshReset" />
<java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
<java-symbol type="bool" name="config_useFixedVolume" />
- <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
- <java-symbol type="bool" name="config_wifi_softap_acs_supported" />
- <java-symbol type="string" name="config_wifi_softap_acs_supported_channel_list" />
- <java-symbol type="bool" name="config_wifi_softap_ieee80211ac_supported" />
<java-symbol type="bool" name="config_enableMultiUserUI"/>
<java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
<java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
@@ -376,23 +368,6 @@
<java-symbol type="integer" name="config_activeTaskDurationHours" />
<java-symbol type="bool" name="config_windowShowCircularMask" />
<java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
- <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
- <java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" />
- <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
- <java-symbol type="bool" name="config_wifi_framework_enable_sar_tx_power_limit" />
- <java-symbol type="bool" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit" />
- <java-symbol type="bool" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit" />
- <java-symbol type="string" name="config_wifi_sar_sensor_type" />
- <java-symbol type="integer" name="config_wifi_framework_sar_free_space_event_id" />
- <java-symbol type="integer" name="config_wifi_framework_sar_near_hand_event_id" />
- <java-symbol type="integer" name="config_wifi_framework_sar_near_head_event_id" />
- <java-symbol type="integer" name="config_wifi_framework_sar_near_body_event_id" />
- <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
- <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
- <java-symbol type="integer" name="config_wifi_logger_ring_buffer_default_size_limit_kb" />
- <java-symbol type="integer" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb" />
- <java-symbol type="array" name="config_wifi_fatal_firmware_alert_error_code_list" />
- <java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
<java-symbol type="bool" name="config_supportMicNearUltrasound" />
<java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
<java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
@@ -416,51 +391,6 @@
<java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" />
<java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" />
<java-symbol type="dimen" name="config_closeToSquareDisplayMaxAspectRatio" />
- <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
- <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_OFFSET" />
- <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_SLOPE" />
- <java-symbol type="integer" name="config_wifi_framework_SAME_BSSID_AWARD" />
- <java-symbol type="integer" name="config_wifi_framework_LAST_SELECTION_AWARD" />
- <java-symbol type="integer" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD" />
- <java-symbol type="integer" name="config_wifi_framework_SECURITY_AWARD" />
- <java-symbol type="integer" name="config_wifi_disconnected_short_scan_interval" />
- <java-symbol type="integer" name="config_wifi_associated_short_scan_interval" />
- <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_backoff" />
- <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_max_interval" />
- <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_max_total_dwell_time" />
- <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_max_num_active_channels" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz" />
- <java-symbol type="integer" name="config_wifi_framework_scan_result_rssi_level_patchup_value" />
- <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
- <java-symbol type="string" name="config_wifi_random_mac_oui" />
- <java-symbol type="integer" name="config_wifi_network_switching_blacklist_time" />
- <java-symbol type="string" name="config_wifi_framework_sap_2G_channel_list" />
- <java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" />
- <java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" />
- <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" />
- <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" />
-
- <java-symbol type="integer" name="config_wifi_framework_soft_ap_timeout_delay" />
-
- <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
- <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_rx_packet_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_tx_packet_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_rx_packet_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_network_switch_tx_packet_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_network_switch_rx_packet_threshold" />
- <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
- <java-symbol type="integer" name="config_wifi_framework_recovery_timeout_delay" />
<java-symbol type="integer" name="config_bluetooth_max_advertisers" />
<java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
<java-symbol type="integer" name="config_bluetooth_max_connected_audio_devices" />
@@ -499,8 +429,6 @@
<java-symbol type="integer" name="config_toastDefaultGravity" />
<java-symbol type="integer" name="config_triplePressOnPowerBehavior" />
<java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
- <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
- <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
<java-symbol type="integer" name="config_windowOutsetBottom" />
<java-symbol type="integer" name="db_connection_pool_size" />
<java-symbol type="integer" name="db_journal_size_limit" />
@@ -757,7 +685,6 @@
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
<java-symbol type="string" name="config_ntpServer" />
<java-symbol type="string" name="config_useragentprofile_url" />
- <java-symbol type="string" name="config_wifi_p2p_device_type" />
<java-symbol type="string" name="config_appsNotReportingCrashes" />
<java-symbol type="string" name="contentServiceSync" />
<java-symbol type="string" name="contentServiceSyncNotificationTitle" />
@@ -1119,27 +1046,6 @@
<java-symbol type="string" name="network_switch_type_name_unknown" />
<java-symbol type="string" name="wifi_no_internet" />
<java-symbol type="string" name="wifi_no_internet_detailed" />
- <java-symbol type="string" name="wifi_softap_config_change" />
- <java-symbol type="string" name="wifi_softap_config_change_summary" />
- <java-symbol type="string" name="wifi_softap_config_change_detailed" />
- <java-symbol type="string" name="wifi_connect_alert_title" />
- <java-symbol type="string" name="wifi_connect_alert_message" />
- <java-symbol type="string" name="wifi_connect_default_application" />
- <java-symbol type="string" name="wifi_p2p_dialog_title" />
- <java-symbol type="string" name="wifi_p2p_enabled_notification_message" />
- <java-symbol type="string" name="wifi_p2p_enabled_notification_title" />
- <java-symbol type="string" name="wifi_p2p_failed_message" />
- <java-symbol type="string" name="wifi_p2p_from_message" />
- <java-symbol type="string" name="wifi_p2p_invitation_sent_title" />
- <java-symbol type="string" name="wifi_p2p_invitation_to_connect_title" />
- <java-symbol type="string" name="wifi_p2p_show_pin_message" />
- <java-symbol type="string" name="wifi_p2p_to_message" />
- <java-symbol type="string" name="wifi_p2p_turnon_message" />
- <java-symbol type="string" name="wifi_p2p_frequency_conflict_message" />
- <java-symbol type="string" name="wifi_tether_configure_ssid_default" />
- <java-symbol type="string" name="wifi_localhotspot_configure_ssid_default" />
- <java-symbol type="string" name="wifi_watchdog_network_disabled" />
- <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" />
<java-symbol type="string" name="imei" />
<java-symbol type="string" name="meid" />
<java-symbol type="string" name="granularity_label_character" />
@@ -1289,7 +1195,6 @@
<java-symbol type="string" name="lockscreen_transport_play_description" />
<java-symbol type="string" name="lockscreen_transport_pause_description" />
<java-symbol type="string" name="config_ethernet_tcp_buffers" />
- <java-symbol type="string" name="config_wifi_tcp_buffers" />
<java-symbol type="string" name="demo_starting_message" />
<java-symbol type="string" name="demo_restarting_message" />
<java-symbol type="string" name="conference_call" />
@@ -1417,8 +1322,6 @@
<java-symbol type="drawable" name="picture_emergency" />
<java-symbol type="drawable" name="platlogo" />
<java-symbol type="drawable" name="stat_notify_sync_error" />
- <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
- <java-symbol type="drawable" name="ic_wifi_settings" />
<java-symbol type="drawable" name="ic_wifi_signal_0" />
<java-symbol type="drawable" name="ic_wifi_signal_1" />
<java-symbol type="drawable" name="ic_wifi_signal_2" />
@@ -1611,8 +1514,6 @@
<java-symbol type="layout" name="web_text_view_dropdown" />
<java-symbol type="layout" name="webview_find" />
<java-symbol type="layout" name="webview_select_singlechoice" />
- <java-symbol type="layout" name="wifi_p2p_dialog" />
- <java-symbol type="layout" name="wifi_p2p_dialog_row" />
<java-symbol type="layout" name="zoom_container" />
<java-symbol type="layout" name="zoom_controls" />
<java-symbol type="layout" name="zoom_magnify" />
@@ -1968,17 +1869,6 @@
<java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
<java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
<java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
- <java-symbol type="bool" name="config_wifi_background_scan_support" />
- <java-symbol type="bool" name="config_wifi_dual_band_support" />
- <java-symbol type="integer" name="config_wifi_max_ap_interfaces" />
- <java-symbol type="bool" name="config_wifi_convert_apband_5ghz_to_any" />
- <java-symbol type="bool" name="config_wifi_local_only_hotspot_5ghz" />
- <java-symbol type="bool" name="config_wifi_connected_mac_randomization_supported" />
- <java-symbol type="bool" name="config_wifi_p2p_mac_randomization_supported" />
- <java-symbol type="bool" name="config_wifi_ap_mac_randomization_supported" />
- <java-symbol type="bool" name="config_wifi_aggressive_randomization_ssid_whitelist_enabled" />
- <java-symbol type="bool" name="config_wifi_link_probing_supported" />
- <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
<java-symbol type="bool" name="config_wimaxEnabled" />
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
@@ -2078,24 +1968,6 @@
<java-symbol type="layout" name="safe_mode" />
<java-symbol type="layout" name="simple_list_item_2_single_choice" />
<java-symbol type="layout" name="app_error_dialog" />
- <java-symbol type="plurals" name="wifi_available" />
- <java-symbol type="plurals" name="wifi_available_detailed" />
- <java-symbol type="string" name="wifi_available_title" />
- <java-symbol type="string" name="wifi_available_title_connecting" />
- <java-symbol type="string" name="wifi_available_title_connected" />
- <java-symbol type="string" name="wifi_available_title_failed_to_connect" />
- <java-symbol type="string" name="wifi_available_content_failed_to_connect" />
- <java-symbol type="string" name="wifi_available_action_connect" />
- <java-symbol type="string" name="wifi_available_action_all_networks" />
- <java-symbol type="string" name="wifi_suggestion_title" />
- <java-symbol type="string" name="wifi_suggestion_content" />
- <java-symbol type="string" name="wifi_suggestion_action_allow_app" />
- <java-symbol type="string" name="wifi_suggestion_action_disallow_app" />
- <java-symbol type="string" name="wifi_wakeup_onboarding_title" />
- <java-symbol type="string" name="wifi_wakeup_onboarding_subtext" />
- <java-symbol type="string" name="wifi_wakeup_onboarding_action_disable" />
- <java-symbol type="string" name="wifi_wakeup_enabled_title" />
- <java-symbol type="string" name="wifi_wakeup_enabled_content" />
<java-symbol type="string" name="accessibility_binding_label" />
<java-symbol type="string" name="adb_active_notification_message" />
<java-symbol type="string" name="adb_active_notification_title" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a0215e1..77b0dba 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -365,7 +365,7 @@
<permission name="android.permission.CHANGE_CONFIGURATION"/>
<permission name="android.permission.CONNECTIVITY_INTERNAL"/>
<permission name="android.permission.DUMP"/>
- <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<permission name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
<permission name="android.permission.LOCAL_MAC_ADDRESS"/>
<permission name="android.permission.MANAGE_USERS"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 1326952..5b9b703 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -301,12 +301,6 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
- "-1483752006": {
- "message": " THUMBNAIL %s: CREATE",
- "level": "INFO",
- "group": "WM_SHOW_TRANSACTIONS",
- "at": "com\/android\/server\/wm\/AppWindowThumbnail.java"
- },
"-1471946192": {
"message": "Marking app token %s with replacing child windows.",
"level": "DEBUG",
@@ -1297,6 +1291,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
+ "531242746": {
+ "message": " THUMBNAIL %s: CREATE",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowContainerThumbnail.java"
+ },
"539077569": {
"message": "Clear freezing of %s force=%b",
"level": "VERBOSE",
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index b7316ab..109d863 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1114,7 +1114,7 @@
* Return the width for stroking.
* <p />
* A value of 0 strokes in hairline mode.
- * Hairlines always draws a single pixel independent of the canva's matrix.
+ * Hairlines always draws a single pixel independent of the canvas's matrix.
*
* @return the paint's stroke width, used whenever the paint's style is
* Stroke or StrokeAndFill.
@@ -1126,7 +1126,7 @@
/**
* Set the width for stroking.
* Pass 0 to stroke in hairline mode.
- * Hairlines always draws a single pixel independent of the canva's matrix.
+ * Hairlines always draws a single pixel independent of the canvas's matrix.
*
* @param width set the paint's stroke width, used whenever the paint's
* style is Stroke or StrokeAndFill.
@@ -1958,8 +1958,8 @@
* <code>
* Paint paint = new Paint();
* paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN);
- * paint.measureText("abc", 0, 3); // Returns the width of "‐abc"
- * Canvas.drawText("abc", 0, 3, 0f, 0f, paint); // Draws "‐abc"
+ * paint.measureText("abc", 0, 3); // Returns the width of "-abc"
+ * Canvas.drawText("abc", 0, 3, 0f, 0f, paint); // Draws "-abc"
* </code>
* </pre>
*
@@ -1985,8 +1985,8 @@
* <code>
* Paint paint = new Paint();
* paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN);
- * paint.measureText("abc", 0, 3); // Returns the width of "abc‐"
- * Canvas.drawText("abc", 0, 3, 0f, 0f, paint); // Draws "abc‐"
+ * paint.measureText("abc", 0, 3); // Returns the width of "abc-"
+ * Canvas.drawText("abc", 0, 3, 0f, 0f, paint); // Draws "abc-"
* </code>
* </pre>
*
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 2041e7a..ecfaec2 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -90,6 +90,7 @@
"libvulkan",
"libui",
"libgui",
+ "libnativedisplay",
"libnativewindow",
"libprotobuf-cpp-lite",
"libft2",
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index a0d3ff9..41e9b4b 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -15,74 +15,21 @@
*/
#include <DeviceInfo.h>
-
-#include "Properties.h"
-
#include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
#include <ui/GraphicTypes.h>
#include <mutex>
#include <thread>
-#include <log/log.h>
+#include "Properties.h"
namespace android {
namespace uirenderer {
-static constexpr android::DisplayInfo sDummyDisplay{
- 1080, // w
- 1920, // h
- 320.0, // xdpi
- 320.0, // ydpi
- 60.0, // fps
- 2.0, // density
- 0, // orientation
- false, // secure?
- 0, // appVsyncOffset
- 0, // presentationDeadline
- 1080, // viewportW
- 1920, // viewportH
-};
-
DeviceInfo* DeviceInfo::get() {
- static DeviceInfo sDeviceInfo;
- return &sDeviceInfo;
-}
-
-static DisplayInfo QueryDisplayInfo() {
- if (Properties::isolatedProcess) {
- return sDummyDisplay;
- }
-
- const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
- LOG_ALWAYS_FATAL_IF(token == nullptr,
- "Failed to get display info because internal display is disconnected");
-
- DisplayInfo displayInfo;
- status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
- LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
- return displayInfo;
-}
-
-static float QueryMaxRefreshRate() {
- if (Properties::isolatedProcess) {
- return sDummyDisplay.fps;
- }
-
- const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
- LOG_ALWAYS_FATAL_IF(token == nullptr,
- "Failed to get display info because internal display is disconnected");
-
- Vector<DisplayInfo> configs;
- configs.reserve(10);
- status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
- LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status);
- LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?");
- float max = 0.0f;
- for (auto& info : configs) {
- max = std::max(max, info.fps);
- }
- return max;
+ static DeviceInfo sDeviceInfo;
+ return &sDeviceInfo;
}
static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkColorType* colorType) {
@@ -123,14 +70,17 @@
}
}
-DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) {
+DeviceInfo::DeviceInfo() {
#if HWUI_NULL_GPU
mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
#else
mMaxTextureSize = -1;
#endif
- mDisplayInfo = QueryDisplayInfo();
- queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+ updateDisplayInfo();
+ queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+}
+DeviceInfo::~DeviceInfo() {
+ ADisplay_release(mDisplays);
}
int DeviceInfo::maxTextureSize() const {
@@ -143,7 +93,36 @@
}
void DeviceInfo::onDisplayConfigChanged() {
- mDisplayInfo = QueryDisplayInfo();
+ updateDisplayInfo();
+}
+
+void DeviceInfo::updateDisplayInfo() {
+ if (Properties::isolatedProcess) {
+ return;
+ }
+
+ if (mCurrentConfig == nullptr) {
+ mDisplaysSize = ADisplay_acquirePhysicalDisplays(&mDisplays);
+ LOG_ALWAYS_FATAL_IF(mDisplays == nullptr || mDisplaysSize <= 0,
+ "Failed to get physical displays: no connected display: %d!", mDisplaysSize);
+ for (size_t i = 0; i < mDisplaysSize; i++) {
+ ADisplayType type = ADisplay_getDisplayType(mDisplays[i]);
+ if (type == ADisplayType::DISPLAY_TYPE_INTERNAL) {
+ mPhysicalDisplayIndex = i;
+ break;
+ }
+ }
+ LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!");
+ mMaxRefreshRate = ADisplay_getMaxSupportedFps(mDisplays[mPhysicalDisplayIndex]);
+ }
+ status_t status = ADisplay_getCurrentConfig(mDisplays[mPhysicalDisplayIndex], &mCurrentConfig);
+ LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);
+ mWidth = ADisplayConfig_getWidth(mCurrentConfig);
+ mHeight = ADisplayConfig_getHeight(mCurrentConfig);
+ mDensity = ADisplayConfig_getDensity(mCurrentConfig);
+ mRefreshRate = ADisplayConfig_getFps(mCurrentConfig);
+ mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
+ mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
}
} /* namespace uirenderer */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 0e3f119..3431583 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,8 +16,8 @@
#ifndef DEVICEINFO_H
#define DEVICEINFO_H
+#include <apex/display.h>
#include <SkImageInfo.h>
-#include <ui/DisplayInfo.h>
#include "utils/Macros.h"
@@ -33,28 +33,44 @@
public:
static DeviceInfo* get();
+ static float getMaxRefreshRate() { return get()->mMaxRefreshRate; }
+ static int32_t getWidth() { return get()->mWidth; }
+ static int32_t getHeight() { return get()->mHeight; }
+ static float getDensity() { return get()->mDensity; }
+ static float getRefreshRate() { return get()->mRefreshRate; }
+ static int64_t getCompositorOffset() { return get()->mCompositorOffset; }
+ static int64_t getAppOffset() { return get()->mAppOffset; }
// this value is only valid after the GPU has been initialized and there is a valid graphics
// context or if you are using the HWUI_NULL_GPU
int maxTextureSize() const;
- const DisplayInfo& displayInfo() const { return mDisplayInfo; }
sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
SkColorType getWideColorType() const { return mWideColorType; }
- float getMaxRefreshRate() const { return mMaxRefreshRate; }
void onDisplayConfigChanged();
private:
friend class renderthread::RenderThread;
static void setMaxTextureSize(int maxTextureSize);
+ void updateDisplayInfo();
DeviceInfo();
+ ~DeviceInfo();
int mMaxTextureSize;
- DisplayInfo mDisplayInfo;
sk_sp<SkColorSpace> mWideColorSpace;
SkColorType mWideColorType;
- const float mMaxRefreshRate;
+ ADisplayConfig* mCurrentConfig = nullptr;
+ ADisplay** mDisplays = nullptr;
+ int mDisplaysSize = 0;
+ int mPhysicalDisplayIndex = -1;
+ float mMaxRefreshRate = 60.0;
+ int32_t mWidth = 1080;
+ int32_t mHeight = 1920;
+ float mDensity = 2.0;
+ float mRefreshRate = 60.0;
+ int64_t mCompositorOffset = 0;
+ int64_t mAppOffset = 0;
};
} /* namespace uirenderer */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index eae3584..10e7160 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -16,8 +16,10 @@
#include "JankTracker.h"
+#include <cutils/ashmem.h>
#include <errno.h>
#include <inttypes.h>
+#include <log/log.h>
#include <statslog.h>
#include <sys/mman.h>
@@ -25,11 +27,9 @@
#include <cmath>
#include <cstdio>
#include <limits>
-
-#include <cutils/ashmem.h>
-#include <log/log.h>
#include <sstream>
+#include "DeviceInfo.h"
#include "Properties.h"
#include "utils/TimeUtils.h"
#include "utils/Trace.h"
@@ -79,11 +79,11 @@
// and filter it out of the frame profile data
static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;
-JankTracker::JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo) {
+JankTracker::JankTracker(ProfileDataContainer* globalData) {
mGlobalData = globalData;
- nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps);
- nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms);
- nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset;
+ nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / DeviceInfo::getRefreshRate());
+ nsecs_t sfOffset = DeviceInfo::getCompositorOffset();
+ nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset();
// There are two different offset cases. If the offsetDelta is positive
// and small, then the intention is to give apps extra time by leveraging
// pipelining between the UI & RT threads. If the offsetDelta is large or
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 08059268..4460266 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -23,7 +23,6 @@
#include "utils/RingBuffer.h"
#include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
#include <array>
#include <memory>
@@ -49,7 +48,7 @@
// TODO: Replace DrawProfiler with this
class JankTracker {
public:
- explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo);
+ explicit JankTracker(ProfileDataContainer* globalData);
void setDescription(JankTrackerType type, const std::string&& name) {
mDescription.type = type;
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 4e7df88..446e81e 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -16,7 +16,6 @@
#include "Properties.h"
#include "Debug.h"
-#include "DeviceInfo.h"
#ifdef __ANDROID__
#include "HWUIProperties.sysprop.h"
#endif
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e979448..24f6035 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -16,7 +16,10 @@
#pragma once
+#ifdef __ANDROID__ // Layoutlib does not support device info
#include "DeviceInfo.h"
+#endif // __ANDROID__
+
#include "Outline.h"
#include "Rect.h"
#include "RevealClip.h"
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index b366a80..eaed46c 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -16,6 +16,7 @@
#include "CacheManager.h"
+#include "DeviceInfo.h"
#include "Layer.h"
#include "Properties.h"
#include "RenderThread.h"
@@ -42,8 +43,8 @@
#define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
-CacheManager::CacheManager(const DisplayInfo& display)
- : mMaxSurfaceArea(display.w * display.h)
+CacheManager::CacheManager()
+ : mMaxSurfaceArea(DeviceInfo::getWidth() * DeviceInfo::getHeight())
, mMaxResourceBytes(mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER)
, mBackgroundResourceBytes(mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE)
// This sets the maximum size for a single texture atlas in the GPU font cache. If
@@ -52,9 +53,9 @@
, mMaxGpuFontAtlasBytes(GrNextSizePow2(mMaxSurfaceArea))
// This sets the maximum size of the CPU font cache to be at least the same size as the
// total number of GPU font caches (i.e. 4 separate GPU atlases).
- , mMaxCpuFontCacheBytes(std::max(mMaxGpuFontAtlasBytes*4, SkGraphics::GetFontCacheLimit()))
+ , mMaxCpuFontCacheBytes(
+ std::max(mMaxGpuFontAtlasBytes * 4, SkGraphics::GetFontCacheLimit()))
, mBackgroundCpuFontCacheBytes(mMaxCpuFontCacheBytes * BACKGROUND_RETENTION_PERCENTAGE) {
-
SkGraphics::SetFontCacheLimit(mMaxCpuFontCacheBytes);
}
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 857710b..968251e 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -21,7 +21,6 @@
#include <GrContext.h>
#endif
#include <SkSurface.h>
-#include <ui/DisplayInfo.h>
#include <utils/String8.h>
#include <vector>
@@ -55,7 +54,7 @@
private:
friend class RenderThread;
- explicit CacheManager(const DisplayInfo& display);
+ explicit CacheManager();
#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
void reset(sk_sp<GrContext> grContext);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 15e0c8d..826a8ea 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -102,13 +102,13 @@
, mGenerationID(0)
, mOpaque(!translucent)
, mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
- , mJankTracker(&thread.globalProfileData(), DeviceInfo::get()->displayInfo())
+ , mJankTracker(&thread.globalProfileData())
, mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos())
, mContentDrawBounds(0, 0, 0, 0)
, mRenderPipeline(std::move(renderPipeline)) {
rootRenderNode->makeRoot();
mRenderNodes.emplace_back(rootRenderNode);
- mProfiler.setDensity(DeviceInfo::get()->displayInfo().density);
+ mProfiler.setDensity(DeviceInfo::getDensity());
setRenderAheadDepth(Properties::defaultRenderAhead);
}
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index ee1a7ce..a446858 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -179,12 +179,11 @@
mEglManager = new EglManager();
mRenderState = new RenderState(*this);
mVkManager = new VulkanManager();
- mCacheManager = new CacheManager(DeviceInfo::get()->displayInfo());
+ mCacheManager = new CacheManager();
}
void RenderThread::setupFrameInterval() {
- auto& displayInfo = DeviceInfo::get()->displayInfo();
- nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / displayInfo.fps);
+ nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / DeviceInfo::getRefreshRate());
mTimeLord.setFrameInterval(frameIntervalNanos);
mDispatchFrameDelay = static_cast<nsecs_t>(frameIntervalNanos * .25f);
}
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 5aa1af3..bdd80721 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -29,7 +29,6 @@
#include <GrContext.h>
#include <SkBitmap.h>
#include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
#include <utils/Looper.h>
#include <utils/Thread.h>
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index 3f1ef93..c83a3c8 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -33,7 +33,8 @@
}
RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
- DisplayInfo displayInfo = DeviceInfo::get()->displayInfo();
+ int32_t width = DeviceInfo::get()->getWidth();
+ int32_t height = DeviceInfo::get()->getHeight();
GrContext* grContext = renderThread.getGrContext();
ASSERT_TRUE(grContext != nullptr);
@@ -42,7 +43,7 @@
std::vector<sk_sp<SkSurface>> surfaces;
while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
- SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
+ SkImageInfo info = SkImageInfo::MakeA8(width, height);
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
@@ -52,8 +53,7 @@
}
// create an image and pin it so that we have something with a unique key in the cache
- sk_sp<Bitmap> bitmap =
- Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h));
+ sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
sk_sp<SkImage> image = bitmap->makeImage();
ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext));
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index b7dd543..c48f6e8 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1890,7 +1890,7 @@
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
- return registerGnssStatusCallback(callback, null);
+ return registerGnssStatusCallback(Runnable::run, callback);
}
/**
@@ -1985,7 +1985,7 @@
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) {
- return addNmeaListener(listener, null);
+ return addNmeaListener(Runnable::run, listener);
}
/**
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 70a343f..7ba122b 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -395,7 +395,7 @@
* <p>The row stride for this color plane, in bytes.</p>
*
* <p>This is the distance between the start of two consecutive rows of
- * pixels in the image. Note that row stried is undefined for some formats
+ * pixels in the image. Note that row stride is undefined for some formats
* such as
* {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
* and calling getRowStride on images of these formats will
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index ce18ab3..cb6c126 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -18,10 +18,14 @@
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -30,6 +34,7 @@
import com.android.internal.annotations.GuardedBy;
+import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -40,12 +45,40 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
-
/**
* A new Media Router
* @hide
*/
public class MediaRouter2 {
+
+ /** @hide */
+ @Retention(SOURCE)
+ @IntDef(value = {
+ SELECT_REASON_UNKNOWN,
+ SELECT_REASON_USER_SELECTED,
+ SELECT_REASON_FALLBACK})
+ public @interface SelectReason {}
+
+ /**
+ * Passed to {@link Callback#onRouteSelected(MediaRoute2Info, int, Bundle)} when the reason
+ * the route was selected is unknown.
+ */
+ public static final int SELECT_REASON_UNKNOWN = 0;
+
+ /**
+ * Passed to {@link Callback#onRouteSelected(MediaRoute2Info, int, Bundle)} when the route
+ * is selected in response to a user's request. For example, when a user has selected
+ * a different device to play media to.
+ */
+ public static final int SELECT_REASON_USER_SELECTED = 1;
+
+ /**
+ * Passed to {@link Callback#onRouteSelected(MediaRoute2Info, int, Bundle)} when the route
+ * is selected as a fallback route. For example, when Wi-Fi is disconnected, the device speaker
+ * may be selected as a fallback route.
+ */
+ public static final int SELECT_REASON_FALLBACK = 2;
+
private static final String TAG = "MR2";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final Object sLock = new Object();
@@ -457,10 +490,31 @@
public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {}
/**
- * Called when routes are changed.
+ * Called when routes are changed. For example, it is called when the route's name
+ * or volume have been changed.
+ *
+ * TODO: Write here what the developers should do when this method is called.
+ * How they can find the exact point how a route is changed?
+ * It can be a volume, name, client package name, ....
+ *
* @param routes the list of routes that have been changed. It's never empty.
*/
public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
+
+ // TODO: Make this callback be called when we add requestSelectRoute().
+ /**
+ * Called when a route is selected. Exactly one route can be selected at a time.
+ * @param route the selected route.
+ * @param reason the reason why the route is selected.
+ * @param connectionHints An optional bundle of provider-specific arguments which may be
+ * used to control the selected route. Can be empty.
+ * @see #SELECT_REASON_UNKNOWN
+ * @see #SELECT_REASON_USER_SELECTED
+ * @see #SELECT_REASON_FALLBACK
+ * @see #getSelectedRoute()
+ */
+ public void onRouteSelected(@NonNull MediaRoute2Info route, @SelectReason int reason,
+ @NonNull Bundle connectionHints) {}
}
final class CallbackRecord {
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 4ed8f42..7d68d02 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -33,6 +33,8 @@
private static final boolean DEBUG = false;
private static final int MSG_ON_FRONTEND_EVENT = 1;
+ private static final int MSG_ON_FILTER_EVENT = 2;
+ private static final int MSG_ON_FILTER_STATUS = 3;
static {
System.loadLibrary("media_tv_tuner");
@@ -86,6 +88,16 @@
void onEvent(int frontendEventType);
}
+ /**
+ * Frontend Callback.
+ */
+ public interface FilterCallback {
+ /**
+ * Invoked when filter status changed.
+ */
+ void onFilterStatus(int status);
+ }
+
@Nullable
private EventHandler createEventHandler() {
Looper looper;
@@ -110,6 +122,13 @@
mFrontend.mCallback.onEvent(msg.arg1);
}
break;
+ case MSG_ON_FILTER_STATUS: {
+ Filter filter = (Filter) msg.obj;
+ if (filter.mCallback != null) {
+ filter.mCallback.onFilterStatus(msg.arg1);
+ }
+ break;
+ }
default:
// fall through
}
@@ -171,13 +190,29 @@
}
protected class Filter {
+ private long mNativeContext;
+ private FilterCallback mCallback;
int mId;
private Filter(int id) {
mId = id;
}
+
+ private void onFilterStatus(int status) {
+ if (mHandler != null) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_ON_FILTER_STATUS, status, 0, this));
+ }
+ }
}
- private Filter openFilter(int type, int subType, int bufferSize) {
- return nativeOpenFilter(type, subType, bufferSize);
+ private Filter openFilter(int type, int subType, int bufferSize, FilterCallback cb) {
+ Filter filter = nativeOpenFilter(type, subType, bufferSize);
+ if (filter != null) {
+ filter.mCallback = cb;
+ if (mHandler == null) {
+ mHandler = createEventHandler();
+ }
+ }
+ return filter;
}
}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 820fe98..8f844d4 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -523,6 +523,40 @@
}
}
+void JDrm::sendEvent(
+ DrmPlugin::EventType eventType,
+ const hardware::hidl_vec<uint8_t> &sessionId,
+ const hardware::hidl_vec<uint8_t> &data) {
+ Parcel obj;
+ DrmUtils::WriteByteArray(obj, sessionId);
+ DrmUtils::WriteByteArray(obj, data);
+ notify(eventType, 0, &obj);
+}
+
+void JDrm::sendExpirationUpdate(
+ const hardware::hidl_vec<uint8_t> &sessionId,
+ int64_t expiryTimeInMS) {
+ Parcel obj;
+ DrmUtils::WriteExpirationUpdateToParcel(obj, sessionId, expiryTimeInMS);
+ notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
+}
+
+void JDrm::sendKeysChange(
+ const hardware::hidl_vec<uint8_t> &sessionId,
+ const std::vector<DrmKeyStatus> &keyStatusList,
+ bool hasNewUsableKey) {
+ Parcel obj;
+ DrmUtils::WriteKeysChange(obj, sessionId, keyStatusList, hasNewUsableKey);
+ notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
+}
+
+void JDrm::sendSessionLostState(
+ const hardware::hidl_vec<uint8_t> &sessionId) {
+ Parcel obj;
+ DrmUtils::WriteByteArray(obj, sessionId);
+ notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
+}
+
void JDrm::disconnect() {
if (mDrm != NULL) {
mDrm->destroyPlugin();
diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h
index 684069b..37d9e07 100644
--- a/media/jni/android_media_MediaDrm.h
+++ b/media/jni/android_media_MediaDrm.h
@@ -21,6 +21,8 @@
#include <media/stagefright/foundation/ABase.h>
#include <mediadrm/IDrm.h>
+#include <mediadrm/IDrmClient.h>
+#include <hidl/HidlSupport.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -44,7 +46,23 @@
status_t initCheck() const;
sp<IDrm> getDrm() { return mDrm; }
- void notify(DrmPlugin::EventType, int extra, const Parcel *obj);
+ void sendEvent(
+ DrmPlugin::EventType eventType,
+ const hardware::hidl_vec<uint8_t> &sessionId,
+ const hardware::hidl_vec<uint8_t> &data) override;
+
+ void sendExpirationUpdate(
+ const hardware::hidl_vec<uint8_t> &sessionId,
+ int64_t expiryTimeInMS) override;
+
+ void sendKeysChange(
+ const hardware::hidl_vec<uint8_t> &sessionId,
+ const std::vector<DrmKeyStatus> &keyStatusList,
+ bool hasNewUsableKey) override;
+
+ void sendSessionLostState(
+ const hardware::hidl_vec<uint8_t> &sessionId) override;
+
status_t setListener(const sp<DrmListener>& listener);
void disconnect();
@@ -63,6 +81,8 @@
static sp<IDrm> MakeDrm();
static sp<IDrm> MakeDrm(const uint8_t uuid[16], const String8 &appPackageName);
+ void notify(DrmPlugin::EventType, int extra, const Parcel *obj);
+
DISALLOW_EVIL_CONSTRUCTORS(JDrm);
};
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index f815097..2640572 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -34,9 +34,11 @@
struct fields_t {
jfieldID context;
+ jfieldID filterContext;
jmethodID frontendInitID;
jmethodID filterInitID;
jmethodID onFrontendEventID;
+ jmethodID onFilterStatusID;
};
static fields_t gFields;
@@ -44,15 +46,27 @@
namespace android {
/////////////// FilterCallback ///////////////////////
//TODO: implement filter callback
-Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /* filterEvent */) {
+Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) {
ALOGD("FilterCallback::onFilterEvent");
return Void();
}
-Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus /*status*/) {
- ALOGD("FilterCallback::onFilterStatu");
+
+Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
+ ALOGD("FilterCallback::onFilterStatus");
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(
+ mFilter,
+ gFields.onFilterStatusID,
+ (jint)status);
return Void();
}
+void FilterCallback::setFilter(const jobject filter) {
+ ALOGD("FilterCallback::setFilter");
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ mFilter = env->NewWeakGlobalRef(filter);
+}
+
/////////////// FrontendCallback ///////////////////////
FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {}
@@ -186,27 +200,35 @@
}
}
- sp<IFilter> f;
- mDemux->openFilter(type, bufferSize, new FilterCallback,
+ sp<IFilter> filterSp;
+ sp<FilterCallback> callback = new FilterCallback();
+ mDemux->openFilter(type, bufferSize, callback,
[&](Result, const sp<IFilter>& filter) {
- f = filter;
+ filterSp = filter;
});
- if (f == NULL) {
+ if (filterSp == NULL) {
ALOGD("Failed to open filter, type = %d", type.mainType);
return NULL;
}
int fId;
- f->getId([&](Result, uint32_t filterId) {
+ filterSp->getId([&](Result, uint32_t filterId) {
fId = filterId;
});
- mFilters[fId] = f;
JNIEnv *env = AndroidRuntime::getJNIEnv();
- return env->NewObject(
- env->FindClass("android/media/tv/tuner/Tuner$Filter"),
- gFields.filterInitID,
- mObject,
- (jint) fId);
+ jobject filterObj =
+ env->NewObject(
+ env->FindClass("android/media/tv/tuner/Tuner$Filter"),
+ gFields.filterInitID,
+ mObject,
+ (jint) fId);
+
+ filterSp->incStrong(filterObj);
+ env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get());
+
+ callback->setFilter(filterObj);
+
+ return filterObj;
}
} // namespace android
@@ -233,6 +255,10 @@
return (JTuner *)env->GetLongField(thiz, gFields.context);
}
+static sp<IFilter> getFilter(JNIEnv *env, jobject filter) {
+ return (IFilter *)env->GetLongField(filter, gFields.filterContext);
+}
+
static void android_media_tv_Tuner_native_init(JNIEnv *env) {
jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
CHECK(clazz != NULL);
@@ -247,8 +273,11 @@
env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
jclass filterClazz = env->FindClass("android/media/tv/tuner/Tuner$Filter");
+ gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J");
gFields.filterInitID =
env->GetMethodID(filterClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
+ gFields.onFilterStatusID =
+ env->GetMethodID(filterClazz, "onFilterStatus", "(I)V");
}
static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 7a889c3..ab48761 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -44,6 +44,10 @@
struct FilterCallback : public IFilterCallback {
virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent);
virtual Return<void> onFilterStatus(const DemuxFilterStatus status);
+
+ void setFilter(const jobject filter);
+private:
+ jweak mFilter;
};
struct FrontendCallback : public IFrontendCallback {
@@ -76,7 +80,6 @@
sp<IFrontend> mFe;
sp<IDemux> mDemux;
int mDemuxId;
- std::unordered_map<int, sp<IFilter>> mFilters;
};
} // namespace android
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index d3d9b28..0bd2e06 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -24,6 +24,8 @@
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.shortcut.ShortcutKeyDispatcher;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.car.CarStatusBarModule;
import com.android.systemui.statusbar.notification.InstantAppNotifier;
@@ -45,7 +47,13 @@
@Binds
@IntoMap
@ClassKey(AuthController.class)
- public abstract SystemUI bindAuthController(AuthController service);
+ public abstract SystemUI bindAuthController(AuthController sysui);
+
+ /** Inject into Divider. */
+ @Binds
+ @IntoMap
+ @ClassKey(Divider.class)
+ public abstract SystemUI bindDivider(Divider sysui);
/** */
@Binds
@@ -57,7 +65,7 @@
@Binds
@IntoMap
@ClassKey(GarbageMonitor.Service.class)
- public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service service);
+ public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);
/** Inject into GlobalActionsComponent. */
@Binds
@@ -107,6 +115,12 @@
@ClassKey(ScreenDecorations.class)
public abstract SystemUI bindScreenDecorations(ScreenDecorations sysui);
+ /** Inject into ShortcutKeyDispatcher. */
+ @Binds
+ @IntoMap
+ @ClassKey(ShortcutKeyDispatcher.class)
+ public abstract SystemUI bindsShortcutKeyDispatcher(ShortcutKeyDispatcher sysui);
+
/** Inject into SizeCompatModeActivityController. */
@Binds
@IntoMap
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index be4b889..c35303e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -18,12 +18,8 @@
import android.content.Context;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.navigationbar.car.CarFacetButtonController;
-import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import javax.inject.Singleton;
@@ -50,11 +46,6 @@
return mCarDependencyComponent;
}
- public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
- ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
- return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
- }
-
@Singleton
@Component(modules = ContextHolder.class)
public interface CarDependencyComponent {
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index d3a6cde..3b63e79 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -28,15 +28,21 @@
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsImplementation;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
import com.android.systemui.statusbar.car.CarStatusBar;
+import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.volume.CarVolumeDialogComponent;
import com.android.systemui.volume.VolumeDialogComponent;
@@ -70,6 +76,12 @@
@Singleton
@Provides
+ static Divider provideDivider(Context context) {
+ return new Divider(context);
+ }
+
+ @Singleton
+ @Provides
@Named(LEAK_REPORT_EMAIL_NAME)
static String provideLeakReportEmail() {
return "buganizer-system+181579@google.com";
@@ -95,6 +107,13 @@
return SysUiServiceProvider.getComponent(context, StatusBar.class);
}
+ @Provides
+ @Singleton
+ static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
+ CommandQueue commandQueue) {
+ return new Recents(context, recentsImplementation, commandQueue);
+ }
+
@Binds
abstract SystemUIRootComponent bindSystemUIRootComponent(
CarSystemUIRootComponent systemUIRootComponent);
@@ -105,4 +124,8 @@
@Binds
abstract VolumeDialogComponent bindVolumeDialogComponent(
CarVolumeDialogComponent carVolumeDialogComponent);
+
+ @Binds
+ abstract StatusBarKeyguardViewManager bindStatusBarKeyguardViewManager(
+ CarStatusBarKeyguardViewManager keyguardViewManager);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index fc0b317..1d14c34 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -55,22 +55,21 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.CarSystemUIFactory;
import com.android.systemui.Dependency;
-import com.android.systemui.ForegroundServiceController;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -81,6 +80,7 @@
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.car.CarQSFragment;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -103,7 +103,6 @@
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -115,12 +114,14 @@
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -131,11 +132,11 @@
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
+import java.util.Optional;
import javax.inject.Named;
@@ -243,7 +244,6 @@
AutoHideController autoHideController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarIconController statusBarIconController,
- DozeLog dozeLog,
PulseExpansionHandler pulseExpansionHandler,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
@@ -261,10 +261,7 @@
NotificationEntryManager notificationEntryManager,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
- ForegroundServiceController foregroundServiceController,
- AppOpsController appOpsController,
KeyguardViewMediator keyguardViewMediator,
- ZenModeController zenModeController,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@@ -291,7 +288,6 @@
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild,
- NotifLog notifLog,
DozeParameters dozeParameters,
ScrimController scrimController,
Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -302,7 +298,12 @@
CommandQueue commandQueue,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
+ Optional<Divider> dividerOptional,
SuperStatusBarViewFactory superStatusBarViewFactory,
+ LightsOutNotifController lightsOutNotifController,
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ ViewMediatorCallback viewMediatorCallback,
+ DismissCallbackRegistry dismissCallbackRegistry,
/* Car Settings injected components. */
CarNavigationBarController carNavigationBarController) {
super(
@@ -312,7 +313,6 @@
autoHideController,
keyguardUpdateMonitor,
statusBarIconController,
- dozeLog,
pulseExpansionHandler,
notificationWakeUpCoordinator,
keyguardBypassController,
@@ -330,10 +330,7 @@
notificationEntryManager,
notificationInterruptionStateProvider,
notificationViewHierarchyManager,
- foregroundServiceController,
- appOpsController,
keyguardViewMediator,
- zenModeController,
notificationAlertingManager,
displayMetrics,
metricsLogger,
@@ -360,7 +357,6 @@
configurationController,
statusBarWindowController,
statusBarWindowViewControllerBuild,
- notifLog,
dozeParameters,
scrimController,
null /* keyguardLiftController */,
@@ -372,7 +368,12 @@
commandQueue,
pluginManager,
remoteInputUriController,
- superStatusBarViewFactory);
+ dividerOptional,
+ lightsOutNotifController,
+ superStatusBarViewFactory,
+ statusBarKeyguardViewManager,
+ viewMediatorCallback,
+ dismissCallbackRegistry);
mScrimController = scrimController;
mCarNavigationBarController = carNavigationBarController;
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index 5921868..0ad0992 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -20,18 +20,43 @@
import android.view.View;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.R;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.phone.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/** Car implementation of the {@link StatusBarKeyguardViewManager}. */
+@Singleton
public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
protected boolean mShouldHideNavBar;
+ @Inject
public CarStatusBarKeyguardViewManager(Context context,
ViewMediatorCallback callback,
- LockPatternUtils lockPatternUtils) {
- super(context, callback, lockPatternUtils);
+ LockPatternUtils lockPatternUtils,
+ SysuiStatusBarStateController sysuiStatusBarStateController,
+ ConfigurationController configurationController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ NavigationModeController navigationModeController,
+ DockManager dockManager,
+ StatusBarWindowController statusBarWindowController,
+ KeyguardStateController keyguardStateController,
+ NotificationMediaManager notificationMediaManager) {
+ super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
+ configurationController, keyguardUpdateMonitor, navigationModeController,
+ dockManager, statusBarWindowController, keyguardStateController,
+ notificationMediaManager);
mShouldHideNavBar = context.getResources()
.getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index b19fae8..542fa44 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -24,20 +24,20 @@
import com.android.internal.logging.MetricsLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.ForegroundServiceController;
+import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.navigationbar.car.CarNavigationBarController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NavigationBarController;
@@ -59,7 +59,6 @@
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -70,11 +69,13 @@
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -85,7 +86,8 @@
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
+
+import java.util.Optional;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -111,7 +113,6 @@
AutoHideController autoHideController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarIconController statusBarIconController,
- DozeLog dozeLog,
PulseExpansionHandler pulseExpansionHandler,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
@@ -129,10 +130,7 @@
NotificationEntryManager notificationEntryManager,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
- ForegroundServiceController foregroundServiceController,
- AppOpsController appOpsController,
KeyguardViewMediator keyguardViewMediator,
- ZenModeController zenModeController,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@@ -159,7 +157,6 @@
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
- NotifLog notifLog,
DozeParameters dozeParameters,
ScrimController scrimController,
Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -170,7 +167,12 @@
CommandQueue commandQueue,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
+ Optional<Divider> dividerOptional,
SuperStatusBarViewFactory superStatusBarViewFactory,
+ LightsOutNotifController lightsOutNotifController,
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ ViewMediatorCallback viewMediatorCallback,
+ DismissCallbackRegistry dismissCallbackRegistry,
CarNavigationBarController carNavigationBarController) {
return new CarStatusBar(
context,
@@ -179,7 +181,6 @@
autoHideController,
keyguardUpdateMonitor,
statusBarIconController,
- dozeLog,
pulseExpansionHandler,
notificationWakeUpCoordinator,
keyguardBypassController,
@@ -197,10 +198,7 @@
notificationEntryManager,
notificationInterruptionStateProvider,
notificationViewHierarchyManager,
- foregroundServiceController,
- appOpsController,
keyguardViewMediator,
- zenModeController,
notificationAlertingManager,
displayMetrics,
metricsLogger,
@@ -227,7 +225,6 @@
configurationController,
statusBarWindowController,
statusBarWindowViewControllerBuilder,
- notifLog,
dozeParameters,
scrimController,
lockscreenWallpaperLazy,
@@ -238,7 +235,12 @@
commandQueue,
pluginManager,
remoteInputUriController,
+ dividerOptional,
superStatusBarViewFactory,
+ lightsOutNotifController,
+ statusBarKeyguardViewManager,
+ viewMediatorCallback,
+ dismissCallbackRegistry,
carNavigationBarController);
}
}
diff --git a/packages/ExternalStorageProvider/res/values-af/strings.xml b/packages/ExternalStorageProvider/res/values-af/strings.xml
index 96b25a4..b7684a7 100644
--- a/packages/ExternalStorageProvider/res/values-af/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-af/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Eksterne berging"</string>
- <string name="storage_description" msgid="8541974407321172792">"Plaaslike berging"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interne berging"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+ <string name="app_label" msgid="748293919008814871">"Eksterne berging"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Plaaslike berging"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interne berging"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumente"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-am/strings.xml b/packages/ExternalStorageProvider/res/values-am/strings.xml
index f2d308c..49de54d 100644
--- a/packages/ExternalStorageProvider/res/values-am/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-am/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ውጫዊ ማከማቻ"</string>
- <string name="storage_description" msgid="8541974407321172792">"አካባቢያዊ ማከማቻ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ውስጣዊ ማከማቻ"</string>
- <string name="root_documents" msgid="4051252304075469250">"ሰነዶች"</string>
+ <string name="app_label" msgid="748293919008814871">"ውጫዊ ማከማቻ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"አካባቢያዊ ማከማቻ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ውስጣዊ ማከማቻ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ሰነዶች"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ar/strings.xml b/packages/ExternalStorageProvider/res/values-ar/strings.xml
index a01fc02..878f560 100644
--- a/packages/ExternalStorageProvider/res/values-ar/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ar/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"وحدة تخزين خارجية"</string>
- <string name="storage_description" msgid="8541974407321172792">"التخزين المحلي"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"وحدة تخزين داخلية"</string>
- <string name="root_documents" msgid="4051252304075469250">"مستندات"</string>
+ <string name="app_label" msgid="748293919008814871">"وحدة تخزين خارجية"</string>
+ <string name="storage_description" msgid="9176081505553938524">"التخزين المحلي"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"وحدة تخزين داخلية"</string>
+ <string name="root_documents" msgid="5695037589229175941">"مستندات"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-as/strings.xml b/packages/ExternalStorageProvider/res/values-as/strings.xml
index 278b84e..92bb1aa 100644
--- a/packages/ExternalStorageProvider/res/values-as/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-as/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"বাহ্যিক সঞ্চয়াগাৰ"</string>
- <string name="storage_description" msgid="8541974407321172792">"স্থানীয় সঞ্চয়াগাৰ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"আভ্যন্তৰীণ সঞ্চয়াগাৰ"</string>
- <string name="root_documents" msgid="4051252304075469250">"নথিপত্রসমূহ"</string>
+ <string name="app_label" msgid="748293919008814871">"বাহ্যিক সঞ্চয়াগাৰ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"স্থানীয় সঞ্চয়াগাৰ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"আভ্যন্তৰীণ সঞ্চয়াগাৰ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"নথিপত্রসমূহ"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-az/strings.xml b/packages/ExternalStorageProvider/res/values-az/strings.xml
index d8c17ee..605a11a 100644
--- a/packages/ExternalStorageProvider/res/values-az/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-az/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Xarici Yaddaş"</string>
- <string name="storage_description" msgid="8541974407321172792">"Yerli yaddaş"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Daxili yaddaş"</string>
- <string name="root_documents" msgid="4051252304075469250">"Sənədlər"</string>
+ <string name="app_label" msgid="748293919008814871">"Xarici Yaddaş"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Yerli yaddaş"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Daxili yaddaş"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Sənədlər"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
index 235b621..88e34fe 100644
--- a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Spoljna memorija"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokalni memorijski prostor"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interna memorija"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Spoljna memorija"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokalni memorijski prostor"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interna memorija"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-be/strings.xml b/packages/ExternalStorageProvider/res/values-be/strings.xml
index 911ff54..07c7da5 100644
--- a/packages/ExternalStorageProvider/res/values-be/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-be/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Вонкавае сховішча"</string>
- <string name="storage_description" msgid="8541974407321172792">"Лакальнае сховішча"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Унутранае сховішча"</string>
- <string name="root_documents" msgid="4051252304075469250">"Дакументы"</string>
+ <string name="app_label" msgid="748293919008814871">"Вонкавае сховішча"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Лакальнае сховішча"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Унутранае сховішча"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Дакументы"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-bg/strings.xml b/packages/ExternalStorageProvider/res/values-bg/strings.xml
index e3b58e4..ca89dc5 100644
--- a/packages/ExternalStorageProvider/res/values-bg/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bg/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Външно хранилище"</string>
- <string name="storage_description" msgid="8541974407321172792">"Локално хранилище"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Вътрешно хранилище"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+ <string name="app_label" msgid="748293919008814871">"Външно хранилище"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Локално хранилище"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Вътрешно хранилище"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-bn/strings.xml b/packages/ExternalStorageProvider/res/values-bn/strings.xml
index 264d82a..2b7f6ad 100644
--- a/packages/ExternalStorageProvider/res/values-bn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bn/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"এক্সটারনাল স্টোরেজ"</string>
- <string name="storage_description" msgid="8541974407321172792">"স্থানীয় স্টোরেজ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ইন্টারনাল স্টোরেজ"</string>
- <string name="root_documents" msgid="4051252304075469250">"দস্তাবেজগুলি"</string>
+ <string name="app_label" msgid="748293919008814871">"এক্সটারনাল স্টোরেজ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"স্থানীয় স্টোরেজ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ইন্টারনাল স্টোরেজ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"দস্তাবেজগুলি"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-bs/strings.xml b/packages/ExternalStorageProvider/res/values-bs/strings.xml
index 1eb3020..2c42df7 100644
--- a/packages/ExternalStorageProvider/res/values-bs/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bs/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Aplikacija za vanjsku pohranu"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokalna pohrana"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interna pohrana"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Aplikacija za vanjsku pohranu"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokalna pohrana"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interna pohrana"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ca/strings.xml b/packages/ExternalStorageProvider/res/values-ca/strings.xml
index a67de7d..117a416 100644
--- a/packages/ExternalStorageProvider/res/values-ca/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ca/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Emmagatzematge extern"</string>
- <string name="storage_description" msgid="8541974407321172792">"Emmagatzematge local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Emmagatzematge intern"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"Emmagatzematge extern"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Emmagatzematge local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Emmagatzematge intern"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-cs/strings.xml b/packages/ExternalStorageProvider/res/values-cs/strings.xml
index b9c54b8..761533d 100644
--- a/packages/ExternalStorageProvider/res/values-cs/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-cs/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Externí úložiště"</string>
- <string name="storage_description" msgid="8541974407321172792">"Místní úložiště"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interní úložiště"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+ <string name="app_label" msgid="748293919008814871">"Externí úložiště"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Místní úložiště"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interní úložiště"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenty"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-da/strings.xml b/packages/ExternalStorageProvider/res/values-da/strings.xml
index 4da1419..9d89c80 100644
--- a/packages/ExternalStorageProvider/res/values-da/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-da/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Ekstern lagerplads"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokalt lager"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Intern lagerplads"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenter"</string>
+ <string name="app_label" msgid="748293919008814871">"Ekstern lagerplads"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokalt lager"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Intern lagerplads"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenter"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-de/strings.xml b/packages/ExternalStorageProvider/res/values-de/strings.xml
index 846152b..cb22276 100644
--- a/packages/ExternalStorageProvider/res/values-de/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-de/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Externer Speicher"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokaler Speicher"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interner Speicher"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+ <string name="app_label" msgid="748293919008814871">"Externer Speicher"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokaler Speicher"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interner Speicher"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumente"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-el/strings.xml b/packages/ExternalStorageProvider/res/values-el/strings.xml
index 1e78e53..02123db 100644
--- a/packages/ExternalStorageProvider/res/values-el/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-el/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Εξωτερικός αποθηκευτικός χώρος"</string>
- <string name="storage_description" msgid="8541974407321172792">"Τοπικός χώρος αποθήκευσης"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Εσωτερικός αποθηκευτικός χώρος"</string>
- <string name="root_documents" msgid="4051252304075469250">"Έγγραφα"</string>
+ <string name="app_label" msgid="748293919008814871">"Εξωτερικός αποθηκευτικός χώρος"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Τοπικός χώρος αποθήκευσης"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Εσωτερικός αποθηκευτικός χώρος"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Έγγραφα"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml b/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
- <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml b/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
- <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml b/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
- <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml b/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
- <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml b/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
index 5034d21..afec109 100644
--- a/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
- <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml b/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
index 8262422..39392a5 100644
--- a/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Almacenamiento externo"</string>
- <string name="storage_description" msgid="8541974407321172792">"Almacenamiento local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+ <string name="app_label" msgid="748293919008814871">"Almacenamiento externo"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Almacenamiento local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Almacenamiento interno"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-es/strings.xml b/packages/ExternalStorageProvider/res/values-es/strings.xml
index 8262422..39392a5 100644
--- a/packages/ExternalStorageProvider/res/values-es/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-es/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Almacenamiento externo"</string>
- <string name="storage_description" msgid="8541974407321172792">"Almacenamiento local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+ <string name="app_label" msgid="748293919008814871">"Almacenamiento externo"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Almacenamiento local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Almacenamiento interno"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-et/strings.xml b/packages/ExternalStorageProvider/res/values-et/strings.xml
index 095202f..7bc135b 100644
--- a/packages/ExternalStorageProvider/res/values-et/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-et/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Väline talletusruum"</string>
- <string name="storage_description" msgid="8541974407321172792">"Kohalik salvestusruum"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Sisemine salvestusruum"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumendid"</string>
+ <string name="app_label" msgid="748293919008814871">"Väline talletusruum"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Kohalik salvestusruum"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Sisemine salvestusruum"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumendid"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-eu/strings.xml b/packages/ExternalStorageProvider/res/values-eu/strings.xml
index c0e8cdd..fb43894 100644
--- a/packages/ExternalStorageProvider/res/values-eu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-eu/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Kanpoko memoria"</string>
- <string name="storage_description" msgid="8541974407321172792">"Biltegi lokala"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Barneko memoria"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumentuak"</string>
+ <string name="app_label" msgid="748293919008814871">"Kanpoko memoria"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Biltegi lokala"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Barneko memoria"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumentuak"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fa/strings.xml b/packages/ExternalStorageProvider/res/values-fa/strings.xml
index 0de4d4d..9eabfd0 100644
--- a/packages/ExternalStorageProvider/res/values-fa/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fa/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"حافظه خارجی"</string>
- <string name="storage_description" msgid="8541974407321172792">"فضای ذخیرهسازی محلی"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"حافظهٔ داخلی"</string>
- <string name="root_documents" msgid="4051252304075469250">"اسناد"</string>
+ <string name="app_label" msgid="748293919008814871">"حافظه خارجی"</string>
+ <string name="storage_description" msgid="9176081505553938524">"فضای ذخیرهسازی محلی"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"حافظهٔ داخلی"</string>
+ <string name="root_documents" msgid="5695037589229175941">"اسناد"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fi/strings.xml b/packages/ExternalStorageProvider/res/values-fi/strings.xml
index 6619568..bbb1c4f 100644
--- a/packages/ExternalStorageProvider/res/values-fi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fi/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Ulkoinen tallennustila"</string>
- <string name="storage_description" msgid="8541974407321172792">"Paikallinen tallennustila"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Sisäinen tallennustila"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumentit"</string>
+ <string name="app_label" msgid="748293919008814871">"Ulkoinen tallennustila"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Paikallinen tallennustila"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Sisäinen tallennustila"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumentit"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml b/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
index e1e8f17..6c07457 100644
--- a/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Stockage externe"</string>
- <string name="storage_description" msgid="8541974407321172792">"Stockage local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"Stockage externe"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Stockage local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Mémoire de stockage interne"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fr/strings.xml b/packages/ExternalStorageProvider/res/values-fr/strings.xml
index e1e8f17..6c07457 100644
--- a/packages/ExternalStorageProvider/res/values-fr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fr/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Stockage externe"</string>
- <string name="storage_description" msgid="8541974407321172792">"Stockage local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+ <string name="app_label" msgid="748293919008814871">"Stockage externe"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Stockage local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Mémoire de stockage interne"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-gl/strings.xml b/packages/ExternalStorageProvider/res/values-gl/strings.xml
index eeb2f51..91d9571 100644
--- a/packages/ExternalStorageProvider/res/values-gl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-gl/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Almacenamento externo"</string>
- <string name="storage_description" msgid="8541974407321172792">"Almacenamento local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Almacenamento interno"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+ <string name="app_label" msgid="748293919008814871">"Almacenamento externo"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Almacenamento local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Almacenamento interno"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-gu/strings.xml b/packages/ExternalStorageProvider/res/values-gu/strings.xml
index 3f59dd3..fc9a34d 100644
--- a/packages/ExternalStorageProvider/res/values-gu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-gu/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"બાહ્ય સંગ્રહ"</string>
- <string name="storage_description" msgid="8541974407321172792">"સ્થાનિક સ્ટોરેજ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"આંતરિક સ્ટોરેજ"</string>
- <string name="root_documents" msgid="4051252304075469250">"દસ્તાવેજો"</string>
+ <string name="app_label" msgid="748293919008814871">"બાહ્ય સંગ્રહ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"સ્થાનિક સ્ટોરેજ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"આંતરિક સ્ટોરેજ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"દસ્તાવેજો"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hi/strings.xml b/packages/ExternalStorageProvider/res/values-hi/strings.xml
index f424871..76f27ff 100644
--- a/packages/ExternalStorageProvider/res/values-hi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hi/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"बाहरी मेमोरी"</string>
- <string name="storage_description" msgid="8541974407321172792">"स्थानीय जगह"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"मोबाइल मेमोरी"</string>
- <string name="root_documents" msgid="4051252304075469250">"दस्तावेज़"</string>
+ <string name="app_label" msgid="748293919008814871">"बाहरी मेमोरी"</string>
+ <string name="storage_description" msgid="9176081505553938524">"स्थानीय जगह"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"मोबाइल मेमोरी"</string>
+ <string name="root_documents" msgid="5695037589229175941">"दस्तावेज़"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hr/strings.xml b/packages/ExternalStorageProvider/res/values-hr/strings.xml
index 1dd696e..bf0ad0c 100644
--- a/packages/ExternalStorageProvider/res/values-hr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hr/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Vanjska pohrana"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokalna pohrana"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Unutarnja pohrana"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Vanjska pohrana"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokalna pohrana"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Unutarnja pohrana"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hu/strings.xml b/packages/ExternalStorageProvider/res/values-hu/strings.xml
index 8201630..021a8bb 100644
--- a/packages/ExternalStorageProvider/res/values-hu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hu/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Külső tárhely"</string>
- <string name="storage_description" msgid="8541974407321172792">"Helyi tárhely"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Belső tárhely"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumentumok"</string>
+ <string name="app_label" msgid="748293919008814871">"Külső tárhely"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Helyi tárhely"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Belső tárhely"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumentumok"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hy/strings.xml b/packages/ExternalStorageProvider/res/values-hy/strings.xml
index b8c2ea7..b846d28 100644
--- a/packages/ExternalStorageProvider/res/values-hy/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hy/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Արտաքին պահոց"</string>
- <string name="storage_description" msgid="8541974407321172792">"Սարքի հիշողություն"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Ներքին պահոց"</string>
- <string name="root_documents" msgid="4051252304075469250">"Փաստաթղթեր"</string>
+ <string name="app_label" msgid="748293919008814871">"Արտաքին պահոց"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Սարքի հիշողություն"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Ներքին պահոց"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Փաստաթղթեր"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-in/strings.xml b/packages/ExternalStorageProvider/res/values-in/strings.xml
index f91d1a5..950e906 100644
--- a/packages/ExternalStorageProvider/res/values-in/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-in/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Penyimpanan Eksternal"</string>
- <string name="storage_description" msgid="8541974407321172792">"Penyimpanan lokal"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Penyimpanan internal"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumen"</string>
+ <string name="app_label" msgid="748293919008814871">"Penyimpanan Eksternal"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Penyimpanan lokal"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Penyimpanan internal"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumen"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-is/strings.xml b/packages/ExternalStorageProvider/res/values-is/strings.xml
index adaf0d4..cac2edb 100644
--- a/packages/ExternalStorageProvider/res/values-is/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-is/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Ytri geymsla"</string>
- <string name="storage_description" msgid="8541974407321172792">"Staðbundin vistun"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Innbyggð geymsla"</string>
- <string name="root_documents" msgid="4051252304075469250">"Skjöl"</string>
+ <string name="app_label" msgid="748293919008814871">"Ytri geymsla"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Staðbundin vistun"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Innbyggð geymsla"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Skjöl"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-it/strings.xml b/packages/ExternalStorageProvider/res/values-it/strings.xml
index 35ba7f3..3a59bed 100644
--- a/packages/ExternalStorageProvider/res/values-it/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-it/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Archivio esterno"</string>
- <string name="storage_description" msgid="8541974407321172792">"Archiviazione locale"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Memoria interna"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Archivio esterno"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Archiviazione locale"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Memoria interna"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documenti"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-iw/strings.xml b/packages/ExternalStorageProvider/res/values-iw/strings.xml
index f98f439..3027a40 100644
--- a/packages/ExternalStorageProvider/res/values-iw/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-iw/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"אחסון חיצוני"</string>
- <string name="storage_description" msgid="8541974407321172792">"אחסון מקומי"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"אחסון פנימי"</string>
- <string name="root_documents" msgid="4051252304075469250">"מסמכים"</string>
+ <string name="app_label" msgid="748293919008814871">"אחסון חיצוני"</string>
+ <string name="storage_description" msgid="9176081505553938524">"אחסון מקומי"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"אחסון פנימי"</string>
+ <string name="root_documents" msgid="5695037589229175941">"מסמכים"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ja/strings.xml b/packages/ExternalStorageProvider/res/values-ja/strings.xml
index c1623d4..ad04123 100644
--- a/packages/ExternalStorageProvider/res/values-ja/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ja/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"外部ストレージ"</string>
- <string name="storage_description" msgid="8541974407321172792">"ローカル ストレージ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"内部ストレージ"</string>
- <string name="root_documents" msgid="4051252304075469250">"ドキュメント"</string>
+ <string name="app_label" msgid="748293919008814871">"外部ストレージ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ローカル ストレージ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"内部ストレージ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ドキュメント"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ka/strings.xml b/packages/ExternalStorageProvider/res/values-ka/strings.xml
index 3886efa..e320aca 100644
--- a/packages/ExternalStorageProvider/res/values-ka/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ka/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"გარე მეხსიერება"</string>
- <string name="storage_description" msgid="8541974407321172792">"ადგილობრივი მეხსიერება"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"შიდა მეხსიერება"</string>
- <string name="root_documents" msgid="4051252304075469250">"დოკუმენტები"</string>
+ <string name="app_label" msgid="748293919008814871">"გარე მეხსიერება"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ადგილობრივი მეხსიერება"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"შიდა მეხსიერება"</string>
+ <string name="root_documents" msgid="5695037589229175941">"დოკუმენტები"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-kk/strings.xml b/packages/ExternalStorageProvider/res/values-kk/strings.xml
index f6ad94d..825b2d1 100644
--- a/packages/ExternalStorageProvider/res/values-kk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-kk/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Сыртқы жад"</string>
- <string name="storage_description" msgid="8541974407321172792">"Жергілікті жад"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Ішкі жад"</string>
- <string name="root_documents" msgid="4051252304075469250">"Құжаттар"</string>
+ <string name="app_label" msgid="748293919008814871">"Сыртқы жад"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Жергілікті жад"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Ішкі жад"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Құжаттар"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-km/strings.xml b/packages/ExternalStorageProvider/res/values-km/strings.xml
index a2bb928..cd87a055 100644
--- a/packages/ExternalStorageProvider/res/values-km/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-km/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ឧបករណ៍ផ្ទុកខាងក្រៅ"</string>
- <string name="storage_description" msgid="8541974407321172792">"ទំហំផ្ទុកមូលដ្ឋាន"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ឧបករណ៍ផ្ទុកខាងក្នុង"</string>
- <string name="root_documents" msgid="4051252304075469250">"ឯកសារ"</string>
+ <string name="app_label" msgid="748293919008814871">"ឧបករណ៍ផ្ទុកខាងក្រៅ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ទំហំផ្ទុកមូលដ្ឋាន"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ឧបករណ៍ផ្ទុកខាងក្នុង"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ឯកសារ"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-kn/strings.xml b/packages/ExternalStorageProvider/res/values-kn/strings.xml
index 2883e06..fe35079 100644
--- a/packages/ExternalStorageProvider/res/values-kn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-kn/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆ"</string>
- <string name="storage_description" msgid="8541974407321172792">"ಸ್ಥಳೀಯ ಸಂಗ್ರಹಣೆ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆ"</string>
- <string name="root_documents" msgid="4051252304075469250">"ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
+ <string name="app_label" msgid="748293919008814871">"ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ಸ್ಥಳೀಯ ಸಂಗ್ರಹಣೆ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ko/strings.xml b/packages/ExternalStorageProvider/res/values-ko/strings.xml
index 1fa3189..6a255eb 100644
--- a/packages/ExternalStorageProvider/res/values-ko/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ko/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"외부 저장소"</string>
- <string name="storage_description" msgid="8541974407321172792">"로컬 저장소"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"내부 저장소"</string>
- <string name="root_documents" msgid="4051252304075469250">"문서"</string>
+ <string name="app_label" msgid="748293919008814871">"외부 저장소"</string>
+ <string name="storage_description" msgid="9176081505553938524">"로컬 저장소"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"내부 저장소"</string>
+ <string name="root_documents" msgid="5695037589229175941">"문서"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ky/strings.xml b/packages/ExternalStorageProvider/res/values-ky/strings.xml
index e7e34cb..d11daec 100644
--- a/packages/ExternalStorageProvider/res/values-ky/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ky/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Тышкы сактагыч"</string>
- <string name="storage_description" msgid="8541974407321172792">"Жергиликтүү сактагыч"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Ички сактагыч"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документтер"</string>
+ <string name="app_label" msgid="748293919008814871">"Тышкы сактагыч"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Жергиликтүү сактагыч"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Ички сактагыч"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документтер"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lo/strings.xml b/packages/ExternalStorageProvider/res/values-lo/strings.xml
index ba344e3..26f7a6e 100644
--- a/packages/ExternalStorageProvider/res/values-lo/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lo/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ"</string>
- <string name="storage_description" msgid="8541974407321172792">"ບ່ອນຈັດເກັບຂໍ້ມູນໃນເຄື່ອງ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
- <string name="root_documents" msgid="4051252304075469250">"ເອກະສານ"</string>
+ <string name="app_label" msgid="748293919008814871">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ບ່ອນຈັດເກັບຂໍ້ມູນໃນເຄື່ອງ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ເອກະສານ"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lt/strings.xml b/packages/ExternalStorageProvider/res/values-lt/strings.xml
index a345673..beca24e 100644
--- a/packages/ExternalStorageProvider/res/values-lt/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lt/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Išorinė atmintinė"</string>
- <string name="storage_description" msgid="8541974407321172792">"Vietinė saugykla"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Vidinė atmintinė"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumentai"</string>
+ <string name="app_label" msgid="748293919008814871">"Išorinė atmintinė"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Vietinė saugykla"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Vidinė atmintinė"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumentai"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lv/strings.xml b/packages/ExternalStorageProvider/res/values-lv/strings.xml
index a3a3ed8..9e362c4 100644
--- a/packages/ExternalStorageProvider/res/values-lv/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lv/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Ārējā krātuve"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokālā krātuve"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Iekšējā atmiņa"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Ārējā krātuve"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokālā krātuve"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Iekšējā atmiņa"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-mk/strings.xml b/packages/ExternalStorageProvider/res/values-mk/strings.xml
index 5ebf8a6..76c6d91 100644
--- a/packages/ExternalStorageProvider/res/values-mk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mk/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Надворешна меморија"</string>
- <string name="storage_description" msgid="8541974407321172792">"Локална меморија"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Внатрешен капацитет"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+ <string name="app_label" msgid="748293919008814871">"Надворешна меморија"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Локална меморија"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Внатрешен капацитет"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ml/strings.xml b/packages/ExternalStorageProvider/res/values-ml/strings.xml
index 2f88c79..fab3f16 100644
--- a/packages/ExternalStorageProvider/res/values-ml/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ml/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ബാഹ്യ സ്റ്റോറേജ്"</string>
- <string name="storage_description" msgid="8541974407321172792">"ലോക്കൽ സ്റ്റോറേജ്"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ആന്തരിക സ്റ്റോറേജ്"</string>
- <string name="root_documents" msgid="4051252304075469250">"പ്രമാണങ്ങൾ"</string>
+ <string name="app_label" msgid="748293919008814871">"ബാഹ്യ സ്റ്റോറേജ്"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ലോക്കൽ സ്റ്റോറേജ്"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ആന്തരിക സ്റ്റോറേജ്"</string>
+ <string name="root_documents" msgid="5695037589229175941">"പ്രമാണങ്ങൾ"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-mn/strings.xml b/packages/ExternalStorageProvider/res/values-mn/strings.xml
index afd5d64..e227b7e 100644
--- a/packages/ExternalStorageProvider/res/values-mn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mn/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Гадаад сан"</string>
- <string name="storage_description" msgid="8541974407321172792">"Дотоод сан"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Дотоод сан"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документүүд"</string>
+ <string name="app_label" msgid="748293919008814871">"Гадаад сан"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Дотоод сан"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Дотоод сан"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документүүд"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-mr/strings.xml b/packages/ExternalStorageProvider/res/values-mr/strings.xml
index 7927440..3059610 100644
--- a/packages/ExternalStorageProvider/res/values-mr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mr/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"बाह्य संचयन"</string>
- <string name="storage_description" msgid="8541974407321172792">"स्थानिक स्टोरेज"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"अंतर्गत स्टोरेज"</string>
- <string name="root_documents" msgid="4051252304075469250">"दस्तऐवज"</string>
+ <string name="app_label" msgid="748293919008814871">"बाह्य संचयन"</string>
+ <string name="storage_description" msgid="9176081505553938524">"स्थानिक स्टोरेज"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"अंतर्गत स्टोरेज"</string>
+ <string name="root_documents" msgid="5695037589229175941">"दस्तऐवज"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ms/strings.xml b/packages/ExternalStorageProvider/res/values-ms/strings.xml
index 4196acd..ebc3ce2 100644
--- a/packages/ExternalStorageProvider/res/values-ms/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ms/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Storan Luaran"</string>
- <string name="storage_description" msgid="8541974407321172792">"Storan setempat"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Storan dalaman"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumen"</string>
+ <string name="app_label" msgid="748293919008814871">"Storan Luaran"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Storan setempat"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Storan dalaman"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumen"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-my/strings.xml b/packages/ExternalStorageProvider/res/values-my/strings.xml
index 1c7a276..6078194 100644
--- a/packages/ExternalStorageProvider/res/values-my/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-my/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ပြင်ပသိုလှောင်ရာပစ္စည်း"</string>
- <string name="storage_description" msgid="8541974407321172792">"စက်တွင်း သိုလှောင်ခန်း"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"စက်တွင်း သိုလှောင်ထားမှု"</string>
- <string name="root_documents" msgid="4051252304075469250">"စာရွက်စာတန်းများ"</string>
+ <string name="app_label" msgid="748293919008814871">"ပြင်ပသိုလှောင်ရာပစ္စည်း"</string>
+ <string name="storage_description" msgid="9176081505553938524">"စက်တွင်း သိုလှောင်ခန်း"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"စက်တွင်း သိုလှောင်ထားမှု"</string>
+ <string name="root_documents" msgid="5695037589229175941">"စာရွက်စာတန်းများ"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-nb/strings.xml b/packages/ExternalStorageProvider/res/values-nb/strings.xml
index 979cb30..1992f72 100644
--- a/packages/ExternalStorageProvider/res/values-nb/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-nb/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Ekstern lagring"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokal lagring"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenter"</string>
+ <string name="app_label" msgid="748293919008814871">"Ekstern lagring"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokal lagring"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Intern lagring"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenter"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ne/strings.xml b/packages/ExternalStorageProvider/res/values-ne/strings.xml
index bbe9c42..bc8871c 100644
--- a/packages/ExternalStorageProvider/res/values-ne/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ne/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"बाह्य भण्डारण"</string>
- <string name="storage_description" msgid="8541974407321172792">"स्थानीय भण्डारण"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"आन्तरिक भण्डारण"</string>
- <string name="root_documents" msgid="4051252304075469250">"कागजातहरू"</string>
+ <string name="app_label" msgid="748293919008814871">"बाह्य भण्डारण"</string>
+ <string name="storage_description" msgid="9176081505553938524">"स्थानीय भण्डारण"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"आन्तरिक भण्डारण"</string>
+ <string name="root_documents" msgid="5695037589229175941">"कागजातहरू"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-nl/strings.xml b/packages/ExternalStorageProvider/res/values-nl/strings.xml
index cea2e9c..455ea50 100644
--- a/packages/ExternalStorageProvider/res/values-nl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-nl/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Externe opslag"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokale opslag"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interne opslag"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documenten"</string>
+ <string name="app_label" msgid="748293919008814871">"Externe opslag"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokale opslag"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interne opslag"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documenten"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-or/strings.xml b/packages/ExternalStorageProvider/res/values-or/strings.xml
index 5387dc7..ba9b811 100644
--- a/packages/ExternalStorageProvider/res/values-or/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-or/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ଏକ୍ସଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍"</string>
- <string name="storage_description" msgid="8541974407321172792">"ଲୋକାଲ୍ ଷ୍ଟୋରେଜ୍"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ଇଣ୍ଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍"</string>
- <string name="root_documents" msgid="4051252304075469250">"ଡକ୍ୟୁମେଣ୍ଟ"</string>
+ <string name="app_label" msgid="748293919008814871">"ଏକ୍ସଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ଲୋକାଲ୍ ଷ୍ଟୋରେଜ୍"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ଇଣ୍ଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ଡକ୍ୟୁମେଣ୍ଟ"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pa/strings.xml b/packages/ExternalStorageProvider/res/values-pa/strings.xml
index 4e9d777..becd075 100644
--- a/packages/ExternalStorageProvider/res/values-pa/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pa/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ਬਾਹਰੀ ਸਟੋਰੇਜ"</string>
- <string name="storage_description" msgid="8541974407321172792">"ਸਥਾਨਕ ਸਟੋਰੇਜ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ"</string>
- <string name="root_documents" msgid="4051252304075469250">"ਦਸਤਾਵੇਜ਼"</string>
+ <string name="app_label" msgid="748293919008814871">"ਬਾਹਰੀ ਸਟੋਰੇਜ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"ਸਥਾਨਕ ਸਟੋਰੇਜ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ਦਸਤਾਵੇਜ਼"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pl/strings.xml b/packages/ExternalStorageProvider/res/values-pl/strings.xml
index f710bad..885f25c 100644
--- a/packages/ExternalStorageProvider/res/values-pl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pl/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Pamięć zewnętrzna"</string>
- <string name="storage_description" msgid="8541974407321172792">"Pamięć lokalna"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Pamięć wewnętrzna"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+ <string name="app_label" msgid="748293919008814871">"Pamięć zewnętrzna"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Pamięć lokalna"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Pamięć wewnętrzna"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenty"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
index 96046ad..aa745f1 100644
--- a/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
- <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+ <string name="app_label" msgid="748293919008814871">"Armazenamento externo"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Armazenamento local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Armazenamento interno"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
index 35de8ef..9683b4c 100644
--- a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
- <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
- <string name="root_documents" msgid="4051252304075469250">"Docs"</string>
+ <string name="app_label" msgid="748293919008814871">"Armazenamento externo"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Armazenamento local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Armazenamento interno"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Docs"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt/strings.xml b/packages/ExternalStorageProvider/res/values-pt/strings.xml
index 96046ad..aa745f1 100644
--- a/packages/ExternalStorageProvider/res/values-pt/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
- <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+ <string name="app_label" msgid="748293919008814871">"Armazenamento externo"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Armazenamento local"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Armazenamento interno"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ro/strings.xml b/packages/ExternalStorageProvider/res/values-ro/strings.xml
index aaa9e41..d060654 100644
--- a/packages/ExternalStorageProvider/res/values-ro/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ro/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Stocare externă"</string>
- <string name="storage_description" msgid="8541974407321172792">"Stocare locală"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Stocare internă"</string>
- <string name="root_documents" msgid="4051252304075469250">"Documente"</string>
+ <string name="app_label" msgid="748293919008814871">"Stocare externă"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Stocare locală"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Stocare internă"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Documente"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ru/strings.xml b/packages/ExternalStorageProvider/res/values-ru/strings.xml
index 222532f..55a7550 100644
--- a/packages/ExternalStorageProvider/res/values-ru/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ru/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Внешний накопитель"</string>
- <string name="storage_description" msgid="8541974407321172792">"Локальное хранилище"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Внутренний накопитель"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документы"</string>
+ <string name="app_label" msgid="748293919008814871">"Внешний накопитель"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Локальное хранилище"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Внутренний накопитель"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документы"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-si/strings.xml b/packages/ExternalStorageProvider/res/values-si/strings.xml
index 1adebec..deaa65f 100644
--- a/packages/ExternalStorageProvider/res/values-si/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-si/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"බාහිර ආචයනය"</string>
- <string name="storage_description" msgid="8541974407321172792">"පෙදෙසි ආචයනය"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"අභ්යන්තර ආචයනය"</string>
- <string name="root_documents" msgid="4051252304075469250">"ලේඛන"</string>
+ <string name="app_label" msgid="748293919008814871">"බාහිර ආචයනය"</string>
+ <string name="storage_description" msgid="9176081505553938524">"පෙදෙසි ආචයනය"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"අභ්යන්තර ආචයනය"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ලේඛන"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sk/strings.xml b/packages/ExternalStorageProvider/res/values-sk/strings.xml
index f94a726..b51210f 100644
--- a/packages/ExternalStorageProvider/res/values-sk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sk/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Externý ukladací priestor"</string>
- <string name="storage_description" msgid="8541974407321172792">"Miestne úložisko"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Interné úložisko"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+ <string name="app_label" msgid="748293919008814871">"Externý ukladací priestor"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Miestne úložisko"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Interné úložisko"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenty"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sl/strings.xml b/packages/ExternalStorageProvider/res/values-sl/strings.xml
index 7992e97..262c2b7 100644
--- a/packages/ExternalStorageProvider/res/values-sl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sl/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Zunanja shramba"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokalna shramba"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Notranja shramba"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Zunanja shramba"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokalna shramba"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Notranja shramba"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sq/strings.xml b/packages/ExternalStorageProvider/res/values-sq/strings.xml
index f73cff1..2a5c557 100644
--- a/packages/ExternalStorageProvider/res/values-sq/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sq/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Hapësirë e jashtme ruajtjeje"</string>
- <string name="storage_description" msgid="8541974407321172792">"Hapësira ruajtëse lokale"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Hapësira e brendshme ruajtëse"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+ <string name="app_label" msgid="748293919008814871">"Hapësirë e jashtme ruajtjeje"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Hapësira ruajtëse lokale"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Hapësira e brendshme ruajtëse"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokumente"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sr/strings.xml b/packages/ExternalStorageProvider/res/values-sr/strings.xml
index 6a7be4c..b44ce18 100644
--- a/packages/ExternalStorageProvider/res/values-sr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sr/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Спољна меморија"</string>
- <string name="storage_description" msgid="8541974407321172792">"Локални меморијски простор"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Интерна меморија"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+ <string name="app_label" msgid="748293919008814871">"Спољна меморија"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Локални меморијски простор"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Интерна меморија"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sv/strings.xml b/packages/ExternalStorageProvider/res/values-sv/strings.xml
index 103e830..11afb19 100644
--- a/packages/ExternalStorageProvider/res/values-sv/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sv/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Extern lagring"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokal lagring"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokument"</string>
+ <string name="app_label" msgid="748293919008814871">"Extern lagring"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokal lagring"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Intern lagring"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokument"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sw/strings.xml b/packages/ExternalStorageProvider/res/values-sw/strings.xml
index fec928c..94231ff 100644
--- a/packages/ExternalStorageProvider/res/values-sw/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sw/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Hifadhi ya Nje"</string>
- <string name="storage_description" msgid="8541974407321172792">"Hifadhi ya ndani"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Hifadhi ya ndani"</string>
- <string name="root_documents" msgid="4051252304075469250">"Hati"</string>
+ <string name="app_label" msgid="748293919008814871">"Hifadhi ya Nje"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Hifadhi ya ndani"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Hifadhi ya ndani"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Hati"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ta/strings.xml b/packages/ExternalStorageProvider/res/values-ta/strings.xml
index 5d56940..1f25d9e 100644
--- a/packages/ExternalStorageProvider/res/values-ta/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ta/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"வெளிப்புறச் சேமிப்பிடம்"</string>
- <string name="storage_description" msgid="8541974407321172792">"சாதனச் சேமிப்பகம்"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"அகச் சேமிப்பிடம்"</string>
- <string name="root_documents" msgid="4051252304075469250">"ஆவணங்கள்"</string>
+ <string name="app_label" msgid="748293919008814871">"வெளிப்புறச் சேமிப்பிடம்"</string>
+ <string name="storage_description" msgid="9176081505553938524">"சாதனச் சேமிப்பகம்"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"அகச் சேமிப்பிடம்"</string>
+ <string name="root_documents" msgid="5695037589229175941">"ஆவணங்கள்"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-te/strings.xml b/packages/ExternalStorageProvider/res/values-te/strings.xml
index 97ca29d..773ae0e 100644
--- a/packages/ExternalStorageProvider/res/values-te/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-te/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"బాహ్య నిల్వ"</string>
- <string name="storage_description" msgid="8541974407321172792">"స్థానిక నిల్వ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"అంతర్గత నిల్వ"</string>
- <string name="root_documents" msgid="4051252304075469250">"పత్రాలు"</string>
+ <string name="app_label" msgid="748293919008814871">"బాహ్య నిల్వ"</string>
+ <string name="storage_description" msgid="9176081505553938524">"స్థానిక నిల్వ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"అంతర్గత నిల్వ"</string>
+ <string name="root_documents" msgid="5695037589229175941">"పత్రాలు"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-th/strings.xml b/packages/ExternalStorageProvider/res/values-th/strings.xml
index 3a3304f..570a91a 100644
--- a/packages/ExternalStorageProvider/res/values-th/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-th/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"ที่จัดเก็บข้อมูลภายนอก"</string>
- <string name="storage_description" msgid="8541974407321172792">"พื้นที่เก็บข้อมูลในเครื่อง"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"ที่จัดเก็บข้อมูลภายใน"</string>
- <string name="root_documents" msgid="4051252304075469250">"เอกสาร"</string>
+ <string name="app_label" msgid="748293919008814871">"ที่จัดเก็บข้อมูลภายนอก"</string>
+ <string name="storage_description" msgid="9176081505553938524">"พื้นที่เก็บข้อมูลในเครื่อง"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"ที่จัดเก็บข้อมูลภายใน"</string>
+ <string name="root_documents" msgid="5695037589229175941">"เอกสาร"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-tl/strings.xml b/packages/ExternalStorageProvider/res/values-tl/strings.xml
index 7b66436d6..0a35373 100644
--- a/packages/ExternalStorageProvider/res/values-tl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-tl/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
- <string name="storage_description" msgid="8541974407321172792">"Lokal na storage"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
- <string name="root_documents" msgid="4051252304075469250">"Mga Dokumento"</string>
+ <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Lokal na storage"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Mga Dokumento"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-tr/strings.xml b/packages/ExternalStorageProvider/res/values-tr/strings.xml
index 39cd4da..2e35805 100644
--- a/packages/ExternalStorageProvider/res/values-tr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-tr/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Harici Depolama"</string>
- <string name="storage_description" msgid="8541974407321172792">"Yerel depolama"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Dahili depolama"</string>
- <string name="root_documents" msgid="4051252304075469250">"Dokümanlar"</string>
+ <string name="app_label" msgid="748293919008814871">"Harici Depolama"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Yerel depolama"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Dahili depolama"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Dokümanlar"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-uk/strings.xml b/packages/ExternalStorageProvider/res/values-uk/strings.xml
index 25acf03..f01ad81 100644
--- a/packages/ExternalStorageProvider/res/values-uk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-uk/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Зовнішня пам’ять"</string>
- <string name="storage_description" msgid="8541974407321172792">"Локальна пам’ять"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Внутрішня пам’ять"</string>
- <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+ <string name="app_label" msgid="748293919008814871">"Зовнішня пам’ять"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Локальна пам’ять"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Внутрішня пам’ять"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ur/strings.xml b/packages/ExternalStorageProvider/res/values-ur/strings.xml
index c22afd9..1aafdd9 100644
--- a/packages/ExternalStorageProvider/res/values-ur/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ur/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"بیرونی اسٹوریج"</string>
- <string name="storage_description" msgid="8541974407321172792">"مقامی اسٹوریج"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"داخلی اسٹوریج"</string>
- <string name="root_documents" msgid="4051252304075469250">"دستاویزات"</string>
+ <string name="app_label" msgid="748293919008814871">"بیرونی اسٹوریج"</string>
+ <string name="storage_description" msgid="9176081505553938524">"مقامی اسٹوریج"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"داخلی اسٹوریج"</string>
+ <string name="root_documents" msgid="5695037589229175941">"دستاویزات"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-uz/strings.xml b/packages/ExternalStorageProvider/res/values-uz/strings.xml
index 48f8fed..87ab668 100644
--- a/packages/ExternalStorageProvider/res/values-uz/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-uz/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Tashqi xotira"</string>
- <string name="storage_description" msgid="8541974407321172792">"Mahalliy xotira"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Ichki xotira"</string>
- <string name="root_documents" msgid="4051252304075469250">"Hujjatlar"</string>
+ <string name="app_label" msgid="748293919008814871">"Tashqi xotira"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Mahalliy xotira"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Ichki xotira"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Hujjatlar"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-vi/strings.xml b/packages/ExternalStorageProvider/res/values-vi/strings.xml
index f7479c0..e898d2c 100644
--- a/packages/ExternalStorageProvider/res/values-vi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-vi/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Bộ nhớ ngoài"</string>
- <string name="storage_description" msgid="8541974407321172792">"Bộ nhớ cục bộ"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Bộ nhớ trong"</string>
- <string name="root_documents" msgid="4051252304075469250">"Tài liệu"</string>
+ <string name="app_label" msgid="748293919008814871">"Bộ nhớ ngoài"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Bộ nhớ cục bộ"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Bộ nhớ trong"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Tài liệu"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
index aa6789f..5be6132 100644
--- a/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"外部存储设备"</string>
- <string name="storage_description" msgid="8541974407321172792">"本地存储空间"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"内部存储空间"</string>
- <string name="root_documents" msgid="4051252304075469250">"文档"</string>
+ <string name="app_label" msgid="748293919008814871">"外部存储设备"</string>
+ <string name="storage_description" msgid="9176081505553938524">"本地存储空间"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"内部存储空间"</string>
+ <string name="root_documents" msgid="5695037589229175941">"文档"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
index 3458c64..1671796 100644
--- a/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"外部儲存空間"</string>
- <string name="storage_description" msgid="8541974407321172792">"本機儲存空間"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"內部儲存空間"</string>
- <string name="root_documents" msgid="4051252304075469250">"文件"</string>
+ <string name="app_label" msgid="748293919008814871">"外部儲存空間"</string>
+ <string name="storage_description" msgid="9176081505553938524">"本機儲存空間"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"內部儲存空間"</string>
+ <string name="root_documents" msgid="5695037589229175941">"文件"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
index 3458c64..1671796 100644
--- a/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"外部儲存空間"</string>
- <string name="storage_description" msgid="8541974407321172792">"本機儲存空間"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"內部儲存空間"</string>
- <string name="root_documents" msgid="4051252304075469250">"文件"</string>
+ <string name="app_label" msgid="748293919008814871">"外部儲存空間"</string>
+ <string name="storage_description" msgid="9176081505553938524">"本機儲存空間"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"內部儲存空間"</string>
+ <string name="root_documents" msgid="5695037589229175941">"文件"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zu/strings.xml b/packages/ExternalStorageProvider/res/values-zu/strings.xml
index 96f454b..3878591 100644
--- a/packages/ExternalStorageProvider/res/values-zu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zu/strings.xml
@@ -16,8 +16,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"Isitoreji sangaphandle"</string>
- <string name="storage_description" msgid="8541974407321172792">"Isitoreji sasendaweni"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"Isitoreji sangaphakathi"</string>
- <string name="root_documents" msgid="4051252304075469250">"Amadokhumenti"</string>
+ <string name="app_label" msgid="748293919008814871">"Isitoreji sangaphandle"</string>
+ <string name="storage_description" msgid="9176081505553938524">"Isitoreji sasendaweni"</string>
+ <string name="root_internal_storage" msgid="4980477711224234931">"Isitoreji sangaphakathi"</string>
+ <string name="root_documents" msgid="5695037589229175941">"Amadokhumenti"</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 0d972c5..e660e43 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -150,7 +150,7 @@
context.getContentResolver().takePersistableUriPermission(iconUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
} catch (SecurityException e) {
- Log.e(TAG, "Failed to take persistable permission for: " + iconUri);
+ Log.e(TAG, "Failed to take persistable permission for: " + iconUri, e);
}
try {
final Bitmap bitmap = MediaStore.Images.Media.getBitmap(
@@ -165,6 +165,8 @@
}
} catch (IOException e) {
Log.e(TAG, "Failed to get drawable for: " + iconUri, e);
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to get permission for: " + iconUri, e);
}
}
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b288eb7..cd64a388 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -60,6 +60,9 @@
<uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
<uses-permission android:name="android.permission.USE_RESERVED_DISK" />
+ <!-- to invoke ContentSuggestionsService -->
+ <uses-permission android:name="android.permission.MANAGE_CONTENT_SUGGESTIONS"/>
+
<!-- Networking and telephony -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 795a8ce3..c2d090e 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -15,12 +15,14 @@
package com.android.systemui;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.SparseArray;
import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.appops.AppOpsController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -33,14 +35,21 @@
*/
@Singleton
public class ForegroundServiceController {
+ private static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
+ AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+ AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_COARSE_LOCATION,
+ AppOpsManager.OP_FINE_LOCATION};
private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
private final Object mMutex = new Object();
private final NotificationEntryManager mEntryManager;
@Inject
- public ForegroundServiceController(NotificationEntryManager entryManager) {
+ public ForegroundServiceController(NotificationEntryManager entryManager,
+ AppOpsController appOpsController) {
mEntryManager = entryManager;
+ appOpsController.addCallback(APP_OPS, this::onAppOpChanged);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 0a547b6..0d400fe 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -33,6 +33,7 @@
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
@@ -42,7 +43,6 @@
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import dagger.Module;
@@ -119,9 +119,13 @@
return mRootComponent;
}
- public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
- ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
- return new StatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
+ /**
+ * Creates an instance of ScreenshotNotificationSmartActionsProvider.
+ * This method is overridden in vendor specific implementation of Sys UI.
+ */
+ public ScreenshotNotificationSmartActionsProvider
+ createScreenshotNotificationSmartActionsProvider() {
+ return new ScreenshotNotificationSmartActionsProvider();
}
public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback,
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index 24357a7..d50666c 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -27,6 +27,8 @@
import android.util.ArrayMap
import android.util.ArraySet
import android.util.Log
+import androidx.annotation.MainThread
+import com.android.internal.util.Preconditions
import com.android.systemui.Dumpable
import java.io.FileDescriptor
import java.io.PrintWriter
@@ -72,7 +74,14 @@
internal fun isRegistered() = registered.get()
- private val registerReceiver = Runnable {
+ // Only modify in BG thread
+ private val actionsToReceivers = ArrayMap<String, MutableSet<ReceiverData>>()
+ private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
+
+ // Only call on BG thread as it reads from the maps
+ private fun createFilter(): IntentFilter {
+ Preconditions.checkState(bgHandler.looper.isCurrentThread,
+ "This method should only be called from BG thread")
val categories = mutableSetOf<String>()
receiverToReceiverData.values.flatten().forEach {
it.filter.categoriesIterator()?.asSequence()?.let {
@@ -80,30 +89,13 @@
}
}
val intentFilter = IntentFilter().apply {
- actionsToReceivers.keys.forEach { addAction(it) }
+ // The keys of the arrayMap are of type String! so null check is needed
+ actionsToReceivers.keys.forEach { if (it != null) addAction(it) else Unit }
categories.forEach { addCategory(it) }
}
-
- if (registered.get()) {
- context.unregisterReceiver(this)
- registered.set(false)
- }
- // Short interval without receiver, this can be problematic
- if (intentFilter.countActions() > 0 && !registered.get()) {
- context.registerReceiverAsUser(
- this,
- UserHandle.of(userId),
- intentFilter,
- null,
- bgHandler)
- registered.set(true)
- }
+ return intentFilter
}
- // Only modify in BG thread
- private val actionsToReceivers = ArrayMap<String, MutableSet<ReceiverData>>()
- private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
-
override fun onReceive(context: Context, intent: Intent) {
val id = if (DEBUG) index.getAndIncrement() else 0
if (DEBUG) Log.w(TAG, "[$id] Received $intent")
@@ -126,6 +118,8 @@
}
private fun handleRegisterReceiver(receiverData: ReceiverData) {
+ Preconditions.checkState(bgHandler.looper.isCurrentThread,
+ "This method should only be called from BG thread")
if (DEBUG) Log.w(TAG, "Register receiver: ${receiverData.receiver}")
receiverToReceiverData.getOrPut(receiverData.receiver, { ArraySet() }).add(receiverData)
var changed = false
@@ -138,11 +132,13 @@
}.add(receiverData)
}
if (changed) {
- mainHandler.post(registerReceiver)
+ createFilterAndRegisterReceiverBG()
}
}
private fun handleUnregisterReceiver(receiver: BroadcastReceiver) {
+ Preconditions.checkState(bgHandler.looper.isCurrentThread,
+ "This method should only be called from BG thread")
if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
val actions = receiverToReceiverData.getOrElse(receiver) { return }
.flatMap { it.filter.actionsIterator().asSequence().asIterable() }.toSet()
@@ -156,10 +152,16 @@
}
}
if (changed) {
- mainHandler.post(registerReceiver)
+ createFilterAndRegisterReceiverBG()
}
}
+ // Only call this from a BG thread
+ private fun createFilterAndRegisterReceiverBG() {
+ val intentFilter = createFilter()
+ mainHandler.post(RegisterReceiverRunnable(intentFilter))
+ }
+
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
pw.println(" Registered=${registered.get()}")
actionsToReceivers.forEach { (action, list) ->
@@ -191,4 +193,30 @@
}
}
}
+
+ private inner class RegisterReceiverRunnable(val intentFilter: IntentFilter) : Runnable {
+
+ /*
+ * Registers and unregisters the BroadcastReceiver
+ *
+ * Must be called from Main Thread
+ */
+ @MainThread
+ override fun run() {
+ if (registered.get()) {
+ context.unregisterReceiver(this@UserBroadcastDispatcher)
+ registered.set(false)
+ }
+ // Short interval without receiver, this can be problematic
+ if (intentFilter.countActions() > 0 && !registered.get()) {
+ context.registerReceiverAsUser(
+ this@UserBroadcastDispatcher,
+ UserHandle.of(userId),
+ intentFilter,
+ null,
+ bgHandler)
+ registered.set(true)
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 6d61b2f..741c95f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -35,12 +35,14 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.BgHandler;
import com.android.systemui.dagger.qualifiers.BgLooper;
import com.android.systemui.dagger.qualifiers.MainHandler;
import com.android.systemui.dagger.qualifiers.MainLooper;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.PluginInitializerImpl;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
@@ -249,4 +251,10 @@
public UserManager providesUserManager(Context context) {
return context.getSystemService(UserManager.class);
}
+
+ /** */
+ @Provides
+ public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
+ return viewMediator.getViewMediatorCallback();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 9f54937..3cf14d6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -28,6 +28,8 @@
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.shortcut.ShortcutKeyDispatcher;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.notification.InstantAppNotifier;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarModule;
@@ -52,11 +54,17 @@
@ClassKey(AuthController.class)
public abstract SystemUI bindAuthController(AuthController service);
+ /** Inject into Divider. */
+ @Binds
+ @IntoMap
+ @ClassKey(Divider.class)
+ public abstract SystemUI bindDivider(Divider sysui);
+
/** Inject into GarbageMonitor.Service. */
@Binds
@IntoMap
@ClassKey(GarbageMonitor.Service.class)
- public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service service);
+ public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);
/** Inject into GlobalActionsComponent. */
@Binds
@@ -106,6 +114,12 @@
@ClassKey(ScreenDecorations.class)
public abstract SystemUI bindScreenDecorations(ScreenDecorations sysui);
+ /** Inject into ShortcutKeyDispatcher. */
+ @Binds
+ @IntoMap
+ @ClassKey(ShortcutKeyDispatcher.class)
+ public abstract SystemUI bindsShortcutKeyDispatcher(ShortcutKeyDispatcher sysui);
+
/** Inject into SizeCompatModeActivityController. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 7b8d3bc..f86aaf1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -19,12 +19,18 @@
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
+import android.content.Context;
+
import androidx.annotation.Nullable;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsImplementation;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
import com.android.systemui.statusbar.notification.collection.NotificationData;
@@ -77,4 +83,17 @@
static boolean provideAllowNotificationLongPress() {
return true;
}
+
+ @Singleton
+ @Provides
+ static Divider provideDivider(Context context) {
+ return new Divider(context);
+ }
+
+ @Provides
+ @Singleton
+ static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
+ CommandQueue commandQueue) {
+ return new Recents(context, recentsImplementation, commandQueue);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index b3a5181..6ae21b3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -25,6 +25,8 @@
import com.android.systemui.assist.AssistModule;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
@@ -75,5 +77,11 @@
abstract CommandQueue optionalCommandQueue();
@BindsOptionalOf
+ abstract Divider optionalDivider();
+
+ @BindsOptionalOf
+ abstract Recents optionalRecents();
+
+ @BindsOptionalOf
abstract StatusBar optionalStatusBar();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
index 7bec5c0..25ac8f8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
@@ -22,14 +22,21 @@
import java.util.ArrayList;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* Registry holding the current set of {@link IKeyguardDismissCallback}s.
*/
+@Singleton
public class DismissCallbackRegistry {
private final ArrayList<DismissCallbackWrapper> mDismissCallbacks = new ArrayList<>();
private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
+ @Inject
+ public DismissCallbackRegistry() {}
+
public void addCallback(IKeyguardDismissCallback callback) {
mDismissCallbacks.add(new DismissCallbackWrapper(callback));
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 3b1edcc..c876fa6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -68,7 +68,6 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -104,6 +103,8 @@
import javax.inject.Inject;
import javax.inject.Singleton;
+import dagger.Lazy;
+
/**
* Mediates requests related to the keyguard. This includes queries about the
* state of the keyguard, power management events that effect whether the keyguard
@@ -236,7 +237,7 @@
*/
private PowerManager.WakeLock mShowKeyguardWakeLock;
- private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final Lazy<StatusBarKeyguardViewManager> mStatusBarKeyguardViewManagerLazy;
// these are protected by synchronized (this)
@@ -282,7 +283,7 @@
* var being non-null as an indicator that there is an in progress request.
*/
private IKeyguardExitCallback mExitSecureCallback;
- private final DismissCallbackRegistry mDismissCallbackRegistry = new DismissCallbackRegistry();
+ private final DismissCallbackRegistry mDismissCallbackRegistry;
// the properties of the keyguard
@@ -587,7 +588,7 @@
@Override
public void setNeedsInput(boolean needsInput) {
- mStatusBarKeyguardViewManager.setNeedsInput(needsInput);
+ mStatusBarKeyguardViewManagerLazy.get().setNeedsInput(needsInput);
}
@Override
@@ -601,7 +602,8 @@
mKeyguardDonePending = true;
mHideAnimationRun = true;
mHideAnimationRunning = true;
- mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
+ mStatusBarKeyguardViewManagerLazy.get()
+ .startPreHideAnimation(mHideAnimationFinishedRunnable);
mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
KEYGUARD_DONE_PENDING_TIMEOUT_MS);
Trace.endSection();
@@ -631,7 +633,7 @@
@Override
public void onCancelClicked() {
- mStatusBarKeyguardViewManager.onCancelClicked();
+ mStatusBarKeyguardViewManagerLazy.get().onCancelClicked();
}
@Override
@@ -688,26 +690,15 @@
Context context,
FalsingManager falsingManager,
LockPatternUtils lockPatternUtils,
- BroadcastDispatcher broadcastDispatcher) {
- this(context, falsingManager, lockPatternUtils, broadcastDispatcher,
- SystemUIFactory.getInstance());
- }
-
- @VisibleForTesting
- KeyguardViewMediator(
- Context context,
- FalsingManager falsingManager,
- LockPatternUtils lockPatternUtils,
BroadcastDispatcher broadcastDispatcher,
- SystemUIFactory systemUIFactory) {
+ Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManagerLazy,
+ DismissCallbackRegistry dismissCallbackRegistry) {
super(context);
mFalsingManager = falsingManager;
mLockPatternUtils = lockPatternUtils;
mBroadcastDispatcher = broadcastDispatcher;
- mStatusBarKeyguardViewManager = systemUIFactory.createStatusBarKeyguardViewManager(
- mContext,
- mViewMediatorCallback,
- mLockPatternUtils);
+ mStatusBarKeyguardViewManagerLazy = statusBarKeyguardViewManagerLazy;
+ mDismissCallbackRegistry = dismissCallbackRegistry;
}
public void userActivity() {
@@ -1259,7 +1250,7 @@
if (mOccluded != isOccluded) {
mOccluded = isOccluded;
mUpdateMonitor.setKeyguardOccluded(isOccluded);
- mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate
+ mStatusBarKeyguardViewManagerLazy.get().setOccluded(isOccluded, animate
&& mDeviceInteractive);
adjustStatusBarLocked();
}
@@ -1330,7 +1321,7 @@
}
// if the keyguard is already showing, don't bother
- if (mStatusBarKeyguardViewManager.isShowing()) {
+ if (mStatusBarKeyguardViewManagerLazy.get().isShowing()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
resetStateLocked();
return;
@@ -1394,7 +1385,7 @@
mDismissCallbackRegistry.addCallback(callback);
}
mCustomMessage = message;
- mStatusBarKeyguardViewManager.dismissAndCollapse();
+ mStatusBarKeyguardViewManagerLazy.get().dismissAndCollapse();
} else if (callback != null) {
new DismissCallbackWrapper(callback).notifyDismissError();
}
@@ -1661,7 +1652,8 @@
} else if (!mHideAnimationRun) {
mHideAnimationRun = true;
mHideAnimationRunning = true;
- mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
+ mStatusBarKeyguardViewManagerLazy.get()
+ .startPreHideAnimation(mHideAnimationFinishedRunnable);
}
}
@@ -1817,7 +1809,7 @@
mHiding = false;
mWakeAndUnlocking = false;
setShowingLocked(true);
- mStatusBarKeyguardViewManager.show(options);
+ mStatusBarKeyguardViewManagerLazy.get().show(options);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
@@ -1835,22 +1827,22 @@
public void run() {
Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
if (DEBUG) Log.d(TAG, "keyguardGoingAway");
- mStatusBarKeyguardViewManager.keyguardGoingAway();
+ mStatusBarKeyguardViewManagerLazy.get().keyguardGoingAway();
int flags = 0;
- if (mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
+ if (mStatusBarKeyguardViewManagerLazy.get().shouldDisableWindowAnimationsForUnlock()
|| (mWakeAndUnlocking && !mPulsing)) {
flags |= WindowManagerPolicyConstants
.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
}
- if (mStatusBarKeyguardViewManager.isGoingToNotificationShade()
+ if (mStatusBarKeyguardViewManagerLazy.get().isGoingToNotificationShade()
|| (mWakeAndUnlocking && mPulsing)) {
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
}
- if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
+ if (mStatusBarKeyguardViewManagerLazy.get().isUnlockWithWallpaper()) {
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
}
- if (mStatusBarKeyguardViewManager.shouldSubtleWindowAnimationsForUnlock()) {
+ if (mStatusBarKeyguardViewManagerLazy.get().shouldSubtleWindowAnimationsForUnlock()) {
flags |= WindowManagerPolicyConstants
.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
}
@@ -1936,7 +1928,7 @@
// Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
// the next draw from here so we don't have to wait for window manager to signal
// this to our ViewRootImpl.
- mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
+ mStatusBarKeyguardViewManagerLazy.get().getViewRootImpl().setReportNextDraw();
notifyDrawn(mDrawnCallback);
mDrawnCallback = null;
}
@@ -1950,7 +1942,7 @@
setShowingLocked(false);
mWakeAndUnlocking = false;
mDismissCallbackRegistry.notifyDismissSucceeded();
- mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
+ mStatusBarKeyguardViewManagerLazy.get().hide(startTime, fadeoutDuration);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
@@ -1996,7 +1988,7 @@
private void handleReset() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleReset");
- mStatusBarKeyguardViewManager.reset(true /* hideBouncerWhenShowing */);
+ mStatusBarKeyguardViewManagerLazy.get().reset(true /* hideBouncerWhenShowing */);
}
}
@@ -2009,7 +2001,7 @@
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
setShowingLocked(true);
- mStatusBarKeyguardViewManager.dismissAndCollapse();
+ mStatusBarKeyguardViewManagerLazy.get().dismissAndCollapse();
}
Trace.endSection();
}
@@ -2017,7 +2009,7 @@
private void handleNotifyStartedGoingToSleep() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep");
- mStatusBarKeyguardViewManager.onStartedGoingToSleep();
+ mStatusBarKeyguardViewManagerLazy.get().onStartedGoingToSleep();
}
}
@@ -2028,7 +2020,7 @@
private void handleNotifyFinishedGoingToSleep() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
- mStatusBarKeyguardViewManager.onFinishedGoingToSleep();
+ mStatusBarKeyguardViewManagerLazy.get().onFinishedGoingToSleep();
}
}
@@ -2036,7 +2028,7 @@
Trace.beginSection("KeyguardViewMediator#handleMotifyStartedWakingUp");
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleNotifyWakingUp");
- mStatusBarKeyguardViewManager.onStartedWakingUp();
+ mStatusBarKeyguardViewManagerLazy.get().onStartedWakingUp();
}
Trace.endSection();
}
@@ -2045,7 +2037,7 @@
Trace.beginSection("KeyguardViewMediator#handleNotifyScreenTurningOn");
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
- mStatusBarKeyguardViewManager.onScreenTurningOn();
+ mStatusBarKeyguardViewManagerLazy.get().onScreenTurningOn();
if (callback != null) {
if (mWakeAndUnlocking) {
mDrawnCallback = callback;
@@ -2064,7 +2056,7 @@
}
synchronized (this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn");
- mStatusBarKeyguardViewManager.onScreenTurnedOn();
+ mStatusBarKeyguardViewManagerLazy.get().onScreenTurnedOn();
}
Trace.endSection();
}
@@ -2113,10 +2105,10 @@
ViewGroup container, NotificationPanelView panelView,
BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
View notificationContainer, KeyguardBypassController bypassController) {
- mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
+ mStatusBarKeyguardViewManagerLazy.get().registerStatusBar(statusBar, container, panelView,
biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
notificationContainer, bypassController, mFalsingManager);
- return mStatusBarKeyguardViewManager;
+ return mStatusBarKeyguardViewManagerLazy.get();
}
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
index 4d18312..4501b8f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
@@ -65,6 +65,8 @@
mMobileRoaming = findViewById(R.id.mobile_roaming);
mCarrierText = findViewById(R.id.qs_carrier_text);
+ mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
+
int colorForeground = Utils.getColorAttrDefaultColor(mContext,
android.R.attr.colorForeground);
mColorForegroundStateList = ColorStateList.valueOf(colorForeground);
@@ -78,7 +80,6 @@
ColorStateList colorStateList = ColorStateList.valueOf(
mDualToneHandler.getSingleColor(mColorForegroundIntensity));
mMobileRoaming.setImageTintList(colorStateList);
- mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
mMobileSignal.setImageTintList(colorStateList);
mMobileSignal.setImageLevel(state.mobileSignalIconId);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 7f11e56..60bc6b6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -57,8 +57,8 @@
private final static String TAG = "OverviewProxyRecentsImpl";
@Nullable
private final Lazy<StatusBar> mStatusBarLazy;
+ private final Optional<Divider> mDividerOptional;
- private SysUiServiceProvider mSysUiServiceProvider;
private Context mContext;
private Handler mHandler;
private TrustManager mTrustManager;
@@ -66,14 +66,15 @@
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
- public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy) {
+ public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy,
+ Optional<Divider> dividerOptional) {
mStatusBarLazy = statusBarLazy.orElse(null);
+ mDividerOptional = dividerOptional;
}
@Override
public void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {
mContext = context;
- mSysUiServiceProvider = sysUiServiceProvider;
mHandler = new Handler();
mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
@@ -164,10 +165,8 @@
runningTask.id, stackCreateMode, initialBounds)) {
// The overview service is handling split screen, so just skip the wait for the
// first draw and notify the divider to start animating now
- final Divider divider = mSysUiServiceProvider.getComponent(Divider.class);
- if (divider != null) {
- divider.onRecentsDrawn();
- }
+ mDividerOptional.ifPresent(Divider::onRecentsDrawn);
+
return true;
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 3fc1398..ba9fc3d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -80,6 +80,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -102,6 +103,7 @@
private final Context mContext;
private final PipUI mPipUI;
+ private final Optional<Divider> mDividerOptional;
private SysUiState mSysUiState;
private final Handler mHandler;
private final NavigationBarController mNavBarController;
@@ -208,10 +210,7 @@
}
long token = Binder.clearCallingIdentity();
try {
- Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
- if (divider != null) {
- divider.onDockedFirstAnimationFrame();
- }
+ mDividerOptional.ifPresent(Divider::onDockedFirstAnimationFrame);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -241,11 +240,9 @@
}
long token = Binder.clearCallingIdentity();
try {
- Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
- if (divider != null) {
- return divider.getView().getNonMinimizedSplitScreenSecondaryBounds();
- }
- return null;
+ return mDividerOptional.map(
+ divider -> divider.getView().getNonMinimizedSplitScreenSecondaryBounds())
+ .orElse(null);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -475,11 +472,12 @@
private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
= this::cleanupAfterDeath;
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public OverviewProxyService(Context context, DeviceProvisionedController provisionController,
NavigationBarController navBarController, NavigationModeController navModeController,
- StatusBarWindowController statusBarWinController,
- SysUiState sysUiState, PipUI pipUI) {
+ StatusBarWindowController statusBarWinController, SysUiState sysUiState, PipUI pipUI,
+ Optional<Divider> dividerOptional) {
mContext = context;
mPipUI = pipUI;
mHandler = new Handler();
@@ -487,6 +485,7 @@
mStatusBarWinController = statusBarWinController;
mDeviceProvisionedController = provisionController;
mConnectionBackoffAttempts = 0;
+ mDividerOptional = dividerOptional;
mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
com.android.internal.R.string.config_recentsComponentName));
mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index a8ecc12..882930b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -28,19 +28,14 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/**
* A proxy to a Recents implementation.
*/
-@Singleton
public class Recents extends SystemUI implements CommandQueue.Callbacks {
private final RecentsImplementation mImpl;
private final CommandQueue mCommandQueue;
- @Inject
public Recents(Context context, RecentsImplementation impl, CommandQueue commandQueue) {
super(context);
mImpl = impl;
@@ -50,7 +45,6 @@
@Override
public void start() {
mCommandQueue.addCallback(this);
- putComponent(Recents.class, this);
mImpl.onStart(mContext, this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 68a2417..3ff6d0d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -17,6 +17,7 @@
package com.android.systemui.screenshot;
import static android.content.Context.NOTIFICATION_SERVICE;
+import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -29,7 +30,9 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
import android.app.Notification;
import android.app.Notification.BigPictureStyle;
import android.app.NotificationManager;
@@ -42,6 +45,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -64,7 +68,10 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.text.TextUtils;
@@ -82,9 +89,12 @@
import android.widget.ImageView;
import android.widget.Toast;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.dagger.qualifiers.MainResources;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -97,8 +107,11 @@
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Collections;
import java.util.Date;
+import java.util.List;
import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -156,6 +169,8 @@
private final BigPictureStyle mNotificationStyle;
private final int mImageWidth;
private final int mImageHeight;
+ private final Handler mHandler;
+ private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
SaveImageInBackgroundTask(Context context, SaveImageInBackgroundData data,
NotificationManager nManager) {
@@ -167,6 +182,11 @@
String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime));
mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
+ // Initialize screenshot notification smart actions provider.
+ mHandler = new Handler();
+ mSmartActionsProvider =
+ SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider();
+
// Create the large notification icon
mImageWidth = data.image.getWidth();
mImageHeight = data.image.getHeight();
@@ -242,6 +262,23 @@
mNotificationStyle.bigLargeIcon((Bitmap) null);
}
+ private int getUserHandleOfForegroundApplication(Context context) {
+ // This logic matches
+ // com.android.systemui.statusbar.phone.PhoneStatusBarPolicy#updateManagedProfile
+ try {
+ return ActivityTaskManager.getService().getLastResumedActivityUserId();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
+ return context.getUserId();
+ }
+ }
+
+ private boolean isManagedProfile(Context context) {
+ UserManager manager = UserManager.get(context);
+ UserInfo info = manager.getUserInfo(getUserHandleOfForegroundApplication(context));
+ return info.isManagedProfile();
+ }
+
/**
* Generates a new hardware bitmap with specified values, copying the content from the
* passed in bitmap.
@@ -268,6 +305,12 @@
Context context = mParams.context;
Bitmap image = mParams.image;
+ boolean smartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true);
+ CompletableFuture<List<Notification.Action>> smartActionsFuture = getSmartActionsFuture(
+ context, image, mSmartActionsProvider, mHandler, smartActionsEnabled,
+ isManagedProfile(context));
+
Resources r = context.getResources();
try {
@@ -378,6 +421,18 @@
mParams.imageUri = uri;
mParams.image = null;
mParams.errorMsgResId = 0;
+
+ if (smartActionsEnabled) {
+ int timeoutMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags
+ .SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
+ 1000);
+ List<Notification.Action> smartActions = getSmartActions(smartActionsFuture,
+ timeoutMs);
+ for (Notification.Action action : smartActions) {
+ mNotificationBuilder.addAction(action);
+ }
+ }
} catch (Exception e) {
// IOException/UnsupportedOperationException may be thrown if external storage is
// not mounted
@@ -1039,6 +1094,58 @@
nManager.notify(SystemMessage.NOTE_GLOBAL_SCREENSHOT, n);
}
+ @VisibleForTesting
+ static CompletableFuture<List<Notification.Action>> getSmartActionsFuture(Context context,
+ Bitmap image, ScreenshotNotificationSmartActionsProvider smartActionsProvider,
+ Handler handler, boolean smartActionsEnabled, boolean isManagedProfile) {
+ if (!smartActionsEnabled) {
+ Slog.i(TAG, "Screenshot Intelligence not enabled, returning empty list.");
+ return CompletableFuture.completedFuture(Collections.emptyList());
+ }
+ if (image.getConfig() != Bitmap.Config.HARDWARE) {
+ Slog.w(TAG, String.format(
+ "Bitmap expected: Hardware, Bitmap found: %s. Returning empty list.",
+ image.getConfig()));
+ return CompletableFuture.completedFuture(Collections.emptyList());
+ }
+
+ Slog.d(TAG, "Screenshot from a managed profile: " + isManagedProfile);
+ CompletableFuture<List<Notification.Action>> smartActionsFuture;
+ try {
+ ActivityManager.RunningTaskInfo runningTask =
+ ActivityManagerWrapper.getInstance().getRunningTask();
+ ComponentName componentName =
+ (runningTask != null && runningTask.topActivity != null)
+ ? runningTask.topActivity
+ : new ComponentName("", "");
+ smartActionsFuture = smartActionsProvider.getActions(image, context,
+ THREAD_POOL_EXECUTOR,
+ handler,
+ componentName,
+ isManagedProfile);
+ } catch (Throwable e) {
+ smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList());
+ Slog.e(TAG, "Failed to get future for screenshot notification smart actions.", e);
+ }
+ return smartActionsFuture;
+ }
+
+ @VisibleForTesting
+ static List<Notification.Action> getSmartActions(
+ CompletableFuture<List<Notification.Action>> smartActionsFuture, int timeoutMs) {
+ try {
+ long startTimeMs = SystemClock.uptimeMillis();
+ List<Notification.Action> actions = smartActionsFuture.get(timeoutMs,
+ TimeUnit.MILLISECONDS);
+ Slog.d(TAG, String.format("Wait time for smart actions: %d ms",
+ SystemClock.uptimeMillis() - startTimeMs));
+ return actions;
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failed to obtain screenshot notification smart actions.", e);
+ return Collections.emptyList();
+ }
+ }
+
/**
* Receiver to proxy the share or edit intent, used to clean up the notification and send
* appropriate signals to the system (ie. to dismiss the keyguard if necessary).
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
new file mode 100644
index 0000000..fa23bf7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
@@ -0,0 +1,58 @@
+/*
+ * 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.systemui.screenshot;
+
+import android.app.Notification;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+
+/**
+ * This class can be overridden by a vendor-specific sys UI implementation,
+ * in order to provide smart actions in the screenshot notification.
+ */
+public class ScreenshotNotificationSmartActionsProvider {
+ private static final String TAG = "ScreenshotActions";
+
+ /**
+ * Default implementation that returns an empty list.
+ * This method is overridden in vendor-specific Sys UI implementation.
+ *
+ * @param bitmap The bitmap of the screenshot. The bitmap config must be {@link
+ * HARDWARE}.
+ * @param context The current app {@link Context}.
+ * @param executor A {@link Executor} that can be used to execute tasks in parallel.
+ * @param handler A {@link Handler} to possibly run UI-thread code.
+ * @param componentName Contains package and activity class names where the screenshot was
+ * taken. This is used as an additional signal to generate and rank more
+ * relevant actions.
+ * @param isManagedProfile The screenshot was taken for a work profile app.
+ */
+ public CompletableFuture<List<Notification.Action>> getActions(Bitmap bitmap, Context context,
+ Executor executor, Handler handler, ComponentName componentName,
+ boolean isManagedProfile) {
+ Log.d(TAG, "Returning empty smart action list.");
+ return CompletableFuture.completedFuture(Collections.emptyList());
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index df9791d..a571f01 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -34,13 +34,18 @@
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.DividerView;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* Dispatches shortcut to System UI components
*/
+@Singleton
public class ShortcutKeyDispatcher extends SystemUI
implements ShortcutKeyServiceProxy.Callbacks {
private static final String TAG = "ShortcutKeyDispatcher";
+ private final Divider mDivider;
private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this);
private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -53,8 +58,10 @@
protected final long SC_DOCK_LEFT = META_MASK | KeyEvent.KEYCODE_LEFT_BRACKET;
protected final long SC_DOCK_RIGHT = META_MASK | KeyEvent.KEYCODE_RIGHT_BRACKET;
- public ShortcutKeyDispatcher(Context context) {
+ @Inject
+ public ShortcutKeyDispatcher(Context context, Divider divider) {
super(context);
+ mDivider = divider;
}
/**
@@ -95,7 +102,7 @@
: SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
} else {
// If there is already a docked window, we respond by resizing the docking pane.
- DividerView dividerView = getComponent(Divider.class).getView();
+ DividerView dividerView = mDivider.getView();
DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
int dividerPosition = dividerView.getCurrentPosition();
DividerSnapAlgorithm.SnapTarget currentTarget =
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index c8b2b6a..d12f3ee 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -59,7 +59,6 @@
public void start() {
mWindowManager = new DividerWindowManager(mContext);
update(mContext.getResources().getConfiguration());
- putComponent(Divider.class, this);
mDockDividerVisibilityListener = new DockDividerVisibilityListener();
try {
WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 681f3ab..2ef1f40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -107,6 +107,7 @@
private ColorStateList mTransientTextColorState;
private ColorStateList mInitialTextColorState;
private boolean mVisible;
+ private boolean mHideTransientMessageOnScreenOff;
private boolean mPowerPluggedIn;
private boolean mPowerPluggedInWired;
@@ -295,15 +296,17 @@
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
*/
public void showTransientIndication(CharSequence transientIndication) {
- showTransientIndication(transientIndication, mInitialTextColorState);
+ showTransientIndication(transientIndication, mInitialTextColorState,
+ false /* hideOnScreenOff */);
}
/**
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
*/
- public void showTransientIndication(CharSequence transientIndication,
- ColorStateList textColorState) {
+ private void showTransientIndication(CharSequence transientIndication,
+ ColorStateList textColorState, boolean hideOnScreenOff) {
mTransientIndication = transientIndication;
+ mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
mTransientTextColorState = textColorState;
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
mHandler.removeMessages(MSG_SWIPE_UP_TO_UNLOCK);
@@ -322,6 +325,7 @@
public void hideTransientIndication() {
if (mTransientIndication != null) {
mTransientIndication = null;
+ mHideTransientMessageOnScreenOff = false;
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
updateIndication(false);
}
@@ -544,7 +548,8 @@
String message = mContext.getString(R.string.keyguard_retry);
mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
- showTransientIndication(mContext.getString(R.string.keyguard_unlock));
+ showTransientIndication(mContext.getString(R.string.keyguard_unlock),
+ mInitialTextColorState, true /* hideOnScreenOff */);
hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
}
}
@@ -554,7 +559,11 @@
return;
}
mDozing = dozing;
- updateIndication(false);
+ if (mHideTransientMessageOnScreenOff && mDozing) {
+ hideTransientIndication();
+ } else {
+ updateIndication(false);
+ }
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -616,8 +625,7 @@
@Override
public void onBiometricHelp(int msgId, String helpString,
BiometricSourceType biometricSourceType) {
- KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
- if (!updateMonitor.isUnlockingWithBiometricAllowed()) {
+ if (!mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed()) {
return;
}
boolean showSwipeToUnlock =
@@ -625,8 +633,8 @@
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
mInitialTextColorState);
- } else if (updateMonitor.isScreenOn()) {
- showTransientIndication(helpString);
+ } else if (mKeyguardUpdateMonitor.isScreenOn()) {
+ showTransientIndication(helpString, mInitialTextColorState, showSwipeToUnlock);
if (!showSwipeToUnlock) {
hideTransientIndicationDelayed(TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
}
@@ -640,8 +648,7 @@
@Override
public void onBiometricError(int msgId, String errString,
BiometricSourceType biometricSourceType) {
- KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
- if (shouldSuppressBiometricError(msgId, biometricSourceType, updateMonitor)) {
+ if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
return;
}
animatePadlockError();
@@ -651,7 +658,7 @@
showSwipeUpToUnlock();
} else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
- } else if (updateMonitor.isScreenOn()) {
+ } else if (mKeyguardUpdateMonitor.isScreenOn()) {
showTransientIndication(errString);
// We want to keep this message around in case the screen was off
hideTransientIndicationDelayed(HIDE_DELAY_MS);
@@ -691,13 +698,15 @@
@Override
public void onTrustAgentErrorMessage(CharSequence message) {
- showTransientIndication(message, Utils.getColorError(mContext));
+ showTransientIndication(message, Utils.getColorError(mContext),
+ false /* hideOnScreenOff */);
}
@Override
public void onScreenTurnedOn() {
if (mMessageToShowOnScreenOn != null) {
- showTransientIndication(mMessageToShowOnScreenOn, Utils.getColorError(mContext));
+ showTransientIndication(mMessageToShowOnScreenOn, Utils.getColorError(mContext),
+ false /* hideOnScreenOff */);
// We want to keep this message around in case the screen was off
hideTransientIndicationDelayed(HIDE_DELAY_MS);
mMessageToShowOnScreenOn = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 404087d..13d90ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -261,6 +261,7 @@
boolean isNew = mNotificationData.get(entry.getKey()) == null;
if (isNew) {
for (NotificationEntryListener listener : mNotificationEntryListeners) {
+ mNotifLog.log(NotifEvent.INFLATED, entry);
listener.onEntryInflated(entry, inflatedFlags);
}
mNotificationData.add(entry);
@@ -270,6 +271,7 @@
}
} else {
for (NotificationEntryListener listener : mNotificationEntryListeners) {
+ mNotifLog.log(NotifEvent.INFLATED, entry);
listener.onEntryReinflated(entry);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
index 2eefe29..3f7fd1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
@@ -19,7 +19,6 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.ForegroundServiceController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -34,17 +33,14 @@
public class NotificationListController {
private final NotificationEntryManager mEntryManager;
private final NotificationListContainer mListContainer;
- private final ForegroundServiceController mForegroundServiceController;
private final DeviceProvisionedController mDeviceProvisionedController;
public NotificationListController(
NotificationEntryManager entryManager,
NotificationListContainer listContainer,
- ForegroundServiceController foregroundServiceController,
DeviceProvisionedController deviceProvisionedController) {
mEntryManager = checkNotNull(entryManager);
mListContainer = checkNotNull(listContainer);
- mForegroundServiceController = checkNotNull(foregroundServiceController);
mDeviceProvisionedController = checkNotNull(deviceProvisionedController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
index 0ef75165..52fd079 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
@@ -41,8 +41,6 @@
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
-import com.android.systemui.statusbar.notification.logging.NotifEvent;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater;
@@ -74,7 +72,6 @@
private final boolean mAllowLongPress;
private final KeyguardBypassController mKeyguardBypassController;
private final StatusBarStateController mStatusBarStateController;
- private final NotifLog mNotifLog;
private NotificationRemoteInputManager mRemoteInputManager;
private NotificationPresenter mPresenter;
@@ -88,14 +85,12 @@
public NotificationRowBinderImpl(Context context, boolean allowLongPress,
KeyguardBypassController keyguardBypassController,
- StatusBarStateController statusBarStateController,
- NotifLog notifLog) {
+ StatusBarStateController statusBarStateController) {
mContext = context;
mMessagingUtil = new NotificationMessagingUtil(context);
mAllowLongPress = allowLongPress;
mKeyguardBypassController = keyguardBypassController;
mStatusBarStateController = statusBarStateController;
- mNotifLog = notifLog;
}
private NotificationRemoteInputManager getRemoteInputManager() {
@@ -149,7 +144,6 @@
row -> {
bindRow(entry, pmUser, sbn, row, onDismissRunnable);
updateNotification(entry, pmUser, sbn, row);
- mNotifLog.log(NotifEvent.INFLATED, sbn);
});
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 2b9912c..8d50f58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -142,6 +142,7 @@
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.ScrollAdapter;
+import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.Assert;
@@ -344,6 +345,7 @@
private boolean mForceNoOverlappingRendering;
private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>();
private FalsingManager mFalsingManager;
+ private final ZenModeController mZenController;
private boolean mAnimationRunning;
private ViewTreeObserver.OnPreDrawListener mRunningAnimationUpdater
= new ViewTreeObserver.OnPreDrawListener() {
@@ -520,7 +522,8 @@
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotificationGutsManager notificationGutsManager,
NotificationSectionsFeatureManager sectionsFeatureManager,
- PeopleHubSectionFooterViewAdapter peopleHubViewAdapter) {
+ PeopleHubSectionFooterViewAdapter peopleHubViewAdapter,
+ ZenModeController zenController) {
super(context, attrs, 0, 0);
Resources res = getResources();
@@ -535,6 +538,7 @@
mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
mKeyguardBypassController = keyguardBypassController;
mFalsingManager = falsingManager;
+ mZenController = zenController;
int[] buckets = sectionsFeatureManager.getNotificationBuckets();
mSectionsManager =
@@ -4882,7 +4886,7 @@
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
int oldTextRes = mEmptyShadeView.getTextResource();
- int newTextRes = mStatusBar.areNotificationsHidden()
+ int newTextRes = mZenController.areNotificationsHiddenInShade()
? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
if (oldTextRes != newTextRes) {
mEmptyShadeView.setText(newTextRes);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
new file mode 100644
index 0000000..93887a6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
@@ -0,0 +1,179 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.Nullable;
+import android.view.View;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+import android.view.animation.AccelerateInterpolator;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Apps can request a low profile mode {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
+ * where status bar and navigation icons dim. In this mode, a notification dot appears
+ * where the notification icons would appear if they would be shown outside of this mode.
+ *
+ * This controller shows and hides the notification dot in the status bar to indicate
+ * whether there are notifications when the device is in {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}.
+ */
+@Singleton
+public class LightsOutNotifController {
+ private final CommandQueue mCommandQueue;
+ private final NotificationEntryManager mEntryManager;
+ private final WindowManager mWindowManager;
+
+ /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int) */
+ @VisibleForTesting @WindowInsetsController.Appearance int mAppearance;
+
+ private int mDisplayId;
+ private View mLightsOutNotifView;
+
+ @Inject
+ LightsOutNotifController(WindowManager windowManager,
+ NotificationEntryManager entryManager,
+ CommandQueue commandQueue) {
+ mWindowManager = windowManager;
+ mEntryManager = entryManager;
+ mCommandQueue = commandQueue;
+ }
+
+ /**
+ * Sets the notification dot view after it is created in the StatusBar.
+ * This is the view this controller will show and hide depending on whether:
+ * 1. there are active notifications
+ * 2. an app has requested {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
+ */
+ void setLightsOutNotifView(View lightsOutNotifView) {
+ destroy();
+ mLightsOutNotifView = lightsOutNotifView;
+
+ if (mLightsOutNotifView != null) {
+ mLightsOutNotifView.setVisibility(View.GONE);
+ mLightsOutNotifView.setAlpha(0f);
+ init();
+ }
+ }
+
+ private void destroy() {
+ mEntryManager.removeNotificationEntryListener(mEntryListener);
+ mCommandQueue.removeCallback(mCallback);
+ }
+
+ private void init() {
+ mDisplayId = mWindowManager.getDefaultDisplay().getDisplayId();
+ mEntryManager.addNotificationEntryListener(mEntryListener);
+ mCommandQueue.addCallback(mCallback);
+
+ updateLightsOutView();
+ }
+
+ private boolean hasActiveNotifications() {
+ return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
+ }
+
+ @VisibleForTesting
+ void updateLightsOutView() {
+ if (mLightsOutNotifView == null) {
+ return;
+ }
+
+ final boolean showDot = shouldShowDot();
+ if (showDot != isShowingDot()) {
+ if (showDot) {
+ mLightsOutNotifView.setAlpha(0f);
+ mLightsOutNotifView.setVisibility(View.VISIBLE);
+ }
+
+ mLightsOutNotifView.animate()
+ .alpha(showDot ? 1 : 0)
+ .setDuration(showDot ? 750 : 250)
+ .setInterpolator(new AccelerateInterpolator(2.0f))
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator a) {
+ mLightsOutNotifView.setAlpha(showDot ? 1 : 0);
+ mLightsOutNotifView.setVisibility(showDot ? View.VISIBLE : View.GONE);
+ }
+ })
+ .start();
+ }
+ }
+
+ @VisibleForTesting
+ boolean isShowingDot() {
+ return mLightsOutNotifView.getVisibility() == View.VISIBLE
+ && mLightsOutNotifView.getAlpha() == 1.0f;
+ }
+
+ @VisibleForTesting
+ boolean shouldShowDot() {
+ return hasActiveNotifications() && areLightsOut();
+ }
+
+ @VisibleForTesting
+ boolean areLightsOut() {
+ return 0 != (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
+ }
+
+ private final CommandQueue.Callbacks mCallback = new CommandQueue.Callbacks() {
+ @Override
+ public void onSystemBarAppearanceChanged(int displayId,
+ @WindowInsetsController.Appearance int appearance,
+ AppearanceRegion[] appearanceRegions,
+ boolean navbarColorManagedByIme) {
+ if (displayId != mDisplayId) {
+ return;
+ }
+ mAppearance = appearance;
+ updateLightsOutView();
+ }
+ };
+
+ private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
+ // Cares about notifications post-filtering
+ @Override
+ public void onNotificationAdded(NotificationEntry entry) {
+ updateLightsOutView();
+ }
+
+ @Override
+ public void onPostEntryUpdated(NotificationEntry entry) {
+ updateLightsOutView();
+ }
+
+ @Override
+ public void onEntryRemoved(@Nullable NotificationEntry entry,
+ NotificationVisibility visibility, boolean removedByUser) {
+ updateLightsOutView();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 816327f..1c46cf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -118,6 +118,7 @@
import java.io.PrintWriter;
import java.util.List;
import java.util.Locale;
+import java.util.Optional;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -162,8 +163,8 @@
private int mDisabledFlags1;
private int mDisabledFlags2;
private StatusBar mStatusBar;
- private Recents mRecents;
- private Divider mDivider;
+ private final Divider mDivider;
+ private final Optional<Recents> mRecentsOptional;
private WindowManager mWindowManager;
private final CommandQueue mCommandQueue;
private long mLastLockToAppLongPress;
@@ -266,7 +267,9 @@
StatusBarStateController statusBarStateController,
SysUiState sysUiFlagsContainer,
BroadcastDispatcher broadcastDispatcher,
- CommandQueue commandQueue) {
+ CommandQueue commandQueue,
+ Divider divider,
+ Optional<Recents> recentsOptional) {
mAccessibilityManagerWrapper = accessibilityManagerWrapper;
mDeviceProvisionedController = deviceProvisionedController;
mStatusBarStateController = statusBarStateController;
@@ -279,6 +282,8 @@
mNavBarMode = navigationModeController.addListener(this);
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
+ mDivider = divider;
+ mRecentsOptional = recentsOptional;
}
// ----- Fragment Lifecycle Callbacks -----
@@ -288,8 +293,6 @@
super.onCreate(savedInstanceState);
mCommandQueue.observe(getLifecycle(), this);
mStatusBar = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
- mRecents = SysUiServiceProvider.getComponent(getContext(), Recents.class);
- mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
mWindowManager = getContext().getSystemService(WindowManager.class);
mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
mContentResolver = getContext().getContentResolver();
@@ -905,7 +908,7 @@
}
private boolean onLongPressRecents() {
- if (mRecents == null || !ActivityTaskManager.supportsMultiWindow(getContext())
+ if (mRecentsOptional.isPresent() || !ActivityTaskManager.supportsMultiWindow(getContext())
|| !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()
|| ActivityManager.isLowRamDeviceStatic()
// If we are connected to the overview service, then disable the recents button
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
index 70cd43a..f359fe7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -142,12 +142,6 @@
void onLaunchAnimationCancelled();
/**
- * When notifications update, give the shade controller a chance to do thing in response to
- * the new data set
- */
- void updateAreThereNotifications();
-
- /**
* Callback to notify the shade controller that a {@link ActivatableNotificationView} has become
* inactive
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index cff2824..910300c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -47,13 +47,10 @@
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
-import android.app.AppOpsManager;
import android.app.IWallpaperManager;
import android.app.KeyguardManager;
import android.app.Notification;
@@ -117,7 +114,6 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AccelerateInterpolator;
import android.widget.DateTimeView;
import com.android.internal.annotations.VisibleForTesting;
@@ -139,7 +135,6 @@
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.EventLogTags;
-import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.Interpolators;
import com.android.systemui.Prefs;
@@ -147,7 +142,6 @@
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
@@ -155,9 +149,9 @@
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.doze.DozeHost;
-import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.ExtensionFragmentListener;
import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
@@ -216,7 +210,6 @@
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -239,7 +232,6 @@
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
@@ -247,6 +239,7 @@
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Map;
+import java.util.Optional;
import javax.inject.Named;
@@ -255,10 +248,10 @@
public class StatusBar extends SystemUI implements DemoMode,
ActivityStarter, KeyguardStateController.Callback,
- OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
+ OnHeadsUpChangedListener, CommandQueue.Callbacks,
ColorExtractor.OnColorsChangedListener, ConfigurationListener,
StatusBarStateController.StateListener, ShadeController,
- ActivityLaunchAnimator.Callback, AppOpsController.Callback {
+ ActivityLaunchAnimator.Callback {
public static final boolean MULTIUSER_DEBUG = false;
public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -377,7 +370,6 @@
private final FeatureFlags mFeatureFlags;
private final StatusBarIconController mIconController;
- private final DozeLog mDozeLog;
private final PulseExpansionHandler mPulseExpansionHandler;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final KeyguardBypassController mKeyguardBypassController;
@@ -391,12 +383,14 @@
private final BroadcastDispatcher mBroadcastDispatcher;
private final ConfigurationController mConfigurationController;
private final StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
- private final NotifLog mNotifLog;
private final DozeParameters mDozeParameters;
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
private final PluginManager mPluginManager;
private final RemoteInputUriController mRemoteInputUriController;
+ private final Optional<Divider> mDividerOptional;
private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+ private final LightsOutNotifController mLightsOutNotifController;
+ private final DismissCallbackRegistry mDismissCallbackRegistry;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -424,10 +418,7 @@
private NotificationListController mNotificationListController;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final NotificationViewHierarchyManager mViewHierarchyManager;
- private final ForegroundServiceController mForegroundServiceController;
- private final AppOpsController mAppOpsController;
private final KeyguardViewMediator mKeyguardViewMediator;
- private final ZenModeController mZenController;
private final NotificationAlertingManager mNotificationAlertingManager;
// for disabling the status bar
@@ -614,25 +605,13 @@
private ActivityIntentHelper mActivityIntentHelper;
- @Override
- public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
- Dependency.get(MAIN_HANDLER).post(() -> {
- mForegroundServiceController.onAppOpChanged(code, uid, packageName, active);
- });
- }
-
- protected static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
- AppOpsManager.OP_RECORD_AUDIO,
- AppOpsManager.OP_COARSE_LOCATION,
- AppOpsManager.OP_FINE_LOCATION};
-
/**
* Public constructor for StatusBar.
*
* StatusBar is considered optional, and therefore can not be marked as @Inject directly.
* Instead, an @Provide method is included.
*/
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public StatusBar(
Context context,
FeatureFlags featureFlags,
@@ -640,7 +619,6 @@
AutoHideController autoHideController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarIconController statusBarIconController,
- DozeLog dozeLog,
PulseExpansionHandler pulseExpansionHandler,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
@@ -658,10 +636,7 @@
NotificationEntryManager notificationEntryManager,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
- ForegroundServiceController foregroundServiceController,
- AppOpsController appOpsController,
KeyguardViewMediator keyguardViewMediator,
- ZenModeController zenModeController,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@@ -688,7 +663,6 @@
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
- NotifLog notifLog,
DozeParameters dozeParameters,
ScrimController scrimController,
@Nullable KeyguardLiftController keyguardLiftController,
@@ -700,14 +674,18 @@
CommandQueue commandQueue,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
- SuperStatusBarViewFactory superStatusBarViewFactory) {
+ Optional<Divider> dividerOptional,
+ LightsOutNotifController lightsOutNotifController,
+ SuperStatusBarViewFactory superStatusBarViewFactory,
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ ViewMediatorCallback viewMediatorCallback,
+ DismissCallbackRegistry dismissCallbackRegistry) {
super(context);
mFeatureFlags = featureFlags;
mLightBarController = lightBarController;
mAutoHideController = autoHideController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mIconController = statusBarIconController;
- mDozeLog = dozeLog;
mPulseExpansionHandler = pulseExpansionHandler;
mWakeUpCoordinator = notificationWakeUpCoordinator;
mKeyguardBypassController = keyguardBypassController;
@@ -725,10 +703,7 @@
mEntryManager = notificationEntryManager;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mViewHierarchyManager = notificationViewHierarchyManager;
- mForegroundServiceController = foregroundServiceController;
- mAppOpsController = appOpsController;
mKeyguardViewMediator = keyguardViewMediator;
- mZenController = zenModeController;
mNotificationAlertingManager = notificationAlertingManager;
mDisplayMetrics = displayMetrics;
mMetricsLogger = metricsLogger;
@@ -755,7 +730,6 @@
mConfigurationController = configurationController;
mStatusBarWindowController = statusBarWindowController;
mStatusBarWindowViewControllerBuilder = statusBarWindowViewControllerBuilder;
- mNotifLog = notifLog;
mDozeServiceHost = dozeServiceHost;
mPowerManager = powerManager;
mDozeParameters = dozeParameters;
@@ -767,7 +741,13 @@
mCommandQueue = commandQueue;
mPluginManager = pluginManager;
mRemoteInputUriController = remoteInputUriController;
+ mDividerOptional = dividerOptional;
+
mSuperStatusBarViewFactory = superStatusBarViewFactory;
+ mLightsOutNotifController = lightsOutNotifController;
+ mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ mKeyguardViewMediatorCallback = viewMediatorCallback;
+ mDismissCallbackRegistry = dismissCallbackRegistry;
mBubbleExpandListener =
(isExpanding, key) -> {
@@ -922,7 +902,6 @@
mConfigurationController.addCallback(this);
// set the initial view visibility
- Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
int disabledFlags1 = result.mDisabledFlags1;
int disabledFlags2 = result.mDisabledFlags2;
Dependency.get(InitController.class).addPostInitTask(
@@ -991,7 +970,6 @@
mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
- mZenController.addCallback(this);
NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
mNotificationLogger.setUpWithContainer(notifListContainer);
@@ -1051,8 +1029,10 @@
mStatusBarStateController, mKeyguardBypassController,
mKeyguardStateController, mWakeUpCoordinator, mCommandQueue);
mHeadsUpAppearanceController.readFrom(oldController);
+
+ mLightsOutNotifController.setLightsOutNotifView(
+ mStatusBarView.findViewById(R.id.notification_lights_out));
mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
- updateAreThereNotifications();
checkBarModes();
}).getFragmentManager()
.beginTransaction()
@@ -1249,8 +1229,7 @@
mContext,
mAllowNotificationLongPress,
mKeyguardBypassController,
- mStatusBarStateController,
- mNotifLog);
+ mStatusBarStateController);
mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
@@ -1261,10 +1240,8 @@
new NotificationListController(
mEntryManager,
(NotificationListContainer) mStackScroller,
- mForegroundServiceController,
mDeviceProvisionedController);
- mAppOpsController.addCallback(APP_OPS, this);
mNotificationShelf.setOnActivatedListener(mPresenter);
mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
@@ -1422,17 +1399,17 @@
protected void startKeyguard() {
Trace.beginSection("StatusBar#startKeyguard");
mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
- mStatusBarKeyguardViewManager = mKeyguardViewMediator.registerStatusBar(this,
- getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
+ mStatusBarKeyguardViewManager.registerStatusBar(
+ /* statusBar= */ this, getBouncerContainer(), mNotificationPanel,
+ mBiometricUnlockController, mDismissCallbackRegistry,
mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
- mKeyguardBypassController);
+ mKeyguardBypassController, mFalsingManager);
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mRemoteInputManager.getController().addCallback(mStatusBarKeyguardViewManager);
mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
- mKeyguardViewMediatorCallback = mKeyguardViewMediator.getViewMediatorCallback();
mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
@@ -1470,8 +1447,8 @@
: SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
return mRecents.splitPrimaryTask(createMode, null, metricsDockAction);
} else {
- Divider divider = getComponent(Divider.class);
- if (divider != null) {
+ if (mDividerOptional.isPresent()) {
+ Divider divider = mDividerOptional.get();
if (divider.isMinimized() && !divider.isHomeStackResizable()) {
// Undocking from the minimized state is not supported
return false;
@@ -1519,10 +1496,6 @@
mQSPanel.clickTile(tile);
}
- public boolean areNotificationsHidden() {
- return mZenController.areNotificationsHiddenInShade();
- }
-
/**
* Request a notification update
* @param reason why we're requesting a notification update
@@ -1540,38 +1513,6 @@
}
}
- public void updateAreThereNotifications() {
- if (SPEW) {
- final boolean clearable = hasActiveNotifications() &&
- mNotificationPanel.hasActiveClearableNotifications();
- Log.d(TAG, "updateAreThereNotifications: N=" +
- mEntryManager.getNotificationData().getActiveNotifications().size() + " any=" +
- hasActiveNotifications() + " clearable=" + clearable);
- }
-
- if (mStatusBarView != null) {
- final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
- final boolean showDot = hasActiveNotifications() && !areLightsOn();
- if (showDot != (nlo.getAlpha() == 1.0f)) {
- if (showDot) {
- nlo.setAlpha(0f);
- nlo.setVisibility(View.VISIBLE);
- }
- nlo.animate()
- .alpha(showDot ? 1 : 0)
- .setDuration(showDot ? 750 : 250)
- .setInterpolator(new AccelerateInterpolator(2.0f))
- .setListener(showDot ? null : new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator _a) {
- nlo.setVisibility(View.GONE);
- }
- })
- .start();
- }
- }
- }
-
private void updateReportRejectedTouchVisibility() {
if (mReportRejectedTouch == null) {
return;
@@ -2300,14 +2241,8 @@
return;
}
boolean barModeChanged = false;
- final int diff = mAppearance ^ appearance;
if (mAppearance != appearance) {
mAppearance = appearance;
-
- // update low profile
- if ((diff & APPEARANCE_LOW_PROFILE_BARS) != 0) {
- updateAreThereNotifications();
- }
barModeChanged = updateBarMode(barMode(mTransientShown, appearance));
}
mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
@@ -2488,10 +2423,6 @@
return mAppImmersive;
}
- private boolean areLightsOn() {
- return 0 == (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
- }
-
public static String viewInfo(View v) {
return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
+ ") " + v.getWidth() + "x" + v.getHeight() + "]";
@@ -2515,10 +2446,6 @@
pw.print(" mStatusBarMode=");
pw.println(BarTransitions.modeToString(mStatusBarMode));
pw.print(" mDozing="); pw.println(mDozing);
- pw.print(" mZenMode=");
- pw.println(Settings.Global.zenModeToString(Settings.Global.getInt(
- mContext.getContentResolver(), Settings.Global.ZEN_MODE,
- Settings.Global.ZEN_MODE_OFF)));
pw.print(" mWallpaperSupported= "); pw.println(mWallpaperSupported);
if (mStatusBarView != null) {
@@ -2555,8 +2482,6 @@
final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
pw.println(" light wallpaper theme: " + lightWpTheme);
- mDozeLog.dump(pw);
-
if (mKeyguardIndicationController != null) {
mKeyguardIndicationController.dump(fd, pw, args);
}
@@ -3945,14 +3870,14 @@
@Override
public void appTransitionCancelled(int displayId) {
if (displayId == mDisplayId) {
- getComponent(Divider.class).onAppTransitionFinished();
+ mDividerOptional.ifPresent(Divider::onAppTransitionFinished);
}
}
@Override
public void appTransitionFinished(int displayId) {
if (displayId == mDisplayId) {
- getComponent(Divider.class).onAppTransitionFinished();
+ mDividerOptional.ifPresent(Divider::onAppTransitionFinished);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 8683586..31d0362 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -42,7 +42,6 @@
import com.android.keyguard.ViewMediatorCallback;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.systemui.DejankUtils;
-import com.android.systemui.Dependency;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
@@ -63,12 +62,16 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
* via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
* which is in turn, reported to this class by the current
* {@link com.android.keyguard.KeyguardViewBase}.
*/
+@Singleton
public class StatusBarKeyguardViewManager implements RemoteInputController.Callback,
StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
PanelExpansionListener, NavigationModeController.ModeChangedListener {
@@ -167,13 +170,11 @@
// Dismiss action to be launched when we stop dozing or the keyguard is gone.
private DismissWithActionRequest mPendingWakeupAction;
- private final KeyguardStateController mKeyguardStateController = Dependency.get(
- KeyguardStateController.class);
- private final NotificationMediaManager mMediaManager =
- Dependency.get(NotificationMediaManager.class);
- private final SysuiStatusBarStateController mStatusBarStateController =
- (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
+ private final KeyguardStateController mKeyguardStateController;
+ private final NotificationMediaManager mMediaManager;
+ private final SysuiStatusBarStateController mStatusBarStateController;
private final DockManager mDockManager;
+ private final KeyguardUpdateMonitor mKeyguardUpdateManager;
private KeyguardBypassController mBypassController;
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
@@ -189,18 +190,33 @@
}
};
- public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
- LockPatternUtils lockPatternUtils) {
+ @Inject
+ public StatusBarKeyguardViewManager(
+ Context context,
+ ViewMediatorCallback callback,
+ LockPatternUtils lockPatternUtils,
+ SysuiStatusBarStateController sysuiStatusBarStateController,
+ ConfigurationController configurationController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ NavigationModeController navigationModeController,
+ DockManager dockManager,
+ StatusBarWindowController statusBarWindowController,
+ KeyguardStateController keyguardStateController,
+ NotificationMediaManager notificationMediaManager) {
mContext = context;
mViewMediatorCallback = callback;
mLockPatternUtils = lockPatternUtils;
- mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
- Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mUpdateMonitorCallback);
+ mStatusBarWindowController = statusBarWindowController;
+ mKeyguardStateController = keyguardStateController;
+ mMediaManager = notificationMediaManager;
+ mKeyguardUpdateManager = keyguardUpdateMonitor;
+ mKeyguardUpdateManager.registerCallback(mUpdateMonitorCallback);
+ mStatusBarStateController = sysuiStatusBarStateController;
mStatusBarStateController.addCallback(this);
- Dependency.get(ConfigurationController.class).addCallback(this);
+ configurationController.addCallback(this);
mGesturalNav = QuickStepContract.isGesturalMode(
- Dependency.get(NavigationModeController.class).addListener(this));
- mDockManager = Dependency.get(DockManager.class);
+ navigationModeController.addListener(this));
+ mDockManager = dockManager;
if (mDockManager != null) {
mDockManager.addListener(mDockEventListener);
mIsDocked = mDockManager.isDocked();
@@ -409,7 +425,7 @@
} else {
showBouncerOrKeyguard(hideBouncerWhenShowing);
}
- Dependency.get(KeyguardUpdateMonitor.class).sendKeyguardReset();
+ mKeyguardUpdateManager.sendKeyguardReset();
updateStates();
}
}
@@ -547,7 +563,7 @@
mKeyguardStateController.isOccluded());
launchPendingWakeupAction();
- if (Dependency.get(KeyguardUpdateMonitor.class).needsSlowUnlockTransition()) {
+ if (mKeyguardUpdateManager.needsSlowUnlockTransition()) {
fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
}
long uptimeMillis = SystemClock.uptimeMillis();
@@ -800,12 +816,11 @@
updateLockIcon();
}
- KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
- updateMonitor.onKeyguardVisibilityChanged(showing && !occluded);
+ mKeyguardUpdateManager.onKeyguardVisibilityChanged(showing && !occluded);
}
if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
- updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
+ mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerShowing);
}
mFirstUpdate = false;
@@ -889,8 +904,7 @@
}
public boolean isGoingToNotificationShade() {
- return ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
- .leaveOpenOnKeyguardHide();
+ return mStatusBarStateController.leaveOpenOnKeyguardHide();
}
public boolean isSecure(int userId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
index 67f6a0c..9811f96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
@@ -26,19 +26,19 @@
import com.android.internal.logging.MetricsLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.ForegroundServiceController;
+import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NavigationBarController;
@@ -60,7 +60,6 @@
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -71,7 +70,8 @@
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
+
+import java.util.Optional;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -97,7 +97,6 @@
AutoHideController autoHideController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarIconController statusBarIconController,
- DozeLog dozeLog,
PulseExpansionHandler pulseExpansionHandler,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
@@ -115,10 +114,7 @@
NotificationEntryManager notificationEntryManager,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
- ForegroundServiceController foregroundServiceController,
- AppOpsController appOpsController,
KeyguardViewMediator keyguardViewMediator,
- ZenModeController zenModeController,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@@ -145,7 +141,6 @@
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
- NotifLog notifLog,
DozeParameters dozeParameters,
ScrimController scrimController,
@Nullable KeyguardLiftController keyguardLiftController,
@@ -157,7 +152,12 @@
CommandQueue commandQueue,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
- SuperStatusBarViewFactory superStatusBarViewFactory) {
+ Optional<Divider> dividerOptional,
+ LightsOutNotifController lightsOutNotifController,
+ SuperStatusBarViewFactory superStatusBarViewFactory,
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ ViewMediatorCallback viewMediatorCallback,
+ DismissCallbackRegistry dismissCallbackRegistry) {
return new StatusBar(
context,
featureFlags,
@@ -165,7 +165,6 @@
autoHideController,
keyguardUpdateMonitor,
statusBarIconController,
- dozeLog,
pulseExpansionHandler,
notificationWakeUpCoordinator,
keyguardBypassController,
@@ -183,10 +182,7 @@
notificationEntryManager,
notificationInterruptionStateProvider,
notificationViewHierarchyManager,
- foregroundServiceController,
- appOpsController,
keyguardViewMediator,
- zenModeController,
notificationAlertingManager,
displayMetrics,
metricsLogger,
@@ -213,7 +209,6 @@
configurationController,
statusBarWindowController,
statusBarWindowViewControllerBuilder,
- notifLog,
dozeParameters,
scrimController,
keyguardLiftController,
@@ -225,6 +220,11 @@
commandQueue,
pluginManager,
remoteInputUriController,
- superStatusBarViewFactory);
+ dividerOptional,
+ lightsOutNotifController,
+ superStatusBarViewFactory,
+ statusBarKeyguardViewManager,
+ viewMediatorCallback,
+ dismissCallbackRegistry);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 02e5ebf..38ff862 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -79,7 +79,8 @@
public class StatusBarNotificationPresenter implements NotificationPresenter,
ConfigurationController.ConfigurationListener,
- NotificationRowBinderImpl.BindRowCallback {
+ NotificationRowBinderImpl.BindRowCallback,
+ CommandQueue.Callbacks {
private final LockscreenGestureLogger mLockscreenGestureLogger =
Dependency.get(LockscreenGestureLogger.class);
@@ -185,17 +186,6 @@
Dependency.get(InitController.class).addPostInitTask(() -> {
NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
@Override
- public void onNotificationAdded(NotificationEntry entry) {
- // Recalculate the position of the sliding windows and the titles.
- mShadeController.updateAreThereNotifications();
- }
-
- @Override
- public void onPostEntryUpdated(NotificationEntry entry) {
- mShadeController.updateAreThereNotifications();
- }
-
- @Override
public void onEntryRemoved(
@Nullable NotificationEntry entry,
NotificationVisibility visibility,
@@ -333,7 +323,6 @@
}
}
}
- mShadeController.updateAreThereNotifications();
}
public boolean hasActiveNotifications() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 768bd13..bb4387eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -41,6 +41,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.appops.AppOpsController;
import com.android.systemui.statusbar.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -52,6 +53,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -59,12 +62,13 @@
private ForegroundServiceController mFsc;
private ForegroundServiceNotificationListener mListener;
private NotificationEntryListener mEntryListener;
- private NotificationEntryManager mEntryManager;
+ @Mock private NotificationEntryManager mEntryManager;
+ @Mock private AppOpsController mAppOpsController;
@Before
public void setUp() throws Exception {
- mEntryManager = mock(NotificationEntryManager.class);
- mFsc = new ForegroundServiceController(mEntryManager);
+ MockitoAnnotations.initMocks(this);
+ mFsc = new ForegroundServiceController(mEntryManager, mAppOpsController);
mListener = new ForegroundServiceNotificationListener(
mContext, mFsc, mEntryManager);
ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index c815279..cbfcfdd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -18,14 +18,12 @@
import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
-import android.content.Context;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -34,8 +32,6 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingManagerFake;
@@ -60,8 +56,8 @@
private @Mock KeyguardUpdateMonitor mUpdateMonitor;
private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private @Mock StatusBarWindowController mStatusBarWindowController;
- private @Mock SystemUIFactory mSystemUIFactory;
private @Mock BroadcastDispatcher mBroadcastDispatcher;
+ private @Mock DismissCallbackRegistry mDismissCallbackRegistry;
private FalsingManagerFake mFalsingManager;
@@ -76,15 +72,11 @@
mStatusBarWindowController);
when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
- when(mSystemUIFactory.createStatusBarKeyguardViewManager(
- any(Context.class),
- any(ViewMediatorCallback.class),
- any(LockPatternUtils.class))).thenReturn(mStatusBarKeyguardViewManager);
TestableLooper.get(this).runWithLooper(() -> {
mViewMediator = new KeyguardViewMediator(
mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher,
- mSystemUIFactory);
+ () -> mStatusBarKeyguardViewManager, mDismissCallbackRegistry);
});
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
new file mode 100644
index 0000000..99850e7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.systemui.screenshot;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+/**
+ * Tests for exception handling and bitmap configuration in adding smart actions to Screenshot
+ * Notification.
+ */
+public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
+ private ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
+ private Handler mHandler;
+
+ @Before
+ public void setup() {
+ mSmartActionsProvider = mock(
+ ScreenshotNotificationSmartActionsProvider.class);
+ mHandler = mock(Handler.class);
+ }
+
+ // Tests any exception thrown in getting smart actions future does not affect regular
+ // screenshot flow.
+ @Test
+ public void testExceptionHandlingInGetSmartActionsFuture()
+ throws Exception {
+ Bitmap bitmap = mock(Bitmap.class);
+ when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
+ ScreenshotNotificationSmartActionsProvider smartActionsProvider = mock(
+ ScreenshotNotificationSmartActionsProvider.class);
+ when(smartActionsProvider.getActions(any(), any(), any(), any(), any(),
+ eq(false))).thenThrow(
+ RuntimeException.class);
+ CompletableFuture<List<Notification.Action>> smartActionsFuture =
+ GlobalScreenshot.getSmartActionsFuture(mContext, bitmap,
+ smartActionsProvider, mHandler, true, false);
+ Assert.assertNotNull(smartActionsFuture);
+ List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
+ Assert.assertEquals(Collections.emptyList(), smartActions);
+ }
+
+ // Tests any exception thrown in waiting for smart actions future to complete does
+ // not affect regular screenshot flow.
+ @Test
+ public void testExceptionHandlingInGetSmartActions()
+ throws Exception {
+ CompletableFuture<List<Notification.Action>> smartActionsFuture = mock(
+ CompletableFuture.class);
+ int timeoutMs = 1000;
+ when(smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)).thenThrow(
+ RuntimeException.class);
+ List<Notification.Action> actions = GlobalScreenshot.getSmartActions(
+ smartActionsFuture, timeoutMs);
+ Assert.assertEquals(Collections.emptyList(), actions);
+ }
+
+ // Tests for a non-hardware bitmap, ScreenshotNotificationSmartActionsProvider is never invoked
+ // and a completed future is returned.
+ @Test
+ public void testUnsupportedBitmapConfiguration()
+ throws Exception {
+ Bitmap bitmap = mock(Bitmap.class);
+ when(bitmap.getConfig()).thenReturn(Bitmap.Config.RGB_565);
+ CompletableFuture<List<Notification.Action>> smartActionsFuture =
+ GlobalScreenshot.getSmartActionsFuture(mContext, bitmap,
+ mSmartActionsProvider, mHandler, true, true);
+ verify(mSmartActionsProvider, never()).getActions(any(), any(), any(), any(), any(),
+ eq(false));
+ Assert.assertNotNull(smartActionsFuture);
+ List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
+ Assert.assertEquals(Collections.emptyList(), smartActions);
+ }
+
+ // Tests for a hardware bitmap, ScreenshotNotificationSmartActionsProvider is invoked once.
+ @Test
+ public void testScreenshotNotificationSmartActionsProviderInvokedOnce() {
+ Bitmap bitmap = mock(Bitmap.class);
+ when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
+ GlobalScreenshot.getSmartActionsFuture(mContext, bitmap, mSmartActionsProvider,
+ mHandler, true, true);
+ verify(mSmartActionsProvider, times(1))
+ .getActions(any(), any(), any(), any(), any(), eq(true));
+ }
+
+ // Tests for a hardware bitmap, a completed future is returned.
+ @Test
+ public void testSupportedBitmapConfiguration()
+ throws Exception {
+ Bitmap bitmap = mock(Bitmap.class);
+ when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
+ ScreenshotNotificationSmartActionsProvider actionsProvider =
+ SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider();
+ CompletableFuture<List<Notification.Action>> smartActionsFuture =
+ GlobalScreenshot.getSmartActionsFuture(mContext, bitmap,
+ actionsProvider,
+ mHandler, true, true);
+ Assert.assertNotNull(smartActionsFuture);
+ List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
+ Assert.assertEquals(smartActions.size(), 0);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index cf6fd4a..d9be8d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -34,8 +34,11 @@
import android.app.trust.TrustManager;
import android.content.Context;
import android.graphics.Color;
+import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Looper;
+import android.os.UserManager;
import android.view.View;
import android.view.ViewGroup;
@@ -51,6 +54,7 @@
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -84,6 +88,10 @@
private StatusBarStateController mStatusBarStateController;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ @Mock
+ private UserManager mUserManager;
private KeyguardIndicationTextView mTextView;
private KeyguardIndicationController mController;
@@ -97,9 +105,13 @@
mTextView = new KeyguardIndicationTextView(mContext);
mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+ mContext.addMockSystemService(UserManager.class, mUserManager);
mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
+ when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.isScreenOn()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
mWakeLock = new WakeLockFake();
@@ -112,6 +124,7 @@
mController = new KeyguardIndicationController(mContext, mIndicationArea, mLockIcon,
mLockPatternUtils, mWakeLock, mShadeController, mAccessibilityController,
mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor);
+ mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
}
@Test
@@ -167,6 +180,49 @@
}
@Test
+ public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromHelp() {
+ createController();
+ String message = "A message";
+
+ mController.setVisible(true);
+ mController.getKeyguardCallback().onBiometricHelp(
+ KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
+ BiometricSourceType.FACE);
+ assertThat(mTextView.getText()).isEqualTo(message);
+ mController.setDozing(true);
+
+ assertThat(mTextView.getText()).isNotEqualTo(message);
+ }
+
+ @Test
+ public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() {
+ createController();
+ String message = mContext.getString(R.string.keyguard_unlock);
+
+ mController.setVisible(true);
+ mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
+ "A message", BiometricSourceType.FACE);
+
+ assertThat(mTextView.getText()).isEqualTo(message);
+ mController.setDozing(true);
+
+ assertThat(mTextView.getText()).isNotEqualTo(message);
+ }
+
+ @Test
+ public void transientIndication_swipeUpToRetry() {
+ createController();
+ String message = mContext.getString(R.string.keyguard_retry);
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+
+ mController.setVisible(true);
+ mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
+ "A message", BiometricSourceType.FACE);
+
+ verify(mStatusBarKeyguardViewManager).showBouncerMessage(eq(message), any());
+ }
+
+ @Test
public void lockIcon_click() {
createController();
@@ -190,6 +246,7 @@
public void updateMonitor_listenerUpdatesIndication() {
createController();
String restingIndication = "Resting indication";
+ reset(mKeyguardUpdateMonitor);
mController.setVisible(true);
assertThat(mTextView.getText()).isEqualTo(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index b2a5109..86ef6e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -258,8 +258,7 @@
NotificationRowBinderImpl notificationRowBinder =
new NotificationRowBinderImpl(mContext, true, /* allowLongPress */
mock(KeyguardBypassController.class),
- mock(StatusBarStateController.class),
- mock(NotifLog.class));
+ mock(StatusBarStateController.class));
notificationRowBinder.setUpWithPresenter(
mPresenter, mListContainer, mHeadsUpManager, mEntryManager, mBindCallback);
notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index c2d2e31..cc56949 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -30,7 +30,6 @@
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.ForegroundServiceController;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationEntryBuilder;
@@ -60,7 +59,6 @@
@Mock private NotificationEntryManager mEntryManager;
@Mock private NotificationListContainer mListContainer;
- @Mock private ForegroundServiceController mForegroundServiceController;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
@@ -88,7 +86,6 @@
mController = new NotificationListController(
mEntryManager,
mListContainer,
- mForegroundServiceController,
mDeviceProvisionedController);
mController.bind();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 012ebf72..6f52e4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -82,6 +82,7 @@
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
@@ -123,6 +124,7 @@
@Mock private MetricsLogger mMetricsLogger;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private ZenModeController mZenModeController;
private TestableNotificationEntryManager mEntryManager;
private int mOriginalInterruptionModelSetting;
@@ -173,7 +175,8 @@
mock(NotificationLockscreenUserManager.class),
mock(NotificationGutsManager.class),
new NotificationSectionsFeatureManager(new DeviceConfigProxyFake(), mContext),
- mock(PeopleHubSectionFooterViewAdapter.class));
+ mock(PeopleHubSectionFooterViewAdapter.class),
+ mZenModeController);
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelf(notificationShelf);
mStackScroller.setStatusBar(mBar);
@@ -211,7 +214,7 @@
@Test
public void updateEmptyView_dndSuppressing() {
when(mEmptyShadeView.willBeGone()).thenReturn(true);
- when(mBar.areNotificationsHidden()).thenReturn(true);
+ when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
mStackScroller.updateEmptyShadeView(true);
@@ -222,7 +225,7 @@
public void updateEmptyView_dndNotSuppressing() {
mStackScroller.setEmptyShadeView(mEmptyShadeView);
when(mEmptyShadeView.willBeGone()).thenReturn(true);
- when(mBar.areNotificationsHidden()).thenReturn(false);
+ when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
mStackScroller.updateEmptyShadeView(true);
@@ -233,11 +236,11 @@
public void updateEmptyView_noNotificationsToDndSuppressing() {
mStackScroller.setEmptyShadeView(mEmptyShadeView);
when(mEmptyShadeView.willBeGone()).thenReturn(true);
- when(mBar.areNotificationsHidden()).thenReturn(false);
+ when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
mStackScroller.updateEmptyShadeView(true);
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
- when(mBar.areNotificationsHidden()).thenReturn(true);
+ when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
mStackScroller.updateEmptyShadeView(true);
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
new file mode 100644
index 0000000..64c1b51
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
@@ -0,0 +1,251 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.Display;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+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;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class LightsOutNotifControllerTest extends SysuiTestCase {
+ private static final int LIGHTS_ON = 0;
+ private static final int LIGHTS_OUT = APPEARANCE_LOW_PROFILE_BARS;
+
+ @Mock private NotificationEntryManager mEntryManager;
+ @Mock private NotificationData mNotificationData;
+ @Mock private CommandQueue mCommandQueue;
+ @Mock private WindowManager mWindowManager;
+ @Mock private Display mDisplay;
+
+ @Captor private ArgumentCaptor<NotificationEntryListener> mListenerCaptor;
+ @Captor private ArgumentCaptor<CommandQueue.Callbacks> mCallbacksCaptor;
+
+ private View mLightsOutView;
+ private LightsOutNotifController mLightsOutNotifController;
+ private ArrayList<NotificationEntry> mActiveNotifications = new ArrayList<>();
+ private int mDisplayId;
+ private NotificationEntryListener mEntryListener;
+ private CommandQueue.Callbacks mCallbacks;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDisplayId = mContext.getDisplayId();
+ mLightsOutView = new View(mContext);
+ when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
+ when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
+ when(mWindowManager.getDefaultDisplay()).thenReturn(mDisplay);
+ when(mDisplay.getDisplayId()).thenReturn(mDisplayId);
+
+ mLightsOutNotifController = new LightsOutNotifController(mWindowManager, mEntryManager,
+ mCommandQueue);
+ mLightsOutNotifController.setLightsOutNotifView(mLightsOutView);
+
+ // Capture the entry listener object so we can simulate events in tests below
+ verify(mEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
+ mEntryListener = checkNotNull(mListenerCaptor.getValue());
+
+ // Capture the callback object so we can simulate callback events in tests below
+ verify(mCommandQueue).addCallback(mCallbacksCaptor.capture());
+ mCallbacks = checkNotNull(mCallbacksCaptor.getValue());
+ }
+
+ @Test
+ public void testAreLightsOut_lightsOut() {
+ mCallbacks.onSystemBarAppearanceChanged(
+ mDisplayId /* display id */,
+ LIGHTS_OUT /* appearance */,
+ null /* appearanceRegions */,
+ false /* navbarColorManagedByIme */);
+ assertTrue(mLightsOutNotifController.areLightsOut());
+ }
+
+ @Test
+ public void testAreLightsOut_lightsOn() {
+ mCallbacks.onSystemBarAppearanceChanged(
+ mDisplayId /* display id */,
+ LIGHTS_ON /* appearance */,
+ null /* appearanceRegions */,
+ false /* navbarColorManagedByIme */);
+ assertFalse(mLightsOutNotifController.areLightsOut());
+ }
+
+ @Test
+ public void testIsShowingDot_visible() {
+ mLightsOutView.setVisibility(View.VISIBLE);
+ mLightsOutView.setAlpha(1.0f);
+ assertTrue(mLightsOutNotifController.isShowingDot());
+ }
+
+ @Test
+ public void testIsShowingDot_gone() {
+ mLightsOutView.setVisibility(View.GONE);
+ mLightsOutView.setAlpha(0f);
+ assertFalse(mLightsOutNotifController.isShowingDot());
+ }
+
+ @Test
+ public void testLightsOut_withNotifs_onSystemBarAppearanceChanged() {
+ // GIVEN active visible notifications
+ mActiveNotifications.add(mock(NotificationEntry.class));
+
+ // WHEN lights out
+ mCallbacks.onSystemBarAppearanceChanged(
+ mDisplayId /* display id */,
+ LIGHTS_OUT /* appearance */,
+ null /* appearanceRegions */,
+ false /* navbarColorManagedByIme */);
+
+ // THEN we should show dot
+ assertTrue(mLightsOutNotifController.shouldShowDot());
+ assertIsShowingDot(true);
+ }
+
+ @Test
+ public void testLightsOut_withoutNotifs_onSystemBarAppearanceChanged() {
+ // GIVEN no active visible notifications
+ mActiveNotifications.clear();
+
+ // WHEN lights out
+ mCallbacks.onSystemBarAppearanceChanged(
+ mDisplayId /* display id */,
+ LIGHTS_OUT /* appearance */,
+ null /* appearanceRegions */,
+ false /* navbarColorManagedByIme */);
+
+ // THEN we shouldn't show the dot
+ assertFalse(mLightsOutNotifController.shouldShowDot());
+ assertIsShowingDot(false);
+ }
+
+ @Test
+ public void testLightsOn_afterLightsOut_onSystemBarAppearanceChanged() {
+ // GIVEN active visible notifications
+ mActiveNotifications.add(mock(NotificationEntry.class));
+
+ // WHEN lights on
+ mCallbacks.onSystemBarAppearanceChanged(
+ mDisplayId /* display id */,
+ LIGHTS_ON /* appearance */,
+ null /* appearanceRegions */,
+ false /* navbarColorManagedByIme */);
+
+ // THEN we shouldn't show the dot
+ assertFalse(mLightsOutNotifController.shouldShowDot());
+ assertIsShowingDot(false);
+ }
+
+ @Test
+ public void testEntryAdded() {
+ // GIVEN no visible notifications and lights out
+ mActiveNotifications.clear();
+ mLightsOutNotifController.mAppearance = LIGHTS_OUT;
+ mLightsOutNotifController.updateLightsOutView();
+ assertIsShowingDot(false);
+
+ // WHEN an active notification is added
+ mActiveNotifications.add(mock(NotificationEntry.class));
+ assertTrue(mLightsOutNotifController.shouldShowDot());
+ mEntryListener.onNotificationAdded(mock(NotificationEntry.class));
+
+ // THEN we should see the dot view
+ assertIsShowingDot(true);
+ }
+
+ @Test
+ public void testEntryRemoved() {
+ // GIVEN a visible notification and lights out
+ mActiveNotifications.add(mock(NotificationEntry.class));
+ mLightsOutNotifController.mAppearance = LIGHTS_OUT;
+ mLightsOutNotifController.updateLightsOutView();
+ assertIsShowingDot(true);
+
+ // WHEN all active notifications are removed
+ mActiveNotifications.clear();
+ assertFalse(mLightsOutNotifController.shouldShowDot());
+ mEntryListener.onEntryRemoved(mock(NotificationEntry.class), null, false);
+
+ // THEN we shouldn't see the dot view
+ assertIsShowingDot(false);
+ }
+
+ @Test
+ public void testEntryUpdated() {
+ // GIVEN no visible notifications and lights out
+ mActiveNotifications.clear();
+ mLightsOutNotifController.mAppearance = LIGHTS_OUT;
+ mLightsOutNotifController.updateLightsOutView();
+ assertIsShowingDot(false);
+
+ // WHEN an active notification is added
+ mActiveNotifications.add(mock(NotificationEntry.class));
+ assertTrue(mLightsOutNotifController.shouldShowDot());
+ mEntryListener.onPostEntryUpdated(mock(NotificationEntry.class));
+
+ // THEN we should see the dot view
+ assertIsShowingDot(true);
+ }
+
+ private void assertIsShowingDot(boolean isShowing) {
+ // cancel the animation so we can check the end state
+ final ViewPropertyAnimator animation = mLightsOutView.animate();
+ if (animation != null) {
+ animation.cancel();
+ }
+
+ if (isShowing) {
+ assertTrue(mLightsOutNotifController.isShowingDot());
+ } else {
+ assertFalse(mLightsOutNotifController.isShowingDot());
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 1255001..9763675 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -79,6 +79,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Optional;
+
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
@@ -95,6 +97,10 @@
private SysUiState mMockSysUiState;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock
+ private Divider mDivider;
+ @Mock
+ private Recents mRecents;
private AccessibilityManagerWrapper mAccessibilityWrapper =
new AccessibilityManagerWrapper(mContext) {
@@ -152,16 +158,12 @@
private void setupSysuiDependency() {
mSysuiContext.putComponent(StatusBar.class, mock(StatusBar.class));
- mSysuiContext.putComponent(Recents.class, mock(Recents.class));
- mSysuiContext.putComponent(Divider.class, mock(Divider.class));
Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
mSysuiTestableContextExternal = (SysuiTestableContext) mSysuiContext.createDisplayContext(
display);
mSysuiTestableContextExternal.putComponent(StatusBar.class, mock(StatusBar.class));
- mSysuiTestableContextExternal.putComponent(Recents.class, mock(Recents.class));
- mSysuiTestableContextExternal.putComponent(Divider.class, mock(Divider.class));
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
WindowManager windowManager = mock(WindowManager.class);
@@ -251,7 +253,9 @@
mock(StatusBarStateController.class),
mMockSysUiState,
mBroadcastDispatcher,
- mCommandQueue);
+ mCommandQueue,
+ mDivider,
+ Optional.of(mRecents));
}
private class HostCallbacksForExternalDisplay extends
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 3e07cff..61e5058 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -41,12 +41,13 @@
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -91,16 +92,21 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mDependency.injectMockDependency(StatusBarWindowController.class);
- mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
- mDependency.injectMockDependency(NotificationMediaManager.class);
- mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
- mDependency.injectTestDependency(KeyguardStateController.class, mKeyguardStateController);
when(mLockIconContainer.getParent()).thenReturn(mock(ViewGroup.class));
when(mLockIconContainer.animate()).thenReturn(mock(ViewPropertyAnimator.class,
RETURNS_DEEP_STUBS));
- mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(getContext(),
- mViewMediatorCallback, mLockPatternUtils);
+ mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(
+ getContext(),
+ mViewMediatorCallback,
+ mLockPatternUtils,
+ mStatusBarStateController,
+ mock(ConfigurationController.class),
+ mock(KeyguardUpdateMonitor.class),
+ mock(NavigationModeController.class),
+ mock(DockManager.class),
+ mock(StatusBarWindowController.class),
+ mKeyguardStateController,
+ mock(NotificationMediaManager.class));
mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry,
mLockIconContainer, mNotificationContainer, mBypassController,
@@ -258,8 +264,19 @@
public TestableStatusBarKeyguardViewManager(Context context,
ViewMediatorCallback callback,
- LockPatternUtils lockPatternUtils) {
- super(context, callback, lockPatternUtils);
+ LockPatternUtils lockPatternUtils,
+ SysuiStatusBarStateController sysuiStatusBarStateController,
+ ConfigurationController configurationController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ NavigationModeController navigationModeController,
+ DockManager dockManager,
+ StatusBarWindowController statusBarWindowController,
+ KeyguardStateController keyguardStateController,
+ NotificationMediaManager notificationMediaManager) {
+ super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
+ configurationController, keyguardUpdateMonitor, navigationModeController,
+ dockManager, statusBarWindowController, keyguardStateController,
+ notificationMediaManager);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index ecb2d81..62fd0c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -74,24 +74,23 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Dependency;
-import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -145,6 +144,7 @@
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Optional;
import dagger.Lazy;
@@ -198,13 +198,10 @@
@Mock private AssistManager mAssistManager;
@Mock private NotificationGutsManager mNotificationGutsManager;
@Mock private NotificationMediaManager mNotificationMediaManager;
- @Mock private ForegroundServiceController mForegroundServiceController;
- @Mock private AppOpsController mAppOpsController;
@Mock private NavigationBarController mNavigationBarController;
@Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier;
@Mock private SysuiColorExtractor mColorExtractor;
@Mock private ColorExtractor.GradientColors mGradientColors;
- @Mock private DozeLog mDozeLog;
@Mock private PulseExpansionHandler mPulseExpansionHandler;
@Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@Mock private KeyguardBypassController mKeyguardBypassController;
@@ -233,7 +230,11 @@
@Mock private KeyguardLiftController mKeyguardLiftController;
@Mock private CommandQueue mCommandQueue;
@Mock private PluginManager mPluginManager;
+ @Mock private Divider mDivider;
@Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+ @Mock private LightsOutNotifController mLightsOutNotifController;
+ @Mock private ViewMediatorCallback mViewMediatorCallback;
+ @Mock private DismissCallbackRegistry mDismissCallbackRegistry;
@Before
public void setup() throws Exception {
@@ -308,7 +309,6 @@
mAutoHideController,
mKeyguardUpdateMonitor,
mStatusBarIconController,
- mDozeLog,
mPulseExpansionHandler,
mNotificationWakeUpCoordinator,
mKeyguardBypassController,
@@ -330,10 +330,7 @@
entryManager,
mNotificationInterruptionStateProvider,
mNotificationViewHierarchyManager,
- mForegroundServiceController,
- mAppOpsController,
mKeyguardViewMediator,
- mZenModeController,
mNotificationAlertingManager,
new DisplayMetrics(),
mMetricsLogger,
@@ -360,7 +357,6 @@
configurationController,
mStatusBarWindowController,
mStatusBarWindowViewControllerBuilder,
- mNotifLog,
mDozeParameters,
mScrimController,
mKeyguardLiftController,
@@ -372,7 +368,12 @@
mCommandQueue,
mPluginManager,
mRemoteInputUriController,
- mSuperStatusBarViewFactory);
+ Optional.of(mDivider),
+ mLightsOutNotifController,
+ mSuperStatusBarViewFactory,
+ mStatusBarKeyguardViewManager,
+ mViewMediatorCallback,
+ mDismissCallbackRegistry);
when(mStatusBarWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
mLockIconContainer);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 067becb..8f1e156 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -335,6 +335,16 @@
return new ComponentNameSet(setting).contains(component);
}
+ @Override
+ public boolean isDeviceAssociated(String packageName, String macAddress, int userId) {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_COMPANION_DEVICES, "isDeviceAssociated");
+
+ return CollectionUtils.any(
+ readAllAssociations(userId, packageName),
+ a -> Objects.equals(a.deviceAddress, macAddress));
+ }
+
private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
checkCallerIsSystemOr(callingPackage);
int userId = getCallingUserId();
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
index ecea251c..9cdb58d 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
@@ -16,7 +16,6 @@
package com.android.server.contentsuggestions;
-import static android.Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE;
import static android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -96,7 +95,7 @@
private void enforceCaller(int userId, String func) {
Context ctx = getContext();
- if (ctx.checkCallingPermission(BIND_CONTENT_SUGGESTIONS_SERVICE) == PERMISSION_GRANTED
+ if (ctx.checkCallingPermission(MANAGE_CONTENT_SUGGESTIONS) == PERMISSION_GRANTED
|| mServiceNameResolver.isTemporary(userId)
|| mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) {
return;
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 486cd5f..7d5b176 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -699,14 +699,16 @@
Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
+ (idle ? " idle" : " active") + " " + bucket);
}
- final boolean changed;
- if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
- changed = mExemptedPackages.add(userId, packageName);
- } else {
- changed = mExemptedPackages.remove(userId, packageName);
- }
- if (changed) {
- mHandler.notifyExemptChanged();
+ synchronized (mLock) {
+ final boolean changed;
+ if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
+ changed = mExemptedPackages.add(userId, packageName);
+ } else {
+ changed = mExemptedPackages.remove(userId, packageName);
+ }
+ if (changed) {
+ mHandler.notifyExemptChanged();
+ }
}
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ce0e9e7..81eb4b3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -97,6 +97,7 @@
import android.net.NetworkPolicyManager;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
+import android.net.NetworkScore;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
@@ -2643,7 +2644,8 @@
break;
}
case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
- updateNetworkScore(nai, msg.arg1);
+ final NetworkScore ns = (NetworkScore) msg.obj;
+ updateNetworkScore(nai, ns);
break;
}
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
@@ -5594,9 +5596,11 @@
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
+ final NetworkScore ns = new NetworkScore();
+ ns.putIntExtension(NetworkScore.LEGACY_SCORE, currentScore);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
- currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd,
+ ns, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd,
mDnsResolver, mNMS, factorySerialNumber);
// Make sure the network capabilities reflect what the agent info says.
nai.setNetworkCapabilities(mixInCapabilities(nai, nc));
@@ -6729,7 +6733,8 @@
}
}
- private void updateNetworkScore(NetworkAgentInfo nai, int score) {
+ 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 +
@@ -6738,7 +6743,7 @@
}
final int oldScore = nai.getCurrentScore();
- nai.setCurrentScore(score);
+ nai.setNetworkScore(ns);
rematchAllNetworksAndRequests(nai, oldScore);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 0ea913f..4361676 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1903,6 +1903,7 @@
}
// Optimization - if there is no pending user switch, return current id
+ // (no need to acquire lock because mTargetUserId and mCurrentUserId are volatile)
if (mTargetUserId == UserHandle.USER_NULL) {
return getUserInfo(mCurrentUserId);
}
@@ -1919,7 +1920,7 @@
int getCurrentOrTargetUserId() {
synchronized (mLock) {
- return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
+ return getCurrentOrTargetUserIdLU();
}
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 2e36a43..7e9a17b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -47,8 +47,8 @@
import android.app.AppOpsManager.HistoricalOps;
import android.app.AppOpsManager.HistoricalOpsRequest;
import android.app.AppOpsManager.Mode;
-import android.app.AppOpsManager.OpFeatureEntry;
import android.app.AppOpsManager.OpEntry;
+import android.app.AppOpsManager.OpFeatureEntry;
import android.app.AppOpsManager.OpFlags;
import android.app.AppOpsManagerInternal;
import android.app.AppOpsManagerInternal.CheckOpsDelegate;
@@ -119,6 +119,12 @@
import com.android.server.LocalServices;
import com.android.server.LockGuard;
+import libcore.util.EmptyArray;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -138,12 +144,6 @@
import java.util.Map;
import java.util.Objects;
-import libcore.util.EmptyArray;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
public class AppOpsService extends IAppOpsService.Stub {
static final String TAG = "AppOps";
static final boolean DEBUG = false;
@@ -2356,7 +2356,6 @@
public void noteAsyncOp(String callingPackageName, int uid, String packageName, int opCode,
String featureId, String message) {
Preconditions.checkNotNull(message);
- Preconditions.checkNotNull(packageName);
verifyAndGetIsPrivileged(uid, packageName);
verifyIncomingUid(uid);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 96b7cb3..24a5b7f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -28,6 +28,7 @@
import android.net.NetworkMisc;
import android.net.NetworkMonitorManager;
import android.net.NetworkRequest;
+import android.net.NetworkScore;
import android.net.NetworkState;
import android.os.Handler;
import android.os.INetworkManagementService;
@@ -227,8 +228,10 @@
// validated).
private boolean mLingering;
- // This represents the last score received from the NetworkAgent.
- private int currentScore;
+ // This represents the characteristics of a network that affects how good the network is
+ // considered for a particular use.
+ @NonNull
+ private NetworkScore mNetworkScore;
// The list of NetworkRequests being satisfied by this Network.
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
@@ -257,8 +260,8 @@
private final Handler mHandler;
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
- LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
- NetworkMisc misc, ConnectivityService connService, INetd netd,
+ LinkProperties lp, NetworkCapabilities nc, @NonNull NetworkScore ns, Context context,
+ Handler handler, NetworkMisc misc, ConnectivityService connService, INetd netd,
IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
this.messenger = messenger;
asyncChannel = ac;
@@ -266,7 +269,7 @@
networkInfo = info;
linkProperties = lp;
networkCapabilities = nc;
- currentScore = score;
+ mNetworkScore = ns;
clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
mConnService = connService;
mContext = context;
@@ -483,7 +486,7 @@
return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
}
- int score = currentScore;
+ int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE);
if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
}
@@ -512,8 +515,13 @@
return getCurrentScore(true);
}
- public void setCurrentScore(int newScore) {
- currentScore = newScore;
+ public void setNetworkScore(@NonNull NetworkScore ns) {
+ mNetworkScore = ns;
+ }
+
+ @NonNull
+ public NetworkScore getNetworkScore() {
+ return mNetworkScore;
}
public NetworkState getNetworkState() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5e76401..5b39fb6 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -8960,6 +8960,7 @@
@VisibleForTesting
void resetAssistantUserSet(int userId) {
+ checkCallerIsSystemOrShell();
mAssistants.setUserSet(userId, false);
handleSavePolicyFile();
}
@@ -8967,12 +8968,14 @@
@VisibleForTesting
@Nullable
ComponentName getApprovedAssistant(int userId) {
+ checkCallerIsSystemOrShell();
List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
return CollectionUtils.firstOrNull(allowedComponents);
}
@VisibleForTesting
protected void simulatePackageSuspendBroadcast(boolean suspend, String pkg) {
+ checkCallerIsSystemOrShell();
// only use for testing: mimic receive broadcast that package is (un)suspended
// but does not actually (un)suspend the package
final Bundle extras = new Bundle();
@@ -8989,6 +8992,7 @@
@VisibleForTesting
protected void simulatePackageDistractionBroadcast(int flag, String[] pkgs) {
+ checkCallerIsSystemOrShell();
// only use for testing: mimic receive broadcast that package is (un)distracting
// but does not actually register that info with packagemanager
final Bundle extras = new Bundle();
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index 979015d..50f16bc 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -32,11 +32,13 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.media.IRingtonePlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Process;
@@ -56,6 +58,7 @@
* Implementation of `cmd notification` in NotificationManagerService.
*/
public class NotificationShellCmd extends ShellCommand {
+ private static final String TAG = "NotifShellCmd";
private static final String USAGE = "usage: cmd notification SUBCMD [args]\n\n"
+ "SUBCMDs:\n"
+ " allow_listener COMPONENT [user_id (current user if not specified)]\n"
@@ -98,18 +101,19 @@
+ "an <intentspec> is (broadcast|service|activity) <args>\n"
+ " <args> are as described in `am start`";
- public static final int NOTIFICATION_ID = 1138;
- public static final String NOTIFICATION_PACKAGE = "android";
- public static final String CHANNEL_ID = "shellcmd";
+ public static final int NOTIFICATION_ID = 2020;
+ public static final String CHANNEL_ID = "shell_cmd";
public static final String CHANNEL_NAME = "Shell command";
public static final int CHANNEL_IMP = NotificationManager.IMPORTANCE_DEFAULT;
private final NotificationManagerService mDirectService;
private final INotificationManager mBinderService;
+ private final PackageManager mPm;
public NotificationShellCmd(NotificationManagerService service) {
mDirectService = service;
mBinderService = service.getBinderService();
+ mPm = mDirectService.getContext().getPackageManager();
}
@Override
@@ -117,6 +121,19 @@
if (cmd == null) {
return handleDefaultCommands(cmd);
}
+ String callingPackage = null;
+ final int callingUid = Binder.getCallingUid();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ String[] packages = mPm.getPackagesForUid(callingUid);
+ if (packages != null && packages.length > 0) {
+ callingPackage = packages[0];
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "failed to get caller pkg", e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
final PrintWriter pw = getOutPrintWriter();
try {
switch (cmd.replace('-', '_')) {
@@ -139,8 +156,7 @@
interruptionFilter = INTERRUPTION_FILTER_ALL;
}
final int filter = interruptionFilter;
- Binder.withCleanCallingIdentity(() -> mBinderService.setInterruptionFilter(
- mDirectService.getContext().getPackageName(), filter));
+ mBinderService.setInterruptionFilter(callingPackage, filter);
}
break;
case "allow_dnd": {
@@ -258,7 +274,7 @@
}
case "post":
case "notify":
- doNotify(pw);
+ doNotify(pw, callingPackage, callingUid);
break;
default:
return handleDefaultCommands(cmd);
@@ -270,27 +286,14 @@
return 0;
}
- void ensureChannel() throws RemoteException {
- final int uid = Process.myUid();
- final int userid = UserHandle.getCallingUserId();
- final long token = Binder.clearCallingIdentity();
- try {
- if (mBinderService.getNotificationChannelForPackage(NOTIFICATION_PACKAGE,
- uid, CHANNEL_ID, false) == null) {
- final NotificationChannel chan = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
- CHANNEL_IMP);
- Slog.v(NotificationManagerService.TAG,
- "creating shell channel for user " + userid + " uid " + uid + ": " + chan);
- mBinderService.createNotificationChannelsForPackage(NOTIFICATION_PACKAGE, uid,
- new ParceledListSlice<NotificationChannel>(
- Collections.singletonList(chan)));
- Slog.v(NotificationManagerService.TAG, "created channel: "
- + mBinderService.getNotificationChannelForPackage(NOTIFICATION_PACKAGE,
- uid, CHANNEL_ID, false));
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ void ensureChannel(String callingPackage, int callingUid) throws RemoteException {
+ final NotificationChannel channel =
+ new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, CHANNEL_IMP);
+ mBinderService.createNotificationChannels(callingPackage,
+ new ParceledListSlice<>(Collections.singletonList(channel)));
+ Slog.v(NotificationManagerService.TAG, "created channel: "
+ + mBinderService.getNotificationChannel(callingPackage,
+ UserHandle.getUserId(callingUid), callingPackage, CHANNEL_ID));
}
Icon parseIcon(Resources res, String encoded) throws IllegalArgumentException {
@@ -319,7 +322,8 @@
return null;
}
- private int doNotify(PrintWriter pw) throws RemoteException, URISyntaxException {
+ private int doNotify(PrintWriter pw, String callingPackage, int callingUid)
+ throws RemoteException, URISyntaxException {
final Context context = mDirectService.getContext();
final Resources res = context.getResources();
final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
@@ -513,26 +517,18 @@
builder.setSmallIcon(smallIcon);
}
- ensureChannel();
+ ensureChannel(callingPackage, callingUid);
final Notification n = builder.build();
pw.println("posting:\n " + n);
Slog.v("NotificationManager", "posting: " + n);
- final int userId = UserHandle.getCallingUserId();
- final long token = Binder.clearCallingIdentity();
- try {
- mBinderService.enqueueNotificationWithTag(
- NOTIFICATION_PACKAGE, NOTIFICATION_PACKAGE,
- tag, NOTIFICATION_ID,
- n, userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ mBinderService.enqueueNotificationWithTag(callingPackage, callingPackage, tag,
+ NOTIFICATION_ID, n, UserHandle.getUserId(callingUid));
if (verbose) {
NotificationRecord nr = mDirectService.findNotificationLocked(
- NOTIFICATION_PACKAGE, tag, NOTIFICATION_ID, userId);
+ callingPackage, tag, NOTIFICATION_ID, UserHandle.getUserId(callingUid));
for (int tries = 3; tries-- > 0; ) {
if (nr != null) break;
try {
@@ -541,7 +537,7 @@
} catch (InterruptedException e) {
}
nr = mDirectService.findNotificationLocked(
- NOTIFICATION_PACKAGE, tag, NOTIFICATION_ID, userId);
+ callingPackage, tag, NOTIFICATION_ID, UserHandle.getUserId(callingUid));
}
if (nr == null) {
pw.println("warning: couldn't find notification after enqueueing");
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 082b08deb..887dbb3 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -138,6 +138,13 @@
private boolean mAreChannelsBypassingDnd;
private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS;
+ private static final String BADGING_FORCED_TRUE = "force_badging_true_for_bug";
+
+ // STOPSHIP (b/142218092) this should be removed before ship
+ static boolean wasBadgingForcedTrue(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(), BADGING_FORCED_TRUE, 0) != 0;
+ }
+
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
ZenModeHelper zenHelper) {
mContext = context;
@@ -145,6 +152,14 @@
mRankingHandler = rankingHandler;
mPm = pm;
+ // STOPSHIP (b/142218092) this should be removed before ship
+ if (!wasBadgingForcedTrue(context)) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BADGING,
+ DEFAULT_SHOW_BADGE ? 1 : 0);
+ Settings.Secure.putInt(context.getContentResolver(), BADGING_FORCED_TRUE, 1);
+ }
+
updateBadgingEnabled();
updateBubblesEnabled();
syncChannelsBypassingDnd(mContext.getUserId());
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 340720e..3c49afb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5694,11 +5694,9 @@
PackageSetting ps = it.next();
if (ps.getInstalled(userId)) {
res[i++] = ps.name;
- } else {
- res = ArrayUtils.removeElement(String.class, res, res[i]);
}
}
- return res;
+ return ArrayUtils.trimToSize(res, i);
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (ps.getInstalled(userId)
@@ -19766,6 +19764,23 @@
}
@Override
+ public String getContentCaptureServicePackageName() {
+ final String flattenedContentCaptureService =
+ mContext.getString(R.string.config_defaultContentCaptureService);
+
+ if (TextUtils.isEmpty(flattenedContentCaptureService)) {
+ return null;
+ }
+
+ final ComponentName contentCaptureServiceComponentName =
+ ComponentName.unflattenFromString(flattenedContentCaptureService);
+ if (contentCaptureServiceComponentName == null) {
+ return null;
+ }
+ return contentCaptureServiceComponentName.getPackageName();
+ }
+
+ @Override
public void setApplicationEnabledSetting(String appPackageName,
int newState, int flags, int userId, String callingPackage) {
if (!mUserManager.exists(userId)) return;
@@ -22256,8 +22271,9 @@
continue;
}
final String packageName = ps.pkg.packageName;
- // Skip over if system app
- if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ // Skip over if system app or static shared library
+ if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
+ || !TextUtils.isEmpty(ps.pkg.staticSharedLibName)) {
continue;
}
if (DEBUG_CLEAN_APKS) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f1c84b8..cc443cb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -115,6 +115,7 @@
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
@@ -438,8 +439,14 @@
}
}
- private void setParamsSize(InstallParams params, String inPath) {
- if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
+ private void setParamsSize(InstallParams params, List<String> inPaths) {
+ if (params.sessionParams.sizeBytes != -1 || STDIN_PATH.equals(inPaths.get(0))) {
+ return;
+ }
+
+ long sessionSize = 0;
+
+ for (String inPath : inPaths) {
final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
if (fd == null) {
getErrPrintWriter().println("Error: Can't open file: " + inPath);
@@ -449,8 +456,8 @@
ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
null, null);
- params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
- pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
+ sessionSize += PackageHelper.calculateInstalledSize(pkgLite,
+ params.sessionParams.abiOverride, fd.getFileDescriptor());
} catch (PackageParserException | IOException e) {
getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
throw new IllegalArgumentException(
@@ -462,6 +469,7 @@
}
}
}
+ params.sessionParams.setSize(sessionSize);
}
/**
* Displays the package file for a package.
@@ -1148,23 +1156,45 @@
private int runInstall() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
final InstallParams params = makeInstallParams();
- final String inPath = getNextArg();
- setParamsSize(params, inPath);
+ ArrayList<String> inPaths = getRemainingArgs();
+ if (inPaths.isEmpty()) {
+ pw.println("Error: must either specify APK files or '-' to read from stdin");
+ return 1;
+ }
+
+ final boolean hasSplits = inPaths.size() > 1;
+
+ if (STDIN_PATH.equals(inPaths.get(0))) {
+ if (hasSplits) {
+ pw.println("Error: can't specify SPLIT(s) along with '-'");
+ return 1;
+ }
+ if (params.sessionParams.sizeBytes == -1) {
+ pw.println("Error: must either specify a package size or an APK file");
+ return 1;
+ }
+ }
+
+ final boolean isApex =
+ (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
+ if (isApex && hasSplits) {
+ pw.println("Error: can't specify SPLIT(s) for APEX");
+ return 1;
+ }
+
+ setParamsSize(params, inPaths);
final int sessionId = doCreateSession(params.sessionParams,
params.installerPackageName, params.userId);
boolean abandonSession = true;
try {
- if (inPath == null && params.sessionParams.sizeBytes == -1) {
- pw.println("Error: must either specify a package size or an APK file");
- return 1;
- }
- final boolean isApex =
- (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
- String splitName = "base." + (isApex ? "apex" : "apk");
- if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
- false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
- return 1;
+ for (String inPath : inPaths) {
+ String splitName = hasSplits ? (new File(inPath)).getName()
+ : "base." + (isApex ? "apex" : "apk");
+ if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
+ false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
+ return 1;
+ }
}
if (doCommitSession(sessionId, false /*logSuccess*/)
!= PackageInstaller.STATUS_SUCCESS) {
@@ -1283,12 +1313,12 @@
final int sessionId = Integer.parseInt(getNextArg());
- final String splitName = getNextArg();
- if (splitName == null) {
+ ArrayList<String> splitNames = getRemainingArgs();
+ if (splitNames.isEmpty()) {
pw.println("Error: split name not specified");
return 1;
}
- return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
+ return doRemoveSplits(sessionId, splitNames, true /*logSuccess*/);
}
private int runInstallExisting() throws RemoteException {
@@ -1731,6 +1761,15 @@
return 0;
}
+ private ArrayList<String> getRemainingArgs() {
+ ArrayList<String> args = new ArrayList<>();
+ String arg;
+ while ((arg = getNextArg()) != null) {
+ args.add(arg);
+ }
+ return args;
+ }
+
private static class SnapshotRuntimeProfileCallback
extends ISnapshotRuntimeProfileCallback.Stub {
private boolean mSuccess = false;
@@ -1802,9 +1841,9 @@
}
// if a split is specified, just remove it and not the whole package
- final String splitName = getNextArg();
- if (splitName != null) {
- return runRemoveSplit(packageName, splitName);
+ ArrayList<String> splitNames = getRemainingArgs();
+ if (!splitNames.isEmpty()) {
+ return runRemoveSplits(packageName, splitNames);
}
userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
@@ -1852,7 +1891,8 @@
}
}
- private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
+ private int runRemoveSplits(String packageName, Collection<String> splitNames)
+ throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1861,7 +1901,7 @@
doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
boolean abandonSession = true;
try {
- if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
+ if (doRemoveSplits(sessionId, splitNames, false /*logSuccess*/)
!= PackageInstaller.STATUS_SUCCESS) {
return 1;
}
@@ -2945,14 +2985,17 @@
}
}
- private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
+ private int doRemoveSplits(int sessionId, Collection<String> splitNames, boolean logSuccess)
throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
PackageInstaller.Session session = null;
try {
session = new PackageInstaller.Session(
mInterface.getPackageInstaller().openSession(sessionId));
- session.removeSplit(splitName);
+
+ for (String splitName : splitNames) {
+ session.removeSplit(splitName);
+ }
if (logSuccess) {
pw.println("Success");
@@ -3237,9 +3280,9 @@
pw.println(" [--enable-rollback]");
pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
pw.println(" [--apex] [--wait TIMEOUT]");
- pw.println(" [PATH|-]");
- pw.println(" Install an application. Must provide the apk data to install, either as a");
- pw.println(" file path or '-' to read from stdin. Options are:");
+ pw.println(" [PATH [SPLIT...]|-]");
+ pw.println(" Install an application. Must provide the apk data to install, either as");
+ pw.println(" file path(s) or '-' to read from stdin. Options are:");
pw.println(" -R: disallow replacement of existing application");
pw.println(" -t: allow test packages");
pw.println(" -i: specify package name of installer owning the app");
@@ -3293,6 +3336,9 @@
pw.println(" will be read from stdin. Options are:");
pw.println(" -S: size in bytes of package, required for stdin");
pw.println("");
+ pw.println(" install-remove SESSION_ID SPLIT...");
+ pw.println(" Mark SPLIT(s) as removed in the given install session.");
+ pw.println("");
pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
pw.println(" Add one or more session IDs to a multi-package session.");
pw.println("");
@@ -3317,9 +3363,10 @@
pw.println("");
pw.println(" move-primary-storage [internal|UUID]");
pw.println("");
- pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
+ pw.println(" uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE]");
+ pw.println(" PACKAGE [SPLIT...]");
pw.println(" Remove the given package name from the system. May remove an entire app");
- pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
+ pw.println(" if no SPLIT names specified, otherwise will remove only the splits of the");
pw.println(" given app. Options are:");
pw.println(" -k: keep the data and cache directories around after package removal.");
pw.println(" --user: remove the app from the given user.");
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 f247037..603b01a 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -150,6 +150,12 @@
ALWAYS_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
}
+ private static final Set<String> COARSE_BACKGROUND_LOCATION_PERMISSIONS = new ArraySet<>();
+ static {
+ COARSE_BACKGROUND_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+ COARSE_BACKGROUND_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+ }
+
private static final Set<String> ACTIVITY_RECOGNITION_PERMISSIONS = new ArraySet<>();
static {
ACTIVITY_RECOGNITION_PERMISSIONS.add(Manifest.permission.ACTIVITY_RECOGNITION);
@@ -724,8 +730,16 @@
mContext.getPackageManager().getSystemTextClassifierPackageName();
if (!TextUtils.isEmpty(textClassifierPackageName)) {
grantPermissionsToSystemPackage(textClassifierPackageName, userId,
- PHONE_PERMISSIONS, SMS_PERMISSIONS, CALENDAR_PERMISSIONS,
- ALWAYS_LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
+ COARSE_BACKGROUND_LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
+ }
+
+ // Content capture
+ String contentCapturePackageName =
+ mContext.getPackageManager().getContentCaptureServicePackageName();
+ if (!TextUtils.isEmpty(contentCapturePackageName)) {
+ grantPermissionsToSystemPackage(contentCapturePackageName, userId,
+ PHONE_PERMISSIONS, SMS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
+ CONTACTS_PERMISSIONS);
}
// Atthention Service
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 3cc6428..dd561e1 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -77,6 +77,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.UserManagerInternal;
import android.os.storage.StorageManager;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
@@ -2818,12 +2819,19 @@
return false; // callingPackage was faked.
}
+ // TODO(b/144048540): DPM needs to take into account the userId, not just the package.
final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
if (dpm.isDeviceOwnerApp(callingPackage) || dpm.isProfileOwnerApp(callingPackage)) {
return true;
}
- final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- return !um.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER);
+ final int callingUserId = UserHandle.getCallingUserId();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+ return !umi.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER, callingUserId);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index ff2c671..c506e27 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -189,6 +189,8 @@
private int reason = APP_TRANSITION_TIMEOUT;
// TODO(b/132736359) The number may need to consider the visibility change.
private int numUndrawnActivities = 1;
+ /** Non-null if the application has reported drawn but its window hasn't. */
+ private Runnable pendingFullyDrawn;
private boolean loggedStartingWindowDrawn;
private boolean launchTraceActive;
@@ -716,6 +718,9 @@
BackgroundThread.getHandler().post(() -> logAppTransition(
currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
+ if (info.pendingFullyDrawn != null) {
+ info.pendingFullyDrawn.run();
+ }
info.launchedActivity.info.launchToken = null;
}
@@ -839,6 +844,15 @@
if (info == null) {
return null;
}
+ if (info.numUndrawnActivities > 0 && info.pendingFullyDrawn == null) {
+ // There are still undrawn activities, postpone reporting fully drawn until all of its
+ // windows are drawn. So that is closer to an usable state.
+ info.pendingFullyDrawn = () -> {
+ logAppTransitionReportedDrawn(r, restoredFromBundle);
+ info.pendingFullyDrawn = null;
+ };
+ return null;
+ }
// Record the handling of the reportFullyDrawn callback in the trace system. This is not
// actually used to trace this function, but instead the logical task that this function
@@ -849,9 +863,10 @@
final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
builder.setPackageName(r.packageName);
builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
- long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
- long startupTimeMs =
- TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - mLastTransitionStartTimeNs);
+ final long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
+ final long startupTimeMs = info.pendingFullyDrawn != null
+ ? info.windowsDrawnDelayMs
+ : TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - mLastTransitionStartTimeNs);
builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
builder.setType(restoredFromBundle
? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d360041..8aa5e77 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1167,7 +1167,7 @@
TaskStack getStack() {
final Task task = getTask();
if (task != null) {
- return task.mStack;
+ return task.getTaskStack();
} else {
return null;
}
@@ -1210,8 +1210,8 @@
if (getDisplayContent() != null) {
getDisplayContent().mClosingApps.remove(this);
}
- } else if (mLastParent != null && mLastParent.mStack != null) {
- task.mStack.mExitingActivities.remove(this);
+ } else if (mLastParent != null && mLastParent.getTaskStack() != null) {
+ task.getTaskStack().mExitingActivities.remove(this);
}
final TaskStack stack = getStack();
@@ -5757,7 +5757,7 @@
mWmService.mTaskSnapshotController.createTaskSnapshot(
task, 1 /* scaleFraction */);
if (snapshot != null) {
- mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, t, this,
+ mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory, t, this,
snapshot.getGraphicBuffer(), true /* relative */);
}
}
@@ -5866,8 +5866,8 @@
return;
}
clearThumbnail();
- mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, getPendingTransaction(),
- this, thumbnailHeader);
+ mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory,
+ getPendingTransaction(), this, thumbnailHeader);
mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
}
@@ -5895,7 +5895,7 @@
if (thumbnail == null) {
return;
}
- mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory,
+ mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory,
getPendingTransaction(), this, thumbnail);
final Animation animation =
getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
@@ -6043,7 +6043,7 @@
}
@VisibleForTesting
- AppWindowThumbnail getThumbnail() {
+ WindowContainerThumbnail getThumbnail() {
return mThumbnail;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 7df1c15..99659b0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -149,6 +149,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService;
@@ -789,14 +790,6 @@
return;
}
- if (windowingMode == WINDOWING_MODE_PINNED || currentMode == WINDOWING_MODE_PINNED) {
- // TODO: Need to remove use of PinnedActivityStack for this to be supported.
- // NOTE: Need to ASS.scheduleUpdatePictureInPictureModeIfNeeded() in
- // setWindowModeUnchecked() when this support is added. See TaskRecord.reparent()
- throw new IllegalArgumentException(
- "Changing pinned windowing mode not currently supported");
- }
-
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && splitScreenStack != null) {
// We already have a split-screen stack in this display, so just move the tasks over.
// TODO: Figure-out how to do all the stuff in
@@ -4915,7 +4908,7 @@
// The final orientation of this activity will change after moving to full screen.
// Start freezing screen here to prevent showing a temporary full screen window.
top.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
- mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+ dismissPip();
return;
}
}
@@ -4924,6 +4917,34 @@
animationDuration, fromFullscreen);
}
+ void dismissPip() {
+ if (!isActivityTypeStandardOrUndefined()) {
+ throw new IllegalArgumentException(
+ "You can't move tasks from non-standard stacks.");
+ }
+ if (getWindowingMode() != WINDOWING_MODE_PINNED) {
+ throw new IllegalArgumentException(
+ "Can't exit pinned mode if it's not pinned already.");
+ }
+
+ final ArrayList<TaskRecord> tasks = getAllTasks();
+
+ if (tasks.size() != 1) {
+ throw new RuntimeException("There should be only one task in a pinned stack.");
+ }
+
+ mWindowManager.inSurfaceTransaction(() -> {
+ final TaskRecord task = tasks.get(0);
+ setWindowingMode(WINDOWING_MODE_UNDEFINED);
+
+ getDisplay().positionChildAtTop(this, false /* includingParents */);
+
+ mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
+ MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext,
+ task.effectiveUid, task.realActivity.flattenToString());
+ });
+ }
+
/**
* Get current bounds of this stack, return empty when it is unavailable.
* @see TaskStack#getAnimationOrCurrentBounds(Rect)
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index f8a7397..5f1c001 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1499,7 +1499,6 @@
mService.deferWindowLayout();
try {
final int windowingMode = fromStack.getWindowingMode();
- final boolean inPinnedWindowingMode = windowingMode == WINDOWING_MODE_PINNED;
final ActivityDisplay toDisplay =
mRootActivityContainer.getActivityDisplay(toDisplayId);
@@ -1526,7 +1525,8 @@
// If we are moving from the pinned stack, then the animation takes care of updating
// the picture-in-picture mode.
- final boolean schedulePictureInPictureModeChange = inPinnedWindowingMode;
+ final boolean schedulePictureInPictureModeChange =
+ windowingMode == WINDOWING_MODE_PINNED;
final ArrayList<TaskRecord> tasks = fromStack.getAllTasks();
if (!tasks.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 2c4d893..e2e2b74 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -22,6 +22,7 @@
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -178,6 +179,13 @@
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
options.setLaunchDisplayId(displayId);
+
+ final ActivityDisplay display =
+ mService.mRootActivityContainer.getActivityDisplay(displayId);
+ // Make sure home stack exist on display.
+ final ActivityStack homeStack =
+ display.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
@@ -185,10 +193,7 @@
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
- final ActivityDisplay display =
- mService.mRootActivityContainer.getActivityDisplay(displayId);
- final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
- if (homeStack != null && homeStack.mInResumeTopActivity) {
+ if (homeStack.mInResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
// again. We need to schedule another resume.
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 6edcb02..77165f2 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1477,10 +1477,8 @@
mIntent.setFlags(mLaunchFlags);
- ActivityRecord reusedActivity = getReusableIntentActivity();
-
- mSupervisor.getLaunchParamsController().calculate(
- reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
+ final TaskRecord reusedTask = getReusableTask();
+ mSupervisor.getLaunchParamsController().calculate(reusedTask != null ? reusedTask : mInTask,
r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
mPreferredDisplayId =
mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
@@ -1495,7 +1493,7 @@
}
// Compute if there is an existing task that should be used for.
- final TaskRecord targetTask = computeTargetTask(reusedActivity);
+ final TaskRecord targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;
// Check if starting activity on given task or on a new task is allowed.
@@ -1507,10 +1505,12 @@
final ActivityRecord targetTaskTop = newTask ? null : targetTask.getTopActivity();
if (targetTaskTop != null) {
// Recycle the target task for this launch.
- startResult = recycleTask(targetTask, targetTaskTop, reusedActivity);
+ startResult = recycleTask(targetTask, targetTaskTop, reusedTask);
if (startResult != START_SUCCESS) {
return startResult;
}
+ } else {
+ mAddingToTask = true;
}
// If the activity being launched is the same as the one currently at the top, then
@@ -1601,10 +1601,8 @@
return START_SUCCESS;
}
- private TaskRecord computeTargetTask(ActivityRecord reusedActivity) {
- if (reusedActivity != null) {
- return reusedActivity.getTaskRecord();
- } else if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
+ private TaskRecord computeTargetTask() {
+ if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
// A new task should be created instead of using existing one.
return null;
@@ -1669,7 +1667,7 @@
* - Determine whether need to add a new activity on top or just brought the task to front.
*/
private int recycleTask(TaskRecord targetTask, ActivityRecord targetTaskTop,
- ActivityRecord reusedActivity) {
+ TaskRecord reusedTask) {
// True if we are clearing top and resetting of a standard (default) launch mode
// ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
final boolean clearTopAndResetStandardLaunchMode =
@@ -1678,12 +1676,12 @@
&& mLaunchMode == LAUNCH_MULTIPLE;
boolean clearTaskForReuse = false;
- if (reusedActivity != null) {
+ if (reusedTask != null) {
// If mStartActivity does not have a task associated with it, associate it with the
// reused activity's task. Do not do so if we're clearing top and resetting for a
// standard launchMode activity.
if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
- mStartActivity.setTaskForReuse(reusedActivity.getTaskRecord());
+ mStartActivity.setTaskForReuse(reusedTask);
clearTaskForReuse = true;
}
@@ -1730,7 +1728,7 @@
return START_RETURN_INTENT_TO_CALLER;
}
- complyActivityFlags(targetTask, reusedActivity);
+ complyActivityFlags(targetTask, reusedTask != null ? reusedTask.getTopActivity() : null);
if (clearTaskForReuse) {
// Clear task for re-use so later code to methods
@@ -2223,7 +2221,7 @@
* Decide whether the new activity should be inserted into an existing task. Returns null
* if not or an ActivityRecord with the task into which the new activity should be added.
*/
- private ActivityRecord getReusableIntentActivity() {
+ private TaskRecord getReusableTask() {
// We may want to try to place the new activity in to an existing task. We always
// do this if the target activity is singleTask or singleInstance; we will also do
// this if NEW_TASK has been requested, and there is not an additional qualifier telling
@@ -2238,8 +2236,10 @@
putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
ActivityRecord intentActivity = null;
if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
- final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
- intentActivity = task != null ? task.getTopActivity() : null;
+ TaskRecord launchTask = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
+ if (launchTask != null) {
+ return launchTask;
+ }
} else if (putIntoExistingTask) {
if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
// There can be one and only one instance of single instance activity in the
@@ -2265,7 +2265,7 @@
intentActivity = null;
}
- return intentActivity;
+ return intentActivity != null ? intentActivity.getTaskRecord() : null;
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index da7af5f..80232d3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2945,7 +2945,6 @@
r.setTaskDescription(td);
final TaskRecord task = r.getTaskRecord();
task.updateTaskDescription();
- mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.getTaskInfo());
}
}
}
@@ -3432,7 +3431,7 @@
if (stack.inFreeformWindowingMode()) {
stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- } else if (!mSizeCompatFreeform) {
+ } else if (!mSizeCompatFreeform && r.inSizeCompatMode()) {
throw new IllegalStateException("Size-compat windows are currently not"
+ "freeform-enabled");
} else if (stack.getParent().inFreeformWindowingMode()) {
@@ -4001,7 +4000,7 @@
stack.animateResizePinnedStack(null /* sourceHintBounds */,
null /* destBounds */, animationDuration, false /* fromFullscreen */);
} else {
- mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+ stack.dismissPip();
}
}
} finally {
@@ -4017,11 +4016,6 @@
}
}
- /**
- * NOTE: For the pinned stack, this method is usually called after the bounds animation has
- * animated the stack to the fullscreen, but can also be called if we are relaunching an
- * activity and clearing the task at the same time.
- */
@Override
// TODO: API should just be about changing windowing modes...
public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index cb9a200..cd7c216 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1922,11 +1922,13 @@
if (taskId < 0) {
return null;
}
- ArrayList<Task> tasks = new ArrayList<>();
+ final ArrayList<Task> tasks = new ArrayList<>();
mDisplayContent.forAllTasks(task -> {
if (task.mTaskId == taskId) {
tasks.add(task);
+ return true;
}
+ return false;
});
return tasks.size() == 1 ? tasks.get(0) : null;
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index dc78922..3eef749 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -48,7 +48,6 @@
import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
@@ -358,7 +357,8 @@
boolean fromHomeKey) {
// Fallback to top focused display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
- displayId = getTopDisplayFocusedStack().mDisplayId;
+ final ActivityStack stack = getTopDisplayFocusedStack();
+ displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
}
Intent homeIntent = null;
@@ -964,30 +964,29 @@
mService.deferWindowLayout();
final ActivityDisplay display = r.getActivityStack().getDisplay();
- ActivityStack stack = display.getPinnedStack();
-
- // This will clear the pinned stack by moving an existing task to the full screen stack,
- // ensuring only one task is present.
- if (stack != null) {
- mStackSupervisor.moveTasksToFullscreenStackLocked(stack, !ON_TOP);
- }
-
- // Need to make sure the pinned stack exist so we can resize it below...
- stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP);
try {
final TaskRecord task = r.getTaskRecord();
- // Resize the pinned stack to match the current size of the task the activity we are
- // going to be moving is currently contained in. We do this to have the right starting
- // animation bounds for the pinned stack to the desired bounds the caller wants.
- stack.resize(task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
- null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, !DEFER_RESUME);
- if (task.getChildCount() == 1) {
- // Defer resume until below, and do not schedule PiP changes until we animate below
- task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME,
- false /* schedulePictureInPictureModeChange */, reason);
+ final ActivityStack pinnedStack = display.getPinnedStack();
+ // This will change the pinned stack's windowing mode to its original mode, ensuring
+ // we only have one stack that is in pinned mode.
+ if (pinnedStack != null) {
+ pinnedStack.dismissPip();
+ }
+
+ final boolean singleActivity = task.getChildCount() == 1;
+
+ final ActivityStack stack;
+ if (singleActivity) {
+ stack = r.getActivityStack();
} else {
+ // In the case of multiple activities, we will create a new stack for it and then
+ // move the PIP activity into the stack.
+ // We will then perform a windowing mode change for both scenarios.
+ stack = display.createStack(
+ r.getActivityStack().getRequestedOverrideWindowingMode(),
+ r.getActivityType(), ON_TOP);
// There are multiple activities in the task and moving the top activity should
// reveal/leave the other activities in their original task.
@@ -1006,6 +1005,8 @@
DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
}
+ stack.setWindowingMode(WINDOWING_MODE_PINNED);
+
// Reset the state that indicates it can enter PiP while pausing after we've moved it
// to the pinned stack
r.supportsEnterPipOnTaskSwitch = false;
@@ -1628,7 +1629,7 @@
return false;
}
- <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
+ ActivityStack getLaunchStack(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) {
return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
-1 /* no realCallingPid */, -1 /* no realCallingUid */);
@@ -1646,7 +1647,7 @@
*
* @return The stack to use for the launch or INVALID_STACK_ID.
*/
- <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
+ ActivityStack getLaunchStack(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
@Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
int realCallingUid) {
@@ -1674,7 +1675,7 @@
}
final int activityType = resolveActivityType(r, options, candidateTask);
- T stack;
+ ActivityStack stack;
// Next preference for stack goes to the display Id set the candidate display.
if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
@@ -1690,7 +1691,7 @@
if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
|| canLaunchOnDisplayFromStartRequest)) {
if (r != null) {
- stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
+ stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
launchParams);
if (stack != null) {
return stack;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index dce15bc..183ca07 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -58,6 +58,7 @@
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ToBooleanFunction;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -67,8 +68,6 @@
final ActivityTaskManagerService mAtmService;
- // TODO: Track parent marks like this in WindowContainer.
- TaskStack mStack;
/* Unique identifier for this task. */
final int mTaskId;
/* User for which this task was created. */
@@ -128,7 +127,6 @@
super(atm.mWindowManager);
mAtmService = atm;
mTaskId = taskId;
- mStack = stack;
mUserId = userId;
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
@@ -139,12 +137,16 @@
// Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
setOrientation(SCREEN_ORIENTATION_UNSET);
// TODO(task-merge): Is this really needed?
- setBounds(getResolvedOverrideBounds());
+ //setBounds(getResolvedOverrideBounds());
}
@Override
DisplayContent getDisplayContent() {
- return mStack != null ? mStack.getDisplayContent() : null;
+ return getTaskStack() != null ? getTaskStack().getDisplayContent() : null;
+ }
+
+ TaskStack getTaskStack() {
+ return (TaskStack) getParent();
}
int getAdjustedAddPosition(ActivityRecord r, int suggestedPosition) {
@@ -199,7 +201,7 @@
// No reason to defer removal of a Task that doesn't have any child.
return false;
}
- return hasWindowsAlive() && mStack.isAnimating(TRANSITION | CHILDREN);
+ return hasWindowsAlive() && getTaskStack().isAnimating(TRANSITION | CHILDREN);
}
@Override
@@ -221,10 +223,10 @@
// TODO: Consolidate this with TaskRecord.reparent()
void reparent(TaskStack stack, int position, boolean moveParents, String reason) {
if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId
- + " from stack=" + mStack);
+ + " from stack=" + getTaskStack());
EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "reParentTask");
- final ActivityStack prevStack = mStack.mActivityStack;
+ final ActivityStack prevStack = getTaskStack().mActivityStack;
final boolean wasTopFocusedStack =
mAtmService.mRootActivityContainer.isTopDisplayFocusedStack(prevStack);
final ActivityDisplay prevStackDisplay = prevStack.getDisplay();
@@ -236,8 +238,8 @@
prevStack.moveHomeStackToFrontIfNeeded(wasTopFocusedStack, prevStackDisplay, reason);
}
- mStack = stack;
- stack.positionChildAt(position, this, moveParents);
+ // TODO(task-merge): Remove cast.
+ stack.positionChildAt(position, (TaskRecord) this, moveParents);
// If we are moving from the fullscreen stack to the pinned stack then we want to preserve
// our insets so that there will not be a jump in the area covered by system decorations.
@@ -247,7 +249,8 @@
/** @see ActivityTaskManagerService#positionTaskInStack(int, int, int). */
void positionAt(int position) {
- mStack.positionChildAt(position, this, false /* includingParents */);
+ // TODO(task-merge): Remove cast.
+ getTaskStack().positionChildAt(position, (TaskRecord) this, false /* includingParents */);
}
void setSendingToBottom(boolean toBottom) {
@@ -271,7 +274,8 @@
@Override
public int setBounds(Rect bounds) {
int rotation = Surface.ROTATION_0;
- final DisplayContent displayContent = mStack != null ? mStack.getDisplayContent() : null;
+ final DisplayContent displayContent = getTaskStack() != null
+ ? getTaskStack().getDisplayContent() : null;
if (displayContent != null) {
rotation = displayContent.getDisplayInfo().rotation;
} else if (bounds == null) {
@@ -462,7 +466,7 @@
/** Bounds of the task to be used for dimming, as well as touch related tests. */
public void getDimBounds(Rect out) {
- final DisplayContent displayContent = mStack.getDisplayContent();
+ final DisplayContent displayContent = getTaskStack().getDisplayContent();
// It doesn't matter if we in particular are part of the resize, since we couldn't have
// a DimLayer anyway if we weren't visible.
final boolean dockedResizing = displayContent != null
@@ -479,9 +483,9 @@
// stack bounds and so we don't even want to use them. Even if the app should not be
// resized the Dim should keep up with the divider.
if (dockedResizing) {
- mStack.getBounds(out);
+ getTaskStack().getBounds(out);
} else {
- mStack.getBounds(mTmpRect);
+ getTaskStack().getBounds(mTmpRect);
mTmpRect.intersect(getBounds());
out.set(mTmpRect);
}
@@ -494,9 +498,9 @@
void setDragResizing(boolean dragResizing, int dragResizeMode) {
if (mDragResizing != dragResizing) {
// No need to check if the mode is allowed if it's leaving dragResize
- if (dragResizing && !DragResizeMode.isModeAllowedForStack(mStack, dragResizeMode)) {
+ if (dragResizing && !DragResizeMode.isModeAllowedForStack(getTaskStack(), dragResizeMode)) {
throw new IllegalArgumentException("Drag resize mode not allow for stack stackId="
- + mStack.mStackId + " dragResizeMode=" + dragResizeMode);
+ + getTaskStack().mStackId + " dragResizeMode=" + dragResizeMode);
}
mDragResizing = dragResizing;
mDragResizeMode = dragResizeMode;
@@ -586,7 +590,7 @@
*/
boolean isFloating() {
return getWindowConfiguration().tasksAreFloating()
- && !mStack.isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
+ && !getTaskStack().isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
}
@Override
@@ -718,6 +722,11 @@
callback.accept(this);
}
+ @Override
+ boolean forAllTasks(ToBooleanFunction<Task> callback) {
+ return callback.apply(this);
+ }
+
/**
* @param canAffectSystemUiFlags If false, all windows in this task can not affect SystemUI
* flags. See {@link WindowState#canAffectSystemUiFlags()}.
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 478b1b5..f7b802d 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -30,6 +30,7 @@
import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.app.IActivityTaskManager;
import android.graphics.Point;
import android.graphics.Rect;
@@ -104,6 +105,7 @@
@VisibleForTesting
Task mTask;
+ WindowState mWindow;
private boolean mResizing;
private boolean mPreserveOrientation;
private boolean mStartOrientationWasLandscape;
@@ -238,8 +240,9 @@
/**
* @param displayContent The Display that the window being dragged is on.
+ * @param win The window which will be dragged.
*/
- void register(DisplayContent displayContent) {
+ void register(DisplayContent displayContent, @NonNull WindowState win) {
final Display display = displayContent.getDisplay();
if (DEBUG_TASK_POSITIONING) {
@@ -309,6 +312,17 @@
display.getRealSize(mMaxVisibleSize);
mDragEnded = false;
+
+ try {
+ mClientCallback = win.mClient.asBinder();
+ mClientCallback.linkToDeath(this, 0 /* flags */);
+ } catch (RemoteException e) {
+ // The caller has died, so clean up TaskPositioningController.
+ mService.mTaskPositioningController.finishTaskPositioning();
+ return;
+ }
+ mWindow = win;
+ mTask = win.getTask();
}
void unregister() {
@@ -341,25 +355,19 @@
ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after re-position");
mDisplayContent.getDisplayRotation().resume();
mDisplayContent = null;
- mClientCallback.unlinkToDeath(this, 0 /* flags */);
+ if (mClientCallback != null) {
+ mClientCallback.unlinkToDeath(this, 0 /* flags */);
+ }
+ mWindow = null;
}
- void startDrag(WindowState win, boolean resize, boolean preserveOrientation, float startX,
- float startY) {
+ void startDrag(boolean resize, boolean preserveOrientation, float startX,
+ float startY) {
if (DEBUG_TASK_POSITIONING) {
- Slog.d(TAG, "startDrag: win=" + win + ", resize=" + resize
+ Slog.d(TAG, "startDrag: win=" + mWindow + ", resize=" + resize
+ ", preserveOrientation=" + preserveOrientation + ", {" + startX + ", "
+ startY + "}");
}
- try {
- mClientCallback = win.mClient.asBinder();
- mClientCallback.linkToDeath(this, 0 /* flags */);
- } catch (RemoteException e) {
- // The caller has died, so clean up TaskPositioningController.
- mService.mTaskPositioningController.finishTaskPositioning();
- return;
- }
- mTask = win.getTask();
// Use the bounds of the task which accounts for
// multiple app windows. Don't use any bounds from win itself as it
// may not be the same size as the task.
@@ -441,7 +449,7 @@
}
// This is a moving or scrolling operation.
- mTask.mStack.getDimBounds(mTmpRect);
+ mTask.getTaskStack().getDimBounds(mTmpRect);
// If a target window is covered by system bar, there is no way to move it again by touch.
// So we exclude them from stack bounds. and then it will be shown inside stable area.
Rect stableBounds = new Rect();
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index e1123fa..c38e63e 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -169,7 +169,7 @@
mPositioningDisplay = displayContent;
mTaskPositioner = TaskPositioner.create(mService);
- mTaskPositioner.register(displayContent);
+ mTaskPositioner.register(displayContent, win);
// We need to grab the touch focus so that the touch events during the
// resizing/scrolling are not sent to the app. 'win' is the main window
@@ -187,7 +187,7 @@
return false;
}
- mTaskPositioner.startDrag(win, resize, preserveOrientation, startX, startY);
+ mTaskPositioner.startDrag(resize, preserveOrientation, startX, startY);
return true;
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 672827f..2975d0a 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -424,6 +424,7 @@
mResizeMode = resizeMode;
mAtmService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+ updateTaskDescription();
}
boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
@@ -791,7 +792,10 @@
} else {
autoRemoveRecents = false;
}
- mResizeMode = info.resizeMode;
+ if (mResizeMode != info.resizeMode) {
+ mResizeMode = info.resizeMode;
+ updateTaskDescription();
+ }
mSupportsPictureInPicture = info.supportsPictureInPicture();
}
@@ -835,8 +839,8 @@
mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.mTaskId;
}
- <T extends ActivityStack> T getStack() {
- return (T) mStack;
+ ActivityStack getStack() {
+ return mStack;
}
// TODO(stack-unify): Can be removed on stack unified.
@@ -1550,12 +1554,15 @@
}
final TaskDescription taskDescription = new TaskDescription(label, null, iconResource,
iconFilename, colorPrimary, colorBackground, statusBarColor, navigationBarColor,
- statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent);
+ statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent,
+ mResizeMode, mMinWidth, mMinHeight);
setTaskDescription(taskDescription);
// Update the task affiliation color if we are the parent of the group
if (mTaskId == mAffiliatedTaskId) {
mAffiliatedTaskColor = taskDescription.getPrimaryColor();
}
+ mAtmService.getTaskChangeNotificationController().notifyTaskDescriptionChanged(
+ getTaskInfo());
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 68b76fb..95a908f 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -84,7 +84,7 @@
import java.util.ArrayList;
import java.util.List;
-public class TaskStack extends WindowContainer<Task> implements
+public class TaskStack extends WindowContainer<TaskRecord> implements
BoundsAnimationTarget, ConfigurationContainerListener {
/** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
* restrict IME adjustment so that a min portion of top stack remains visible.*/
@@ -102,7 +102,6 @@
private Rect mTmpRect3 = new Rect();
/** For Pinned stack controlling. */
- private Rect mTmpFromBounds = new Rect();
private Rect mTmpToBounds = new Rect();
/** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
@@ -489,20 +488,18 @@
* @param position Target position to add the task to.
* @param showForAllUsers Whether to show the task regardless of the current user.
*/
- void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
+ void addChild(TaskRecord task, int position, boolean showForAllUsers, boolean moveParents) {
// Add child task.
- task.mStack = this;
addChild(task, null);
// Move child to a proper position, as some restriction for position might apply.
position = positionChildAt(
position, task, moveParents /* includingParents */, showForAllUsers);
- // TODO(task-merge): Remove cast.
- mActivityStack.onChildAdded((TaskRecord) task, position);
+ mActivityStack.onChildAdded(task, position);
}
@Override
- void addChild(Task task, int position) {
+ void addChild(TaskRecord task, int position) {
addChild(task, position, task.showForAllUsers(), false /* includingParents */);
}
@@ -520,7 +517,7 @@
getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
}
- void positionChildAtTop(Task child, boolean includingParents) {
+ void positionChildAtTop(TaskRecord child, boolean includingParents) {
if (child == null) {
// TODO: Fix the call-points that cause this to happen.
return;
@@ -535,7 +532,7 @@
displayContent.layoutAndAssignWindowLayersIfNeeded();
}
- void positionChildAtBottom(Task child, boolean includingParents) {
+ void positionChildAtBottom(TaskRecord child, boolean includingParents) {
if (child == null) {
// TODO: Fix the call-points that cause this to happen.
return;
@@ -550,7 +547,7 @@
}
@Override
- void positionChildAt(int position, Task child, boolean includingParents) {
+ void positionChildAt(int position, TaskRecord child, boolean includingParents) {
positionChildAt(position, child, includingParents, child.showForAllUsers());
}
@@ -559,7 +556,7 @@
* {@link TaskStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it can receive
* showForAllUsers param from {@link ActivityRecord} instead of {@link Task#showForAllUsers()}.
*/
- int positionChildAt(int position, Task child, boolean includingParents,
+ int positionChildAt(int position, TaskRecord child, boolean includingParents,
boolean showForAllUsers) {
final int targetPosition = findPositionForTask(child, position, showForAllUsers);
super.positionChildAt(targetPosition, child, includingParents);
@@ -666,7 +663,7 @@
* @param task The Task to delete.
*/
@Override
- void removeChild(Task task) {
+ void removeChild(TaskRecord task) {
if (!mChildren.contains(task)) {
// Not really in this stack anymore...
return;
@@ -674,10 +671,8 @@
if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeChild: task=" + task);
super.removeChild(task);
- task.mStack = null;
- // TODO(task-merge): Remove cast.
- mActivityStack.onChildRemoved((TaskRecord) task, mDisplayContent);
+ mActivityStack.onChildRemoved(task, mDisplayContent);
}
@Override
@@ -963,7 +958,7 @@
super.switchUser();
int top = mChildren.size();
for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
- Task task = mChildren.get(taskNdx);
+ TaskRecord task = mChildren.get(taskNdx);
if (mWmService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
mChildren.remove(taskNdx);
mChildren.add(task);
@@ -1576,7 +1571,7 @@
mActivityStack.mService.notifyPinnedStackAnimationEnded();
if (moveToFullscreen) {
- mActivityStack.mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+ mActivityStack.dismissPip();
}
} else {
// No PiP animation, just run the normal animation-end logic
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index a393ba6..11658f9 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -237,7 +237,7 @@
* This gets used during some open/close transitions as well as during a change transition
* where it represents the starting-state snapshot.
*/
- AppWindowThumbnail mThumbnail;
+ WindowContainerThumbnail mThumbnail;
final Rect mTransitStartRect = new Rect();
final Point mTmpPoint = new Point();
protected final Rect mTmpRect = new Rect();
@@ -1121,6 +1121,21 @@
}
}
+ /**
+ * For all tasks at or below this container call the callback.
+ *
+ * @param callback Calls the {@link ToBooleanFunction#apply} method for each task found and
+ * stops the search if {@link ToBooleanFunction#apply} returns {@code true}.
+ */
+ boolean forAllTasks(ToBooleanFunction<Task> callback) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ if (mChildren.get(i).forAllTasks(callback)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
WindowState getWindow(Predicate<WindowState> callback) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState w = mChildren.get(i).getWindow(callback);
@@ -1520,8 +1535,8 @@
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WC#applyAnimation");
if (okToAnimate()) {
- Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp, transit,
- enter, isVoiceInteraction);
+ final Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp,
+ transit, enter, isVoiceInteraction);
AnimationAdapter adapter = adapters.first;
AnimationAdapter thumbnailAdapter = adapters.second;
if (adapter != null) {
@@ -1580,18 +1595,16 @@
final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
- AnimationAdapter adapter = new LocalAnimationAdapter(
+ final AnimationAdapter adapter = new LocalAnimationAdapter(
new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
durationScale, true /* isAppAnimation */, false /* isThumbnail */),
getSurfaceAnimationRunner());
- AnimationAdapter thumbnailAdapter = null;
- if (mThumbnail != null) {
- thumbnailAdapter = new LocalAnimationAdapter(
- new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
- durationScale, true /* isAppAnimation */, true /* isThumbnail */),
- getSurfaceAnimationRunner());
- }
+ final AnimationAdapter thumbnailAdapter = mThumbnail != null
+ ? new LocalAnimationAdapter(new WindowChangeAnimationSpec(mTransitStartRect,
+ mTmpRect, displayInfo, durationScale, true /* isAppAnimation */,
+ true /* isThumbnail */), getSurfaceAnimationRunner())
+ : null;
resultAdapters = new Pair<>(adapter, thumbnailAdapter);
mTransit = transit;
mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
similarity index 66%
rename from services/core/java/com/android/server/wm/AppWindowThumbnail.java
rename to services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index acd96e9..604eae6 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -11,7 +11,7 @@
* 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
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -19,10 +19,10 @@
import static android.view.SurfaceControl.METADATA_OWNER_UID;
import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
-import static com.android.server.wm.AppWindowThumbnailProto.HEIGHT;
-import static com.android.server.wm.AppWindowThumbnailProto.SURFACE_ANIMATOR;
-import static com.android.server.wm.AppWindowThumbnailProto.WIDTH;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowContainerThumbnailProto.HEIGHT;
+import static com.android.server.wm.WindowContainerThumbnailProto.SURFACE_ANIMATOR;
+import static com.android.server.wm.WindowContainerThumbnailProto.WIDTH;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
@@ -30,7 +30,7 @@
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Point;
-import android.os.Binder;
+import android.os.Process;
import android.util.proto.ProtoOutputStream;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -44,39 +44,40 @@
import java.util.function.Supplier;
/**
- * Represents a surface that is displayed over an {@link ActivityRecord}
+ * Represents a surface that is displayed over a subclass of {@link WindowContainer}
*/
-class AppWindowThumbnail implements Animatable {
+class WindowContainerThumbnail implements Animatable {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM;
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainerThumbnail" : TAG_WM;
- private final ActivityRecord mActivityRecord;
+ private final WindowContainer mWindowContainer;
private SurfaceControl mSurfaceControl;
private final SurfaceAnimator mSurfaceAnimator;
private final int mWidth;
private final int mHeight;
private final boolean mRelative;
- AppWindowThumbnail(Supplier<Surface> surfaceFactory, Transaction t, ActivityRecord activity,
- GraphicBuffer thumbnailHeader) {
- this(surfaceFactory, t, activity, thumbnailHeader, false /* relative */);
+ WindowContainerThumbnail(Supplier<Surface> surfaceFactory, Transaction t,
+ WindowContainer container, GraphicBuffer thumbnailHeader) {
+ this(surfaceFactory, t, container, thumbnailHeader, false /* relative */);
}
/**
* @param t Transaction to create the thumbnail in.
- * @param activity {@link ActivityRecord} to associate this thumbnail with.
+ * @param container The sub-class of {@link WindowContainer} to associate this thumbnail with.
* @param thumbnailHeader A thumbnail or placeholder for thumbnail to initialize with.
- * @param relative Whether this thumbnail will be a child of activity (and thus positioned
+ * @param relative Whether this thumbnail will be a child of the container (and thus positioned
* relative to it) or not.
*/
- AppWindowThumbnail(Supplier<Surface> surfaceFactory, Transaction t, ActivityRecord activity,
- GraphicBuffer thumbnailHeader, boolean relative) {
- this(t, activity, thumbnailHeader, relative, surfaceFactory.get(), null);
+ WindowContainerThumbnail(Supplier<Surface> surfaceFactory, Transaction t,
+ WindowContainer container, GraphicBuffer thumbnailHeader, boolean relative) {
+ this(t, container, thumbnailHeader, relative, surfaceFactory.get(), null);
}
- AppWindowThumbnail(Transaction t, ActivityRecord activity, GraphicBuffer thumbnailHeader,
- boolean relative, Surface drawSurface, SurfaceAnimator animator) {
- mActivityRecord = activity;
+ WindowContainerThumbnail(Transaction t, WindowContainer container,
+ GraphicBuffer thumbnailHeader, boolean relative, Surface drawSurface,
+ SurfaceAnimator animator) {
+ mWindowContainer = container;
mRelative = relative;
if (animator != null) {
mSurfaceAnimator = animator;
@@ -84,24 +85,21 @@
// We can't use a delegating constructor since we need to
// reference this::onAnimationFinished
mSurfaceAnimator =
- new SurfaceAnimator(this, this::onAnimationFinished, activity.mWmService);
+ new SurfaceAnimator(this, this::onAnimationFinished, container.mWmService);
}
mWidth = thumbnailHeader.getWidth();
mHeight = thumbnailHeader.getHeight();
// Create a new surface for the thumbnail
- WindowState window = mActivityRecord.findMainWindow();
-
// TODO: This should be attached as a child to the app token, once the thumbnail animations
// use relative coordinates. Once we start animating task we can also consider attaching
// this to the task.
- mSurfaceControl = mActivityRecord.makeSurface()
- .setName("thumbnail anim: " + mActivityRecord.toString())
+ mSurfaceControl = mWindowContainer.makeSurface()
+ .setName("thumbnail anim: " + mWindowContainer.toString())
.setBufferSize(mWidth, mHeight)
.setFormat(PixelFormat.TRANSLUCENT)
- .setMetadata(METADATA_WINDOW_TYPE, mActivityRecord.windowType)
- .setMetadata(METADATA_OWNER_UID,
- window != null ? window.mOwnerUid : Binder.getCallingUid())
+ .setMetadata(METADATA_WINDOW_TYPE, mWindowContainer.getWindowingMode())
+ .setMetadata(METADATA_OWNER_UID, Process.myUid())
.build();
ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl);
@@ -112,11 +110,11 @@
drawSurface.release();
t.show(mSurfaceControl);
- // We parent the thumbnail to the task, and just place it on top of anything else in the
- // task.
+ // We parent the thumbnail to the container, and just place it on top of anything else in
+ // the container.
t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
if (relative) {
- t.reparent(mSurfaceControl, mActivityRecord.getSurfaceControl());
+ t.reparent(mSurfaceControl, mWindowContainer.getSurfaceControl());
}
}
@@ -126,12 +124,12 @@
void startAnimation(Transaction t, Animation anim, Point position) {
anim.restrictDuration(MAX_ANIMATION_DURATION);
- anim.scaleCurrentDuration(mActivityRecord.mWmService.getTransitionAnimationScaleLocked());
+ anim.scaleCurrentDuration(mWindowContainer.mWmService.getTransitionAnimationScaleLocked());
mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter(
new WindowAnimationSpec(anim, position,
- mActivityRecord.getDisplayContent().mAppTransition.canSkipFirstFrame(),
- mActivityRecord.getDisplayContent().getWindowCornerRadius()),
- mActivityRecord.mWmService.mSurfaceAnimationRunner), false /* hidden */);
+ mWindowContainer.getDisplayContent().mAppTransition.canSkipFirstFrame(),
+ mWindowContainer.getDisplayContent().getWindowCornerRadius()),
+ mWindowContainer.mWmService.mSurfaceAnimationRunner), false /* hidden */);
}
/**
@@ -161,10 +159,11 @@
/**
* Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
- * com.android.server.wm.AppWindowThumbnailProto}.
+ * com.android.server.wm.WindowContainerThumbnailProto}.
*
- * @param proto Stream to write the AppWindowThumbnail object to.
- * @param fieldId Field Id of the AppWindowThumbnail as defined in the parent message.
+ * @param proto Stream to write the WindowContainerThumbnailProto object to.
+ * @param fieldId Field Id of the WindowContainerThumbnailProto as defined in the parent
+ * message.
* @hide
*/
void writeToProto(ProtoOutputStream proto, long fieldId) {
@@ -179,19 +178,19 @@
@Override
public Transaction getPendingTransaction() {
- return mActivityRecord.getPendingTransaction();
+ return mWindowContainer.getPendingTransaction();
}
@Override
public void commitPendingTransaction() {
- mActivityRecord.commitPendingTransaction();
+ mWindowContainer.commitPendingTransaction();
}
@Override
public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
t.setLayer(leash, Integer.MAX_VALUE);
if (mRelative) {
- t.reparent(leash, mActivityRecord.getSurfaceControl());
+ t.reparent(leash, mWindowContainer.getSurfaceControl());
}
}
@@ -205,7 +204,7 @@
@Override
public Builder makeAnimationLeash() {
- return mActivityRecord.makeSurface();
+ return mWindowContainer.makeSurface();
}
@Override
@@ -215,12 +214,12 @@
@Override
public SurfaceControl getAnimationLeashParent() {
- return mActivityRecord.getAppAnimationLayer();
+ return mWindowContainer.getAnimationLeashParent();
}
@Override
public SurfaceControl getParentSurfaceControl() {
- return mActivityRecord.getParentSurfaceControl();
+ return mWindowContainer.getParentSurfaceControl();
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ab937e0a..2c56b11 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4361,7 +4361,7 @@
final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent();
final ActivityRecord focusedApp = topFocusedDisplay.mFocusedApp;
return (focusedApp != null && focusedApp.getTask() != null)
- ? focusedApp.getTask().mStack : null;
+ ? focusedApp.getTask().getTaskStack() : null;
}
public boolean detectSafeMode() {
@@ -7657,7 +7657,7 @@
return;
}
- final TaskStack stack = task.mStack;
+ final TaskStack stack = task.getTaskStack();
// We ignore home stack since we don't want home stack to move to front when touched.
// Specifically, in freeform we don't want tapping on home to cause the freeform apps to go
// behind home. See b/117376413
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 344befa..d196c34 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1283,7 +1283,7 @@
// notify the client of frame changes in this case. Not only is it a lot of churn, but
// the frame may not correspond to the surface size or the onscreen area at various
// phases in the animation, and the client will become sad and confused.
- if (task != null && task.mStack.isAnimatingBounds()) {
+ if (task != null && task.getTaskStack().isAnimatingBounds()) {
return;
}
@@ -1423,8 +1423,8 @@
TaskStack getStack() {
Task task = getTask();
if (task != null) {
- if (task.mStack != null) {
- return task.mStack;
+ if (task.getTaskStack() != null) {
+ return task.getTaskStack();
}
}
// Some system windows (e.g. "Power off" dialog) don't have a task, but we would still
@@ -1443,7 +1443,7 @@
bounds.setEmpty();
mTmpRect.setEmpty();
if (intersectWithStackBounds) {
- final TaskStack stack = task.mStack;
+ final TaskStack stack = task.getTaskStack();
if (stack != null) {
stack.getDimBounds(mTmpRect);
} else {
@@ -1845,8 +1845,8 @@
final int top = mWindowFrames.mFrame.top;
final Task task = getTask();
final boolean adjustedForMinimizedDockOrIme = task != null
- && (task.mStack.isAdjustedForMinimizedDockedStack()
- || task.mStack.isAdjustedForIme());
+ && (task.getTaskStack().isAdjustedForMinimizedDockedStack()
+ || task.getTaskStack().isAdjustedForIme());
if (mToken.okToAnimate()
&& (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
&& !isDragResizing() && !adjustedForMinimizedDockOrIme
@@ -1882,7 +1882,7 @@
boolean isObscuringDisplay() {
Task task = getTask();
- if (task != null && task.mStack != null && !task.mStack.fillsParent()) {
+ if (task != null && task.getTaskStack() != null && !task.getTaskStack().fillsParent()) {
return false;
}
return isOpaqueDrawn() && fillsDisplay();
@@ -2301,8 +2301,8 @@
void applyAdjustForImeIfNeeded() {
final Task task = getTask();
- if (task != null && task.mStack != null && task.mStack.isAdjustedForIme()) {
- task.mStack.applyAdjustForImeIfNeeded(task);
+ if (task != null && task.getTaskStack() != null && task.getTaskStack().isAdjustedForIme()) {
+ task.getTaskStack().applyAdjustForImeIfNeeded(task);
}
}
@@ -2633,7 +2633,7 @@
return false;
}
- return mActivityRecord.getTask().mStack.shouldIgnoreInput()
+ return mActivityRecord.getTask().getTaskStack().shouldIgnoreInput()
|| mActivityRecord.hiddenRequested
|| isAnimatingToRecents();
}
@@ -3153,7 +3153,7 @@
return;
}
- final TaskStack stack = task.mStack;
+ final TaskStack stack = task.getTaskStack();
if (stack == null) {
return;
}
@@ -3167,7 +3167,7 @@
return;
}
- final TaskStack stack = task.mStack;
+ final TaskStack stack = task.getTaskStack();
if (stack == null) {
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index fef3a9d..a853828 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -892,10 +892,10 @@
int posX = 0;
int posY = 0;
- task.mStack.getDimBounds(mTmpStackBounds);
+ task.getTaskStack().getDimBounds(mTmpStackBounds);
boolean allowStretching = false;
- task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
+ task.getTaskStack().getFinalAnimationSourceHintBounds(mTmpSourceBounds);
// If we don't have source bounds, we can attempt to use the content insets
// in the following scenario:
// 1. We have content insets.
@@ -905,8 +905,8 @@
// because of the force-scale until resize state.
if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0
|| mWin.mLastRelayoutContentInsets.height() > 0)
- && !task.mStack.lastAnimatingBoundsWasToFullscreen()) {
- mTmpSourceBounds.set(task.mStack.mPreAnimationBounds);
+ && !task.getTaskStack().lastAnimatingBoundsWasToFullscreen()) {
+ mTmpSourceBounds.set(task.getTaskStack().mPreAnimationBounds);
mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
allowStretching = true;
}
@@ -920,7 +920,7 @@
if (!mTmpSourceBounds.isEmpty()) {
// Get the final target stack bounds, if we are not animating, this is just the
// current stack bounds
- task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds);
+ task.getTaskStack().getFinalAnimationBounds(mTmpAnimatingBounds);
// Calculate the current progress and interpolate the difference between the target
// and source bounds
@@ -1499,7 +1499,7 @@
*/
boolean isForceScaled() {
final Task task = mWin.getTask();
- if (task != null && task.mStack.isForceScaled()) {
+ if (task != null && task.getTaskStack().isForceScaled()) {
return true;
}
return mForceScaleUntilResize;
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 8ddb86b..3726228 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -67,7 +67,11 @@
Return<bool> supportsAmplitudeControl() override {
int32_t cap = 0;
if (!mVib->getCapabilities(&cap).isOk()) return false;
- return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+ 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 {
@@ -96,7 +100,11 @@
}
Return<V1_0::Status> setExternalControl(bool enabled) override {
- return toHidlStatus(mVib->setExternalControl(enabled));
+ 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,
@@ -154,21 +162,30 @@
sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
int timeoutMs = 0;
- V1_0::Status status = toHidlStatus(
+ Return<V1_0::Status> status = toHidlStatus(
mVib->perform(static_cast<aidl::Effect>(effect),
static_cast<aidl::EffectStrength>(strength), cb, &timeoutMs));
- _hidl_cb(status, timeoutMs);
- return android::hardware::Status::ok();
+
+ 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;
- V1_0::Status toHidlStatus(const android::binder::Status& status) {
+ 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;
}
@@ -247,8 +264,14 @@
}
ALOGE("Failed to issue command to vibrator HAL. Retrying.");
+
// Restoring connection to the HAL.
- mHal = I::tryGetService();
+ sp<aidl::IVibrator> aidlVib = checkVintfService<aidl::IVibrator>();
+ if (aidlVib) {
+ mHal = new VibratorShim(aidlVib);
+ } else {
+ mHal = I::tryGetService();
+ }
}
return ret;
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java
index fa90b29..0d44318 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java
@@ -116,8 +116,8 @@
ArgumentCaptor<Notification> notificationCaptor =
ArgumentCaptor.forClass(Notification.class);
verify(mMockBinderService).enqueueNotificationWithTag(
- eq(NotificationShellCmd.NOTIFICATION_PACKAGE),
- eq("android"),
+ eq(getContext().getPackageName()),
+ eq(getContext().getPackageName()),
eq(aTag),
eq(NotificationShellCmd.NOTIFICATION_ID),
notificationCaptor.capture(),
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 7c867b6..44cacd8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -195,9 +195,15 @@
public void testOnReportFullyDrawn() {
onActivityLaunched();
+ // The activity reports fully drawn before windows drawn, then the fully drawn event will
+ // be pending (see {@link WindowingModeTransitionInfo#pendingFullyDrawn}).
mActivityMetricsLogger.logAppTransitionReportedDrawn(mTopActivity, false);
+ notifyTransitionStarting();
+ // The pending fully drawn event should send when the actual windows drawn event occurs.
+ notifyWindowsDrawn(mTopActivity);
verifyAsync(mLaunchObserver).onReportFullyDrawn(eqProto(mTopActivity), anyLong());
+ verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
verifyNoMoreInteractions(mLaunchObserver);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index c5301b8..7b9be3d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -62,7 +62,7 @@
public void setUpOnDisplay(DisplayContent dc) {
mActivity = createTestActivityRecord(dc, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
mTask = mActivity.getTask();
- mStack = mTask.mStack;
+ mStack = mTask.getTaskStack();
// Set a remote animator with snapshot disabled. Snapshots don't work in wmtests.
RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 01489c6..bd137fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -119,7 +119,7 @@
waitUntilHandlersIdle();
exitingApp.mIsExiting = true;
- exitingApp.getTask().mStack.mExitingActivities.add(exitingApp);
+ exitingApp.getTask().getTaskStack().mExitingActivities.add(exitingApp);
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 63f70c0..e0e9a58 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -114,16 +114,15 @@
public void testReplacingTaskInPinnedStack() {
final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
.setStack(mFullscreenStack).build();
- final TaskRecord firstTask = firstActivity.getTaskRecord();
+ final TaskRecord task = firstActivity.getTaskRecord();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task)
.setStack(mFullscreenStack).build();
- final TaskRecord secondTask = secondActivity.getTaskRecord();
mFullscreenStack.moveToFront("testReplacingTaskInPinnedStack");
// Ensure full screen stack has both tasks.
- ensureStackPlacement(mFullscreenStack, firstTask, secondTask);
+ ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity);
// Move first activity to pinned stack.
final Rect sourceBounds = new Rect();
@@ -133,8 +132,8 @@
final ActivityDisplay display = mFullscreenStack.getDisplay();
ActivityStack pinnedStack = display.getPinnedStack();
// Ensure a task has moved over.
- ensureStackPlacement(pinnedStack, firstTask);
- ensureStackPlacement(mFullscreenStack, secondTask);
+ ensureStackPlacement(pinnedStack, firstActivity);
+ ensureStackPlacement(mFullscreenStack, secondActivity);
// Move second activity to pinned stack.
mRootActivityContainer.moveActivityToPinnedStack(secondActivity, sourceBounds,
@@ -144,21 +143,27 @@
pinnedStack = display.getPinnedStack();
mFullscreenStack = display.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
// Ensure stacks have swapped tasks.
- ensureStackPlacement(pinnedStack, secondTask);
- ensureStackPlacement(mFullscreenStack, firstTask);
+ ensureStackPlacement(pinnedStack, secondActivity);
+ ensureStackPlacement(mFullscreenStack, firstActivity);
}
- private static void ensureStackPlacement(ActivityStack stack, TaskRecord... tasks) {
- final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
- assertEquals("Expecting " + Arrays.deepToString(tasks) + " got " + stackTasks,
- stackTasks.size(), tasks != null ? tasks.length : 0);
+ private static void ensureStackPlacement(ActivityStack stack, ActivityRecord... activities) {
+ final TaskRecord task = stack.getAllTasks().get(0);
+ final ArrayList<ActivityRecord> stackActivities = new ArrayList<>();
- if (tasks == null) {
+ for (int i = 0; i < task.getChildCount(); i++) {
+ stackActivities.add(task.getChildAt(i));
+ }
+
+ assertEquals("Expecting " + Arrays.deepToString(activities) + " got " + stackActivities,
+ stackActivities.size(), activities != null ? activities.length : 0);
+
+ if (activities == null) {
return;
}
- for (TaskRecord task : tasks) {
- assertTrue(stackTasks.contains(task));
+ for (ActivityRecord activity : activities) {
+ assertTrue(stackActivities.contains(activity));
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
index 012eb52..9275512b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
@@ -66,7 +66,6 @@
private int mMinVisibleWidth;
private int mMinVisibleHeight;
private TaskPositioner mPositioner;
- private WindowState mWindow;
@Before
public void setUp() {
@@ -81,17 +80,16 @@
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
removeGlobalMinSizeRestriction();
+ WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "window");
mPositioner = new TaskPositioner(mWm, mWm.mAtmService);
- mPositioner.register(mDisplayContent);
- mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window");
- mPositioner.mTask = mWindow.getTask();
- mWindow.getStack().setWindowingMode(WINDOWING_MODE_FREEFORM);
+ mPositioner.register(mDisplayContent, win);
+
+ win.getStack().setWindowingMode(WINDOWING_MODE_FREEFORM);
}
@After
public void tearDown() {
- mWindow = null;
mPositioner = null;
}
@@ -122,8 +120,8 @@
mPositioner.mTask.setBounds(r, true);
// Start a drag resize starting upper left.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
assertBoundsEquals(r, mPositioner.getWindowDragBounds());
// Drag to a good landscape size.
@@ -149,8 +147,8 @@
mPositioner.getWindowDragBounds());
// Start a drag resize left and see that only the left coord changes..
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, midY);
// Drag to the left.
mPositioner.resizeDrag(0.0f, midY);
@@ -184,8 +182,8 @@
mPositioner.mTask.setBounds(r, true);
// Drag upper left.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
mPositioner.resizeDrag(0.0f, 0.0f);
assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -193,8 +191,8 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag upper.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, midX, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX,
+ r.top - MOUSE_DELTA_Y);
mPositioner.resizeDrag(0.0f, 0.0f);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -202,8 +200,8 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag upper right.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
mPositioner.resizeDrag(r.right + 100, 0.0f);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -211,8 +209,8 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag right.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.right + MOUSE_DELTA_X, midY);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.right + MOUSE_DELTA_X, midY);
mPositioner.resizeDrag(r.right + 100, 0.0f);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -220,8 +218,7 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag bottom right.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */,
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
@@ -230,8 +227,8 @@
assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag bottom.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, midX, r.bottom + MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX,
+ r.bottom + MOUSE_DELTA_Y);
mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -239,8 +236,8 @@
assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag bottom left.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
mPositioner.resizeDrag(0.0f, r.bottom + 100);
assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -248,8 +245,8 @@
assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag left.
- mPositioner.startDrag(mWindow, true /* resizing */,
- false /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+ mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, midY);
mPositioner.resizeDrag(0.0f, r.bottom + 100);
assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -266,8 +263,8 @@
final Rect r = new Rect(100, 220, 700, 520);
mPositioner.mTask.setBounds(r, true);
- mPositioner.startDrag(mWindow, true /* resizing */,
- true /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
assertBoundsEquals(r, mPositioner.getWindowDragBounds());
// Drag to a good landscape size.
@@ -305,8 +302,8 @@
final int midY = (r.top + r.bottom) / 2;
mPositioner.mTask.setBounds(r, true);
- mPositioner.startDrag(mWindow, true /* resizing */,
- true /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+ mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, midY);
// Drag to the left.
mPositioner.resizeDrag(0.0f, midY);
@@ -346,8 +343,8 @@
final int midX = (r.left + r.right) / 2;
mPositioner.mTask.setBounds(r, true);
- mPositioner.startDrag(mWindow, true /*resizing*/,
- true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/, midX,
+ r.top - MOUSE_DELTA_Y);
// Drag to the left (no change).
mPositioner.resizeDrag(0.0f, r.top);
@@ -382,8 +379,8 @@
final Rect r = new Rect(330, 100, 630, 600);
mPositioner.mTask.setBounds(r, true);
- mPositioner.startDrag(mWindow, true /*resizing*/,
- true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/,
+ r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
assertBoundsEquals(r, mPositioner.getWindowDragBounds());
// Drag to a good landscape size.
@@ -416,8 +413,8 @@
final int midY = (r.top + r.bottom) / 2;
mPositioner.mTask.setBounds(r, true);
- mPositioner.startDrag(mWindow, true /* resizing */,
- true /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+ mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
+ r.left - MOUSE_DELTA_X, midY);
// Drag to the left.
mPositioner.resizeDrag(0.0f, midY);
@@ -459,8 +456,8 @@
final int midX = (r.left + r.right) / 2;
mPositioner.mTask.setBounds(r, true);
- mPositioner.startDrag(mWindow, true /* resizing */,
- true /* preserveOrientation */, midX, r.top - MOUSE_DELTA_Y);
+ mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, midX,
+ r.top - MOUSE_DELTA_Y);
// Drag to the left (no change).
mPositioner.resizeDrag(0.0f, r.top);
@@ -502,7 +499,7 @@
public void testFinishingMovingWhenBinderDied() {
spyOn(mWm.mTaskPositioningController);
- mPositioner.startDrag(mWindow, false, false, 0 /* startX */, 0 /* startY */);
+ mPositioner.startDrag(false, false, 0 /* startX */, 0 /* startY */);
verify(mWm.mTaskPositioningController, never()).finishTaskPositioning();
mPositioner.binderDied();
verify(mWm.mTaskPositioningController).finishTaskPositioning();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
index a66c79c..7897047 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -121,7 +121,7 @@
false /* includingParents */);
// Move the task of {@code mDisplayContent} to top.
- stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+ stack.positionChildAt(WindowContainer.POSITION_TOP, (TaskRecord) task, true /* includingParents */);
final int indexOfDisplayWithPinnedStack = mWm.mRoot.mChildren.indexOf(mDisplayContent);
assertEquals("The testing DisplayContent should be moved to top with task",
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 164d28d..a9d0ea1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -58,12 +58,12 @@
final Task task2 = createTaskInStack(stack, 1 /* userId */);
// Current user task should be moved to top.
- stack.positionChildAt(WindowContainer.POSITION_TOP, task1, false /* includingParents */);
+ stack.positionChildAt(WindowContainer.POSITION_TOP, (TaskRecord) task1, false /* includingParents */);
assertEquals(stack.mChildren.get(0), task2);
assertEquals(stack.mChildren.get(1), task1);
// Non-current user won't be moved to top.
- stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
+ stack.positionChildAt(WindowContainer.POSITION_TOP, (TaskRecord) task2, false /* includingParents */);
assertEquals(stack.mChildren.get(0), task2);
assertEquals(stack.mChildren.get(1), task1);
}
@@ -112,12 +112,12 @@
public void testStackRemoveImmediately() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(stack, 0 /* userId */);
- assertEquals(stack, task.mStack);
+ assertEquals(stack, task.getTaskStack());
// Remove stack and check if its child is also removed.
stack.removeImmediately();
assertNull(stack.getDisplayContent());
- assertNull(task.mStack);
+ assertNull(task.getTaskStack());
}
@Test
@@ -133,7 +133,7 @@
assertEquals(0, stack.getChildCount());
assertNull(stack.getDisplayContent());
assertNull(task.getDisplayContent());
- assertNull(task.mStack);
+ assertNull(task.getTaskStack());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
similarity index 86%
rename from services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
rename to services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
index 8520d21..b8de3ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
@@ -37,27 +37,27 @@
* Test class for {@link TaskSnapshotSurface}.
*
* Build/Install/Run:
- * atest FrameworksServicesTest:AppWindowThumbnailTest
+ * atest WmTests:WindowContainerThumbnailTest
*
*/
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class AppWindowThumbnailTest extends WindowTestsBase {
- private AppWindowThumbnail buildThumbnail() {
+public class WindowContainerThumbnailTest extends WindowTestsBase {
+ private WindowContainerThumbnail buildThumbnail() {
final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888,
GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
final ActivityRecord mockAr = mock(ActivityRecord.class);
when(mockAr.getPendingTransaction()).thenReturn(new StubTransaction());
when(mockAr.makeSurface()).thenReturn(new MockSurfaceControlBuilder());
- return new AppWindowThumbnail(new StubTransaction(), mockAr,
+ return new WindowContainerThumbnail(new StubTransaction(), mockAr,
buffer, false, mock(Surface.class), mock(SurfaceAnimator.class));
}
@Test
@FlakyTest(bugId = 131005232)
public void testDestroy_nullsSurface() {
- final AppWindowThumbnail t = buildThumbnail();
+ final WindowContainerThumbnail t = buildThumbnail();
assertNotNull(t.getSurfaceControl());
t.destroy();
assertNull(t.getSurfaceControl());
diff --git a/telephony/java/android/telephony/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java
similarity index 91%
rename from telephony/java/android/telephony/CallerInfo.java
rename to telecomm/java/android/telecom/CallerInfo.java
index f87ac50..a5d25e2 100644
--- a/telephony/java/android/telephony/CallerInfo.java
+++ b/telecomm/java/android/telecom/CallerInfo.java
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package android.telephony;
+package android.telecom;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -33,8 +32,10 @@
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.RawContacts;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
-import android.util.Log;
import com.android.i18n.phonenumbers.NumberParseException;
import com.android.i18n.phonenumbers.PhoneNumberUtil;
@@ -50,10 +51,9 @@
*
* {@hide}
*/
-@SystemApi
public class CallerInfo {
private static final String TAG = "CallerInfo";
- private static final boolean VDBG = Rlog.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean VDBG = Log.VERBOSE;
/** @hide */
public static final long USER_TYPE_CURRENT = 0;
@@ -215,7 +215,7 @@
info.contactExists = false;
info.userType = USER_TYPE_CURRENT;
- if (VDBG) Rlog.v(TAG, "getCallerInfo() based on cursor...");
+ if (VDBG) Log.v(TAG, "getCallerInfo() based on cursor...");
if (cursor != null) {
if (cursor.moveToFirst()) {
@@ -263,7 +263,7 @@
if (contactId != 0 && !Contacts.isEnterpriseContactId(contactId)) {
info.contactIdOrZero = contactId;
if (VDBG) {
- Rlog.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero);
+ Log.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero);
}
}
if (Contacts.isEnterpriseContactId(contactId)) {
@@ -271,7 +271,7 @@
}
} else {
// No valid columnIndex, so we can't look up person_id.
- Rlog.w(TAG, "Couldn't find contact_id column for " + contactRef);
+ Log.w(TAG, "Couldn't find contact_id column for " + contactRef);
// Watch out: this means that anything that depends on
// person_id will be broken (like contact photo lookups in
// the in-call UI, for example.)
@@ -356,7 +356,7 @@
info = getCallerInfo(context, contactRef,
cr.query(contactRef, null, null, null, null));
} catch (RuntimeException re) {
- Rlog.e(TAG, "Error getting caller info.", re);
+ Log.e(TAG, re, "Error getting caller info.");
}
}
return info;
@@ -376,7 +376,7 @@
*/
@UnsupportedAppUsage
public static CallerInfo getCallerInfo(Context context, String number) {
- if (VDBG) Rlog.v(TAG, "getCallerInfo() based on number...");
+ if (VDBG) Log.v(TAG, "getCallerInfo() based on number...");
int subId = SubscriptionManager.getDefaultSubscriptionId();
return getCallerInfo(context, number, subId);
@@ -407,8 +407,8 @@
// shortcut and skip the query.
if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
return new CallerInfo().markAsEmergency(context);
- } else if (PhoneNumberUtils.isVoiceMailNumber(subId, number)) {
- return new CallerInfo().markAsVoiceMail();
+ } else if (PhoneNumberUtils.isVoiceMailNumber(null, subId, number)) {
+ return new CallerInfo().markAsVoiceMail(context, subId);
}
Uri contactUri = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI,
@@ -542,36 +542,20 @@
}
- /**
- * Mark this CallerInfo as a voicemail call. The voicemail label
- * is obtained from the telephony manager. Caller must hold the
- * READ_PHONE_STATE permission otherwise the phoneNumber will be
- * set to null.
- * @return this instance.
- */
- // TODO: As in the emergency number handling, we end up writing a
- // string in the phone number field.
- /* package */ CallerInfo markAsVoiceMail() {
-
- int subId = SubscriptionManager.getDefaultSubscriptionId();
- return markAsVoiceMail(subId);
-
- }
-
- /* package */ CallerInfo markAsVoiceMail(int subId) {
+ /* package */ CallerInfo markAsVoiceMail(Context context, int subId) {
mIsVoiceMail = true;
try {
- String voiceMailLabel = TelephonyManager.getDefault().getVoiceMailAlphaTag(subId);
-
- phoneNumber = voiceMailLabel;
+ phoneNumber = context.getSystemService(TelephonyManager.class)
+ .createForSubscriptionId(subId)
+ .getVoiceMailAlphaTag();
} catch (SecurityException se) {
// Should never happen: if this process does not have
// permission to retrieve VM tag, it should not have
// permission to retrieve VM number and would not call
// this method.
// Leave phoneNumber untouched.
- Rlog.e(TAG, "Cannot access VoiceMail.", se);
+ Log.e(TAG, se, "Cannot access VoiceMail.");
}
// TODO: There is no voicemail picture?
// FIXME: FIND ANOTHER ICON
@@ -630,10 +614,10 @@
// So instead, figure out the column to use for person_id by just
// looking at the URI itself.
- if (VDBG) Rlog.v(TAG, "- getColumnIndexForPersonId: contactRef URI = '"
+ if (VDBG) Log.v(TAG, "- getColumnIndexForPersonId: contactRef URI = '"
+ contactRef + "'...");
// Warning: Do not enable the following logging (due to ANR risk.)
- // if (VDBG) Rlog.v(TAG, "- MIME type: "
+ // if (VDBG) Log.v(TAG, "- MIME type: "
// + context.getContentResolver().getType(contactRef));
String url = contactRef.toString();
@@ -641,25 +625,25 @@
if (url.startsWith("content://com.android.contacts/data/phones")) {
// Direct lookup in the Phone table.
// MIME type: Phone.CONTENT_ITEM_TYPE (= "vnd.android.cursor.item/phone_v2")
- if (VDBG) Rlog.v(TAG, "'data/phones' URI; using RawContacts.CONTACT_ID");
+ if (VDBG) Log.v(TAG, "'data/phones' URI; using RawContacts.CONTACT_ID");
columnName = RawContacts.CONTACT_ID;
} else if (url.startsWith("content://com.android.contacts/data")) {
// Direct lookup in the Data table.
// MIME type: Data.CONTENT_TYPE (= "vnd.android.cursor.dir/data")
- if (VDBG) Rlog.v(TAG, "'data' URI; using Data.CONTACT_ID");
+ if (VDBG) Log.v(TAG, "'data' URI; using Data.CONTACT_ID");
// (Note Data.CONTACT_ID and RawContacts.CONTACT_ID are equivalent.)
columnName = Data.CONTACT_ID;
} else if (url.startsWith("content://com.android.contacts/phone_lookup")) {
// Lookup in the PhoneLookup table, which provides "fuzzy matching"
// for phone numbers.
// MIME type: PhoneLookup.CONTENT_TYPE (= "vnd.android.cursor.dir/phone_lookup")
- if (VDBG) Rlog.v(TAG, "'phone_lookup' URI; using PhoneLookup._ID");
+ if (VDBG) Log.v(TAG, "'phone_lookup' URI; using PhoneLookup._ID");
columnName = PhoneLookup._ID;
} else {
- Rlog.w(TAG, "Unexpected prefix for contactRef '" + url + "'");
+ Log.w(TAG, "Unexpected prefix for contactRef '" + url + "'");
}
int columnIndex = (columnName != null) ? cursor.getColumnIndex(columnName) : -1;
- if (VDBG) Rlog.v(TAG, "==> Using column '" + columnName
+ if (VDBG) Log.v(TAG, "==> Using column '" + columnName
+ "' (columnIndex = " + columnIndex + ") for person_id lookup...");
return columnIndex;
}
@@ -689,7 +673,7 @@
* @hide
*/
public static String getGeoDescription(Context context, String number) {
- if (VDBG) Rlog.v(TAG, "getGeoDescription('" + number + "')...");
+ if (VDBG) Log.v(TAG, "getGeoDescription('" + number + "')...");
if (TextUtils.isEmpty(number)) {
return null;
@@ -702,18 +686,18 @@
String countryIso = getCurrentCountryIso(context, locale);
PhoneNumber pn = null;
try {
- if (VDBG) Rlog.v(TAG, "parsing '" + number
+ if (VDBG) Log.v(TAG, "parsing '" + number
+ "' for countryIso '" + countryIso + "'...");
pn = util.parse(number, countryIso);
- if (VDBG) Rlog.v(TAG, "- parsed number: " + pn);
+ if (VDBG) Log.v(TAG, "- parsed number: " + pn);
} catch (NumberParseException e) {
- Rlog.w(TAG, "getGeoDescription: NumberParseException for incoming number '"
- + Rlog.pii(TAG, number) + "'");
+ Log.w(TAG, "getGeoDescription: NumberParseException for incoming number '"
+ + Log.pii(number) + "'");
}
if (pn != null) {
String description = geocoder.getDescriptionForNumber(pn, locale);
- if (VDBG) Rlog.v(TAG, "- got description: '" + description + "'");
+ if (VDBG) Log.v(TAG, "- got description: '" + description + "'");
return description;
} else {
return null;
@@ -733,12 +717,12 @@
if (country != null) {
countryIso = country.getCountryIso();
} else {
- Rlog.e(TAG, "CountryDetector.detectCountry() returned null.");
+ Log.e(TAG, new Exception(), "CountryDetector.detectCountry() returned null.");
}
}
if (countryIso == null) {
countryIso = locale.getCountry();
- Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
+ Log.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
+ countryIso);
}
return countryIso;
diff --git a/telephony/java/android/telephony/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
similarity index 91%
rename from telephony/java/android/telephony/CallerInfoAsyncQuery.java
rename to telecomm/java/android/telecom/CallerInfoAsyncQuery.java
index 88b471e..4a50e98 100644
--- a/telephony/java/android/telephony/CallerInfoAsyncQuery.java
+++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.telephony;
+package android.telecom;
import android.app.ActivityManager;
import android.content.AsyncQueryHandler;
@@ -31,6 +31,8 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract.PhoneLookup;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import dalvik.annotation.compat.UnsupportedAppUsage;
@@ -107,12 +109,12 @@
*/
static ContentResolver getCurrentProfileContentResolver(Context context) {
- if (DBG) Rlog.d(LOG_TAG, "Trying to get current content resolver...");
+ if (DBG) Log.d(LOG_TAG, "Trying to get current content resolver...");
final int currentUser = ActivityManager.getCurrentUser();
final int myUser = UserManager.get(context).getUserHandle();
- if (DBG) Rlog.d(LOG_TAG, "myUser=" + myUser + "currentUser=" + currentUser);
+ if (DBG) Log.d(LOG_TAG, "myUser=" + myUser + "currentUser=" + currentUser);
if (myUser != currentUser) {
final Context otherContext;
@@ -121,7 +123,7 @@
/* flags =*/ 0, UserHandle.of(currentUser));
return otherContext.getContentResolver();
} catch (NameNotFoundException e) {
- Rlog.e(LOG_TAG, "Can't find self package", e);
+ Log.e(LOG_TAG, e, "Can't find self package");
// Fall back to the primary user.
}
}
@@ -186,13 +188,13 @@
// However, if there is any code that this Handler calls (such as in
// super.handleMessage) that DOES place unexpected messages on the
// queue, then we need pass these messages on.
- Rlog.i(LOG_TAG, "Unexpected command (CookieWrapper is null): " + msg.what +
+ Log.i(LOG_TAG, "Unexpected command (CookieWrapper is null): " + msg.what +
" ignored by CallerInfoWorkerHandler, passing onto parent.");
super.handleMessage(msg);
} else {
- Rlog.d(LOG_TAG, "Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
+ Log.d(LOG_TAG, "Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
" command: " + msg.what + " query URI: " + sanitizeUriToString(args.uri));
switch (cw.event) {
@@ -233,7 +235,7 @@
cw.geoDescription = CallerInfo.getGeoDescription(mContext, cw.number);
final long duration = SystemClock.elapsedRealtime() - startTimeMillis;
if (duration > 500) {
- if (DBG) Rlog.d(LOG_TAG, "[handleGeoDescription]" +
+ if (DBG) Log.d(LOG_TAG, "[handleGeoDescription]" +
"Spends long time to retrieve Geo description: " + duration);
}
}
@@ -270,7 +272,7 @@
*/
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
- Rlog.d(LOG_TAG, "##### onQueryComplete() ##### query complete for token: " + token);
+ Log.d(LOG_TAG, "##### onQueryComplete() ##### query complete for token: " + token);
//get the cookie and notify the listener.
CookieWrapper cw = (CookieWrapper) cookie;
@@ -279,7 +281,7 @@
// from within this code.
// However, if there is any code that calls this method, we should
// check the parameters to make sure they're viable.
- Rlog.i(LOG_TAG, "Cookie is null, ignoring onQueryComplete() request.");
+ Log.i(LOG_TAG, "Cookie is null, ignoring onQueryComplete() request.");
if (cursor != null) {
cursor.close();
}
@@ -328,16 +330,16 @@
// comments at the top of CallerInfo class).
mCallerInfo = new CallerInfo().markAsEmergency(mContext);
} else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
- mCallerInfo = new CallerInfo().markAsVoiceMail(cw.subId);
+ mCallerInfo = new CallerInfo().markAsVoiceMail(mContext, cw.subId);
} else {
mCallerInfo = CallerInfo.getCallerInfo(mContext, mQueryUri, cursor);
- if (DBG) Rlog.d(LOG_TAG, "==> Got mCallerInfo: " + mCallerInfo);
+ if (DBG) Log.d(LOG_TAG, "==> Got mCallerInfo: " + mCallerInfo);
CallerInfo newCallerInfo = CallerInfo.doSecondaryLookupIfNecessary(
mContext, cw.number, mCallerInfo);
if (newCallerInfo != mCallerInfo) {
mCallerInfo = newCallerInfo;
- if (DBG) Rlog.d(LOG_TAG, "#####async contact look up with numeric username"
+ if (DBG) Log.d(LOG_TAG, "#####async contact look up with numeric username"
+ mCallerInfo);
}
@@ -353,7 +355,7 @@
// the geo description, so it would be unnecessary to query it.
if (ENABLE_UNKNOWN_NUMBER_GEO_DESCRIPTION) {
if (TextUtils.isEmpty(mCallerInfo.getName())) {
- if (DBG) Rlog.d(LOG_TAG, "start querying geo description");
+ if (DBG) Log.d(LOG_TAG, "start querying geo description");
cw.event = EVENT_GET_GEO_DESCRIPTION;
startQuery(token, cw, null, null, null, null, null);
return;
@@ -361,7 +363,7 @@
}
}
- if (DBG) Rlog.d(LOG_TAG, "constructing CallerInfo object for token: " + token);
+ if (DBG) Log.d(LOG_TAG, "constructing CallerInfo object for token: " + token);
//notify that we can clean up the queue after this.
CookieWrapper endMarker = new CookieWrapper();
@@ -374,14 +376,14 @@
mPendingListenerCallbacks.add(new Runnable() {
@Override
public void run() {
- if (DBG) Rlog.d(LOG_TAG, "notifying listener: "
+ if (DBG) Log.d(LOG_TAG, "notifying listener: "
+ cw.listener.getClass().toString() + " for token: " + token
+ mCallerInfo);
cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
}
});
} else {
- Rlog.w(LOG_TAG, "There is no listener to notify for this query.");
+ Log.w(LOG_TAG, "There is no listener to notify for this query.");
}
if (cursor != null) {
@@ -406,7 +408,7 @@
CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
c.allocate(context, contactRef);
- if (DBG) Rlog.d(LOG_TAG, "starting query for URI: " + contactRef + " handler: " + c.toString());
+ if (DBG) Log.d(LOG_TAG, "starting query for URI: " + contactRef + " handler: " + c.toString());
//create cookieWrapper, start query
CookieWrapper cw = new CookieWrapper();
@@ -452,9 +454,9 @@
OnQueryCompleteListener listener, Object cookie, int subId) {
if (DBG) {
- Rlog.d(LOG_TAG, "##### CallerInfoAsyncQuery startQuery()... #####");
- Rlog.d(LOG_TAG, "- number: " + /*number*/ "xxxxxxx");
- Rlog.d(LOG_TAG, "- cookie: " + cookie);
+ Log.d(LOG_TAG, "##### CallerInfoAsyncQuery startQuery()... #####");
+ Log.d(LOG_TAG, "- number: " + /*number*/ "xxxxxxx");
+ Log.d(LOG_TAG, "- cookie: " + cookie);
}
// Construct the URI object and query params, and start the query.
@@ -466,7 +468,7 @@
.build();
if (DBG) {
- Rlog.d(LOG_TAG, "==> contactRef: " + sanitizeUriToString(contactRef));
+ Log.d(LOG_TAG, "==> contactRef: " + sanitizeUriToString(contactRef));
}
CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
@@ -503,8 +505,8 @@
*/
public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
- if (DBG) Rlog.d(LOG_TAG, "adding listener to query: " + sanitizeUriToString(mHandler.mQueryUri) +
- " handler: " + mHandler.toString());
+ if (DBG) Log.d(LOG_TAG, "adding listener to query: "
+ + sanitizeUriToString(mHandler.mQueryUri) + " handler: " + mHandler.toString());
//create cookieWrapper, add query request to end of queue.
CookieWrapper cw = new CookieWrapper();
diff --git a/telephony/common/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java
index 93f3065..95ae409 100755
--- a/telephony/common/com/google/android/mms/pdu/PduPersister.java
+++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java
@@ -1548,6 +1548,7 @@
public void release() {
Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI);
SqliteWrapper.delete(mContext, mContentResolver, uri, null, null);
+ mDrmManagerClient.release();
}
/**
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/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 dbada25..a315e6d 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2287,6 +2287,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
*/
@@ -2840,6 +2911,27 @@
*/
public static final String KEY_5G_WATCHDOG_TIME_MS_LONG =
"5g_watchdog_time_long";
+ /**
+ * Controls whether to switch data to primary from opportunistic subscription
+ * if primary is out of service. This control only affects system or 1st party app
+ * initiated data switch, but will not override data switch initiated by privileged carrier apps
+ * This carrier config is used to disable this feature.
+ * @hide
+ */
+ public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL =
+ "switch_data_to_primary_if_primary_is_oos_bool";
+
+ /**
+ * Controls back off time in milli seconds for switching back to
+ * opportunistic subscription. This time will be added to
+ * {@link CarrierConfigManager#KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG} to
+ * determine hysteresis time if there is frequent switching
+ * (determined by system app or 1st party app) between primary and opportunistic
+ * subscription.
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG =
+ "opportunistic_network_backoff_time_long";
/**
* Indicates zero or more emergency number prefix(es), because some carrier requires
@@ -3648,6 +3740,9 @@
sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true);
/* Default value is 1 hour. */
sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
+ sDefaults.putBoolean(KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL, true);
+ /* Default value is 10 seconds. */
+ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG, 10000);
sDefaults.putAll(Gps.getDefaults());
sDefaults.putAll(Wifi.getDefaults());
sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index aa7e21a..85110c2 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
@@ -369,7 +370,7 @@
* @hide
*/
@UnsupportedAppUsage
- public static String toString(int cause) {
+ public static @NonNull String toString(int cause) {
switch (cause) {
case NOT_DISCONNECTED:
return "NOT_DISCONNECTED";
diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java
new file mode 100644
index 0000000..02d8be3
--- /dev/null
+++ b/telephony/java/android/telephony/ImsManager.java
@@ -0,0 +1,66 @@
+/*
+ * 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.telephony.ims;
+
+import android.annotation.SystemService;
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+/**
+ * Provides access to information about Telephony IMS services on the device.
+ *
+ * @hide
+ */
+@SystemService(Context.TELEPHONY_IMS_SERVICE)
+public class ImsManager {
+
+ private Context mContext;
+
+ public ImsManager(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Create an instance of ImsRcsManager for the subscription id specified.
+ *
+ * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
+ * @throws IllegalArgumentException if the subscription is invalid.
+ * @return a ImsRcsManager instance with the specific subscription ID.
+ */
+ public ImsRcsManager getImsRcsManager(int subscriptionId) {
+ if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
+ throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
+ }
+
+ return new ImsRcsManager(mContext, subscriptionId);
+ }
+
+ /**
+ * Create an instance of ImsMmTelManager for the subscription id specified.
+ *
+ * @param subscriptionId The ID of the subscription that this ImsMmTelManager will use.
+ * @throws IllegalArgumentException if the subscription is invalid.
+ * @return a ImsMmTelManager instance with the specific subscription ID.
+ */
+ public ImsMmTelManager getImsMmTelManager(int subscriptionId) {
+ if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
+ throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
+ }
+
+ return new ImsMmTelManager(subscriptionId);
+ }
+}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index af3ba5e..4a1bc1f 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,12 +16,12 @@
package android.telephony;
-import com.android.i18n.phonenumbers.NumberParseException;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
-import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
-import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -42,7 +42,10 @@
import android.text.style.TtsSpan;
import android.util.SparseIntArray;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
+import com.android.i18n.phonenumbers.NumberParseException;
+import com.android.i18n.phonenumbers.PhoneNumberUtil;
+import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -2247,8 +2250,10 @@
* to read the VM number.
* @hide
*/
- @UnsupportedAppUsage
- public static boolean isVoiceMailNumber(Context context, int subId, String number) {
+ @SystemApi
+ @TestApi
+ public static boolean isVoiceMailNumber(@NonNull Context context, int subId,
+ @Nullable String number) {
String vmNumber, mdn;
try {
final TelephonyManager tm;
@@ -2734,8 +2739,9 @@
* @param number
* @return true if number contains @
*/
- @UnsupportedAppUsage
- public static boolean isUriNumber(String number) {
+ @SystemApi
+ @TestApi
+ public static boolean isUriNumber(@Nullable String number) {
// Note we allow either "@" or "%40" to indicate a URI, in case
// the passed-in string is URI-escaped. (Neither "@" nor "%40"
// will ever be found in a legal PSTN number.)
@@ -2752,8 +2758,9 @@
*
* @hide
*/
- @UnsupportedAppUsage
- public static String getUsernameFromUriNumber(String number) {
+ @SystemApi
+ @TestApi
+ public static @NonNull String getUsernameFromUriNumber(@NonNull String number) {
// The delimiter between username and domain name can be
// either "@" or "%40" (the URI-escaped equivalent.)
int delimiterIndex = number.indexOf('@');
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
index adf7154..d8a4754 100644
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ b/telephony/java/android/telephony/SmsCbLocation.java
@@ -65,9 +65,8 @@
/**
* 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
*/
- 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/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 0bf2aa7..1309b4d 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -903,10 +903,12 @@
* {@link ActivityThread#currentPackageName()} is null.
* @hide
*/
- public void sendMultipartTextMessageExternal(
- String destinationAddress, String scAddress, ArrayList<String> parts,
- ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
- String packageName) {
+ @SystemApi
+ @TestApi
+ public void sendMultipartTextMessage(
+ @NonNull String destinationAddress, @NonNull String scAddress,
+ @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
+ @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
deliveryIntents, true /* persistMessage*/,
ActivityThread.currentPackageName() == null
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 75e4fec..dfcfed7 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -31,6 +31,7 @@
import android.annotation.SuppressAutoDoc;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
@@ -155,6 +156,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
/**
@@ -174,6 +176,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "advanced_calling");
@@ -192,6 +195,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
/**
@@ -209,6 +213,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "wfc_roaming_mode");
@@ -228,6 +233,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "vt_enabled");
@@ -246,6 +252,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
CONTENT_URI, "wfc_roaming_enabled");
@@ -1819,13 +1826,27 @@
return subId;
}
- /** @hide */
- public void setDefaultVoiceSubId(int subId) {
- if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId);
+ /**
+ * Sets the system's default voice subscription id.
+ *
+ * On a data-only device, this is a no-op.
+ *
+ * May throw a {@link RuntimeException} if the provided subscription id is equal to
+ * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
+ *
+ * @param subscriptionId A valid subscription ID to set as the system default, or
+ * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+ public void setDefaultVoiceSubscriptionId(int subscriptionId) {
+ if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- iSub.setDefaultVoiceSubId(subId);
+ iSub.setDefaultVoiceSubId(subscriptionId);
}
} catch (RemoteException ex) {
// ignore it
@@ -1833,6 +1854,15 @@
}
/**
+ * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
+ * compatibility.
+ * @hide
+ */
+ public void setDefaultVoiceSubId(int subId) {
+ setDefaultVoiceSubscriptionId(subId);
+ }
+
+ /**
* Return the SubscriptionInfo for default voice subscription.
*
* Will return null on data only devices, or on error.
@@ -2916,6 +2946,7 @@
* permission or had carrier privilege permission on the subscription.
* {@link TelephonyManager#hasCarrierPrivileges()}
*
+ * @throws IllegalStateException if Telephony service is in bad state.
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
*
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4eb5a36..baa6953 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -38,6 +38,7 @@
import android.annotation.WorkerThread;
import android.app.ActivityThread;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
@@ -96,6 +97,7 @@
import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.SmsApplication;
import com.android.internal.telephony.TelephonyProperties;
import dalvik.system.VMRuntime;
@@ -460,6 +462,25 @@
getActiveModemCount());
}
+ /**
+ * Gets the maximum number of SIMs that can be active, based on the device's multisim
+ * configuration.
+ * @return 1 for single-SIM, DSDS, and TSTS devices. 2 for DSDA devices.
+ * @hide
+ */
+ @SystemApi
+ public int getMaxNumberOfSimultaneouslyActiveSims() {
+ switch (getMultiSimConfiguration()) {
+ case UNKNOWN:
+ case DSDS:
+ case TSTS:
+ return 1;
+ case DSDA:
+ return 2;
+ }
+ return 1;
+ }
+
/** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public static TelephonyManager from(Context context) {
@@ -8029,6 +8050,7 @@
/** @hide */
@SystemApi
+ @TestApi
public List<String> getCarrierPackageNamesForIntent(Intent intent) {
return getCarrierPackageNamesForIntentAndPhone(intent, getPhoneId());
}
@@ -9406,6 +9428,21 @@
}
/**
+ * Gets the default Respond Via Message application
+ * @param context context from the calling app
+ * @param updateIfNeeded update the default app if there is no valid default app configured.
+ * @return component name of the app and class to direct Respond Via Message intent to, or
+ * {@code null} if the functionality is not supported.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static @Nullable ComponentName getDefaultRespondViaMessageApplication(
+ @NonNull Context context, boolean updateIfNeeded) {
+ return SmsApplication.getDefaultRespondViaMessageApplication(context, updateIfNeeded);
+ }
+
+ /**
* Set the alphabetic name of current registered operator.
* @param name the alphabetic name of current registered operator.
* @hide
@@ -9507,7 +9544,7 @@
* @hide
*/
@UnsupportedAppUsage
- public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
+ public int getSubIdForPhoneAccount(@Nullable PhoneAccount phoneAccount) {
int retval = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
try {
ITelephony service = getITelephony();
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index a5d6266..60774e7 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1944,8 +1944,9 @@
* {@link ApnSetting} built from this builder otherwise.
*/
public ApnSetting build() {
- if ((mApnTypeBitmask & TYPE_ALL) == 0 || TextUtils.isEmpty(mApnName)
- || TextUtils.isEmpty(mEntryName)) {
+ if ((mApnTypeBitmask & (TYPE_DEFAULT | TYPE_MMS | TYPE_SUPL | TYPE_DUN | TYPE_HIPRI |
+ TYPE_FOTA | TYPE_IMS | TYPE_CBS | TYPE_IA | TYPE_EMERGENCY | TYPE_MCX)) == 0
+ || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) {
return null;
}
return new ApnSetting(this);
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 6f062f4..eb6c12c 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;
@@ -36,6 +37,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class ImsConferenceState implements Parcelable {
/**
* conference-info : user
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 eb2ebca..177d9b3 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;
@@ -34,6 +35,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..eb0e2f7 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 {
/**
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 6432016..21707b0 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -22,11 +22,15 @@
import android.annotation.RequiresPermission;
import android.content.Context;
import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.telephony.AccessNetworkConstants;
-import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
+import android.util.Log;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -35,10 +39,11 @@
* Manager for interfacing with the framework RCS services, including the User Capability Exchange
* (UCE) service, as well as managing user settings.
*
- * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager.
+ * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
* @hide
*/
public class ImsRcsManager implements RegistrationManager {
+ private static final String TAG = "ImsRcsManager";
/**
* Receives RCS availability status updates from the ImsService.
@@ -112,30 +117,23 @@
private final int mSubId;
private final Context mContext;
-
/**
- * Create an instance of ImsRcsManager for the subscription id specified.
- *
- * @param context The context to create this ImsRcsManager instance within.
- * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
- * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
- * @throws IllegalArgumentException if the subscription is invalid.
+ * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this class.
* @hide
*/
- public static ImsRcsManager createForSubscriptionId(Context context, int subscriptionId) {
- if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
- throw new IllegalArgumentException("Invalid subscription ID");
- }
-
- return new ImsRcsManager(context, subscriptionId);
+ public ImsRcsManager(Context context, int subId) {
+ mSubId = subId;
+ mContext = context;
}
/**
- * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this class.
+ * @return A {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
+ * this subscription.
+ * @hide
*/
- private ImsRcsManager(Context context, int subId) {
- mContext = context;
- mSubId = subId;
+ @NonNull
+ public RcsUceAdapter getUceAdapter() {
+ return new RcsUceAdapter(mSubId);
}
/**{@inheritDoc}*/
@@ -225,9 +223,22 @@
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
+
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "Register availability callback: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
c.setExecutor(executor);
- throw new UnsupportedOperationException("registerRcsAvailabilityCallback is not"
- + "supported.");
+ try {
+ imsRcsController.registerRcsAvailabilityCallback(c.getBinder());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#registerRcsAvailabilityCallback", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -238,14 +249,31 @@
* inactive subscription, it will result in a no-op.
* @param c The RCS {@link AvailabilityCallback} to be removed.
* @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
+ * @throws ImsException if the IMS service is not available when calling this method
+ * {@link ImsRcsController#unregisterRcsAvailabilityCallback()}.
+ * See {@link ImsException#getCode()} for more information on the error codes.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c) {
+ public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c)
+ throws ImsException {
if (c == null) {
throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
}
- throw new UnsupportedOperationException("unregisterRcsAvailabilityCallback is not"
- + "supported.");
+
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "Unregister availability callback: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ imsRcsController.unregisterRcsAvailabilityCallback(c.getBinder());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#unregisterRcsAvailabilityCallback", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -260,10 +288,27 @@
* rather the subscription is capable of this service over IMS.
* @see #isAvailable(int)
* @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL
+ * @throws ImsException if the IMS service is not available when calling this method
+ * {@link ImsRcsController#isCapable(int, int)}.
+ * See {@link ImsException#getCode()} for more information on the error codes.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
- throw new UnsupportedOperationException("isCapable is not supported.");
+ public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+ throws ImsException {
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "isCapable: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.isCapable(mSubId, capability);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#isCapable", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -277,18 +322,31 @@
* false otherwise. If the capability is available, IMS is registered and the service is
* currently available over IMS.
* @see #isCapable(int)
+ * @throws ImsException if the IMS service is not available when calling this method
+ * {@link ImsRcsController#isAvailable(int, int)}.
+ * See {@link ImsException#getCode()} for more information on the error codes.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
- throw new UnsupportedOperationException("isAvailable is not supported.");
+ public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+ throws ImsException {
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "isAvailable: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.isAvailable(mSubId, capability);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#isAvailable", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
- /**
- * @return A new {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
- * this subscription.
- */
- @NonNull
- public RcsUceAdapter getUceAdapter() {
- return new RcsUceAdapter(mSubId);
+ private IImsRcsController getIImsRcsController() {
+ IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
+ return IImsRcsController.Stub.asInterface(binder);
}
}
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 10251d7..663b09a 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/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index a6a7a84..b47bcb9 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -23,6 +23,13 @@
import android.annotation.RequiresPermission;
import android.content.Context;
import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.ims.aidl.IImsRcsController;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,6 +43,7 @@
* @hide
*/
public class RcsUceAdapter {
+ private static final String TAG = "RcsUceAdapter";
/**
* An unknown error has caused the request to fail.
@@ -188,7 +196,6 @@
/**
* Not to be instantiated directly, use
- * {@link ImsRcsManager#createForSubscriptionId(Context, int)} and
* {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
*/
RcsUceAdapter(int subId) {
@@ -218,7 +225,45 @@
public void requestCapabilities(@CallbackExecutor Executor executor,
@NonNull List<Uri> contactNumbers,
@NonNull CapabilitiesCallback c) throws ImsException {
- throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
+ if (c == null) {
+ throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ if (contactNumbers == null) {
+ throw new IllegalArgumentException("Must include non-null contact number list.");
+ }
+
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "requestCapabilities: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
+ @Override
+ public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() ->
+ c.onCapabilitiesReceived(contactCapabilities)));
+ }
+ @Override
+ public void onError(int errorCode) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() ->
+ c.onError(errorCode)));
+ }
+ };
+
+ try {
+ imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -233,7 +278,20 @@
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @PublishState int getUcePublishState() throws ImsException {
- throw new UnsupportedOperationException("getPublishState is not supported.");
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "getUcePublishState: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.getUcePublishState(mSubId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#getUcePublishState", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -252,9 +310,22 @@
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isUceSettingEnabled() throws ImsException {
- // TODO: add SubscriptionController column for this property.
- throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "isUceSettingEnabled: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.isUceSettingEnabled(mSubId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
+
/**
* Change the user’s setting for whether or not UCE is enabled for the associated subscription.
* @param isEnabled the user's setting for whether or not they wish for Presence and User
@@ -270,7 +341,24 @@
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
- // TODO: add SubscriptionController column for this property.
- throw new UnsupportedOperationException("setUceSettingEnabled is not supported.");
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "setUceSettingEnabled: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ imsRcsController.setUceSettingEnabled(mSubId, isEnabled);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#setUceSettingEnabled", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
+ private IImsRcsController getIImsRcsController() {
+ IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
+ return IImsRcsController.Stub.asInterface(binder);
}
}
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/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
new file mode 100644
index 0000000..b379bd0
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+
+/**
+ * Interface used to interact with the Telephony IMS.
+ *
+ * {@hide}
+ */
+interface IImsRcsController {
+ void registerRcsAvailabilityCallback(IImsCapabilityCallback c);
+ void unregisterRcsAvailabilityCallback(IImsCapabilityCallback c);
+ boolean isCapable(int subId, int capability);
+ boolean isAvailable(int subId, int capability);
+
+ // ImsUceAdapter specific
+ void requestCapabilities(int subId, in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+ int getUcePublishState(int subId);
+ boolean isUceSettingEnabled(int subId);
+ void setUceSettingEnabled(int subId, boolean isEnabled);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
new file mode 100644
index 0000000..5975930
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.telephony.ims.aidl;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+/**
+ * Provides interface for RCS UCE when receive a change.
+ *
+ * {@hide}
+ */
+oneway interface IRcsUceControllerCallback {
+ void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
+ void onError(int errorCode);
+}
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..119f890 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";
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/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 5766287..5ce42fd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -215,7 +215,7 @@
private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
byte[] pdu, int wacOffset) {
// little-endian
- int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
+ int wacDataLength = ((pdu[wacOffset + 1] & 0xff) << 8) | (pdu[wacOffset] & 0xff);
int offset = wacOffset + 2;
if (offset + wacDataLength > pdu.length) {
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 8ee0428..06be5e2 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -35,7 +35,7 @@
import android.provider.DeviceConfig;
import android.text.TextUtils;
-import androidx.test.InstrumentationRegistry;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.cts.install.lib.Install;
import com.android.cts.install.lib.InstallUtils;
@@ -184,7 +184,7 @@
@Test
public void testNativeWatchdogTriggersRollback_Phase1() throws Exception {
resetModuleMetadataPackage();
- Context context = InstrumentationRegistry.getContext();
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
PackageInfo metadataPackageInfo = context.getPackageManager().getPackageInfo(
MODULE_META_DATA_PACKAGE, 0);
String metadataApkPath = metadataPackageInfo.applicationInfo.sourceDir;
@@ -251,11 +251,11 @@
@Test
public void testNetworkFailedRollback_Phase3() throws Exception {
- // Sleep for > health check deadline
+ // Sleep for > health check deadline (120s to trigger rollback + 120s to reboot)
// The device is expected to reboot during sleeping. This device method will fail and
// the host will catch the assertion. If reboot doesn't happen, the host will fail the
// assertion.
- Thread.sleep(TimeUnit.SECONDS.toMillis(120));
+ Thread.sleep(TimeUnit.SECONDS.toMillis(240));
}
@Test
@@ -268,7 +268,7 @@
private static String getNetworkStackPackageName() {
Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
ComponentName comp = intent.resolveSystemService(
- InstrumentationRegistry.getContext().getPackageManager(), 0);
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(), 0);
return comp.getPackageName();
}
@@ -289,8 +289,8 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
int sessionId = Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
- PackageInstaller pi = InstrumentationRegistry.getContext().getPackageManager()
- .getPackageInstaller();
+ PackageInstaller pi = InstrumentationRegistry.getInstrumentation().getContext()
+ .getPackageManager().getPackageInstaller();
pi.abandonSession(sessionId);
// Remove the first intent sender result, so that the next staged install session does not
@@ -346,8 +346,8 @@
@Nullable
private static String getModuleMetadataPackageName() {
- String packageName = InstrumentationRegistry.getContext().getResources().getString(
- R.string.config_defaultModuleMetadataProvider);
+ String packageName = InstrumentationRegistry.getInstrumentation().getContext()
+ .getResources().getString(R.string.config_defaultModuleMetadataProvider);
if (TextUtils.isEmpty(packageName)) {
return null;
}
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 bfd5dd5..557d498 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
@@ -22,6 +22,7 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,6 +48,11 @@
phase));
}
+ @Before
+ public void setUp() throws Exception {
+ getDevice().reboot();
+ }
+
/**
* Tests watchdog triggered staged rollbacks involving only apks.
*/
diff --git a/tests/net/common/java/android/net/NetworkScoreTest.kt b/tests/net/common/java/android/net/NetworkScoreTest.kt
new file mode 100644
index 0000000..30836b7
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkScoreTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.assertParcelSane
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_SCORE = 80
+private const val KEY_DEFAULT_CAPABILITIES = "DEFAULT_CAPABILITIES"
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkScoreTest {
+ @Test
+ fun testParcelNetworkScore() {
+ val networkScore = NetworkScore()
+ val defaultCap = NetworkCapabilities()
+ networkScore.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+ assertEquals(defaultCap, networkScore.getExtension(KEY_DEFAULT_CAPABILITIES))
+ networkScore.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+ assertEquals(TEST_SCORE, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+ assertParcelSane(networkScore, 1)
+ }
+
+ @Test
+ fun testNullKeyAndValue() {
+ val networkScore = NetworkScore()
+ val defaultCap = NetworkCapabilities()
+ networkScore.putIntExtension(null, TEST_SCORE)
+ assertEquals(TEST_SCORE, networkScore.getIntExtension(null))
+ networkScore.putExtension(null, defaultCap)
+ assertEquals(defaultCap, networkScore.getExtension(null))
+ networkScore.putExtension(null, null)
+ val result: Parcelable? = networkScore.getExtension(null)
+ assertEquals(null, result)
+ }
+
+ @Test
+ fun testRemoveExtension() {
+ val networkScore = NetworkScore()
+ val defaultCap = NetworkCapabilities()
+ networkScore.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+ networkScore.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+ assertEquals(defaultCap, networkScore.getExtension(KEY_DEFAULT_CAPABILITIES))
+ assertEquals(TEST_SCORE, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+ networkScore.removeExtension(KEY_DEFAULT_CAPABILITIES)
+ networkScore.removeExtension(NetworkScore.LEGACY_SCORE)
+ val result: Parcelable? = networkScore.getExtension(KEY_DEFAULT_CAPABILITIES)
+ assertEquals(null, result)
+ assertEquals(0, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+ }
+
+ @Test
+ fun testEqualsNetworkScore() {
+ val ns1 = NetworkScore()
+ val ns2 = NetworkScore()
+ assertTrue(ns1.equals(ns2))
+ assertEquals(ns1.hashCode(), ns2.hashCode())
+
+ ns1.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+ assertFalse(ns1.equals(ns2))
+ assertNotEquals(ns1.hashCode(), ns2.hashCode())
+ ns2.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+ assertTrue(ns1.equals(ns2))
+ assertEquals(ns1.hashCode(), ns2.hashCode())
+
+ val defaultCap = NetworkCapabilities()
+ ns1.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+ assertFalse(ns1.equals(ns2))
+ assertNotEquals(ns1.hashCode(), ns2.hashCode())
+ ns2.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+ assertTrue(ns1.equals(ns2))
+ assertEquals(ns1.hashCode(), ns2.hashCode())
+
+ ns1.putIntExtension(null, 10)
+ assertFalse(ns1.equals(ns2))
+ assertNotEquals(ns1.hashCode(), ns2.hashCode())
+ ns2.putIntExtension(null, 10)
+ assertTrue(ns1.equals(ns2))
+ assertEquals(ns1.hashCode(), ns2.hashCode())
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 142769f..535298f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -39,6 +39,7 @@
import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkMisc;
+import android.net.NetworkScore;
import android.os.INetworkManagementService;
import android.text.format.DateUtils;
@@ -354,8 +355,10 @@
NetworkCapabilities caps = new NetworkCapabilities();
caps.addCapability(0);
caps.addTransportType(transport);
+ NetworkScore ns = new NetworkScore();
+ ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50);
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
- caps, 50, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
+ caps, ns, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
NetworkFactory.SerialNumber.NONE);
nai.everValidated = true;
return nai;
diff --git a/tools/apilint/apilint b/tools/apilint/apilint
deleted file mode 100755
index e42857f..0000000
--- a/tools/apilint/apilint
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-if [ "$1" == "--help" -o "$1" == "-h" ]; then
-echo "Usage: apilint [FILTERS...]"
-echo " Shows lint from currently open files (as diffed from HEAD), i.e. errors"
-echo " you will receive if you upload this CL."
-echo
-echo "Usage: apilint --all [FILTERS...]"
-echo " Shows all lint errors present in the current working directory, regardless"
-echo " of when they were added."
-echo
-echo "Usage: apilint --level API_LEVEL [FILTERS...]"
-echo " Shows lint as it stands in API_LEVEL"
-echo
-echo "Usage: apilint --shal SHA [FILTERS...]"
-echo " Shows lint from locally commited git change SHA."
-echo
-echo "Usage: apilint --unreleased [FILTERS...]"
-echo " Shows all lint errors in the current working directory directory added since"
-echo " the last released SDK version."
-echo
-echo "FILTERS"
-echo " List of class or package names by which to filter the results."
-echo
-exit
-fi
-
-if [ \( -z "$ANDROID_BUILD_TOP" \) \
- -a \( ! -f frameworks/base/api/current.txt \) \
- -a \( ! -f frameworks/base/api/system-current.txt \) \
- ]; then
- echo "apilint must be run either with ANDROID_BUILD_TOP set or from the" 1>&2
- echo "root of the android source tree" 1>&2
- exit 1
-fi
-
-if [ ${ANDROID_BUILD_TOP:0:1} != "/" ]; then
- echo "ANDROID_BUILD_TOP must be an absolute path, not: $ANDROID_BUILD_TOP" 1>&2
- exit 1
-fi
-
-if [ -z "$ANDROID_BUILD_TOP" ]; then
- ANDROID_BUILD_TOP=$(pwd)
-fi
-
-FW_BASE=$ANDROID_BUILD_TOP/frameworks/base
-
-MODE=open
-
-OPTIONS=$(getopt -n apilint -o "" -l "all,sha:,unreleased" -- "$@")
-
-[ $? -eq 0 ] || {
- exit 1
-}
-
-eval set -- "$OPTIONS"
-while true; do
- case "$1" in
- --all)
- MODE=all
- ;;
- --sha)
- shift; # The arg is next in position args
- MODE=sha
- SHA=$1
- ;;
- --unreleased)
- MODE=unreleased
- ;;
- --)
- shift
- break
- ;;
- esac
- shift
-done
-FILTERS=
-for var in "$@"
-do
- FILTERS="$FILTERS --filter $var"
-done
-
-if [ $MODE = "all" ]; then
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SDK" \
- $FILTERS \
- $ANDROID_BUILD_TOP/frameworks/base/api/current.txt
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SystemApi" \
- $FILTERS \
- --base-current $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
- $ANDROID_BUILD_TOP/frameworks/base/api/system-current.txt
-elif [ $MODE = "open" ]; then
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SDK" \
- $FILTERS \
- $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
- <(cd $FW_BASE ; git show HEAD:api/current.txt)
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SystemApi" \
- $FILTERS \
- --base-current $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
- --base-previous <(cd $FW_BASE ; git show HEAD:api/current.txt) \
- $ANDROID_BUILD_TOP/frameworks/base/api/system-current.txt \
- <(cd $FW_BASE ; git show HEAD:api/system-current.txt)
-elif [ $MODE = "sha" ]; then
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SDK" \
- $FILTERS \
- <(cd $FW_BASE ; git show $SHA:api/current.txt) \
- <(cd $FW_BASE ; git show $SHA^:api/current.txt)
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SystemApi" \
- $FILTERS \
- --base-current <(cd $FW_BASE ; git show $SHA:api/current.txt) \
- --base-previous <(cd $FW_BASE ; git show $SHA^:api/current.txt) \
- <(cd $FW_BASE ; git show $SHA:api/system-current.txt) \
- <(cd $FW_BASE ; git show $SHA^:api/system-current.txt)
-elif [ $MODE = "unreleased" ]; then
- LAST_SDK=$(ls $ANDROID_BUILD_TOP/prebuilts/sdk | grep "^[0-9][0-9]*$" | sort -n | tail -n 1)
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SDK" \
- $FILTERS \
- $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
- $ANDROID_BUILD_TOP/prebuilts/sdk/$LAST_SDK/public/api/android.txt
- python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
- --title "SystemApi" \
- $FILTERS \
- --base-current $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
- --base-previous $ANDROID_BUILD_TOP/prebuilts/sdk/$LAST_SDK/public/api/android.txt \
- $ANDROID_BUILD_TOP/frameworks/base/api/system-current.txt \
- $ANDROID_BUILD_TOP/prebuilts/sdk/$LAST_SDK/system/api/android.txt
-fi
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
deleted file mode 100644
index 912c1ad..0000000
--- a/tools/apilint/apilint.py
+++ /dev/null
@@ -1,2353 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Enforces common Android public API design patterns. It ignores lint messages from
-a previous API level, if provided.
-
-Usage: apilint.py current.txt
-Usage: apilint.py current.txt previous.txt
-
-You can also splice in blame details like this:
-$ git blame api/current.txt -t -e > /tmp/currentblame.txt
-$ apilint.py /tmp/currentblame.txt previous.txt --no-color
-"""
-
-import re, sys, collections, traceback, argparse, itertools
-
-
-BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
-
-ALLOW_GOOGLE = False
-USE_COLOR = True
-
-def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False):
- # manually derived from http://en.wikipedia.org/wiki/ANSI_escape_code#Codes
- if not USE_COLOR: return ""
- codes = []
- if reset: codes.append("0")
- else:
- if not fg is None: codes.append("3%d" % (fg))
- if not bg is None:
- if not bright: codes.append("4%d" % (bg))
- else: codes.append("10%d" % (bg))
- if bold: codes.append("1")
- elif dim: codes.append("2")
- else: codes.append("22")
- return "\033[%sm" % (";".join(codes))
-
-
-class Field():
- def __init__(self, clazz, line, raw, blame, sig_format = 1):
- self.clazz = clazz
- self.line = line
- self.raw = raw.strip(" {;")
- self.blame = blame
-
- if sig_format == 2:
- V2LineParser(raw).parse_into_field(self)
- elif sig_format == 1:
- # drop generics for now; may need multiple passes
- raw = re.sub("<[^<]+?>", "", raw)
- raw = re.sub("<[^<]+?>", "", raw)
-
- raw = raw.split()
- self.split = list(raw)
-
- for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]:
- while r in raw: raw.remove(r)
-
- # ignore annotations for now
- raw = [ r for r in raw if not r.startswith("@") ]
-
- self.typ = raw[0]
- self.name = raw[1].strip(";")
- if len(raw) >= 4 and raw[2] == "=":
- self.value = raw[3].strip(';"')
- else:
- self.value = None
- self.annotations = []
-
- self.ident = "-".join((self.typ, self.name, self.value or ""))
-
- def __hash__(self):
- return hash(self.raw)
-
- def __repr__(self):
- return self.raw
-
-
-class Argument(object):
-
- __slots__ = ["type", "annotations", "name", "default"]
-
- def __init__(self, type):
- self.type = type
- self.annotations = []
- self.name = None
- self.default = None
-
-
-class Method():
- def __init__(self, clazz, line, raw, blame, sig_format = 1):
- self.clazz = clazz
- self.line = line
- self.raw = raw.strip(" {;")
- self.blame = blame
-
- if sig_format == 2:
- V2LineParser(raw).parse_into_method(self)
- elif sig_format == 1:
- # drop generics for now; may need multiple passes
- raw = re.sub("<[^<]+?>", "", raw)
- raw = re.sub("<[^<]+?>", "", raw)
-
- # handle each clause differently
- raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups()
-
- # parse prefixes
- raw = re.split("[\s]+", raw_prefix)
- for r in ["", ";"]:
- while r in raw: raw.remove(r)
- self.split = list(raw)
-
- for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator", "synchronized"]:
- while r in raw: raw.remove(r)
-
- self.typ = raw[0]
- self.name = raw[1]
-
- # parse args
- self.detailed_args = []
- for arg in re.split(",\s*", raw_args):
- arg = re.split("\s", arg)
- # ignore annotations for now
- arg = [ a for a in arg if not a.startswith("@") ]
- if len(arg[0]) > 0:
- self.detailed_args.append(Argument(arg[0]))
-
- # parse throws
- self.throws = []
- for throw in re.split(",\s*", raw_throws):
- self.throws.append(throw)
-
- self.annotations = []
- else:
- raise ValueError("Unknown signature format: " + sig_format)
-
- self.args = map(lambda a: a.type, self.detailed_args)
- self.ident = "-".join((self.typ, self.name, "-".join(self.args)))
-
- def sig_matches(self, typ, name, args):
- return typ == self.typ and name == self.name and args == self.args
-
- def __hash__(self):
- return hash(self.raw)
-
- def __repr__(self):
- return self.raw
-
-
-class Class():
- def __init__(self, pkg, line, raw, blame, sig_format = 1):
- self.pkg = pkg
- self.line = line
- self.raw = raw.strip(" {;")
- self.blame = blame
- self.ctors = []
- self.fields = []
- self.methods = []
- self.annotations = []
-
- if sig_format == 2:
- V2LineParser(raw).parse_into_class(self)
- elif sig_format == 1:
- # drop generics for now; may need multiple passes
- raw = re.sub("<[^<]+?>", "", raw)
- raw = re.sub("<[^<]+?>", "", raw)
-
- raw = raw.split()
- self.split = list(raw)
- if "class" in raw:
- self.fullname = raw[raw.index("class")+1]
- elif "interface" in raw:
- self.fullname = raw[raw.index("interface")+1]
- elif "@interface" in raw:
- self.fullname = raw[raw.index("@interface")+1]
- else:
- raise ValueError("Funky class type %s" % (self.raw))
-
- if "extends" in raw:
- self.extends = raw[raw.index("extends")+1]
- else:
- self.extends = None
-
- if "implements" in raw:
- self.implements = raw[raw.index("implements")+1]
- self.implements_all = [self.implements]
- else:
- self.implements = None
- self.implements_all = []
- else:
- raise ValueError("Unknown signature format: " + sig_format)
-
- self.fullname = self.pkg.name + "." + self.fullname
- self.fullname_path = self.fullname.split(".")
-
- if self.extends is not None:
- self.extends_path = self.extends.split(".")
- else:
- self.extends_path = []
-
- self.name = self.fullname[self.fullname.rindex(".")+1:]
-
- def merge_from(self, other):
- self.ctors.extend(other.ctors)
- self.fields.extend(other.fields)
- self.methods.extend(other.methods)
-
- def __hash__(self):
- return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods)))
-
- def __repr__(self):
- return self.raw
-
-
-class Package():
- NAME = re.compile("package(?: .*)? ([A-Za-z0-9.]+)")
-
- def __init__(self, line, raw, blame):
- self.line = line
- self.raw = raw.strip(" {;")
- self.blame = blame
-
- self.name = Package.NAME.match(raw).group(1)
- self.name_path = self.name.split(".")
-
- def __repr__(self):
- return self.raw
-
-class V2Tokenizer(object):
- __slots__ = ["raw"]
-
- SIGNATURE_PREFIX = "// Signature format: "
- DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.')
- STRING_SPECIAL = re.compile(r'["\\]')
-
- def __init__(self, raw):
- self.raw = raw
-
- def tokenize(self):
- tokens = []
- current = 0
- raw = self.raw
- length = len(raw)
-
- while current < length:
- while current < length:
- start = current
- match = V2Tokenizer.DELIMITER.search(raw, start)
- if match is not None:
- match_start = match.start()
- if match_start == current:
- end = match.end()
- else:
- end = match_start
- else:
- end = length
-
- token = raw[start:end]
- current = end
-
- if token == "" or token[0] == " ":
- continue
- else:
- break
-
- if token == "@":
- if raw[start:start+11] == "@interface ":
- current = start + 11
- tokens.append("@interface")
- continue
- elif token == '/':
- if raw[start:start+2] == "//":
- current = length
- continue
- elif token == '"':
- current, string_token = self.tokenize_string(raw, length, current)
- tokens.append(token + string_token)
- continue
-
- tokens.append(token)
-
- return tokens
-
- def tokenize_string(self, raw, length, current):
- start = current
- end = length
- while start < end:
- match = V2Tokenizer.STRING_SPECIAL.search(raw, start)
- if match:
- if match.group() == '"':
- end = match.end()
- break
- elif match.group() == '\\':
- # ignore whatever is after the slash
- start += 2
- else:
- raise ValueError("Unexpected match: `%s`" % (match.group()))
- else:
- raise ValueError("Unexpected EOF tokenizing string: `%s`" % (raw[current - 1:],))
-
- token = raw[current:end]
- return end, token
-
-class V2LineParser(object):
- __slots__ = ["tokenized", "current", "len"]
-
- FIELD_KINDS = ("field", "property", "enum_constant")
- MODIFIERS = set("public protected internal private abstract default static final transient volatile synchronized native operator sealed strictfp infix inline suspend vararg".split())
- JAVA_LANG_TYPES = set("AbstractMethodError AbstractStringBuilder Appendable ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AssertionError AutoCloseable Boolean BootstrapMethodError Byte Character CharSequence Class ClassCastException ClassCircularityError ClassFormatError ClassLoader ClassNotFoundException Cloneable CloneNotSupportedException Comparable Compiler Deprecated Double Enum EnumConstantNotPresentException Error Exception ExceptionInInitializerError Float FunctionalInterface IllegalAccessError IllegalAccessException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IncompatibleClassChangeError IndexOutOfBoundsException InheritableThreadLocal InstantiationError InstantiationException Integer InternalError InterruptedException Iterable LinkageError Long Math NegativeArraySizeException NoClassDefFoundError NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NullPointerException Number NumberFormatException Object OutOfMemoryError Override Package package-info.java Process ProcessBuilder ProcessEnvironment ProcessImpl Readable ReflectiveOperationException Runnable Runtime RuntimeException RuntimePermission SafeVarargs SecurityException SecurityManager Short StackOverflowError StackTraceElement StrictMath String StringBuffer StringBuilder StringIndexOutOfBoundsException SuppressWarnings System Thread ThreadDeath ThreadGroup ThreadLocal Throwable TypeNotPresentException UNIXProcess UnknownError UnsatisfiedLinkError UnsupportedClassVersionError UnsupportedOperationException VerifyError VirtualMachineError Void".split())
-
- def __init__(self, raw):
- self.tokenized = V2Tokenizer(raw).tokenize()
- self.current = 0
- self.len = len(self.tokenized)
-
- def parse_into_method(self, method):
- method.split = []
- kind = self.parse_one_of("ctor", "method")
- method.split.append(kind)
- method.annotations = self.parse_annotations()
- method.split.extend(self.parse_modifiers())
- self.parse_matching_paren("<", ">")
- if "@Deprecated" in method.annotations:
- method.split.append("deprecated")
- if kind == "ctor":
- method.typ = "ctor"
- else:
- method.typ = self.parse_type()
- method.split.append(method.typ)
- method.name = self.parse_name()
- method.split.append(method.name)
- self.parse_token("(")
- method.detailed_args = self.parse_args()
- self.parse_token(")")
- method.throws = self.parse_throws()
- if "@interface" in method.clazz.split:
- self.parse_annotation_default()
- self.parse_token(";")
- self.parse_eof()
-
- def parse_into_class(self, clazz):
- clazz.split = []
- clazz.annotations = self.parse_annotations()
- if "@Deprecated" in clazz.annotations:
- clazz.split.append("deprecated")
- clazz.split.extend(self.parse_modifiers())
- kind = self.parse_one_of("class", "interface", "@interface", "enum")
- if kind == "enum":
- # enums are implicitly final
- clazz.split.append("final")
- clazz.split.append(kind)
- clazz.fullname = self.parse_name()
- self.parse_matching_paren("<", ">")
- extends = self.parse_extends()
- clazz.extends = extends[0] if extends else None
- clazz.implements_all = self.parse_implements()
- # The checks assume that interfaces are always found in implements, which isn't true for
- # subinterfaces.
- if not clazz.implements_all and "interface" in clazz.split:
- clazz.implements_all = [clazz.extends]
- clazz.implements = clazz.implements_all[0] if clazz.implements_all else None
- self.parse_token("{")
- self.parse_eof()
-
- def parse_into_field(self, field):
- kind = self.parse_one_of(*V2LineParser.FIELD_KINDS)
- field.split = [kind]
- field.annotations = self.parse_annotations()
- if "@Deprecated" in field.annotations:
- field.split.append("deprecated")
- field.split.extend(self.parse_modifiers())
- field.typ = self.parse_type()
- field.split.append(field.typ)
- field.name = self.parse_name()
- field.split.append(field.name)
- if self.parse_if("="):
- field.value = self.parse_value_stripped()
- else:
- field.value = None
-
- self.parse_token(";")
- self.parse_eof()
-
- def lookahead(self):
- return self.tokenized[self.current]
-
- def parse_one_of(self, *options):
- found = self.lookahead()
- if found not in options:
- raise ValueError("Parsing failed, expected one of `%s` but found `%s` in %s" % (options, found, repr(self.tokenized)))
- return self.parse_token()
-
- def parse_token(self, tok = None):
- found = self.lookahead()
- if tok is not None and found != tok:
- raise ValueError("Parsing failed, expected `%s` but found `%s` in %s" % (tok, found, repr(self.tokenized)))
- self.current += 1
- return found
-
- def eof(self):
- return self.current == self.len
-
- def parse_eof(self):
- if not self.eof():
- raise ValueError("Parsing failed, expected EOF, but %s has not been parsed in %s" % (self.tokenized[self.current:], self.tokenized))
-
- def parse_if(self, tok):
- if not self.eof() and self.lookahead() == tok:
- self.parse_token()
- return True
- return False
-
- def parse_annotations(self):
- ret = []
- while self.lookahead() == "@":
- ret.append(self.parse_annotation())
- return ret
-
- def parse_annotation(self):
- ret = self.parse_token("@") + self.parse_token()
- self.parse_matching_paren("(", ")")
- return ret
-
- def parse_matching_paren(self, open, close):
- start = self.current
- if not self.parse_if(open):
- return
- length = len(self.tokenized)
- count = 1
- while count > 0:
- if self.current == length:
- raise ValueError("Unexpected EOF looking for closing paren: `%s`" % (self.tokenized[start:],))
- t = self.parse_token()
- if t == open:
- count += 1
- elif t == close:
- count -= 1
- return self.tokenized[start:self.current]
-
- def parse_modifiers(self):
- ret = []
- while self.lookahead() in V2LineParser.MODIFIERS:
- ret.append(self.parse_token())
- return ret
-
- def parse_kotlin_nullability(self):
- t = self.lookahead()
- if t == "?" or t == "!":
- return self.parse_token()
- return None
-
- def parse_type(self):
- self.parse_annotations()
- type = self.parse_token()
- if type[-1] == '.':
- self.parse_annotations()
- type += self.parse_token()
- if type in V2LineParser.JAVA_LANG_TYPES:
- type = "java.lang." + type
- self.parse_matching_paren("<", ">")
- while True:
- t = self.lookahead()
- if t == "@":
- self.parse_annotation()
- elif t == "[]":
- type += self.parse_token()
- elif self.parse_kotlin_nullability() is not None:
- pass # discard nullability for now
- else:
- break
- return type
-
- def parse_arg_type(self):
- type = self.parse_type()
- if self.parse_if("..."):
- type += "..."
- self.parse_kotlin_nullability() # discard nullability for now
- return type
-
- def parse_name(self):
- return self.parse_token()
-
- def parse_args(self):
- args = []
- if self.lookahead() == ")":
- return args
-
- while True:
- args.append(self.parse_arg())
- if self.lookahead() == ")":
- return args
- self.parse_token(",")
-
- def parse_arg(self):
- self.parse_if("vararg") # kotlin vararg
- annotations = self.parse_annotations()
- arg = Argument(self.parse_arg_type())
- arg.annotations = annotations
- l = self.lookahead()
- if l != "," and l != ")":
- if self.lookahead() != '=':
- arg.name = self.parse_token() # kotlin argument name
- if self.parse_if('='): # kotlin default value
- arg.default = self.parse_expression()
- return arg
-
- def parse_expression(self):
- while not self.lookahead() in [')', ',', ';']:
- (self.parse_matching_paren('(', ')') or
- self.parse_matching_paren('{', '}') or
- self.parse_token())
-
- def parse_throws(self):
- ret = []
- if self.parse_if("throws"):
- ret.append(self.parse_type())
- while self.parse_if(","):
- ret.append(self.parse_type())
- return ret
-
- def parse_extends(self):
- if self.parse_if("extends"):
- return self.parse_space_delimited_type_list()
- return []
-
- def parse_implements(self):
- if self.parse_if("implements"):
- return self.parse_space_delimited_type_list()
- return []
-
- def parse_space_delimited_type_list(self, terminals = ["implements", "{"]):
- types = []
- while True:
- types.append(self.parse_type())
- if self.lookahead() in terminals:
- return types
-
- def parse_annotation_default(self):
- if self.parse_if("default"):
- self.parse_expression()
-
- def parse_value(self):
- if self.lookahead() == "{":
- return " ".join(self.parse_matching_paren("{", "}"))
- elif self.lookahead() == "(":
- return " ".join(self.parse_matching_paren("(", ")"))
- else:
- return self.parse_token()
-
- def parse_value_stripped(self):
- value = self.parse_value()
- if value[0] == '"':
- return value[1:-1]
- return value
-
-
-def _parse_stream(f, clazz_cb=None, base_f=None, out_classes_with_base=None,
- in_classes_with_base=[]):
- api = {}
- in_classes_with_base = _retry_iterator(in_classes_with_base)
-
- if base_f:
- base_classes = _retry_iterator(_parse_stream_to_generator(base_f))
- else:
- base_classes = []
-
- def handle_class(clazz):
- if clazz_cb:
- clazz_cb(clazz)
- else: # In callback mode, don't keep track of the full API
- api[clazz.fullname] = clazz
-
- def handle_missed_classes_with_base(clazz):
- for c in _yield_until_matching_class(in_classes_with_base, clazz):
- base_class = _skip_to_matching_class(base_classes, c)
- if base_class:
- handle_class(base_class)
-
- for clazz in _parse_stream_to_generator(f):
- # Before looking at clazz, let's see if there's some classes that were not present, but
- # may have an entry in the base stream.
- handle_missed_classes_with_base(clazz)
-
- base_class = _skip_to_matching_class(base_classes, clazz)
- if base_class:
- clazz.merge_from(base_class)
- if out_classes_with_base is not None:
- out_classes_with_base.append(clazz)
- handle_class(clazz)
-
- handle_missed_classes_with_base(None)
-
- return api
-
-def _parse_stream_to_generator(f):
- line = 0
- pkg = None
- clazz = None
- blame = None
- sig_format = 1
-
- re_blame = re.compile(r"^(\^?[a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
-
- field_prefixes = map(lambda kind: " %s" % (kind,), V2LineParser.FIELD_KINDS)
- def startsWithFieldPrefix(raw):
- for prefix in field_prefixes:
- if raw.startswith(prefix):
- return True
- return False
-
- for raw in f:
- line += 1
- raw = raw.rstrip()
- match = re_blame.match(raw)
- if match is not None:
- blame = match.groups()[0:2]
- if blame[0].startswith("^"): # Outside of blame range
- blame = None
- raw = match.groups()[2]
- else:
- blame = None
-
- if line == 1 and V2Tokenizer.SIGNATURE_PREFIX in raw:
- sig_format_string = raw[len(V2Tokenizer.SIGNATURE_PREFIX):]
- if sig_format_string in ["2.0", "3.0"]:
- sig_format = 2
- else:
- raise ValueError("Unknown format: %s" % (sig_format_string,))
- elif raw.startswith("package"):
- pkg = Package(line, raw, blame)
- elif raw.startswith(" ") and raw.endswith("{"):
- clazz = Class(pkg, line, raw, blame, sig_format=sig_format)
- elif raw.startswith(" ctor"):
- clazz.ctors.append(Method(clazz, line, raw, blame, sig_format=sig_format))
- elif raw.startswith(" method"):
- clazz.methods.append(Method(clazz, line, raw, blame, sig_format=sig_format))
- elif startsWithFieldPrefix(raw):
- clazz.fields.append(Field(clazz, line, raw, blame, sig_format=sig_format))
- elif raw.startswith(" }") and clazz:
- yield clazz
-
-def _retry_iterator(it):
- """Wraps an iterator, such that calling send(True) on it will redeliver the same element"""
- for e in it:
- while True:
- retry = yield e
- if not retry:
- break
- # send() was called, asking us to redeliver clazz on next(). Still need to yield
- # a dummy value to the send() first though.
- if (yield "Returning clazz on next()"):
- raise TypeError("send() must be followed by next(), not send()")
-
-def _skip_to_matching_class(classes, needle):
- """Takes a classes iterator and consumes entries until it returns the class we're looking for
-
- This relies on classes being sorted by package and class name."""
-
- for clazz in classes:
- if clazz.pkg.name < needle.pkg.name:
- # We haven't reached the right package yet
- continue
- if clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname:
- # We're in the right package, but not the right class yet
- continue
- if clazz.fullname == needle.fullname:
- return clazz
- # We ran past the right class. Send it back into the generator, then report failure.
- classes.send(clazz)
- return None
-
-def _yield_until_matching_class(classes, needle):
- """Takes a class iterator and yields entries it until it reaches the class we're looking for.
-
- This relies on classes being sorted by package and class name."""
-
- for clazz in classes:
- if needle is None:
- yield clazz
- elif clazz.pkg.name < needle.pkg.name:
- # We haven't reached the right package yet
- yield clazz
- elif clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname:
- # We're in the right package, but not the right class yet
- yield clazz
- elif clazz.fullname == needle.fullname:
- # Class found, abort.
- return
- else:
- # We ran past the right class. Send it back into the iterator, then abort.
- classes.send(clazz)
- return
-
-class Failure():
- def __init__(self, sig, clazz, detail, error, rule, msg):
- self.clazz = clazz
- self.sig = sig
- self.error = error
- self.rule = rule
- self.msg = msg
-
- if error:
- self.head = "Error %s" % (rule) if rule else "Error"
- dump = "%s%s:%s %s" % (format(fg=RED, bg=BLACK, bold=True), self.head, format(reset=True), msg)
- else:
- self.head = "Warning %s" % (rule) if rule else "Warning"
- dump = "%s%s:%s %s" % (format(fg=YELLOW, bg=BLACK, bold=True), self.head, format(reset=True), msg)
-
- self.line = clazz.line
- blame = clazz.blame
- if detail is not None:
- dump += "\n in " + repr(detail)
- self.line = detail.line
- blame = detail.blame
- dump += "\n in " + repr(clazz)
- dump += "\n in " + repr(clazz.pkg)
- dump += "\n at line " + repr(self.line)
- if blame is not None:
- dump += "\n last modified by %s in %s" % (blame[1], blame[0])
-
- self.dump = dump
-
- def __repr__(self):
- return self.dump
-
-
-failures = {}
-
-def _fail(clazz, detail, error, rule, msg):
- """Records an API failure to be processed later."""
- global failures
-
- sig = "%s-%s-%s" % (clazz.fullname, detail.ident if detail else None, msg)
- sig = sig.replace(" deprecated ", " ")
-
- failures[sig] = Failure(sig, clazz, detail, error, rule, msg)
-
-
-def warn(clazz, detail, rule, msg):
- _fail(clazz, detail, False, rule, msg)
-
-def error(clazz, detail, rule, msg):
- _fail(clazz, detail, True, rule, msg)
-
-
-noticed = {}
-
-def notice(clazz):
- global noticed
-
- noticed[clazz.fullname] = hash(clazz)
-
-
-verifiers = {}
-
-def verifier(f):
- verifiers[f.__name__] = f
- return f
-
-
-@verifier
-def verify_constants(clazz):
- """All static final constants must be FOO_NAME style."""
- if re.match("android\.R\.[a-z]+", clazz.fullname): return
- if clazz.fullname.startswith("android.os.Build"): return
- if clazz.fullname == "android.system.OsConstants": return
-
- req = ["java.lang.String","byte","short","int","long","float","double","boolean","char"]
- for f in clazz.fields:
- if "static" in f.split and "final" in f.split:
- if re.match("[A-Z0-9_]+", f.name) is None:
- error(clazz, f, "C2", "Constant field names must be FOO_NAME")
- if f.typ != "java.lang.String":
- if f.name.startswith("MIN_") or f.name.startswith("MAX_"):
- warn(clazz, f, "C8", "If min/max could change in future, make them dynamic methods")
- if f.typ in req and f.value is None:
- error(clazz, f, None, "All constants must be defined at compile time")
-
-@verifier
-def verify_enums(clazz):
- """Enums are bad, mmkay?"""
- if clazz.extends == "java.lang.Enum" or "enum" in clazz.split:
- error(clazz, None, "F5", "Enums are not allowed")
-
-@verifier
-def verify_class_names(clazz):
- """Try catching malformed class names like myMtp or MTPUser."""
- if clazz.fullname.startswith("android.opengl"): return
- if clazz.fullname.startswith("android.renderscript"): return
- if re.match("android\.R\.[a-z]+", clazz.fullname): return
-
- if re.search("[A-Z]{2,}", clazz.name) is not None:
- warn(clazz, None, "S1", "Class names with acronyms should be Mtp not MTP")
- if re.match("[^A-Z]", clazz.name):
- error(clazz, None, "S1", "Class must start with uppercase char")
- if clazz.name.endswith("Impl"):
- error(clazz, None, None, "Don't expose your implementation details")
-
-
-@verifier
-def verify_method_names(clazz):
- """Try catching malformed method names, like Foo() or getMTU()."""
- if clazz.fullname.startswith("android.opengl"): return
- if clazz.fullname.startswith("android.renderscript"): return
- if clazz.fullname == "android.system.OsConstants": return
-
- for m in clazz.methods:
- if re.search("[A-Z]{2,}", m.name) is not None:
- warn(clazz, m, "S1", "Method names with acronyms should be getMtu() instead of getMTU()")
- if re.match("[^a-z]", m.name):
- error(clazz, m, "S1", "Method name must start with lowercase char")
-
-
-@verifier
-def verify_callbacks(clazz):
- """Verify Callback classes.
- All methods must follow onFoo() naming style."""
- if clazz.fullname == "android.speech.tts.SynthesisCallback": return
-
- if clazz.name.endswith("Callbacks"):
- error(clazz, None, "L1", "Callback class names should be singular")
- if clazz.name.endswith("Observer"):
- warn(clazz, None, "L1", "Class should be named FooCallback")
-
- if clazz.name.endswith("Callback"):
- for m in clazz.methods:
- if not re.match("on[A-Z][a-z]*", m.name):
- error(clazz, m, "L1", "Callback method names must be onFoo() style")
-
-
-@verifier
-def verify_listeners(clazz):
- """Verify Listener classes.
- All Listener classes must be interface.
- All methods must follow onFoo() naming style.
- If only a single method, it must match class name:
- interface OnFooListener { void onFoo() }"""
-
- if clazz.name.endswith("Listener"):
- if "abstract" in clazz.split and "class" in clazz.split:
- error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback")
-
- for m in clazz.methods:
- if not re.match("on[A-Z][a-z]*", m.name):
- error(clazz, m, "L1", "Listener method names must be onFoo() style")
-
- if len(clazz.methods) == 1 and clazz.name.startswith("On"):
- m = clazz.methods[0]
- if (m.name + "Listener").lower() != clazz.name.lower():
- error(clazz, m, "L1", "Single listener method name must match class name")
-
-
-@verifier
-def verify_actions(clazz):
- """Verify intent actions.
- All action names must be named ACTION_FOO.
- All action values must be scoped by package and match name:
- package android.foo {
- String ACTION_BAR = "android.foo.action.BAR";
- }"""
- for f in clazz.fields:
- if f.value is None: continue
- if f.name.startswith("EXTRA_"): continue
- if f.name == "SERVICE_INTERFACE" or f.name == "PROVIDER_INTERFACE": continue
- if "INTERACTION" in f.name: continue
-
- if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
- if "_ACTION" in f.name or "ACTION_" in f.name or ".action." in f.value.lower():
- if not f.name.startswith("ACTION_"):
- error(clazz, f, "C3", "Intent action constant name must be ACTION_FOO")
- else:
- if clazz.fullname == "android.content.Intent":
- prefix = "android.intent.action"
- elif clazz.fullname == "android.provider.Settings":
- prefix = "android.settings"
- elif clazz.fullname == "android.app.admin.DevicePolicyManager" or clazz.fullname == "android.app.admin.DeviceAdminReceiver":
- prefix = "android.app.action"
- else:
- prefix = clazz.pkg.name + ".action"
- expected = prefix + "." + f.name[7:]
- if f.value != expected:
- error(clazz, f, "C4", "Inconsistent action value; expected '%s'" % (expected))
-
-
-@verifier
-def verify_extras(clazz):
- """Verify intent extras.
- All extra names must be named EXTRA_FOO.
- All extra values must be scoped by package and match name:
- package android.foo {
- String EXTRA_BAR = "android.foo.extra.BAR";
- }"""
- if clazz.fullname == "android.app.Notification": return
- if clazz.fullname == "android.appwidget.AppWidgetManager": return
-
- for f in clazz.fields:
- if f.value is None: continue
- if f.name.startswith("ACTION_"): continue
-
- if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
- if "_EXTRA" in f.name or "EXTRA_" in f.name or ".extra" in f.value.lower():
- if not f.name.startswith("EXTRA_"):
- error(clazz, f, "C3", "Intent extra must be EXTRA_FOO")
- else:
- if clazz.pkg.name == "android.content" and clazz.name == "Intent":
- prefix = "android.intent.extra"
- elif clazz.pkg.name == "android.app.admin":
- prefix = "android.app.extra"
- else:
- prefix = clazz.pkg.name + ".extra"
- expected = prefix + "." + f.name[6:]
- if f.value != expected:
- error(clazz, f, "C4", "Inconsistent extra value; expected '%s'" % (expected))
-
-
-@verifier
-def verify_equals(clazz):
- """Verify that equals() and hashCode() must be overridden together."""
- eq = False
- hc = False
- for m in clazz.methods:
- if "static" in m.split: continue
- if m.sig_matches("boolean", "equals", ["java.lang.Object"]): eq = True
- if m.sig_matches("int", "hashCode", []): hc = True
- if eq != hc:
- error(clazz, None, "M8", "Must override both equals and hashCode; missing one")
-
-
-@verifier
-def verify_parcelable(clazz):
- """Verify that Parcelable objects aren't hiding required bits."""
- if clazz.implements == "android.os.Parcelable":
- creator = [ i for i in clazz.fields if i.name == "CREATOR" ]
- write = [ i for i in clazz.methods if i.name == "writeToParcel" ]
- describe = [ i for i in clazz.methods if i.name == "describeContents" ]
-
- if len(creator) == 0 or len(write) == 0 or len(describe) == 0:
- error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")
-
- if "final" not in clazz.split:
- error(clazz, None, "FW8", "Parcelable classes must be final")
-
- for c in clazz.ctors:
- if c.args == ["android.os.Parcel"]:
- error(clazz, c, "FW3", "Parcelable inflation is exposed through CREATOR, not raw constructors")
-
-
-@verifier
-def verify_protected(clazz):
- """Verify that no protected methods or fields are allowed."""
- for m in clazz.methods:
- if m.name == "finalize": continue
- if "protected" in m.split:
- error(clazz, m, "M7", "Protected methods not allowed; must be public")
- for f in clazz.fields:
- if "protected" in f.split:
- error(clazz, f, "M7", "Protected fields not allowed; must be public")
-
-
-@verifier
-def verify_fields(clazz):
- """Verify that all exposed fields are final.
- Exposed fields must follow myName style.
- Catch internal mFoo objects being exposed."""
-
- IGNORE_BARE_FIELDS = [
- "android.app.ActivityManager.RecentTaskInfo",
- "android.app.Notification",
- "android.content.pm.ActivityInfo",
- "android.content.pm.ApplicationInfo",
- "android.content.pm.ComponentInfo",
- "android.content.pm.ResolveInfo",
- "android.content.pm.FeatureGroupInfo",
- "android.content.pm.InstrumentationInfo",
- "android.content.pm.PackageInfo",
- "android.content.pm.PackageItemInfo",
- "android.content.res.Configuration",
- "android.graphics.BitmapFactory.Options",
- "android.os.Message",
- "android.system.StructPollfd",
- ]
-
- for f in clazz.fields:
- if not "final" in f.split:
- if clazz.fullname in IGNORE_BARE_FIELDS:
- pass
- elif clazz.fullname.endswith("LayoutParams"):
- pass
- elif clazz.fullname.startswith("android.util.Mutable"):
- pass
- else:
- error(clazz, f, "F2", "Bare fields must be marked final, or add accessors if mutable")
-
- if "static" not in f.split and "property" not in f.split:
- if not re.match("[a-z]([a-zA-Z]+)?", f.name):
- error(clazz, f, "S1", "Non-static fields must be named using myField style")
-
- if re.match("[ms][A-Z]", f.name):
- error(clazz, f, "F1", "Internal objects must not be exposed")
-
- if re.match("[A-Z_]+", f.name):
- if "static" not in f.split or "final" not in f.split:
- error(clazz, f, "C2", "Constants must be marked static final")
-
-
-@verifier
-def verify_register(clazz):
- """Verify parity of registration methods.
- Callback objects use register/unregister methods.
- Listener objects use add/remove methods."""
- methods = [ m.name for m in clazz.methods ]
- for m in clazz.methods:
- if "Callback" in m.raw:
- if m.name.startswith("register"):
- other = "unregister" + m.name[8:]
- if other not in methods:
- error(clazz, m, "L2", "Missing unregister method")
- if m.name.startswith("unregister"):
- other = "register" + m.name[10:]
- if other not in methods:
- error(clazz, m, "L2", "Missing register method")
-
- if m.name.startswith("add") or m.name.startswith("remove"):
- error(clazz, m, "L3", "Callback methods should be named register/unregister")
-
- if "Listener" in m.raw:
- if m.name.startswith("add"):
- other = "remove" + m.name[3:]
- if other not in methods:
- error(clazz, m, "L2", "Missing remove method")
- if m.name.startswith("remove") and not m.name.startswith("removeAll"):
- other = "add" + m.name[6:]
- if other not in methods:
- error(clazz, m, "L2", "Missing add method")
-
- if m.name.startswith("register") or m.name.startswith("unregister"):
- error(clazz, m, "L3", "Listener methods should be named add/remove")
-
-
-@verifier
-def verify_sync(clazz):
- """Verify synchronized methods aren't exposed."""
- for m in clazz.methods:
- if "synchronized" in m.split:
- error(clazz, m, "M5", "Internal locks must not be exposed")
-
-
-@verifier
-def verify_intent_builder(clazz):
- """Verify that Intent builders are createFooIntent() style."""
- if clazz.name == "Intent": return
-
- for m in clazz.methods:
- if m.typ == "android.content.Intent":
- if m.name.startswith("create") and m.name.endswith("Intent"):
- pass
- else:
- warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")
-
-
-@verifier
-def verify_helper_classes(clazz):
- """Verify that helper classes are named consistently with what they extend.
- All developer extendable methods should be named onFoo()."""
- test_methods = False
- if clazz.extends == "android.app.Service":
- test_methods = True
- if not clazz.name.endswith("Service"):
- error(clazz, None, "CL4", "Inconsistent class name; should be FooService")
-
- found = False
- for f in clazz.fields:
- if f.name == "SERVICE_INTERFACE":
- found = True
- if f.value != clazz.fullname:
- error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname))
-
- if clazz.extends == "android.content.ContentProvider":
- test_methods = True
- if not clazz.name.endswith("Provider"):
- error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider")
-
- found = False
- for f in clazz.fields:
- if f.name == "PROVIDER_INTERFACE":
- found = True
- if f.value != clazz.fullname:
- error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname))
-
- if clazz.extends == "android.content.BroadcastReceiver":
- test_methods = True
- if not clazz.name.endswith("Receiver"):
- error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver")
-
- if clazz.extends == "android.app.Activity":
- test_methods = True
- if not clazz.name.endswith("Activity"):
- error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity")
-
- if test_methods:
- for m in clazz.methods:
- if "final" in m.split: continue
- if not re.match("on[A-Z]", m.name):
- if "abstract" in m.split:
- warn(clazz, m, None, "Methods implemented by developers should be named onFoo()")
- else:
- warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")
-
-
-@verifier
-def verify_builder(clazz):
- """Verify builder classes.
- Methods should return the builder to enable chaining."""
- if clazz.extends: return
- if not clazz.name.endswith("Builder"): return
-
- if clazz.name != "Builder":
- warn(clazz, None, None, "Builder should be defined as inner class")
-
- has_build = False
- for m in clazz.methods:
- if m.name == "build":
- has_build = True
- continue
-
- if m.name.startswith("get"): continue
- if m.name.startswith("clear"): continue
-
- if m.name.startswith("with"):
- warn(clazz, m, None, "Builder methods names should use setFoo() style")
-
- if m.name.startswith("set"):
- if not m.typ.endswith(clazz.fullname):
- warn(clazz, m, "M4", "Methods must return the builder object")
-
- if not has_build:
- warn(clazz, None, None, "Missing build() method")
-
- if "final" not in clazz.split:
- error(clazz, None, None, "Builder should be final")
-
-
-@verifier
-def verify_aidl(clazz):
- """Catch people exposing raw AIDL."""
- if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface":
- error(clazz, None, None, "Raw AIDL interfaces must not be exposed")
-
-
-@verifier
-def verify_internal(clazz):
- """Catch people exposing internal classes."""
- if clazz.pkg.name.startswith("com.android"):
- error(clazz, None, None, "Internal classes must not be exposed")
-
-def layering_build_ranking(ranking_list):
- r = {}
- for rank, ps in enumerate(ranking_list):
- if not isinstance(ps, list):
- ps = [ps]
- for p in ps:
- rs = r
- for n in p.split('.'):
- if n not in rs:
- rs[n] = {}
- rs = rs[n]
- rs['-rank'] = rank
- return r
-
-LAYERING_PACKAGE_RANKING = layering_build_ranking([
- ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"],
- "android.app",
- "android.widget",
- "android.view",
- "android.animation",
- "android.provider",
- ["android.content","android.graphics.drawable"],
- "android.database",
- "android.text",
- "android.graphics",
- "android.os",
- "android.util"
-])
-
-@verifier
-def verify_layering(clazz):
- """Catch package layering violations.
- For example, something in android.os depending on android.app."""
-
- def rank(p):
- r = None
- l = LAYERING_PACKAGE_RANKING
- for n in p.split('.'):
- if n in l:
- l = l[n]
- if '-rank' in l:
- r = l['-rank']
- else:
- break
- return r
-
- cr = rank(clazz.pkg.name)
- if cr is None: return
-
- for f in clazz.fields:
- ir = rank(f.typ)
- if ir is not None and ir < cr:
- warn(clazz, f, "FW6", "Field type violates package layering")
-
- for m in itertools.chain(clazz.methods, clazz.ctors):
- ir = rank(m.typ)
- if ir is not None and ir < cr:
- warn(clazz, m, "FW6", "Method return type violates package layering")
- for arg in m.args:
- ir = rank(arg)
- if ir is not None and ir < cr:
- warn(clazz, m, "FW6", "Method argument type violates package layering")
-
-
-@verifier
-def verify_boolean(clazz):
- """Verifies that boolean accessors are named correctly.
- For example, hasFoo() and setHasFoo()."""
-
- def is_get(m): return len(m.args) == 0 and m.typ == "boolean"
- def is_set(m): return len(m.args) == 1 and m.args[0] == "boolean"
-
- gets = [ m for m in clazz.methods if is_get(m) ]
- sets = [ m for m in clazz.methods if is_set(m) ]
-
- def error_if_exists(methods, trigger, expected, actual):
- for m in methods:
- if m.name == actual:
- error(clazz, m, "M6", "Symmetric method for %s must be named %s" % (trigger, expected))
-
- for m in clazz.methods:
- if is_get(m):
- if re.match("is[A-Z]", m.name):
- target = m.name[2:]
- expected = "setIs" + target
- error_if_exists(sets, m.name, expected, "setHas" + target)
- elif re.match("has[A-Z]", m.name):
- target = m.name[3:]
- expected = "setHas" + target
- error_if_exists(sets, m.name, expected, "setIs" + target)
- error_if_exists(sets, m.name, expected, "set" + target)
- elif re.match("get[A-Z]", m.name):
- target = m.name[3:]
- expected = "set" + target
- error_if_exists(sets, m.name, expected, "setIs" + target)
- error_if_exists(sets, m.name, expected, "setHas" + target)
-
- if is_set(m):
- if re.match("set[A-Z]", m.name):
- target = m.name[3:]
- expected = "get" + target
- error_if_exists(sets, m.name, expected, "is" + target)
- error_if_exists(sets, m.name, expected, "has" + target)
-
-
-@verifier
-def verify_collections(clazz):
- """Verifies that collection types are interfaces."""
- if clazz.fullname == "android.os.Bundle": return
- if clazz.fullname == "android.os.Parcel": return
-
- bad = ["java.util.Vector", "java.util.LinkedList", "java.util.ArrayList", "java.util.Stack",
- "java.util.HashMap", "java.util.HashSet", "android.util.ArraySet", "android.util.ArrayMap"]
- for m in clazz.methods:
- if m.typ in bad:
- error(clazz, m, "CL2", "Return type is concrete collection; must be higher-level interface")
- for arg in m.args:
- if arg in bad:
- error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")
-
-
-@verifier
-def verify_uris(clazz):
- bad = ["java.net.URL", "java.net.URI", "android.net.URL"]
-
- for f in clazz.fields:
- if f.typ in bad:
- error(clazz, f, None, "Field must be android.net.Uri instead of " + f.typ)
-
- for m in clazz.methods + clazz.ctors:
- if m.typ in bad:
- error(clazz, m, None, "Must return android.net.Uri instead of " + m.typ)
- for arg in m.args:
- if arg in bad:
- error(clazz, m, None, "Argument must take android.net.Uri instead of " + arg)
-
-
-@verifier
-def verify_flags(clazz):
- """Verifies that flags are non-overlapping."""
- known = collections.defaultdict(int)
- for f in clazz.fields:
- if "FLAG_" in f.name:
- try:
- val = int(f.value)
- except:
- continue
-
- scope = f.name[0:f.name.index("FLAG_")]
- if val & known[scope]:
- warn(clazz, f, "C1", "Found overlapping flag constant value")
- known[scope] |= val
-
-
-@verifier
-def verify_exception(clazz):
- """Verifies that methods don't throw generic exceptions."""
- for m in clazz.methods:
- for t in m.throws:
- if t in ["java.lang.Exception", "java.lang.Throwable", "java.lang.Error"]:
- error(clazz, m, "S1", "Methods must not throw generic exceptions")
-
- if t in ["android.os.RemoteException"]:
- if clazz.fullname == "android.content.ContentProviderClient": continue
- if clazz.fullname == "android.os.Binder": continue
- if clazz.fullname == "android.os.IBinder": continue
-
- error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
-
- if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]:
- warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException")
-
-
-GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE)
-
-# Not marked as @verifier, because it is only conditionally applied.
-def verify_google(clazz):
- """Verifies that APIs never reference Google."""
-
- if GOOGLE_IGNORECASE.search(clazz.raw) is not None:
- error(clazz, None, None, "Must never reference Google")
-
- for test in clazz.ctors, clazz.fields, clazz.methods:
- for t in test:
- if GOOGLE_IGNORECASE.search(t.raw) is not None:
- error(clazz, t, None, "Must never reference Google")
-
-
-@verifier
-def verify_bitset(clazz):
- """Verifies that we avoid using heavy BitSet."""
-
- for f in clazz.fields:
- if f.typ == "java.util.BitSet":
- error(clazz, f, None, "Field type must not be heavy BitSet")
-
- for m in clazz.methods:
- if m.typ == "java.util.BitSet":
- error(clazz, m, None, "Return type must not be heavy BitSet")
- for arg in m.args:
- if arg == "java.util.BitSet":
- error(clazz, m, None, "Argument type must not be heavy BitSet")
-
-
-@verifier
-def verify_manager(clazz):
- """Verifies that FooManager is only obtained from Context."""
-
- if not clazz.name.endswith("Manager"): return
-
- for c in clazz.ctors:
- error(clazz, c, None, "Managers must always be obtained from Context; no direct constructors")
-
- for m in clazz.methods:
- if m.typ == clazz.fullname:
- error(clazz, m, None, "Managers must always be obtained from Context")
-
-
-@verifier
-def verify_boxed(clazz):
- """Verifies that methods avoid boxed primitives."""
-
- boxed = ["java.lang.Number","java.lang.Byte","java.lang.Double","java.lang.Float","java.lang.Integer","java.lang.Long","java.lang.Short"]
-
- for c in clazz.ctors:
- for arg in c.args:
- if arg in boxed:
- error(clazz, c, "M11", "Must avoid boxed primitives")
-
- for f in clazz.fields:
- if f.typ in boxed:
- error(clazz, f, "M11", "Must avoid boxed primitives")
-
- for m in clazz.methods:
- if m.typ in boxed:
- error(clazz, m, "M11", "Must avoid boxed primitives")
- for arg in m.args:
- if arg in boxed:
- error(clazz, m, "M11", "Must avoid boxed primitives")
-
-
-@verifier
-def verify_static_utils(clazz):
- """Verifies that helper classes can't be constructed."""
- if clazz.fullname.startswith("android.opengl"): return
- if clazz.fullname.startswith("android.R"): return
-
- # Only care about classes with default constructors
- if len(clazz.ctors) == 1 and len(clazz.ctors[0].args) == 0:
- test = []
- test.extend(clazz.fields)
- test.extend(clazz.methods)
-
- if len(test) == 0: return
- for t in test:
- if "static" not in t.split:
- return
-
- error(clazz, None, None, "Fully-static utility classes must not have constructor")
-
-
-# @verifier # Disabled for now
-def verify_overload_args(clazz):
- """Verifies that method overloads add new arguments at the end."""
- if clazz.fullname.startswith("android.opengl"): return
-
- overloads = collections.defaultdict(list)
- for m in clazz.methods:
- if "deprecated" in m.split: continue
- overloads[m.name].append(m)
-
- for name, methods in overloads.items():
- if len(methods) <= 1: continue
-
- # Look for arguments common across all overloads
- def cluster(args):
- count = collections.defaultdict(int)
- res = set()
- for i in range(len(args)):
- a = args[i]
- res.add("%s#%d" % (a, count[a]))
- count[a] += 1
- return res
-
- common_args = cluster(methods[0].args)
- for m in methods:
- common_args = common_args & cluster(m.args)
-
- if len(common_args) == 0: continue
-
- # Require that all common arguments are present at start of signature
- locked_sig = None
- for m in methods:
- sig = m.args[0:len(common_args)]
- if not common_args.issubset(cluster(sig)):
- warn(clazz, m, "M2", "Expected common arguments [%s] at beginning of overloaded method" % (", ".join(common_args)))
- elif not locked_sig:
- locked_sig = sig
- elif locked_sig != sig:
- error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))
-
-
-@verifier
-def verify_callback_handlers(clazz):
- """Verifies that methods adding listener/callback have overload
- for specifying delivery thread."""
-
- # Ignore UI packages which assume main thread
- skip = [
- "animation",
- "view",
- "graphics",
- "transition",
- "widget",
- "webkit",
- ]
- for s in skip:
- if s in clazz.pkg.name_path: return
- if s in clazz.extends_path: return
-
- # Ignore UI classes which assume main thread
- if "app" in clazz.pkg.name_path or "app" in clazz.extends_path:
- for s in ["ActionBar","Dialog","Application","Activity","Fragment","Loader"]:
- if s in clazz.fullname: return
- if "content" in clazz.pkg.name_path or "content" in clazz.extends_path:
- for s in ["Loader"]:
- if s in clazz.fullname: return
-
- found = {}
- by_name = collections.defaultdict(list)
- examine = clazz.ctors + clazz.methods
- for m in examine:
- if m.name.startswith("unregister"): continue
- if m.name.startswith("remove"): continue
- if re.match("on[A-Z]+", m.name): continue
-
- by_name[m.name].append(m)
-
- for a in m.args:
- if a.endswith("Listener") or a.endswith("Callback") or a.endswith("Callbacks"):
- found[m.name] = m
-
- for f in found.values():
- takes_handler = False
- takes_exec = False
- for m in by_name[f.name]:
- if "android.os.Handler" in m.args:
- takes_handler = True
- if "java.util.concurrent.Executor" in m.args:
- takes_exec = True
- if not takes_exec:
- warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Executor")
-
-
-@verifier
-def verify_context_first(clazz):
- """Verifies that methods accepting a Context keep it the first argument."""
- examine = clazz.ctors + clazz.methods
- for m in examine:
- if len(m.args) > 1 and m.args[0] != "android.content.Context":
- if "android.content.Context" in m.args[1:]:
- error(clazz, m, "M3", "Context is distinct, so it must be the first argument")
- if len(m.args) > 1 and m.args[0] != "android.content.ContentResolver":
- if "android.content.ContentResolver" in m.args[1:]:
- error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")
-
-
-@verifier
-def verify_listener_last(clazz):
- """Verifies that methods accepting a Listener or Callback keep them as last arguments."""
- examine = clazz.ctors + clazz.methods
- for m in examine:
- if "Listener" in m.name or "Callback" in m.name: continue
- found = False
- for a in m.args:
- if a.endswith("Callback") or a.endswith("Callbacks") or a.endswith("Listener"):
- found = True
- elif found:
- warn(clazz, m, "M3", "Listeners should always be at end of argument list")
-
-
-@verifier
-def verify_resource_names(clazz):
- """Verifies that resource names have consistent case."""
- if not re.match("android\.R\.[a-z]+", clazz.fullname): return
-
- # Resources defined by files are foo_bar_baz
- if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]:
- for f in clazz.fields:
- if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
- if f.name.startswith("config_"):
- error(clazz, f, None, "Expected config name to be config_fooBarBaz style")
-
- if re.match("[a-z1-9_]+$", f.name): continue
- error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style")
-
- # Resources defined inside files are fooBarBaz
- if clazz.name in ["array","attr","id","bool","fraction","integer"]:
- for f in clazz.fields:
- if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
- if re.match("layout_[a-z][a-zA-Z1-9]*$", f.name): continue
- if re.match("state_[a-z_]*$", f.name): continue
-
- if re.match("[a-z][a-zA-Z1-9]*$", f.name): continue
- error(clazz, f, "C7", "Expected resource name in this class to be fooBarBaz style")
-
- # Styles are FooBar_Baz
- if clazz.name in ["style"]:
- for f in clazz.fields:
- if re.match("[A-Z][A-Za-z1-9]+(_[A-Z][A-Za-z1-9]+?)*$", f.name): continue
- error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")
-
-
-@verifier
-def verify_files(clazz):
- """Verifies that methods accepting File also accept streams."""
-
- has_file = set()
- has_stream = set()
-
- test = []
- test.extend(clazz.ctors)
- test.extend(clazz.methods)
-
- for m in test:
- if "java.io.File" in m.args:
- has_file.add(m)
- if "java.io.FileDescriptor" in m.args or "android.os.ParcelFileDescriptor" in m.args or "java.io.InputStream" in m.args or "java.io.OutputStream" in m.args:
- has_stream.add(m.name)
-
- for m in has_file:
- if m.name not in has_stream:
- warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")
-
-
-@verifier
-def verify_manager_list(clazz):
- """Verifies that managers return List<? extends Parcelable> instead of arrays."""
-
- if not clazz.name.endswith("Manager"): return
-
- for m in clazz.methods:
- if m.typ.startswith("android.") and m.typ.endswith("[]"):
- warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")
-
-
-@verifier
-def verify_abstract_inner(clazz):
- """Verifies that abstract inner classes are static."""
-
- if re.match(".+?\.[A-Z][^\.]+\.[A-Z]", clazz.fullname):
- if "abstract" in clazz.split and "static" not in clazz.split:
- warn(clazz, None, None, "Abstract inner classes should be static to improve testability")
-
-
-@verifier
-def verify_runtime_exceptions(clazz):
- """Verifies that runtime exceptions aren't listed in throws."""
-
- banned = [
- "java.lang.NullPointerException",
- "java.lang.ClassCastException",
- "java.lang.IndexOutOfBoundsException",
- "java.lang.reflect.UndeclaredThrowableException",
- "java.lang.reflect.MalformedParametersException",
- "java.lang.reflect.MalformedParameterizedTypeException",
- "java.lang.invoke.WrongMethodTypeException",
- "java.lang.EnumConstantNotPresentException",
- "java.lang.IllegalMonitorStateException",
- "java.lang.SecurityException",
- "java.lang.UnsupportedOperationException",
- "java.lang.annotation.AnnotationTypeMismatchException",
- "java.lang.annotation.IncompleteAnnotationException",
- "java.lang.TypeNotPresentException",
- "java.lang.IllegalStateException",
- "java.lang.ArithmeticException",
- "java.lang.IllegalArgumentException",
- "java.lang.ArrayStoreException",
- "java.lang.NegativeArraySizeException",
- "java.util.MissingResourceException",
- "java.util.EmptyStackException",
- "java.util.concurrent.CompletionException",
- "java.util.concurrent.RejectedExecutionException",
- "java.util.IllformedLocaleException",
- "java.util.ConcurrentModificationException",
- "java.util.NoSuchElementException",
- "java.io.UncheckedIOException",
- "java.time.DateTimeException",
- "java.security.ProviderException",
- "java.nio.BufferUnderflowException",
- "java.nio.BufferOverflowException",
- ]
-
- examine = clazz.ctors + clazz.methods
- for m in examine:
- for t in m.throws:
- if t in banned:
- error(clazz, m, None, "Methods must not mention RuntimeException subclasses in throws clauses")
-
-
-@verifier
-def verify_error(clazz):
- """Verifies that we always use Exception instead of Error."""
- if not clazz.extends: return
- if clazz.extends.endswith("Error"):
- error(clazz, None, None, "Trouble must be reported through an Exception, not Error")
- if clazz.extends.endswith("Exception") and not clazz.name.endswith("Exception"):
- error(clazz, None, None, "Exceptions must be named FooException")
-
-
-@verifier
-def verify_units(clazz):
- """Verifies that we use consistent naming for units."""
-
- # If we find K, recommend replacing with V
- bad = {
- "Ns": "Nanos",
- "Ms": "Millis or Micros",
- "Sec": "Seconds", "Secs": "Seconds",
- "Hr": "Hours", "Hrs": "Hours",
- "Mo": "Months", "Mos": "Months",
- "Yr": "Years", "Yrs": "Years",
- "Byte": "Bytes", "Space": "Bytes",
- }
-
- for m in clazz.methods:
- if m.typ not in ["short","int","long"]: continue
- for k, v in bad.iteritems():
- if m.name.endswith(k):
- error(clazz, m, None, "Expected method name units to be " + v)
- if m.name.endswith("Nanos") or m.name.endswith("Micros"):
- warn(clazz, m, None, "Returned time values are strongly encouraged to be in milliseconds unless you need the extra precision")
- if m.name.endswith("Seconds"):
- error(clazz, m, None, "Returned time values must be in milliseconds")
-
- for m in clazz.methods:
- typ = m.typ
- if typ == "void":
- if len(m.args) != 1: continue
- typ = m.args[0]
-
- if m.name.endswith("Fraction") and typ != "float":
- error(clazz, m, None, "Fractions must use floats")
- if m.name.endswith("Percentage") and typ != "int":
- error(clazz, m, None, "Percentage must use ints")
-
-
-@verifier
-def verify_closable(clazz):
- """Verifies that classes are AutoClosable."""
- if "java.lang.AutoCloseable" in clazz.implements_all: return
- if "java.io.Closeable" in clazz.implements_all: return
-
- for m in clazz.methods:
- if len(m.args) > 0: continue
- if m.name in ["close","release","destroy","finish","finalize","disconnect","shutdown","stop","free","quit"]:
- warn(clazz, m, None, "Classes that release resources should implement AutoClosable and CloseGuard")
- return
-
-
-@verifier
-def verify_member_name_not_kotlin_keyword(clazz):
- """Prevent method names which are keywords in Kotlin."""
-
- # https://kotlinlang.org/docs/reference/keyword-reference.html#hard-keywords
- # This list does not include Java keywords as those are already impossible to use.
- keywords = [
- 'as',
- 'fun',
- 'in',
- 'is',
- 'object',
- 'typealias',
- 'val',
- 'var',
- 'when',
- ]
-
- for m in clazz.methods:
- if m.name in keywords:
- error(clazz, m, None, "Method name must not be a Kotlin keyword")
- for f in clazz.fields:
- if f.name in keywords:
- error(clazz, f, None, "Field name must not be a Kotlin keyword")
-
-
-@verifier
-def verify_method_name_not_kotlin_operator(clazz):
- """Warn about method names which become operators in Kotlin."""
-
- binary = set()
-
- def unique_binary_op(m, op):
- if op in binary:
- error(clazz, m, None, "Only one of '{0}' and '{0}Assign' methods should be present for Kotlin".format(op))
- binary.add(op)
-
- for m in clazz.methods:
- if 'static' in m.split or 'operator' in m.split:
- continue
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#unary-prefix-operators
- if m.name in ['unaryPlus', 'unaryMinus', 'not'] and len(m.args) == 0:
- warn(clazz, m, None, "Method can be invoked as a unary operator from Kotlin")
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#increments-and-decrements
- if m.name in ['inc', 'dec'] and len(m.args) == 0 and m.typ != 'void':
- # This only applies if the return type is the same or a subtype of the enclosing class, but we have no
- # practical way of checking that relationship here.
- warn(clazz, m, None, "Method can be invoked as a pre/postfix inc/decrement operator from Kotlin")
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#arithmetic
- if m.name in ['plus', 'minus', 'times', 'div', 'rem', 'mod', 'rangeTo'] and len(m.args) == 1:
- warn(clazz, m, None, "Method can be invoked as a binary operator from Kotlin")
- unique_binary_op(m, m.name)
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#in
- if m.name == 'contains' and len(m.args) == 1 and m.typ == 'boolean':
- warn(clazz, m, None, "Method can be invoked as a 'in' operator from Kotlin")
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
- if (m.name == 'get' and len(m.args) > 0) or (m.name == 'set' and len(m.args) > 1):
- warn(clazz, m, None, "Method can be invoked with an indexing operator from Kotlin")
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#invoke
- if m.name == 'invoke':
- warn(clazz, m, None, "Method can be invoked with function call syntax from Kotlin")
-
- # https://kotlinlang.org/docs/reference/operator-overloading.html#assignments
- if m.name in ['plusAssign', 'minusAssign', 'timesAssign', 'divAssign', 'remAssign', 'modAssign'] \
- and len(m.args) == 1 \
- and m.typ == 'void':
- warn(clazz, m, None, "Method can be invoked as a compound assignment operator from Kotlin")
- unique_binary_op(m, m.name[:-6]) # Remove 'Assign' suffix
-
-
-@verifier
-def verify_collections_over_arrays(clazz):
- """Warn that [] should be Collections."""
-
- if "@interface" in clazz.split:
- return
-
- safe = ["java.lang.String[]","byte[]","short[]","int[]","long[]","float[]","double[]","boolean[]","char[]"]
- for m in clazz.methods:
- if m.typ.endswith("[]") and m.typ not in safe:
- warn(clazz, m, None, "Method should return Collection<> (or subclass) instead of raw array")
- for arg in m.args:
- if arg.endswith("[]") and arg not in safe:
- warn(clazz, m, None, "Method argument should be Collection<> (or subclass) instead of raw array")
-
-
-@verifier
-def verify_user_handle(clazz):
- """Methods taking UserHandle should be ForUser or AsUser."""
- if clazz.name.endswith("Listener") or clazz.name.endswith("Callback") or clazz.name.endswith("Callbacks"): return
- if clazz.fullname == "android.app.admin.DeviceAdminReceiver": return
- if clazz.fullname == "android.content.pm.LauncherApps": return
- if clazz.fullname == "android.os.UserHandle": return
- if clazz.fullname == "android.os.UserManager": return
-
- for m in clazz.methods:
- if re.match("on[A-Z]+", m.name): continue
-
- has_arg = "android.os.UserHandle" in m.args
- has_name = m.name.endswith("AsUser") or m.name.endswith("ForUser")
-
- if clazz.fullname.endswith("Manager") and has_arg:
- warn(clazz, m, None, "When a method overload is needed to target a specific "
- "UserHandle, callers should be directed to use "
- "Context.createPackageContextAsUser() and re-obtain the relevant "
- "Manager, and no new API should be added")
- elif has_arg and not has_name:
- warn(clazz, m, None, "Method taking UserHandle should be named 'doFooAsUser' "
- "or 'queryFooForUser'")
-
-
-@verifier
-def verify_params(clazz):
- """Parameter classes should be 'Params'."""
- if clazz.name.endswith("Params"): return
- if clazz.fullname == "android.app.ActivityOptions": return
- if clazz.fullname == "android.app.BroadcastOptions": return
- if clazz.fullname == "android.os.Bundle": return
- if clazz.fullname == "android.os.BaseBundle": return
- if clazz.fullname == "android.os.PersistableBundle": return
-
- bad = ["Param","Parameter","Parameters","Args","Arg","Argument","Arguments","Options","Bundle"]
- for b in bad:
- if clazz.name.endswith(b):
- error(clazz, None, None, "Classes holding a set of parameters should be called 'FooParams'")
-
-
-@verifier
-def verify_services(clazz):
- """Service name should be FOO_BAR_SERVICE = 'foo_bar'."""
- if clazz.fullname != "android.content.Context": return
-
- for f in clazz.fields:
- if f.typ != "java.lang.String": continue
- found = re.match(r"([A-Z_]+)_SERVICE", f.name)
- if found:
- expected = found.group(1).lower()
- if f.value != expected:
- error(clazz, f, "C4", "Inconsistent service value; expected '%s'" % (expected))
-
-
-@verifier
-def verify_tense(clazz):
- """Verify tenses of method names."""
- if clazz.fullname.startswith("android.opengl"): return
-
- for m in clazz.methods:
- if m.name.endswith("Enable"):
- warn(clazz, m, None, "Unexpected tense; probably meant 'enabled'")
-
-
-@verifier
-def verify_icu(clazz):
- """Verifies that richer ICU replacements are used."""
- better = {
- "java.util.TimeZone": "android.icu.util.TimeZone",
- "java.util.Calendar": "android.icu.util.Calendar",
- "java.util.Locale": "android.icu.util.ULocale",
- "java.util.ResourceBundle": "android.icu.util.UResourceBundle",
- "java.util.SimpleTimeZone": "android.icu.util.SimpleTimeZone",
- "java.util.StringTokenizer": "android.icu.util.StringTokenizer",
- "java.util.GregorianCalendar": "android.icu.util.GregorianCalendar",
- "java.lang.Character": "android.icu.lang.UCharacter",
- "java.text.BreakIterator": "android.icu.text.BreakIterator",
- "java.text.Collator": "android.icu.text.Collator",
- "java.text.DecimalFormatSymbols": "android.icu.text.DecimalFormatSymbols",
- "java.text.NumberFormat": "android.icu.text.NumberFormat",
- "java.text.DateFormatSymbols": "android.icu.text.DateFormatSymbols",
- "java.text.DateFormat": "android.icu.text.DateFormat",
- "java.text.SimpleDateFormat": "android.icu.text.SimpleDateFormat",
- "java.text.MessageFormat": "android.icu.text.MessageFormat",
- "java.text.DecimalFormat": "android.icu.text.DecimalFormat",
- }
-
- for m in clazz.ctors + clazz.methods:
- types = []
- types.extend(m.typ)
- types.extend(m.args)
- for arg in types:
- if arg in better:
- warn(clazz, m, None, "Type %s should be replaced with richer ICU type %s" % (arg, better[arg]))
-
-
-@verifier
-def verify_clone(clazz):
- """Verify that clone() isn't implemented; see EJ page 61."""
- for m in clazz.methods:
- if m.name == "clone":
- error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()")
-
-
-@verifier
-def verify_pfd(clazz):
- """Verify that android APIs use PFD over FD."""
- if clazz.fullname == "android.os.FileUtils" or clazz.fullname == "android.system.Os":
- return
-
- examine = clazz.ctors + clazz.methods
- for m in examine:
- if m.typ == "java.io.FileDescriptor":
- error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
- if m.typ == "int":
- if "Fd" in m.name or "FD" in m.name or "FileDescriptor" in m.name:
- error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
- for arg in m.args:
- if arg == "java.io.FileDescriptor":
- error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
-
- for f in clazz.fields:
- if f.typ == "java.io.FileDescriptor":
- error(clazz, f, "FW11", "Must use ParcelFileDescriptor")
-
-
-@verifier
-def verify_numbers(clazz):
- """Discourage small numbers types like short and byte."""
-
- discouraged = ["short","byte"]
-
- for c in clazz.ctors:
- for arg in c.args:
- if arg in discouraged:
- warn(clazz, c, "FW12", "Should avoid odd sized primitives; use int instead")
-
- for f in clazz.fields:
- if f.typ in discouraged:
- warn(clazz, f, "FW12", "Should avoid odd sized primitives; use int instead")
-
- for m in clazz.methods:
- if m.typ in discouraged:
- warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
- for arg in m.args:
- if arg in discouraged:
- warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
-
-
-PRIMITIVES = {"void", "int", "float", "boolean", "short", "char", "byte", "long", "double"}
-
-@verifier
-def verify_nullability(clazz):
- """Catches missing nullability annotations"""
-
- for f in clazz.fields:
- if "enum_constant" in f.split:
- continue # Enum constants are never null
- if f.value is not None and 'final' in f.split:
- continue # Nullability of constants can be inferred.
- if f.typ not in PRIMITIVES and not has_nullability(f.annotations):
- error(clazz, f, "M12", "Field must be marked either @NonNull or @Nullable")
-
- for c in clazz.ctors:
- verify_nullability_args(clazz, c)
-
- for m in clazz.methods:
- if m.name == "writeToParcel" or m.name == "onReceive" or m.name == "onBind":
- continue # Parcelable.writeToParcel(), BroadcastReceiver.onReceive(), and Service.onBind() are not yet annotated
-
- if (m.name == "equals" and m.args == ["java.lang.Object"] or
- m.name == "toString" and m.args == []):
- continue # Nullability of equals and toString is implicit.
-
- if m.typ not in PRIMITIVES and not has_nullability(m.annotations):
- error(clazz, m, "M12", "Return value must be marked either @NonNull or @Nullable")
- verify_nullability_args(clazz, m)
-
-def verify_nullability_args(clazz, m):
- for i, arg in enumerate(m.detailed_args):
- if arg.type not in PRIMITIVES and not has_nullability(arg.annotations):
- error(clazz, m, "M12", "Argument %d must be marked either @NonNull or @Nullable" % (i+1,))
-
-def has_nullability(annotations):
- return "@NonNull" in annotations or "@Nullable" in annotations
-
-
-@verifier
-def verify_intdef(clazz):
- """intdefs must be @hide, because the constant names cannot be stored in
- the stubs (only the values are, which is not useful)"""
- if "@interface" not in clazz.split:
- return
- if "@IntDef" in clazz.annotations or "@LongDef" in clazz.annotations:
- error(clazz, None, None, "@IntDef and @LongDef annotations must be @hide")
-
-
-@verifier
-def verify_singleton(clazz):
- """Catch singleton objects with constructors."""
-
- singleton = False
- for m in clazz.methods:
- if m.name.startswith("get") and m.name.endswith("Instance") and " static " in m.raw:
- singleton = True
-
- if singleton:
- for c in clazz.ctors:
- error(clazz, c, None, "Singleton classes should use getInstance() methods")
-
-
-
-def is_interesting(clazz):
- """Test if given class is interesting from an Android PoV."""
-
- if clazz.pkg.name.startswith("java"): return False
- if clazz.pkg.name.startswith("junit"): return False
- if clazz.pkg.name.startswith("org.apache"): return False
- if clazz.pkg.name.startswith("org.xml"): return False
- if clazz.pkg.name.startswith("org.json"): return False
- if clazz.pkg.name.startswith("org.w3c"): return False
- if clazz.pkg.name.startswith("android.icu."): return False
- return True
-
-
-def examine_clazz(clazz):
- """Find all style issues in the given class."""
-
- notice(clazz)
-
- if not is_interesting(clazz): return
-
- for v in verifiers.itervalues():
- v(clazz)
-
- if not ALLOW_GOOGLE: verify_google(clazz)
-
-
-def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None):
- """Find all style issues in the given API stream."""
- global failures, noticed
- failures = {}
- noticed = {}
- _parse_stream(stream, examine_clazz, base_f=base_stream,
- in_classes_with_base=in_classes_with_base,
- out_classes_with_base=out_classes_with_base)
- return (failures, noticed)
-
-
-def examine_api(api):
- """Find all style issues in the given parsed API."""
- global failures
- failures = {}
- for key in sorted(api.keys()):
- examine_clazz(api[key])
- return failures
-
-
-def verify_compat(cur, prev):
- """Find any incompatible API changes between two levels."""
- global failures
-
- def class_exists(api, test):
- return test.fullname in api
-
- def ctor_exists(api, clazz, test):
- for m in clazz.ctors:
- if m.ident == test.ident: return True
- return False
-
- def all_methods(api, clazz):
- methods = list(clazz.methods)
- if clazz.extends is not None:
- methods.extend(all_methods(api, api[clazz.extends]))
- return methods
-
- def method_exists(api, clazz, test):
- methods = all_methods(api, clazz)
- for m in methods:
- if m.ident == test.ident: return True
- return False
-
- def field_exists(api, clazz, test):
- for f in clazz.fields:
- if f.ident == test.ident: return True
- return False
-
- failures = {}
- for key in sorted(prev.keys()):
- prev_clazz = prev[key]
-
- if not class_exists(cur, prev_clazz):
- error(prev_clazz, None, None, "Class removed or incompatible change")
- continue
-
- cur_clazz = cur[key]
-
- for test in prev_clazz.ctors:
- if not ctor_exists(cur, cur_clazz, test):
- error(prev_clazz, prev_ctor, None, "Constructor removed or incompatible change")
-
- methods = all_methods(prev, prev_clazz)
- for test in methods:
- if not method_exists(cur, cur_clazz, test):
- error(prev_clazz, test, None, "Method removed or incompatible change")
-
- for test in prev_clazz.fields:
- if not field_exists(cur, cur_clazz, test):
- error(prev_clazz, test, None, "Field removed or incompatible change")
-
- return failures
-
-
-def match_filter(filters, fullname):
- for f in filters:
- if fullname == f:
- return True
- if fullname.startswith(f + '.'):
- return True
- return False
-
-
-def show_deprecations_at_birth(cur, prev):
- """Show API deprecations at birth."""
- global failures
-
- # Remove all existing things so we're left with new
- for prev_clazz in prev.values():
- if prev_clazz.fullname not in cur:
- # The class was removed this release; we can safely ignore it.
- continue
-
- cur_clazz = cur[prev_clazz.fullname]
- if not is_interesting(cur_clazz): continue
-
- sigs = { i.ident: i for i in prev_clazz.ctors }
- cur_clazz.ctors = [ i for i in cur_clazz.ctors if i.ident not in sigs ]
- sigs = { i.ident: i for i in prev_clazz.methods }
- cur_clazz.methods = [ i for i in cur_clazz.methods if i.ident not in sigs ]
- sigs = { i.ident: i for i in prev_clazz.fields }
- cur_clazz.fields = [ i for i in cur_clazz.fields if i.ident not in sigs ]
-
- # Forget about class entirely when nothing new
- if len(cur_clazz.ctors) == 0 and len(cur_clazz.methods) == 0 and len(cur_clazz.fields) == 0:
- del cur[prev_clazz.fullname]
-
- for clazz in cur.values():
- if not is_interesting(clazz): continue
-
- if "deprecated" in clazz.split and not clazz.fullname in prev:
- error(clazz, None, None, "Found API deprecation at birth")
-
- for i in clazz.ctors + clazz.methods + clazz.fields:
- if "deprecated" in i.split:
- error(clazz, i, None, "Found API deprecation at birth")
-
- print "%s Deprecated at birth %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True),
- format(reset=True)))
- for f in sorted(failures):
- print failures[f]
- print
-
-
-def show_stats(cur, prev):
- """Show API stats."""
-
- stats = collections.defaultdict(int)
- for cur_clazz in cur.values():
- if not is_interesting(cur_clazz): continue
-
- if cur_clazz.fullname not in prev:
- stats['new_classes'] += 1
- stats['new_ctors'] += len(cur_clazz.ctors)
- stats['new_methods'] += len(cur_clazz.methods)
- stats['new_fields'] += len(cur_clazz.fields)
- else:
- prev_clazz = prev[cur_clazz.fullname]
-
- sigs = { i.ident: i for i in prev_clazz.ctors }
- ctors = len([ i for i in cur_clazz.ctors if i.ident not in sigs ])
- sigs = { i.ident: i for i in prev_clazz.methods }
- methods = len([ i for i in cur_clazz.methods if i.ident not in sigs ])
- sigs = { i.ident: i for i in prev_clazz.fields }
- fields = len([ i for i in cur_clazz.fields if i.ident not in sigs ])
-
- if ctors + methods + fields > 0:
- stats['extend_classes'] += 1
- stats['extend_ctors'] += ctors
- stats['extend_methods'] += methods
- stats['extend_fields'] += fields
-
- print "#", "".join([ k.ljust(20) for k in sorted(stats.keys()) ])
- print " ", "".join([ str(stats[k]).ljust(20) for k in sorted(stats.keys()) ])
-
-
-def main():
- parser = argparse.ArgumentParser(description="Enforces common Android public API design \
- patterns. It ignores lint messages from a previous API level, if provided.")
- parser.add_argument("--base-current", nargs='?', type=argparse.FileType('r'), default=None,
- help="The base current.txt to use when examining system-current.txt or"
- " test-current.txt")
- parser.add_argument("--base-previous", nargs='?', type=argparse.FileType('r'), default=None,
- help="The base previous.txt to use when examining system-previous.txt or"
- " test-previous.txt")
- parser.add_argument("--no-color", action='store_const', const=True,
- help="Disable terminal colors")
- parser.add_argument("--color", action='store_const', const=True,
- help="Use terminal colors")
- parser.add_argument("--allow-google", action='store_const', const=True,
- help="Allow references to Google")
- parser.add_argument("--show-noticed", action='store_const', const=True,
- help="Show API changes noticed")
- parser.add_argument("--show-deprecations-at-birth", action='store_const', const=True,
- help="Show API deprecations at birth")
- parser.add_argument("--show-stats", action='store_const', const=True,
- help="Show API stats")
- parser.add_argument("--title", action='store', default=None,
- help="Title to put in for display purposes")
- parser.add_argument("--filter", action="append",
- help="If provided, only show lint for the given packages or classes.")
- parser.add_argument("current.txt", type=argparse.FileType('r'), help="current.txt")
- parser.add_argument("previous.txt", nargs='?', type=argparse.FileType('r'), default=None,
- help="previous.txt")
- args = vars(parser.parse_args())
-
- if args['no_color']:
- USE_COLOR = False
- elif args['color']:
- USE_COLOR = True
- else:
- USE_COLOR = sys.stdout.isatty()
-
- if args['allow_google']:
- ALLOW_GOOGLE = True
-
- current_file = args['current.txt']
- base_current_file = args['base_current']
- previous_file = args['previous.txt']
- base_previous_file = args['base_previous']
- filters = args['filter']
- if not filters:
- filters = []
- title = args['title']
- if not title:
- title = current_file.name
-
- if args['show_deprecations_at_birth']:
- with current_file as f:
- cur = _parse_stream(f)
- with previous_file as f:
- prev = _parse_stream(f)
- show_deprecations_at_birth(cur, prev)
- sys.exit()
-
- if args['show_stats']:
- with current_file as f:
- cur = _parse_stream(f)
- with previous_file as f:
- prev = _parse_stream(f)
- show_stats(cur, prev)
- sys.exit()
-
- classes_with_base = []
-
- with current_file as f:
- if base_current_file:
- with base_current_file as base_f:
- cur_fail, cur_noticed = examine_stream(f, base_f,
- out_classes_with_base=classes_with_base)
- else:
- cur_fail, cur_noticed = examine_stream(f, out_classes_with_base=classes_with_base)
-
- if not previous_file is None:
- with previous_file as f:
- if base_previous_file:
- with base_previous_file as base_f:
- prev_fail, prev_noticed = examine_stream(f, base_f,
- in_classes_with_base=classes_with_base)
- else:
- prev_fail, prev_noticed = examine_stream(f, in_classes_with_base=classes_with_base)
-
- # ignore errors from previous API level
- for p in prev_fail:
- if p in cur_fail:
- del cur_fail[p]
-
- # ignore classes unchanged from previous API level
- for k, v in prev_noticed.iteritems():
- if k in cur_noticed and v == cur_noticed[k]:
- del cur_noticed[k]
-
- """
- # NOTE: disabled because of memory pressure
- # look for compatibility issues
- compat_fail = verify_compat(cur, prev)
-
- print "%s API compatibility issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
- for f in sorted(compat_fail):
- print compat_fail[f]
- print
- """
-
- # ignore everything but the given filters, if provided
- if filters:
- cur_fail = dict([(key, failure) for key, failure in cur_fail.iteritems()
- if match_filter(filters, failure.clazz.fullname)])
-
- if args['show_noticed'] and len(cur_noticed) != 0:
- print "%s API changes noticed %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
- for f in sorted(cur_noticed.keys()):
- print f
- print
-
- if len(cur_fail) != 0:
- print "%s API style issues: %s %s" % ((format(fg=WHITE, bg=BLUE, bold=True),
- title, format(reset=True)))
- for f in filters:
- print "%s filter: %s %s" % ((format(fg=WHITE, bg=BLUE, bold=True),
- f, format(reset=True)))
- print
- for f in sorted(cur_fail):
- print cur_fail[f]
- print
- print "%d errors" % len(cur_fail)
- sys.exit(77)
-
-if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- sys.exit(1)
diff --git a/tools/apilint/apilint_sha.sh b/tools/apilint/apilint_sha.sh
deleted file mode 100755
index 2a45b10..0000000
--- a/tools/apilint/apilint_sha.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-if git show --name-only --pretty=format: $1 | grep api/ > /dev/null; then
- python tools/apilint/apilint.py <(git show $1:api/current.txt) <(git show $1^:api/current.txt)
-fi
diff --git a/tools/apilint/apilint_sha_system.sh b/tools/apilint/apilint_sha_system.sh
deleted file mode 100755
index 8538a3d..0000000
--- a/tools/apilint/apilint_sha_system.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-if git show --name-only --pretty=format: $1 | grep api/ > /dev/null; then
- python tools/apilint/apilint.py \
- --base-current <(git show $1:api/current.txt) \
- --base-previous <(git show $1^:api/current.txt) \
- <(git show $1:api/system-current.txt) \
- <(git show $1^:api/system-current.txt)
-fi
diff --git a/tools/apilint/apilint_stats.sh b/tools/apilint/apilint_stats.sh
deleted file mode 100755
index 052d9a5..0000000
--- a/tools/apilint/apilint_stats.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-API=28
-while [ $API -gt 14 ]; do
- echo "# Changes in API $((API))"
- python tools/apilint/apilint.py --show-stats ../../prebuilts/sdk/$((API))/public/api/android.txt ../../prebuilts/sdk/$((API-1))/public/api/android.txt
- let API=API-1
-done
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
deleted file mode 100644
index 811cb9a..0000000
--- a/tools/apilint/apilint_test.py
+++ /dev/null
@@ -1,414 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-import unittest
-
-import apilint
-
-def cls(pkg, name):
- return apilint.Class(apilint.Package(999, "package %s {" % pkg, None), 999,
- "public final class %s {" % name, None)
-
-_ri = apilint._retry_iterator
-
-c1 = cls("android.app", "ActivityManager")
-c2 = cls("android.app", "Notification")
-c3 = cls("android.app", "Notification.Action")
-c4 = cls("android.graphics", "Bitmap")
-
-class UtilTests(unittest.TestCase):
- def test_retry_iterator(self):
- it = apilint._retry_iterator([1, 2, 3, 4])
- self.assertEqual(it.next(), 1)
- self.assertEqual(it.next(), 2)
- self.assertEqual(it.next(), 3)
- it.send("retry")
- self.assertEqual(it.next(), 3)
- self.assertEqual(it.next(), 4)
- with self.assertRaises(StopIteration):
- it.next()
-
- def test_retry_iterator_one(self):
- it = apilint._retry_iterator([1])
- self.assertEqual(it.next(), 1)
- it.send("retry")
- self.assertEqual(it.next(), 1)
- with self.assertRaises(StopIteration):
- it.next()
-
- def test_retry_iterator_one(self):
- it = apilint._retry_iterator([1])
- self.assertEqual(it.next(), 1)
- it.send("retry")
- self.assertEqual(it.next(), 1)
- with self.assertRaises(StopIteration):
- it.next()
-
- def test_skip_to_matching_class_found(self):
- it = _ri([c1, c2, c3, c4])
- self.assertEquals(apilint._skip_to_matching_class(it, c3),
- c3)
- self.assertEqual(it.next(), c4)
-
- def test_skip_to_matching_class_not_found(self):
- it = _ri([c1, c2, c3, c4])
- self.assertEquals(apilint._skip_to_matching_class(it, cls("android.content", "ContentProvider")),
- None)
- self.assertEqual(it.next(), c4)
-
- def test_yield_until_matching_class_found(self):
- it = _ri([c1, c2, c3, c4])
- self.assertEquals(list(apilint._yield_until_matching_class(it, c3)),
- [c1, c2])
- self.assertEqual(it.next(), c4)
-
- def test_yield_until_matching_class_not_found(self):
- it = _ri([c1, c2, c3, c4])
- self.assertEquals(list(apilint._yield_until_matching_class(it, cls("android.content", "ContentProvider"))),
- [c1, c2, c3])
- self.assertEqual(it.next(), c4)
-
- def test_yield_until_matching_class_None(self):
- it = _ri([c1, c2, c3, c4])
- self.assertEquals(list(apilint._yield_until_matching_class(it, None)),
- [c1, c2, c3, c4])
-
-
-faulty_current_txt = """
-// Signature format: 2.0
-package android.app {
- public final class Activity {
- }
-
- public final class WallpaperColors implements android.os.Parcelable {
- ctor public WallpaperColors(@NonNull android.os.Parcel);
- method public int describeContents();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
- }
-}
-""".strip().split('\n')
-
-ok_current_txt = """
-// Signature format: 2.0
-package android.app {
- public final class Activity {
- }
-
- public final class WallpaperColors implements android.os.Parcelable {
- ctor public WallpaperColors();
- method public int describeContents();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
- }
-}
-""".strip().split('\n')
-
-system_current_txt = """
-// Signature format: 2.0
-package android.app {
- public final class WallpaperColors implements android.os.Parcelable {
- method public int getSomething();
- }
-}
-""".strip().split('\n')
-
-
-
-class BaseFileTests(unittest.TestCase):
- def test_base_file_avoids_errors(self):
- failures, _ = apilint.examine_stream(system_current_txt, ok_current_txt)
- self.assertEquals(failures, {})
-
- def test_class_with_base_finds_same_errors(self):
- failures_with_classes_with_base, _ = apilint.examine_stream("", faulty_current_txt,
- in_classes_with_base=[cls("android.app", "WallpaperColors")])
- failures_with_system_txt, _ = apilint.examine_stream(system_current_txt, faulty_current_txt)
-
- self.assertEquals(failures_with_classes_with_base.keys(), failures_with_system_txt.keys())
-
- def test_classes_with_base_is_emited(self):
- classes_with_base = []
- _, _ = apilint.examine_stream(system_current_txt, faulty_current_txt,
- out_classes_with_base=classes_with_base)
- self.assertEquals(map(lambda x: x.fullname, classes_with_base), ["android.app.WallpaperColors"])
-
-class ParseV2Stream(unittest.TestCase):
- def test_field_kinds(self):
- api = apilint._parse_stream("""
-// Signature format: 2.0
-package android {
- public enum SomeEnum {
- enum_constant public static final android.SomeEnum ENUM_CONST;
- field public static final int FIELD_CONST;
- property public final int someProperty;
- ctor public SomeEnum();
- method public Object? getObject();
- }
-}
- """.strip().split('\n'))
-
- self.assertEquals(api['android.SomeEnum'].fields[0].split[0], 'enum_constant')
- self.assertEquals(api['android.SomeEnum'].fields[1].split[0], 'field')
- self.assertEquals(api['android.SomeEnum'].fields[2].split[0], 'property')
- self.assertEquals(api['android.SomeEnum'].ctors[0].split[0], 'ctor')
- self.assertEquals(api['android.SomeEnum'].methods[0].split[0], 'method')
-
-class ParseV3Stream(unittest.TestCase):
- def test_field_kinds(self):
- api = apilint._parse_stream("""
-// Signature format: 3.0
-package a {
-
- public final class ContextKt {
- method public static inline <reified T> T! getSystemService(android.content.Context);
- method public static inline void withStyledAttributes(android.content.Context, android.util.AttributeSet? set = null, int[] attrs, @AttrRes int defStyleAttr = 0, @StyleRes int defStyleRes = 0, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
- }
-}
- """.strip().split('\n'))
- self.assertEquals(api['a.ContextKt'].methods[0].name, 'getSystemService')
- self.assertEquals(api['a.ContextKt'].methods[0].split[:4], ['method', 'public', 'static', 'inline'])
- self.assertEquals(api['a.ContextKt'].methods[1].name, 'withStyledAttributes')
- self.assertEquals(api['a.ContextKt'].methods[1].split[:4], ['method', 'public', 'static', 'inline'])
-
-class V2TokenizerTests(unittest.TestCase):
- def _test(self, raw, expected):
- self.assertEquals(apilint.V2Tokenizer(raw).tokenize(), expected)
-
- def test_simple(self):
- self._test(" method public some.Type someName(some.Argument arg, int arg);",
- ['method', 'public', 'some.Type', 'someName', '(', 'some.Argument',
- 'arg', ',', 'int', 'arg', ')', ';'])
- self._test("class Some.Class extends SomeOther {",
- ['class', 'Some.Class', 'extends', 'SomeOther', '{'])
-
- def test_varargs(self):
- self._test("name(String...)",
- ['name', '(', 'String', '...', ')'])
-
- def test_kotlin(self):
- self._test("String? name(String!...)",
- ['String', '?', 'name', '(', 'String', '!', '...', ')'])
-
- def test_annotation(self):
- self._test("method @Nullable public void name();",
- ['method', '@', 'Nullable', 'public', 'void', 'name', '(', ')', ';'])
-
- def test_annotation_args(self):
- self._test("@Some(val=1, other=2) class Class {",
- ['@', 'Some', '(', 'val', '=', '1', ',', 'other', '=', '2', ')',
- 'class', 'Class', '{'])
- def test_comment(self):
- self._test("some //comment", ['some'])
-
- def test_strings(self):
- self._test(r'"" "foo" "\"" "\\"', ['""', '"foo"', r'"\""', r'"\\"'])
-
- def test_at_interface(self):
- self._test("public @interface Annotation {",
- ['public', '@interface', 'Annotation', '{'])
-
- def test_array_type(self):
- self._test("int[][]", ['int', '[]', '[]'])
-
- def test_generics(self):
- self._test("<>foobar<A extends Object>",
- ['<', '>', 'foobar', '<', 'A', 'extends', 'Object', '>'])
-
-class V2ParserTests(unittest.TestCase):
- def _cls(self, raw):
- pkg = apilint.Package(999, "package pkg {", None)
- return apilint.Class(pkg, 1, raw, '', sig_format=2)
-
- def _method(self, raw, cls=None):
- if not cls:
- cls = self._cls("class Class {")
- return apilint.Method(cls, 1, raw, '', sig_format=2)
-
- def _field(self, raw):
- cls = self._cls("class Class {")
- return apilint.Field(cls, 1, raw, '', sig_format=2)
-
- def test_parse_package(self):
- pkg = apilint.Package(999, "package wifi.p2p {", None)
- self.assertEquals("wifi.p2p", pkg.name)
-
- def test_class(self):
- cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {")
- self.assertTrue('deprecated' in cls.split)
- self.assertTrue('static' in cls.split)
- self.assertTrue('abstract' in cls.split)
- self.assertTrue('class' in cls.split)
- self.assertEquals('Super', cls.extends)
- self.assertEquals('Interface', cls.implements)
- self.assertEquals('pkg.Some.Name', cls.fullname)
-
- def test_enum(self):
- cls = self._cls("public enum Some.Name {")
- self._field("enum_constant public static final android.ValueType COLOR;")
-
- def test_interface(self):
- cls = self._cls("@Deprecated @IntRange(from=1, to=2) public interface Some.Name extends Interface<Class> {")
- self.assertTrue('deprecated' in cls.split)
- self.assertTrue('interface' in cls.split)
- self.assertEquals('Interface', cls.extends)
- self.assertEquals('Interface', cls.implements)
- self.assertEquals('pkg.Some.Name', cls.fullname)
-
- def test_at_interface(self):
- cls = self._cls("@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SuppressLint {")
- self.assertTrue('@interface' in cls.split)
- self.assertEquals('pkg.SuppressLint', cls.fullname)
-
- def test_parse_method(self):
- m = self._method("method @Deprecated public static native <T> Class<T>[][] name("
- + "Class<T[]>[][], Class<T[][][]>[][]...) throws Exception, T;")
- self.assertTrue('static' in m.split)
- self.assertTrue('public' in m.split)
- self.assertTrue('method' in m.split)
- self.assertTrue('native' in m.split)
- self.assertTrue('deprecated' in m.split)
- self.assertEquals('java.lang.Class[][]', m.typ)
- self.assertEquals('name', m.name)
- self.assertEquals(['java.lang.Class[][]', 'java.lang.Class[][]...'], m.args)
- self.assertEquals(['java.lang.Exception', 'T'], m.throws)
-
- def test_ctor(self):
- m = self._method("ctor @Deprecated <T> ClassName();")
- self.assertTrue('ctor' in m.split)
- self.assertTrue('deprecated' in m.split)
- self.assertEquals('ctor', m.typ)
- self.assertEquals('ClassName', m.name)
-
- def test_parse_annotation_method(self):
- cls = self._cls("@interface Annotation {")
- self._method('method abstract String category() default "";', cls=cls)
- self._method('method abstract boolean deepExport() default false;', cls=cls)
- self._method('method abstract ViewDebug.FlagToString[] flagMapping() default {};', cls=cls)
- self._method('method abstract ViewDebug.FlagToString[] flagMapping() default (double)java.lang.Float.NEGATIVE_INFINITY;', cls=cls)
-
- def test_parse_string_field(self):
- f = self._field('field @Deprecated public final String SOME_NAME = "value";')
- self.assertTrue('field' in f.split)
- self.assertTrue('deprecated' in f.split)
- self.assertTrue('final' in f.split)
- self.assertEquals('java.lang.String', f.typ)
- self.assertEquals('SOME_NAME', f.name)
- self.assertEquals('value', f.value)
-
- def test_parse_field(self):
- f = self._field('field public Object SOME_NAME;')
- self.assertTrue('field' in f.split)
- self.assertEquals('java.lang.Object', f.typ)
- self.assertEquals('SOME_NAME', f.name)
- self.assertEquals(None, f.value)
-
- def test_parse_int_field(self):
- f = self._field('field public int NAME = 123;')
- self.assertTrue('field' in f.split)
- self.assertEquals('int', f.typ)
- self.assertEquals('NAME', f.name)
- self.assertEquals('123', f.value)
-
- def test_parse_quotient_field(self):
- f = self._field('field public int NAME = (0.0/0.0);')
- self.assertTrue('field' in f.split)
- self.assertEquals('int', f.typ)
- self.assertEquals('NAME', f.name)
- self.assertEquals('( 0.0 / 0.0 )', f.value)
-
- def test_kotlin_types(self):
- self._field('field public List<Integer[]?[]!>?[]![]? NAME;')
- self._method("method <T?> Class<T!>?[]![][]? name(Type!, Type argname,"
- + "Class<T?>[][]?[]!...!) throws Exception, T;")
- self._method("method <T> T name(T a = 1, T b = A(1), Lambda f = { false }, N? n = null, "
- + """double c = (1/0), float d = 1.0f, String s = "heyo", char c = 'a');""")
-
- def test_kotlin_operator(self):
- self._method('method public operator void unaryPlus(androidx.navigation.NavDestination);')
- self._method('method public static operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);')
- self._method('method public static operator <T> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);')
-
- def test_kotlin_property(self):
- self._field('property public VM value;')
- self._field('property public final String? action;')
-
- def test_kotlin_varargs(self):
- self._method('method public void error(int p = "42", Integer int2 = "null", int p1 = "42", vararg String args);')
-
- def test_kotlin_default_values(self):
- self._method('method public void foo(String! = null, String! = "Hello World", int = 42);')
- self._method('method void method(String, String firstArg = "hello", int secondArg = "42", String thirdArg = "world");')
- self._method('method void method(String, String firstArg = "hello", int secondArg = "42");')
- self._method('method void method(String, String firstArg = "hello");')
- self._method('method void edit(android.Type, boolean commit = false, Function1<? super Editor,kotlin.Unit> action);')
- self._method('method <K, V> LruCache<K,V> lruCache(int maxSize, Function2<? super K,? super V,java.lang.Integer> sizeOf = { _, _ -> 1 }, Function1<? extends V> create = { (V)null }, Function4<kotlin.Unit> onEntryRemoved = { _, _, _, _ -> });')
- self._method('method android.Bitmap? drawToBitmap(android.View, android.Config config = android.graphics.Bitmap.Config.ARGB_8888);')
- self._method('method void emptyLambda(Function0<kotlin.Unit> sizeOf = {});')
- self._method('method void method1(int p = 42, Integer? int2 = null, int p1 = 42, String str = "hello world", java.lang.String... args);')
- self._method('method void method2(int p, int int2 = (2 * int) * some.other.pkg.Constants.Misc.SIZE);')
- self._method('method void method3(String str, int p, int int2 = double(int) + str.length);')
- self._method('method void print(test.pkg.Foo foo = test.pkg.Foo());')
-
- def test_type_use_annotation(self):
- self._method('method public static int codePointAt(char @NonNull [], int);')
- self._method('method @NonNull public java.util.Set<java.util.Map.@NonNull Entry<K,V>> entrySet();')
-
- m = self._method('method @NonNull public java.lang.annotation.@NonNull Annotation @NonNull [] getAnnotations();')
- self.assertEquals('java.lang.annotation.Annotation[]', m.typ)
-
- m = self._method('method @NonNull public abstract java.lang.annotation.@NonNull Annotation @NonNull [] @NonNull [] getParameterAnnotations();')
- self.assertEquals('java.lang.annotation.Annotation[][]', m.typ)
-
- m = self._method('method @NonNull public @NonNull String @NonNull [] split(@NonNull String, int);')
- self.assertEquals('java.lang.String[]', m.typ)
-
-class PackageTests(unittest.TestCase):
- def _package(self, raw):
- return apilint.Package(123, raw, "blame")
-
- def test_regular_package(self):
- p = self._package("package an.pref.int {")
- self.assertEquals('an.pref.int', p.name)
-
- def test_annotation_package(self):
- p = self._package("package @RestrictTo(a.b.C) an.pref.int {")
- self.assertEquals('an.pref.int', p.name)
-
- def test_multi_annotation_package(self):
- p = self._package("package @Rt(a.b.L_G_P) @RestrictTo(a.b.C) an.pref.int {")
- self.assertEquals('an.pref.int', p.name)
-
-class FilterTests(unittest.TestCase):
- def test_filter_match_prefix(self):
- self.assertTrue(apilint.match_filter(["a"], "a.B"))
- self.assertTrue(apilint.match_filter(["a.B"], "a.B.C"))
-
- def test_filter_dont_match_prefix(self):
- self.assertFalse(apilint.match_filter(["c"], "a.B"))
- self.assertFalse(apilint.match_filter(["a."], "a.B"))
- self.assertFalse(apilint.match_filter(["a.B."], "a.B.C"))
-
- def test_filter_match_exact(self):
- self.assertTrue(apilint.match_filter(["a.B"], "a.B"))
-
- def test_filter_dont_match_exact(self):
- self.assertFalse(apilint.match_filter([""], "a.B"))
- self.assertFalse(apilint.match_filter(["a.C"], "a.B"))
- self.assertFalse(apilint.match_filter(["a.C"], "a.B"))
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
new file mode 100644
index 0000000..b49e49b
--- /dev/null
+++ b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.net.wifi.WifiNetworkSuggestion;
+
+/**
+ * Interface for suggestion network connection listener.
+ *
+ * @hide
+ */
+oneway interface ISuggestionConnectionStatusListener
+{
+ void onConnectionStatus(in WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 023df70..bc73a93f1 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -30,6 +30,7 @@
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IScanResultsListener;
import android.net.wifi.ISoftApCallback;
+import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.IOnWifiUsabilityStatsListener;
@@ -236,4 +237,8 @@
void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier);
void unregisterScanResultsListener(int listenerIdentifier);
+
+ void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName);
+
+ void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName);
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index aa895a6..ed1a2f9 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -549,6 +549,7 @@
/**
* Extension IDs
*/
+ public static final int EID_EXT_HE_CAPABILITIES = 35;
public static final int EID_EXT_HE_OPERATION = 36;
@UnsupportedAppUsage
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8108fef..2cf3b59 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -208,6 +208,33 @@
public @interface NetworkSuggestionsStatusCode {}
/**
+ * Reason code if suggested network connection attempt failed with an unknown failure.
+ */
+ public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0;
+ /**
+ * Reason code if suggested network connection attempt failed with association failure.
+ */
+ public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1;
+ /**
+ * Reason code if suggested network connection attempt failed with an authentication failure.
+ */
+ public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2;
+ /**
+ * Reason code if suggested network connection attempt failed with an IP provision failure.
+ */
+ public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3;
+
+ /** @hide */
+ @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"},
+ value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN,
+ STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION,
+ STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION,
+ STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SuggestionConnectionStatusCode {}
+
+ /**
* Broadcast intent action indicating whether Wi-Fi scanning is allowed currently
* @hide
*/
@@ -2220,6 +2247,10 @@
public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect)
/** @hide */
public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC
+ /** @hide */
+ public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 0x200000000L; // Random STA MAC
+ /** @hide */
+ public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC
private long getSupportedFeatures() {
try {
@@ -2345,6 +2376,24 @@
}
/**
+ * @return true if this device supports connected MAC randomization.
+ * @hide
+ */
+ @SystemApi
+ public boolean isConnectedMacRandomizationSupported() {
+ return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC);
+ }
+
+ /**
+ * @return true if this device supports connected MAC randomization.
+ * @hide
+ */
+ @SystemApi
+ public boolean isApMacRandomizationSupported() {
+ return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC);
+ }
+
+ /**
* Return the record of {@link WifiActivityEnergyInfo} object that
* has the activity and energy info. This can be used to ascertain what
* the controller has been up to, since the last sample.
@@ -5229,7 +5278,7 @@
}
/**
- * Base class for scan results listener. Should be implemented by applications and set when
+ * Interface for scan results listener. Should be implemented by applications and set when
* calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}.
*/
public interface ScanResultsListener {
@@ -5315,4 +5364,108 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Interface for suggestion connection status listener.
+ * Should be implemented by applications and set when calling
+ * {@link WifiManager#addSuggestionConnectionStatusListener(
+ * Executor, SuggestionConnectionStatusListener)}.
+ */
+ public interface SuggestionConnectionStatusListener {
+
+ /**
+ * Called when the framework attempted to connect to a suggestion provided by the
+ * registering app, but the connection to the suggestion failed.
+ * @param wifiNetworkSuggestion The suggestion which failed to connect.
+ * @param failureReason the connection failure reason code. One of
+ * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION},
+ * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION},
+ * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING}
+ * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN}
+ */
+ void onConnectionStatus(
+ @NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
+ @SuggestionConnectionStatusCode int failureReason);
+ }
+
+ private class SuggestionConnectionStatusListenerProxy extends
+ ISuggestionConnectionStatusListener.Stub {
+ private final Executor mExecutor;
+ private final SuggestionConnectionStatusListener mListener;
+
+ SuggestionConnectionStatusListenerProxy(@NonNull Executor executor,
+ @NonNull SuggestionConnectionStatusListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
+ int failureReason) {
+ mExecutor.execute(() ->
+ mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason));
+ }
+
+ }
+
+ /**
+ * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}.
+ * Caller will receive the event when suggested network have connection failure.
+ * Caller can remove a previously registered listener using
+ * {@link WifiManager#removeSuggestionConnectionStatusListener(
+ * SuggestionConnectionStatusListener)}
+ * Same caller can add multiple listeners to monitor the event.
+ * <p>
+ * Applications should have the
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
+ * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions.
+ * Callers without the permission will trigger a {@link java.lang.SecurityException}.
+ * <p>
+ *
+ * @param executor The executor to execute the listener of the {@code listener} object.
+ * @param listener listener for suggestion network connection failure.
+ */
+ @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
+ public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull SuggestionConnectionStatusListener listener) {
+ if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
+ if (executor == null) throw new IllegalArgumentException("Executor cannot be null");
+ Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener
+ + ", executor=" + executor);
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.registerSuggestionConnectionStatusListener(new Binder(),
+ new SuggestionConnectionStatusListenerProxy(executor, listener),
+ listener.hashCode(), mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ }
+
+ /**
+ * Allow callers to remove a previously registered listener. After calling this method,
+ * applications will no longer receive suggestion connection events through that listener.
+ *
+ * @param listener listener to remove.
+ */
+ @RequiresPermission(ACCESS_WIFI_STATE)
+ public void removeSuggestionConnectionStatusListener(
+ @NonNull SuggestionConnectionStatusListener listener) {
+ if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
+ Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener);
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.unregisterSuggestionConnectionStatusListener(listener.hashCode(),
+ mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 67993e1..0a99326 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -138,7 +138,8 @@
public List<Integer> getAvailableChannels(@WifiBand int band) {
try {
Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName());
- return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+ List<Integer> channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+ return channels == null ? new ArrayList<>() : channels;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
index 64dfc34..be4eecc 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
@@ -16,6 +16,8 @@
package android.net.wifi.rtt;
+import static android.net.wifi.ScanResult.InformationElement.EID_EXTENSION_PRESENT;
+import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES;
import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES;
import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES;
@@ -106,7 +108,7 @@
public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
/** @hide */
- @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT})
+ @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE})
@Retention(RetentionPolicy.SOURCE)
public @interface PreambleType {
}
@@ -126,6 +128,10 @@
*/
public static final int PREAMBLE_VHT = 2;
+ /**
+ * Preamble type: HE.
+ */
+ public static final int PREAMBLE_HE = 3;
/**
* The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the
@@ -307,14 +313,21 @@
if (scanResult.informationElements != null && scanResult.informationElements.length != 0) {
boolean htCapabilitiesPresent = false;
boolean vhtCapabilitiesPresent = false;
+ boolean heCapabilitiesPresent = false;
+
for (ScanResult.InformationElement ie : scanResult.informationElements) {
if (ie.id == EID_HT_CAPABILITIES) {
htCapabilitiesPresent = true;
} else if (ie.id == EID_VHT_CAPABILITIES) {
vhtCapabilitiesPresent = true;
+ } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_HE_CAPABILITIES) {
+ heCapabilitiesPresent = true;
}
}
- if (vhtCapabilitiesPresent) {
+
+ if (heCapabilitiesPresent) {
+ preamble = PREAMBLE_HE;
+ } else if (vhtCapabilitiesPresent) {
preamble = PREAMBLE_VHT;
} else if (htCapabilitiesPresent) {
preamble = PREAMBLE_HT;
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 4b7d205..671708f 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -28,6 +28,7 @@
import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.IScanResultsListener;
import android.net.wifi.ISoftApCallback;
+import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.IWifiManager;
@@ -540,4 +541,17 @@
public void unregisterScanResultsListener(int listenerIdentifier) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void registerSuggestionConnectionStatusListener(IBinder binder,
+ ISuggestionConnectionStatusListener listener,
+ int listenerIdentifier, String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void unregisterSuggestionConnectionStatusListener(int listenerIdentifier,
+ String packageName) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 14e994c..a78cca3 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -61,6 +61,7 @@
import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
import android.net.wifi.WifiManager.ScanResultsListener;
import android.net.wifi.WifiManager.SoftApCallback;
+import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
import android.net.wifi.WifiManager.TrafficStateCallback;
import android.os.Binder;
import android.os.Build;
@@ -109,12 +110,14 @@
@Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
@Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
@Mock ScanResultsListener mScanResultListener;
+ @Mock SuggestionConnectionStatusListener mListener;
@Mock Executor mCallbackExecutor;
@Mock Executor mExecutor;
private Handler mHandler;
private TestLooper mLooper;
private WifiManager mWifiManager;
+ private WifiNetworkSuggestion mWifiNetworkSuggestion;
@Before
public void setUp() throws Exception {
@@ -126,6 +129,7 @@
when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
verify(mWifiService).getVerboseLoggingLevel();
+ mWifiNetworkSuggestion = new WifiNetworkSuggestion();
}
/**
@@ -1803,4 +1807,69 @@
public void testRemoveScanResultsListenerWithNullListener() throws Exception {
mWifiManager.removeScanResultsListener(null);
}
+
+ /**
+ * Verify an IllegalArgumentException is thrown if executor not provided.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testAddSuggestionConnectionStatusListenerWithNullExecutor() {
+ mWifiManager.addSuggestionConnectionStatusListener(null, mListener);
+ }
+
+ /**
+ * Verify an IllegalArgumentException is thrown if listener is not provided.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testAddSuggestionConnectionStatusListenerWithNullListener() {
+ mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null);
+ }
+
+ /**
+ * Verify client provided listener is being called to the right listener.
+ */
+ @Test
+ public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
+ int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+ ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
+ Executor executor = new SynchronousExecutor();
+ mWifiManager.addSuggestionConnectionStatusListener(executor, mListener);
+ verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
+ callbackCaptor.capture(), anyInt(), anyString());
+ callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode);
+ verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode));
+ }
+
+ /**
+ * Verify client provided listener is being called to the right executor.
+ */
+ @Test
+ public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
+ int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+ ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
+ mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
+ verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
+ callbackCaptor.capture(), anyInt(), anyString());
+ callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode);
+ verify(mExecutor).execute(any(Runnable.class));
+ }
+
+ /**
+ * Verify an IllegalArgumentException is thrown if listener is not provided.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testRemoveSuggestionConnectionListenerWithNullListener() {
+ mWifiManager.removeSuggestionConnectionStatusListener(null);
+ }
+
+ /**
+ * Verify removeSuggestionConnectionListener.
+ */
+ @Test
+ public void testRemoveSuggestionConnectionListener() throws Exception {
+
+ mWifiManager.removeSuggestionConnectionStatusListener(mListener);
+ verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString());
+ }
}