summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--cmds/statsd/src/atoms.proto39
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp3
-rw-r--r--core/java/android/os/storage/StorageManager.java2
-rw-r--r--core/java/android/os/storage/VolumeRecord.java9
-rw-r--r--core/java/android/service/appprediction/AppPredictionService.java16
-rw-r--r--core/java/android/view/SurfaceControl.java3
-rw-r--r--core/java/android/view/WindowInsets.java4
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureSession.java41
-rw-r--r--core/java/android/widget/NumberPicker.java1
-rw-r--r--packages/CaptivePortalLogin/Android.bp20
-rw-r--r--packages/NetworkPermissionConfig/Android.bp21
-rw-r--r--packages/NetworkStack/Android.bp6
-rw-r--r--packages/NetworkStack/src/android/net/apf/ApfFilter.java113
-rw-r--r--packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java23
-rw-r--r--packages/NetworkStack/tests/src/android/net/apf/ApfTest.java19
-rw-r--r--packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java4
-rw-r--r--packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java6
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml41
-rw-r--r--packages/SystemUI/res/layout/left_docked_overlay.xml19
-rw-r--r--packages/SystemUI/res/layout/right_docked_overlay.xml19
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java1
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java16
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java5
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java12
-rw-r--r--services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java20
-rw-r--r--services/core/java/com/android/server/pm/Installer.java1
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java28
-rw-r--r--services/core/java/com/android/server/stats/StatsCompanionService.java60
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java12
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java34
-rw-r--r--services/core/java/com/android/server/wm/Task.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java13
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java37
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java8
-rw-r--r--services/java/com/android/server/SystemServer.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java9
-rw-r--r--services/usage/java/com/android/server/usage/StorageStatsService.java1
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java6
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyPermissions.java146
-rw-r--r--tests/net/common/Android.bp1
-rw-r--r--tests/net/common/java/android/net/NetworkTest.java2
48 files changed, 571 insertions, 286 deletions
diff --git a/api/current.txt b/api/current.txt
index 3246c9ff1ece..35c6f45d7eaf 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -52864,6 +52864,7 @@ package android.view.contentcapture {
method @Nullable public final android.view.contentcapture.ContentCaptureContext getContentCaptureContext();
method @NonNull public final android.view.contentcapture.ContentCaptureSessionId getContentCaptureSessionId();
method @NonNull public android.view.autofill.AutofillId newAutofillId(@NonNull android.view.autofill.AutofillId, long);
+ method @NonNull public final android.view.ViewStructure newViewStructure(@NonNull android.view.View);
method @NonNull public final android.view.ViewStructure newVirtualViewStructure(@NonNull android.view.autofill.AutofillId, long);
method public final void notifyViewAppeared(@NonNull android.view.ViewStructure);
method public final void notifyViewDisappeared(@NonNull android.view.autofill.AutofillId);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index f5dd8523a4c2..b25cf690b159 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -364,6 +364,7 @@ message Atom {
AppsOnExternalStorageInfo apps_on_external_storage_info = 10057;
FaceSettings face_settings = 10058;
CoolingDevice cooling_device = 10059;
+ AppOps app_ops = 10060;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -6363,3 +6364,41 @@ message GarageModeInfo {
// Whether GarageMode is entered.
optional bool is_garage_mode = 1;
}
+
+/**
+ * Historical app ops data per package.
+ */
+message AppOps {
+ // Uid of the package requesting the op
+ optional int32 uid = 1 [(is_uid) = true];
+
+ // Nmae of the package performing the op
+ optional string package_name = 2;
+
+ // operation id; maps to the OP_* constants in AppOpsManager.java
+ optional int32 op_id = 3;
+
+ // The number of times the op was granted while the app was in the
+ // foreground (only for trusted requests)
+ optional int64 trusted_foreground_granted_count = 4;
+
+ // The number of times the op was granted while the app was in the
+ // background (only for trusted requests)
+ optional int64 trusted_background_granted_count = 5;
+
+ // The number of times the op was rejected while the app was in the
+ // foreground (only for trusted requests)
+ optional int64 trusted_foreground_rejected_count = 6;
+
+ // The number of times the op was rejected while the app was in the
+ // background (only for trusted requests)
+ optional int64 trusted_background_rejected_count = 7;
+
+ // For long-running operations, total duration of the operation
+ // while the app was in the foreground (only for trusted requests)
+ optional int64 trusted_foreground_duration_millis = 8;
+
+ // For long-running operations, total duration of the operation
+ // while the app was in the background (only for trusted requests)
+ optional int64 trusted_background_duration_millis = 9;
+}
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 2ffe18e20c24..914d60d3daca 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -260,6 +260,9 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// Face Settings
{android::util::FACE_SETTINGS,
{.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
+ // App ops
+ {android::util::APP_OPS,
+ {.puller = new StatsCompanionServicePuller(android::util::APP_OPS)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index ee62af57b9a0..69c1295df4f9 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -248,6 +248,8 @@ public class StorageManager {
public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
/** {@hide} */
public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
+ /** {@hide} */
+ public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
/** {@hide} */
public static final int FLAG_FOR_WRITE = 1 << 8;
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
index b6ee26114963..1a794ebf2a59 100644
--- a/core/java/android/os/storage/VolumeRecord.java
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -25,6 +25,7 @@ import android.util.TimeUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
+import java.util.Locale;
import java.util.Objects;
/**
@@ -45,6 +46,7 @@ public class VolumeRecord implements Parcelable {
public String nickname;
public int userFlags;
public long createdMillis;
+ public long lastSeenMillis;
public long lastTrimMillis;
public long lastBenchMillis;
@@ -61,6 +63,7 @@ public class VolumeRecord implements Parcelable {
nickname = parcel.readString();
userFlags = parcel.readInt();
createdMillis = parcel.readLong();
+ lastSeenMillis = parcel.readLong();
lastTrimMillis = parcel.readLong();
lastBenchMillis = parcel.readLong();
}
@@ -73,6 +76,10 @@ public class VolumeRecord implements Parcelable {
return fsUuid;
}
+ public String getNormalizedFsUuid() {
+ return fsUuid != null ? fsUuid.toLowerCase(Locale.US) : null;
+ }
+
public String getNickname() {
return nickname;
}
@@ -97,6 +104,7 @@ public class VolumeRecord implements Parcelable {
DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
pw.println();
pw.printPair("createdMillis", TimeUtils.formatForLogging(createdMillis));
+ pw.printPair("lastSeenMillis", TimeUtils.formatForLogging(lastSeenMillis));
pw.printPair("lastTrimMillis", TimeUtils.formatForLogging(lastTrimMillis));
pw.printPair("lastBenchMillis", TimeUtils.formatForLogging(lastBenchMillis));
pw.decreaseIndent();
@@ -155,6 +163,7 @@ public class VolumeRecord implements Parcelable {
parcel.writeString(nickname);
parcel.writeInt(userFlags);
parcel.writeLong(createdMillis);
+ parcel.writeLong(lastSeenMillis);
parcel.writeLong(lastTrimMillis);
parcel.writeLong(lastBenchMillis);
}
diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java
index 1391d43b00ca..be20570ef62d 100644
--- a/core/java/android/service/appprediction/AppPredictionService.java
+++ b/core/java/android/service/appprediction/AppPredictionService.java
@@ -39,6 +39,7 @@ import android.os.Looper;
import android.os.RemoteException;
import android.service.appprediction.IPredictionService.Stub;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.Slog;
import java.util.ArrayList;
@@ -46,7 +47,7 @@ import java.util.List;
import java.util.function.Consumer;
/**
- * TODO(b/111701043): Add java docs
+ * A service used to predict app and shortcut usage.
*
* @hide
*/
@@ -58,7 +59,9 @@ public abstract class AppPredictionService extends Service {
/**
* The {@link Intent} that must be declared as handled by the service.
- * TODO(b/111701043): Add any docs about permissions the service must hold
+ *
+ * <p>The service must also require the {@link android.permission#MANAGE_APP_PREDICTIONS}
+ * permission.
*
* @hide
*/
@@ -145,8 +148,11 @@ public abstract class AppPredictionService extends Service {
@Override
@NonNull
public final IBinder onBind(@NonNull Intent intent) {
- // TODO(b/111701043): Verify that the action is valid
- return mInterface.asBinder();
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mInterface.asBinder();
+ }
+ Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
+ return null;
}
/**
@@ -180,7 +186,6 @@ public abstract class AppPredictionService extends Service {
/**
* Called by the client app to request sorting of targets based on prediction rank.
- * TODO(b/111701043): Implement CancellationSignal so caller can cancel a long running request
*/
@MainThread
public abstract void onSortAppTargets(@NonNull AppPredictionSessionId sessionId,
@@ -254,7 +259,6 @@ public abstract class AppPredictionService extends Service {
/**
* Called by the client app to request target predictions. This method is only called if there
* are one or more prediction callbacks registered.
- * TODO(b/111701043): Add java docs
*
* @see #updatePredictions(AppPredictionSessionId, List)
*/
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index d67c8847f3bc..63e14853b51d 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -2660,6 +2660,9 @@ public final class SurfaceControl implements Parcelable {
*/
@NonNull
public Transaction merge(@NonNull Transaction other) {
+ if (this == other) {
+ return this;
+ }
mResizedSurfaces.putAll(other.mResizedSurfaces);
other.mResizedSurfaces.clear();
nativeMergeTransaction(mNativeObject, other.mNativeObject);
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 2d292ef7b25c..9340b71a5280 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -156,7 +156,9 @@ public final class WindowInsets {
* @param src Source to copy insets from
*/
public WindowInsets(WindowInsets src) {
- this(src.mTypeInsetsMap, src.mTypeMaxInsetsMap, src.mTypeVisibilityMap, src.mIsRound,
+ this(src.mSystemWindowInsetsConsumed ? null : src.mTypeInsetsMap,
+ src.mStableInsetsConsumed ? null : src.mTypeMaxInsetsMap,
+ src.mTypeVisibilityMap, src.mIsRound,
src.mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(src));
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index abb570318e68..f9f26251b15e 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -441,7 +441,46 @@ public abstract class ContentCaptureSession implements AutoCloseable {
/**
* Creates a {@link ViewStructure} for a "standard" view.
*
- * @hide
+ * <p>This method should be called after a visible view is laid out; the view then must populate
+ * the structure and pass it to {@link #notifyViewAppeared(ViewStructure)}.
+ *
+ * <b>Note: </b>views that manage a virtual structure under this view must populate just the
+ * node representing this view and return right away, then asynchronously report (not
+ * necessarily in the UI thread) when the children nodes appear, disappear or have their text
+ * changed by calling {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)},
+ * {@link ContentCaptureSession#notifyViewDisappeared(AutofillId)}, and
+ * {@link ContentCaptureSession#notifyViewTextChanged(AutofillId, CharSequence)} respectively.
+ * The structure for the a child must be created using
+ * {@link ContentCaptureSession#newVirtualViewStructure(AutofillId, long)}, and the
+ * {@code autofillId} for a child can be obtained either through
+ * {@code childStructure.getAutofillId()} or
+ * {@link ContentCaptureSession#newAutofillId(AutofillId, long)}.
+ *
+ * <p>When the virtual view hierarchy represents a web page, you should also:
+ *
+ * <ul>
+ * <li>Call {@link ContentCaptureManager#getContentCaptureConditions()} to infer content capture
+ * events should be generate for that URL.
+ * <li>Create a new {@link ContentCaptureSession} child for every HTML element that renders a
+ * new URL (like an {@code IFRAME}) and use that session to notify events from that subtree.
+ * </ul>
+ *
+ * <p><b>Note: </b>the following methods of the {@code structure} will be ignored:
+ * <ul>
+ * <li>{@link ViewStructure#setChildCount(int)}
+ * <li>{@link ViewStructure#addChildCount(int)}
+ * <li>{@link ViewStructure#getChildCount()}
+ * <li>{@link ViewStructure#newChild(int)}
+ * <li>{@link ViewStructure#asyncNewChild(int)}
+ * <li>{@link ViewStructure#asyncCommit()}
+ * <li>{@link ViewStructure#setWebDomain(String)}
+ * <li>{@link ViewStructure#newHtmlInfoBuilder(String)}
+ * <li>{@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}
+ * <li>{@link ViewStructure#setDataIsSensitive(boolean)}
+ * <li>{@link ViewStructure#setAlpha(float)}
+ * <li>{@link ViewStructure#setElevation(float)}
+ * <li>{@link ViewStructure#setTransformation(android.graphics.Matrix)}
+ * </ul>
*/
@NonNull
public final ViewStructure newViewStructure(@NonNull View view) {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 685e8de3c01a..efd5daf0b455 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -774,7 +774,6 @@ public class NumberPicker extends LinearLayout {
mInputText.setFilters(new InputFilter[] {
new InputTextFilter()
});
- mInputText.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
index a345091aa71e..1f6c2aef657c 100644
--- a/packages/CaptivePortalLogin/Android.bp
+++ b/packages/CaptivePortalLogin/Android.bp
@@ -14,12 +14,11 @@
// limitations under the License.
//
-android_app {
- name: "CaptivePortalLogin",
+java_defaults {
+ name: "CaptivePortalLoginDefaults",
srcs: ["src/**/*.java"],
sdk_version: "system_current",
min_sdk_version: "28",
- certificate: "networkstack",
static_libs: [
"androidx.legacy_legacy-support-v4",
"metrics-constants-protos",
@@ -27,3 +26,18 @@ android_app {
],
manifest: "AndroidManifest.xml",
}
+
+android_app {
+ name: "CaptivePortalLogin",
+ defaults: ["CaptivePortalLoginDefaults"],
+ certificate: "networkstack",
+}
+
+// Alternative CaptivePortalLogin signed with the platform cert, to use
+// with InProcessNetworkStack.
+android_app {
+ name: "PlatformCaptivePortalLogin",
+ defaults: ["CaptivePortalLoginDefaults"],
+ certificate: "platform",
+ overrides: ["CaptivePortalLogin"],
+}
diff --git a/packages/NetworkPermissionConfig/Android.bp b/packages/NetworkPermissionConfig/Android.bp
index d0d3276c0e32..6e50459a1dd3 100644
--- a/packages/NetworkPermissionConfig/Android.bp
+++ b/packages/NetworkPermissionConfig/Android.bp
@@ -14,15 +14,28 @@
// limitations under the License.
//
-// Stub APK to define permissions for NetworkStack
-android_app {
- name: "NetworkPermissionConfig",
+java_defaults {
+ name: "NetworkPermissionConfigDefaults",
// TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
// a classes.dex.
srcs: ["src/**/*.java"],
platform_apis: true,
min_sdk_version: "28",
- certificate: "networkstack",
privileged: true,
manifest: "AndroidManifest.xml",
}
+
+// Stub APK to define permissions for NetworkStack
+android_app {
+ name: "NetworkPermissionConfig",
+ defaults: ["NetworkPermissionConfigDefaults"],
+ certificate: "networkstack",
+}
+
+// Alternative stub APK signed with platform certificate. To use with InProcessNetworkStack.
+android_app {
+ name: "PlatformNetworkPermissionConfig",
+ defaults: ["NetworkPermissionConfigDefaults"],
+ certificate: "platform",
+ overrides: ["NetworkPermissionConfig"],
+}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 64718da8333b..e15526a571f5 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -98,8 +98,6 @@ java_defaults {
optimize: {
proguard_flags_files: ["proguard.flags"],
},
- // The permission configuration *must* be included to ensure security of the device
- required: ["NetworkPermissionConfig"],
}
// Non-updatable network stack running in the system server process for devices not using the module
@@ -110,6 +108,8 @@ android_app {
manifest: "AndroidManifest_InProcess.xml",
// InProcessNetworkStack is a replacement for NetworkStack
overrides: ["NetworkStack"],
+ // The permission configuration *must* be included to ensure security of the device
+ required: ["PlatformNetworkPermissionConfig"],
}
// Updatable network stack packaged as an application
@@ -119,6 +119,8 @@ android_app {
certificate: "networkstack",
manifest: "AndroidManifest.xml",
use_embedded_native_libs: true,
+ // The permission configuration *must* be included to ensure security of the device
+ required: ["NetworkPermissionConfig"],
}
genrule {
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
index 2e1e96e45a1d..f05431968684 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
@@ -156,8 +156,7 @@ public class ApfFilter {
DROPPED_ARP_REPLY_SPA_NO_HOST,
DROPPED_IPV4_KEEPALIVE_ACK,
DROPPED_IPV6_KEEPALIVE_ACK,
- DROPPED_IPV4_NATT_KEEPALIVE,
- DROPPED_IPV6_NATT_KEEPALIVE;
+ DROPPED_IPV4_NATT_KEEPALIVE;
// Returns the negative byte offset from the end of the APF data segment for
// a given counter.
@@ -873,17 +872,17 @@ public class ApfFilter {
}
// A class to hold NAT-T keepalive ack information.
- private abstract static class NattKeepaliveAck extends KeepalivePacket {
+ private class NattKeepaliveResponse extends KeepalivePacket {
static final int UDP_LENGTH_OFFSET = 4;
static final int UDP_HEADER_LEN = 8;
- protected static class NattKeepaliveAckData {
+ protected class NattKeepaliveResponseData {
public final byte[] srcAddress;
public final int srcPort;
public final byte[] dstAddress;
public final int dstPort;
- NattKeepaliveAckData(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
+ NattKeepaliveResponseData(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
srcAddress = sentKeepalivePacket.dstAddress;
srcPort = sentKeepalivePacket.dstPort;
dstAddress = sentKeepalivePacket.srcAddress;
@@ -891,19 +890,19 @@ public class ApfFilter {
}
}
- protected final NattKeepaliveAckData mPacket;
+ protected final NattKeepaliveResponseData mPacket;
protected final byte[] mSrcDstAddr;
protected final byte[] mPortFingerprint;
// NAT-T keepalive packet
protected final byte[] mPayload = {(byte) 0xff};
- NattKeepaliveAck(final NattKeepaliveAckData packet, final byte[] srcDstAddr) {
- mPacket = packet;
- mSrcDstAddr = srcDstAddr;
+ NattKeepaliveResponse(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
+ mPacket = new NattKeepaliveResponseData(sentKeepalivePacket);
+ mSrcDstAddr = concatArrays(mPacket.srcAddress, mPacket.dstAddress);
mPortFingerprint = generatePortFingerprint(mPacket.srcPort, mPacket.dstPort);
}
- static byte[] generatePortFingerprint(int srcPort, int dstPort) {
+ byte[] generatePortFingerprint(int srcPort, int dstPort) {
final ByteBuffer fp = ByteBuffer.allocate(4);
fp.order(ByteOrder.BIG_ENDIAN);
fp.putShort((short) srcPort);
@@ -911,27 +910,6 @@ public class ApfFilter {
return fp.array();
}
- public String toString() {
- try {
- return String.format("%s -> %s",
- NetworkStackUtils.addressAndPortToString(
- InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
- NetworkStackUtils.addressAndPortToString(
- InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort));
- } catch (UnknownHostException e) {
- return "Unknown host";
- }
- }
- }
-
- private class NattKeepaliveAckV4 extends NattKeepaliveAck {
- NattKeepaliveAckV4(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
- this(new NattKeepaliveAckData(sentKeepalivePacket));
- }
- NattKeepaliveAckV4(final NattKeepaliveAckData packet) {
- super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
- }
-
@Override
void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
final String nextFilterLabel = "natt_keepalive_filter" + getUniqueNumberLocked();
@@ -949,10 +927,9 @@ public class ApfFilter {
gen.addAddR1();
gen.addJumpIfR0NotEquals(1, nextFilterLabel);
- // R0 = R0 + R1 -> R0 contains IP header
- gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
- gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN);
- gen.addAddR1();
+ // Check that the ports match
+ gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+ gen.addAdd(ETH_HEADER_LEN);
gen.addJumpIfBytesNotEqual(Register.R0, mPortFingerprint, nextFilterLabel);
// Payload offset = R0 + UDP header length
@@ -963,20 +940,17 @@ public class ApfFilter {
gen.addJump(mCountAndDropLabel);
gen.defineLabel(nextFilterLabel);
}
- }
-
- private class NattKeepaliveAckV6 extends NattKeepaliveAck {
- NattKeepaliveAckV6(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
- this(new NattKeepaliveAckData(sentKeepalivePacket));
- }
-
- NattKeepaliveAckV6(final NattKeepaliveAckData packet) {
- super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
- }
- @Override
- void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
- throw new UnsupportedOperationException("IPv6 NAT-T Keepalive is not supported yet");
+ public String toString() {
+ try {
+ return String.format("%s -> %s",
+ NetworkStackUtils.addressAndPortToString(
+ InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
+ NetworkStackUtils.addressAndPortToString(
+ InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort));
+ } catch (UnknownHostException e) {
+ return "Unknown host";
+ }
}
}
@@ -1296,6 +1270,7 @@ public class ApfFilter {
gen.addJump(mCountAndDropLabel);
} else {
generateV4KeepaliveFilters(gen);
+ generateV4NattKeepaliveFilters(gen);
}
// Otherwise, pass
@@ -1303,36 +1278,36 @@ public class ApfFilter {
gen.addJump(mCountAndPassLabel);
}
- private void generateFilters(ApfGenerator gen, Class<?> filterType, int proto, int offset,
- String label) throws IllegalInstructionException {
- final boolean haveKeepaliveAcks = NetworkStackUtils.any(mKeepalivePackets,
+ private void generateKeepaliveFilters(ApfGenerator gen, Class<?> filterType, int proto,
+ int offset, String label) throws IllegalInstructionException {
+ final boolean haveKeepaliveResponses = NetworkStackUtils.any(mKeepalivePackets,
ack -> filterType.isInstance(ack));
// If no keepalive packets of this type
- if (!haveKeepaliveAcks) return;
+ if (!haveKeepaliveResponses) return;
// If not the right proto, skip keepalive filters
gen.addLoad8(Register.R0, offset);
gen.addJumpIfR0NotEquals(proto, label);
- // Drop Keepalive packets
+ // Drop Keepalive responses
for (int i = 0; i < mKeepalivePackets.size(); ++i) {
- final KeepalivePacket ack = mKeepalivePackets.valueAt(i);
- if (filterType.isInstance(ack)) ack.generateFilterLocked(gen);
+ final KeepalivePacket response = mKeepalivePackets.valueAt(i);
+ if (filterType.isInstance(response)) response.generateFilterLocked(gen);
}
gen.defineLabel(label);
}
private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
- generateFilters(gen, TcpKeepaliveAckV4.class, IPPROTO_TCP, IPV4_PROTOCOL_OFFSET,
+ generateKeepaliveFilters(gen, TcpKeepaliveAckV4.class, IPPROTO_TCP, IPV4_PROTOCOL_OFFSET,
"skip_v4_keepalive_filter");
}
private void generateV4NattKeepaliveFilters(ApfGenerator gen)
throws IllegalInstructionException {
- generateFilters(gen, NattKeepaliveAckV4.class, IPPROTO_UDP, IPV4_PROTOCOL_OFFSET,
- "skip_v4_nattkeepalive_filter");
+ generateKeepaliveFilters(gen, NattKeepaliveResponse.class,
+ IPPROTO_UDP, IPV4_PROTOCOL_OFFSET, "skip_v4_nattkeepalive_filter");
}
/**
@@ -1417,7 +1392,7 @@ public class ApfFilter {
}
private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
- generateFilters(gen, TcpKeepaliveAckV6.class, IPPROTO_TCP, IPV6_NEXT_HEADER_OFFSET,
+ generateKeepaliveFilters(gen, TcpKeepaliveAckV6.class, IPPROTO_TCP, IPV6_NEXT_HEADER_OFFSET,
"skip_v6_keepalive_filter");
}
@@ -1819,8 +1794,8 @@ public class ApfFilter {
}
/**
- * Add NATT keepalive packet filter.
- * This will add a filter to drop NATT keepalive packet which is passed as an argument.
+ * Add NAT-T keepalive packet filter.
+ * This will add a filter to drop NAT-T keepalive packet which is passed as an argument.
*
* @param slot The index used to access the filter.
* @param sentKeepalivePacket The attributes of the sent keepalive packet.
@@ -1829,12 +1804,12 @@ public class ApfFilter {
final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
log("Adding NAT-T keepalive packet(" + slot + ")");
if (null != mKeepalivePackets.get(slot)) {
- throw new IllegalArgumentException("Natt Keepalive slot " + slot + " is occupied");
+ throw new IllegalArgumentException("NAT-T Keepalive slot " + slot + " is occupied");
}
- final int ipVersion = sentKeepalivePacket.srcAddress.length == 4 ? 4 : 6;
- mKeepalivePackets.put(slot, (ipVersion == 4)
- ? new NattKeepaliveAckV4(sentKeepalivePacket)
- : new NattKeepaliveAckV6(sentKeepalivePacket));
+ if (sentKeepalivePacket.srcAddress.length != 4) {
+ throw new IllegalArgumentException("NAT-T keepalive is only supported on IPv4");
+ }
+ mKeepalivePackets.put(slot, new NattKeepaliveResponse(sentKeepalivePacket));
installNewProgramLocked();
}
@@ -1908,7 +1883,7 @@ public class ApfFilter {
if (keepalivePacket instanceof TcpKeepaliveAck) {
pw.print("Slot ");
pw.print(mKeepalivePackets.keyAt(i));
- pw.print(" : ");
+ pw.print(": ");
pw.println(keepalivePacket);
}
}
@@ -1918,10 +1893,10 @@ public class ApfFilter {
pw.increaseIndent();
for (int i = 0; i < mKeepalivePackets.size(); ++i) {
final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
- if (keepalivePacket instanceof NattKeepaliveAck) {
+ if (keepalivePacket instanceof NattKeepaliveResponse) {
pw.print("Slot ");
pw.print(mKeepalivePackets.keyAt(i));
- pw.print(" : ");
+ pw.print(": ");
pw.println(keepalivePacket);
}
}
diff --git a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java b/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
index 85f94e17a088..4767d5574a00 100644
--- a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
+++ b/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
@@ -55,12 +55,23 @@ public class DnsUtils {
throws UnknownHostException {
final List<InetAddress> result = new ArrayList<InetAddress>();
- result.addAll(Arrays.asList(
- getAllByName(dnsResolver, network, host, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
- timeout)));
- result.addAll(Arrays.asList(
- getAllByName(dnsResolver, network, host, TYPE_A, FLAG_NO_CACHE_LOOKUP,
- timeout)));
+ try {
+ result.addAll(Arrays.asList(
+ getAllByName(dnsResolver, network, host, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
+ timeout)));
+ } catch (UnknownHostException e) {
+ // Might happen if the host is v4-only, still need to query TYPE_A
+ }
+ try {
+ result.addAll(Arrays.asList(
+ getAllByName(dnsResolver, network, host, TYPE_A, FLAG_NO_CACHE_LOOKUP,
+ timeout)));
+ } catch (UnknownHostException e) {
+ // Might happen if the host is v6-only, still need to return AAAA answers
+ }
+ if (result.size() == 0) {
+ throw new UnknownHostException(host);
+ }
return result.toArray(new InetAddress[0]);
}
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
index 41c3fab8f0d0..8f2b96807860 100644
--- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
+++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
@@ -1734,7 +1734,8 @@ public class ApfTest {
final int dstPort = 4500;
final int slot1 = 1;
// NAT-T keepalive
- final byte[] payload = {(byte) 0xff};
+ final byte[] kaPayload = {(byte) 0xff};
+ final byte[] nonKaPayload = {(byte) 0xfe};
// src: 10.0.0.5, port: 1024
// dst: 10.0.0.6, port: 4500
@@ -1753,15 +1754,21 @@ public class ApfTest {
// Verify IPv4 keepalive packet is dropped
// src: 10.0.0.6, port: 4500
// dst: 10.0.0.5, port: 1024
- final byte[] nattKaPkt = ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR,
+ byte[] pkt = ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR,
IPV4_KEEPALIVE_SRC_ADDR, dstPort, srcPort, 1 /* dataLength */);
- System.arraycopy(payload, 0, nattKaPkt, IPV4_UDP_PAYLOAD_OFFSET, payload.length);
- assertDrop(program, nattKaPkt);
- // Verify IPv4 non-keepalive packet from the same source address is passed
+ System.arraycopy(kaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, kaPayload.length);
+ assertDrop(program, pkt);
+
+ // Verify a packet with payload length 1 byte but it is not 0xff will pass the filter.
+ System.arraycopy(nonKaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, nonKaPayload.length);
+ assertPass(program, pkt);
+
+ // Verify IPv4 non-keepalive response packet from the same source address is passed
assertPass(program,
ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
dstPort, srcPort, 10 /* dataLength */));
- // Verify IPv4 non-keepalive packet from other source address is passed
+
+ // Verify IPv4 non-keepalive response packet from other source address is passed
assertPass(program,
ipv4UdpPacket(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
dstPort, srcPort, 10 /* dataLength */));
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index abfb9c8ae282..832b7124dc05 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -298,8 +298,10 @@ public class NetworkMonitorTest {
setFallbackSpecs(null); // Test with no fallback spec by default
when(mRandom.nextInt()).thenReturn(0);
+ // DNS probe timeout should not be defined more than half of HANDLER_TIMEOUT_MS. Otherwise,
+ // it will fail the test because of timeout expired for querying AAAA and A sequentially.
when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
- .thenReturn(500);
+ .thenReturn(200);
doAnswer((invocation) -> {
URL url = invocation.getArgument(0);
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
index b7bb751c1582..a150de95fcf0 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
@@ -662,11 +662,17 @@ public class LegacyRecentsImpl implements RecentsImplementation {
public final void onBusEvent(ExpandPipEvent event) {
PipUI pipUi = getComponent(PipUI.class);
+ if (pipUi == null) {
+ return;
+ }
pipUi.expandPip();
}
public final void onBusEvent(HidePipMenuEvent event) {
PipUI pipUi = getComponent(PipUI.class);
+ if (pipUi == null) {
+ return;
+ }
event.getAnimationTrigger().increment();
pipUi.hidePipMenu(() -> {
event.getAnimationTrigger().increment();
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index cdef09d73f77..2792a019f8d8 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -31,23 +31,36 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
android:layout_gravity="bottom|center_horizontal"
- android:orientation="vertical">
+ android:orientation="horizontal">
- <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
- android:id="@+id/keyguard_indication_enterprise_disclosure"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
- android:visibility="gone" />
+ <include layout="@layout/left_docked_overlay" />
- <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
- android:id="@+id/keyguard_indication_text"
- android:layout_width="match_parent"
+ <LinearLayout
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
- android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
- android:accessibilityLiveRegion="polite" />
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical|center_horizontal"
+ android:orientation="vertical">
+
+ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+ android:id="@+id/keyguard_indication_enterprise_disclosure"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+ android:visibility="gone" />
+
+ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+ android:id="@+id/keyguard_indication_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+ android:accessibilityLiveRegion="polite" />
+
+ </LinearLayout>
+
+ <include layout="@layout/right_docked_overlay" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/left_docked_overlay.xml b/packages/SystemUI/res/layout/left_docked_overlay.xml
new file mode 100644
index 000000000000..430143ca3bc2
--- /dev/null
+++ b/packages/SystemUI/res/layout/left_docked_overlay.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/layout/right_docked_overlay.xml b/packages/SystemUI/res/layout/right_docked_overlay.xml
new file mode 100644
index 000000000000..430143ca3bc2
--- /dev/null
+++ b/packages/SystemUI/res/layout/right_docked_overlay.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index dd6ccb2b3a88..ea8565e8d301 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -238,6 +238,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private boolean mIsDreaming;
private final DevicePolicyManager mDevicePolicyManager;
private boolean mLogoutEnabled;
+ // If the user long pressed the lock icon, disabling face auth for the current session.
+ private boolean mLockIconPressed;
/**
* Short delay before restarting biometric authentication after a successful try
@@ -1384,6 +1386,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
private void handleScreenTurnedOff() {
+ mLockIconPressed = false;
mHardwareFingerprintUnavailableRetryCount = 0;
mHardwareFaceUnavailableRetryCount = 0;
final int count = mCallbacks.size();
@@ -1625,10 +1628,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
&& !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
- && !mKeyguardGoingAway && mFaceSettingEnabledForUser
+ && !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
&& mUserManager.isUserUnlocked(user) && mIsPrimaryUser;
}
+ /**
+ * Whenever the lock icon is long pressed, disabling trust agents.
+ * This means that we cannot auth passively (face) until the user presses power.
+ */
+ public void onLockIconPressed() {
+ mLockIconPressed = true;
+ mUserFaceAuthenticated.put(getCurrentUser(), false);
+ updateFaceListeningState();
+ }
private void startListeningForFingerprint() {
if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index a76c9dc9f40a..fd76a79eab2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -189,6 +189,7 @@ public class KeyguardIndicationController implements StateListener,
mLockscreenGestureLogger.write(MetricsProto.MetricsEvent.ACTION_LS_LOCK,
0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
showTransientIndication(R.string.keyguard_indication_trust_disabled);
+ mKeyguardUpdateMonitor.onLockIconPressed();
mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
return true;
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 6d9a77c58227..daee55bd3d61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -261,6 +261,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
longClickCaptor.getValue().onLongClick(mLockIcon);
verify(mLockPatternUtils).requireCredentialEntry(anyInt());
+ verify(mKeyguardUpdateMonitor).onLockIconPressed();
}
@Test
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c6461491b8cd..fc355b7cce2f 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -286,6 +286,7 @@ class StorageManagerService extends IStorageManager.Stub
private static final String ATTR_NICKNAME = "nickname";
private static final String ATTR_USER_FLAGS = "userFlags";
private static final String ATTR_CREATED_MILLIS = "createdMillis";
+ private static final String ATTR_LAST_SEEN_MILLIS = "lastSeenMillis";
private static final String ATTR_LAST_TRIM_MILLIS = "lastTrimMillis";
private static final String ATTR_LAST_BENCH_MILLIS = "lastBenchMillis";
@@ -1313,7 +1314,7 @@ class StorageManagerService extends IStorageManager.Stub
private void onVolumeStateChangedLocked(VolumeInfo vol, int oldState, int newState) {
// Remember that we saw this volume so we're ready to accept user
// metadata, or so we can annoy them when a private volume is ejected
- if (vol.isMountedReadable() && !TextUtils.isEmpty(vol.fsUuid)) {
+ if (!TextUtils.isEmpty(vol.fsUuid)) {
VolumeRecord rec = mRecords.get(vol.fsUuid);
if (rec == null) {
rec = new VolumeRecord(vol.type, vol.fsUuid);
@@ -1323,14 +1324,15 @@ class StorageManagerService extends IStorageManager.Stub
rec.nickname = vol.disk.getDescription();
}
mRecords.put(rec.fsUuid, rec);
- writeSettingsLocked();
} else {
// Handle upgrade case where we didn't store partition GUID
if (TextUtils.isEmpty(rec.partGuid)) {
rec.partGuid = vol.partGuid;
- writeSettingsLocked();
}
}
+
+ rec.lastSeenMillis = System.currentTimeMillis();
+ writeSettingsLocked();
}
mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);
@@ -1731,9 +1733,10 @@ class StorageManagerService extends IStorageManager.Stub
meta.partGuid = readStringAttribute(in, ATTR_PART_GUID);
meta.nickname = readStringAttribute(in, ATTR_NICKNAME);
meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS);
- meta.createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
- meta.lastTrimMillis = readLongAttribute(in, ATTR_LAST_TRIM_MILLIS);
- meta.lastBenchMillis = readLongAttribute(in, ATTR_LAST_BENCH_MILLIS);
+ meta.createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS, 0);
+ meta.lastSeenMillis = readLongAttribute(in, ATTR_LAST_SEEN_MILLIS, 0);
+ meta.lastTrimMillis = readLongAttribute(in, ATTR_LAST_TRIM_MILLIS, 0);
+ meta.lastBenchMillis = readLongAttribute(in, ATTR_LAST_BENCH_MILLIS, 0);
return meta;
}
@@ -1745,6 +1748,7 @@ class StorageManagerService extends IStorageManager.Stub
writeStringAttribute(out, ATTR_NICKNAME, rec.nickname);
writeIntAttribute(out, ATTR_USER_FLAGS, rec.userFlags);
writeLongAttribute(out, ATTR_CREATED_MILLIS, rec.createdMillis);
+ writeLongAttribute(out, ATTR_LAST_SEEN_MILLIS, rec.lastSeenMillis);
writeLongAttribute(out, ATTR_LAST_TRIM_MILLIS, rec.lastTrimMillis);
writeLongAttribute(out, ATTR_LAST_BENCH_MILLIS, rec.lastBenchMillis);
out.endTag(null, TAG_VOLUME);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 88919df04f00..b9a6a1020a77 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -760,7 +760,6 @@ public class BiometricService extends SystemService {
@Override // Binder call
public int canAuthenticate(String opPackageName) {
checkPermission();
- checkAppOp(opPackageName, Binder.getCallingUid());
final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
@@ -833,9 +832,9 @@ public class BiometricService extends SystemService {
}
private void checkPermission() {
- if (getContext().checkCallingPermission(USE_FINGERPRINT)
+ if (getContext().checkCallingOrSelfPermission(USE_FINGERPRINT)
!= PackageManager.PERMISSION_GRANTED) {
- getContext().enforceCallingPermission(USE_BIOMETRIC,
+ getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC,
"Must have USE_BIOMETRIC permission");
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c2125b0a997d..b246eb6d38bd 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -421,8 +421,9 @@ public class LockSettingsService extends ILockSettings.Stub {
new PasswordSlotManager());
}
- public boolean hasBiometrics() {
- return BiometricManager.hasBiometrics(mContext);
+ public boolean hasEnrolledBiometrics() {
+ BiometricManager bm = mContext.getSystemService(BiometricManager.class);
+ return bm.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
}
public int binderGetCallingUid() {
@@ -2502,7 +2503,8 @@ public class LockSettingsService extends ILockSettings.Stub {
// TODO: When lockout is handled under the HAL for all biometrics (fingerprint),
// we need to generate challenge for each one, have it signed by GK and reset lockout
// for each modality.
- if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
+ && mInjector.hasEnrolledBiometrics()) {
challenge = mContext.getSystemService(FaceManager.class).generateChallenge();
}
@@ -2544,8 +2546,8 @@ public class LockSettingsService extends ILockSettings.Stub {
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
- // Reset lockout
- if (mInjector.hasBiometrics()) {
+ // Reset lockout only if user has enrolled templates
+ if (mInjector.hasEnrolledBiometrics()) {
BiometricManager bm = mContext.getSystemService(BiometricManager.class);
Slog.i(TAG, "Resetting lockout, length: "
+ authResult.gkResponse.getPayload().length);
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
index ef94000d3a6b..388e51f203ca 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -30,6 +30,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
+import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
@@ -43,6 +44,7 @@ import javax.crypto.spec.SecretKeySpec;
public class SyntheticPasswordCrypto {
private static final int PROFILE_KEY_IV_SIZE = 12;
+ private static final int DEFAULT_TAG_LENGTH_BITS = 128;
private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
// Time between the user credential is verified with GK and the decryption of synthetic password
@@ -60,13 +62,14 @@ public class SyntheticPasswordCrypto {
byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
- cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
+ cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(DEFAULT_TAG_LENGTH_BITS, iv));
return cipher.doFinal(ciphertext);
}
private static byte[] encrypt(SecretKey key, byte[] blob)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
- InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+ InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
+ InvalidParameterSpecException {
if (blob == null) {
return null;
}
@@ -79,6 +82,11 @@ public class SyntheticPasswordCrypto {
if (iv.length != PROFILE_KEY_IV_SIZE) {
throw new RuntimeException("Invalid iv length: " + iv.length);
}
+ final GCMParameterSpec spec = cipher.getParameters().getParameterSpec(
+ GCMParameterSpec.class);
+ if (spec.getTLen() != DEFAULT_TAG_LENGTH_BITS) {
+ throw new RuntimeException("Invalid tag length: " + spec.getTLen());
+ }
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(iv);
outputStream.write(ciphertext);
@@ -92,7 +100,8 @@ public class SyntheticPasswordCrypto {
try {
return encrypt(key, message);
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
- | IllegalBlockSizeException | BadPaddingException | IOException e) {
+ | IllegalBlockSizeException | BadPaddingException | IOException
+ | InvalidParameterSpecException e) {
e.printStackTrace();
return null;
}
@@ -147,7 +156,7 @@ public class SyntheticPasswordCrypto {
public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
- keyGenerator.init(new SecureRandom());
+ keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
@@ -169,7 +178,8 @@ public class SyntheticPasswordCrypto {
} catch (CertificateException | IOException | BadPaddingException
| IllegalBlockSizeException
| KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
- | InvalidKeyException e) {
+ | InvalidKeyException
+ | InvalidParameterSpecException e) {
e.printStackTrace();
throw new RuntimeException("Failed to encrypt blob", e);
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index bab612d3c092..9d115963423d 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -73,6 +73,7 @@ public class Installer extends SystemService {
public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
+ public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
public static final int FLAG_CLEAR_CACHE_ONLY = IInstalld.FLAG_CLEAR_CACHE_ONLY;
public static final int FLAG_CLEAR_CODE_CACHE_ONLY = IInstalld.FLAG_CLEAR_CODE_CACHE_ONLY;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 85833ab38533..36b763734330 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -89,6 +89,7 @@ import static android.content.pm.PackageParser.isApkFile;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
+import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
@@ -3249,7 +3250,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
// No apps are running this early, so no need to freeze
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
- StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
+ FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
@@ -3501,8 +3502,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
return false;
}
- clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
- | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
+ | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
mDexManager.notifyPackageUpdated(pkg.packageName,
pkg.baseCodePath, pkg.splitCodePaths);
}
@@ -15980,6 +15981,9 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mInstallLock) {
// Clean up both app data and code
// All package moves are frozen until finished
+
+ // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
+ // this task was only focused on moving data on internal storage.
for (int userId : userIds) {
try {
mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
@@ -17080,8 +17084,8 @@ public class PackageManagerService extends IPackageManager.Stub
final String packageName = pkg.packageName;
prepareAppDataAfterInstallLIF(pkg);
if (reconciledPkg.prepareResult.clearCodeCache) {
- clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
- | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
+ | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
if (reconciledPkg.prepareResult.replace) {
mDexManager.notifyPackageUpdated(pkg.packageName,
@@ -18853,7 +18857,7 @@ public class PackageManagerService extends IPackageManager.Stub
resolvedPkg.setVolumeUuid(deletedPs.volumeUuid);
}
destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
- StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
destroyAppProfilesLIF(resolvedPkg);
if (outInfo != null) {
outInfo.dataRemoved = true;
@@ -19605,7 +19609,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
destroyAppDataLIF(pkg, nextUserId,
- StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
removeKeystoreDataIfNeeded(nextUserId, ps.appId);
final SparseBooleanArray changedUsers = new SparseBooleanArray();
@@ -19741,7 +19745,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
clearAppDataLIF(pkg, userId,
- StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
removeKeystoreDataIfNeeded(userId, appId);
@@ -19972,8 +19976,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (doClearData) {
synchronized (mInstallLock) {
- final int flags = StorageManager.FLAG_STORAGE_DE
- | StorageManager.FLAG_STORAGE_CE;
+ final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
// We're only clearing cache files, so we don't care if the
// app is unfrozen and still able to run
clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
@@ -22521,9 +22524,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
- clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
- StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
- | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
+ | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
}
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 1edb93a0cdb9..7d0da68a0750 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -15,6 +15,7 @@
*/
package com.android.server.stats;
+import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
import static android.os.Process.getPidsForCommands;
@@ -33,6 +34,11 @@ import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
+import android.app.AppOpsManager;
+import android.app.AppOpsManager.HistoricalOps;
+import android.app.AppOpsManager.HistoricalOpsRequest;
+import android.app.AppOpsManager.HistoricalPackageOps;
+import android.app.AppOpsManager.HistoricalUidOps;
import android.app.ProcessMemoryHighWaterMark;
import android.app.ProcessMemoryState;
import android.app.StatsManager;
@@ -146,6 +152,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -154,6 +162,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -1941,6 +1950,53 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
+ private void pullAppOps(long elapsedNanos, final long wallClockNanos,
+ List<StatsLogEventWrapper> pulledData) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+
+ CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
+ HistoricalOpsRequest histOpsRequest =
+ new HistoricalOpsRequest.Builder(
+ Instant.now().minus(1, ChronoUnit.HOURS).toEpochMilli(),
+ Long.MAX_VALUE).build();
+ appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
+
+ HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
+ TimeUnit.MILLISECONDS);
+
+ StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS, elapsedNanos,
+ wallClockNanos);
+
+ for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
+ final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
+ final int uid = uidOps.getUid();
+ for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
+ final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
+ for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
+ final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
+ e.writeInt(uid);
+ e.writeString(packageOps.getPackageName());
+ e.writeInt(op.getOpCode());
+ e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+ pulledData.add(e);
+ }
+ }
+ }
+ } catch (Throwable t) {
+ Log.e(TAG, "Could not read appops", t);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+
/**
* Add a RoleHolder atom for each package that holds a role.
*
@@ -2331,6 +2387,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
+ case StatsLog.APP_OPS: {
+ pullAppOps(elapsedNanos, wallClockNanos, ret);
+ break;
+ }
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index fd90f0339e63..ecbecbafd3d5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2005,7 +2005,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
}
layoutLetterbox(winHint);
if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
- mLetterbox.applySurfaceChanges(mPendingTransaction);
+ mLetterbox.applySurfaceChanges(getPendingTransaction());
}
}
@@ -3059,13 +3059,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
if (mSurfaceControl != null) {
if (show && !mLastSurfaceShowing) {
- mPendingTransaction.show(mSurfaceControl);
+ getPendingTransaction().show(mSurfaceControl);
} else if (!show && mLastSurfaceShowing) {
- mPendingTransaction.hide(mSurfaceControl);
+ getPendingTransaction().hide(mSurfaceControl);
}
}
if (mThumbnail != null) {
- mThumbnail.setShowing(mPendingTransaction, show);
+ mThumbnail.setShowing(getPendingTransaction(), show);
}
mLastSurfaceShowing = show;
super.prepareSurfaces();
@@ -3225,8 +3225,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
private void updateColorTransform() {
if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
- mPendingTransaction.setColorTransform(mSurfaceControl, mLastAppSaturationInfo.mMatrix,
- mLastAppSaturationInfo.mTranslation);
+ getPendingTransaction().setColorTransform(mSurfaceControl,
+ mLastAppSaturationInfo.mMatrix, mLastAppSaturationInfo.mTranslation);
mWmService.scheduleAnimationLocked();
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a61b27e90202..6ad8ece2b612 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1479,7 +1479,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// the top of the method, the caller is obligated to call computeNewConfigurationLocked().
// By updating the Display info here it will be available to
// #computeScreenConfiguration() later.
- updateDisplayAndOrientation(getConfiguration().uiMode);
+ updateDisplayAndOrientation(getConfiguration().uiMode, null /* outConfig */);
// NOTE: We disable the rotation in the emulator because
// it doesn't support hardware OpenGL emulation yet.
@@ -1577,7 +1577,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
* changed.
* Do not call if {@link WindowManagerService#mDisplayReady} == false.
*/
- private DisplayInfo updateDisplayAndOrientation(int uiMode) {
+ private DisplayInfo updateDisplayAndOrientation(int uiMode, Configuration outConfig) {
// Use the effective "visual" dimensions based on current rotation
final boolean rotated = (mRotation == ROTATION_90 || mRotation == ROTATION_270);
final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
@@ -1609,6 +1609,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mDisplayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
}
+ computeSizeRangesAndScreenLayout(mDisplayInfo, rotated, uiMode, dw, dh,
+ mDisplayMetrics.density, outConfig);
+
// We usually set the override info in DisplayManager so that we get consistent display
// metrics values when displays are changing and don't send out new values until WM is aware
// of them. However, we don't do this for displays that serve as containers for ActivityView
@@ -1657,7 +1660,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
* Do not call if mDisplayReady == false.
*/
void computeScreenConfiguration(Configuration config) {
- final DisplayInfo displayInfo = updateDisplayAndOrientation(config.uiMode);
+ final DisplayInfo displayInfo = updateDisplayAndOrientation(config.uiMode, config);
calculateBounds(displayInfo, mTmpBounds);
config.windowConfiguration.setBounds(mTmpBounds);
@@ -1687,9 +1690,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
final boolean rotated = (displayInfo.rotation == Surface.ROTATION_90
|| displayInfo.rotation == Surface.ROTATION_270);
- computeSizeRangesAndScreenLayout(displayInfo, rotated, config.uiMode, dw, dh, density,
- config);
-
config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
| ((displayInfo.flags & Display.FLAG_ROUND) != 0
? Configuration.SCREENLAYOUT_ROUND_YES
@@ -1843,6 +1843,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, uiMode, unrotDh, unrotDw);
adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, uiMode, unrotDw, unrotDh);
adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, uiMode, unrotDh, unrotDw);
+
+ if (outConfig == null) {
+ return;
+ }
int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
displayInfo.displayCutout);
@@ -3339,7 +3343,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
final SurfaceControl newParent =
shouldAttachToDisplay ? mWindowingLayer : computeImeParent();
if (newParent != null) {
- mPendingTransaction.reparent(mImeWindowsContainers.mSurfaceControl, newParent);
+ getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
scheduleAnimation();
}
}
@@ -3746,7 +3750,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mPortalWindowHandle.touchableRegion.getBounds(mTmpRect);
if (!mTmpBounds.equals(mTmpRect)) {
mPortalWindowHandle.touchableRegion.set(mTmpBounds);
- mPendingTransaction.setInputWindowInfo(mParentSurfaceControl, mPortalWindowHandle);
+ getPendingTransaction().setInputWindowInfo(
+ mParentSurfaceControl, mPortalWindowHandle);
}
}
}
@@ -4834,18 +4839,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
try {
final ScreenRotationAnimation screenRotationAnimation =
mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
+ final Transaction transaction = getPendingTransaction();
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats);
- mPendingTransaction.setMatrix(mWindowingLayer,
+ transaction.setMatrix(mWindowingLayer,
mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
- mPendingTransaction.setPosition(mWindowingLayer,
+ transaction.setPosition(mWindowingLayer,
mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
- mPendingTransaction.setAlpha(mWindowingLayer,
+ transaction.setAlpha(mWindowingLayer,
screenRotationAnimation.getEnterTransformation().getAlpha());
}
super.prepareSurfaces();
+
+ // TODO: Once we totally eliminate global transaction we will pass transaction in here
+ // rather than merging to global.
+ SurfaceControl.mergeToGlobalTransaction(transaction);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@@ -5001,7 +5011,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (mPortalWindowHandle == null) {
mPortalWindowHandle = createPortalWindowHandle(sc.toString());
}
- mPendingTransaction.setInputWindowInfo(sc, mPortalWindowHandle)
+ getPendingTransaction().setInputWindowInfo(sc, mPortalWindowHandle)
.reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc);
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bb7867ce53ec..38201069ebca 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -138,6 +138,7 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta
setOrientation(SCREEN_ORIENTATION_UNSET);
}
+ @Override
DisplayContent getDisplayContent() {
return mStack != null ? mStack.getDisplayContent() : null;
}
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index 17e4b897c9da..ee4e462cb85e 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -77,7 +77,7 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable {
@Override
public SurfaceControl.Transaction getPendingTransaction() {
- return mTask.mPendingTransaction;
+ return mTask.getPendingTransaction();
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 757f6a1c2f94..ab5e071f572a 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -93,10 +93,6 @@ public class TaskStack extends WindowContainer<Task> implements
/** Unique identifier */
final int mStackId;
- /** The display this stack sits under. */
- // TODO: Track parent marks like this in WindowContainer.
- private DisplayContent mDisplayContent;
-
/** For comparison with DisplayContent bounds. */
private Rect mTmpRect = new Rect();
private Rect mTmpRect2 = new Rect();
@@ -177,10 +173,6 @@ public class TaskStack extends WindowContainer<Task> implements
EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
}
- DisplayContent getDisplayContent() {
- return mDisplayContent;
- }
-
Task findHomeTask() {
if (!isActivityTypeHome() || mChildren.isEmpty()) {
return null;
@@ -825,8 +817,7 @@ public class TaskStack extends WindowContainer<Task> implements
throw new IllegalStateException("onDisplayChanged: Already attached");
}
- final boolean movedToNewDisplay = mDisplayContent == null;
- mDisplayContent = dc;
+ super.onDisplayChanged(dc);
updateSurfaceBounds();
if (mAnimationBackgroundSurface == null) {
@@ -834,8 +825,6 @@ public class TaskStack extends WindowContainer<Task> implements
.setName("animation background stackId=" + mStackId)
.build();
}
-
- super.onDisplayChanged(dc);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d5c3e4f34c26..bbef261d17bb 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -109,14 +109,19 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// The owner/creator for this container. No controller if null.
WindowContainerController mController;
+ // The display this window container is on.
+ protected DisplayContent mDisplayContent;
+
protected SurfaceControl mSurfaceControl;
private int mLastLayer = 0;
private SurfaceControl mLastRelativeToLayer = null;
+ // TODO(b/132320879): Remove this from WindowContainers except DisplayContent.
+ private final Transaction mPendingTransaction;
+
/**
* Applied as part of the animation pass in "prepareSurfaces".
*/
- protected final Transaction mPendingTransaction;
protected final SurfaceAnimator mSurfaceAnimator;
protected final WindowManagerService mWmService;
@@ -320,12 +325,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
if (mSurfaceControl != null) {
- mPendingTransaction.remove(mSurfaceControl);
+ getPendingTransaction().remove(mSurfaceControl);
// Merge to parent transaction to ensure the transactions on this WindowContainer are
// applied in native even if WindowContainer is removed.
if (mParent != null) {
- mParent.getPendingTransaction().merge(mPendingTransaction);
+ mParent.getPendingTransaction().merge(getPendingTransaction());
}
mSurfaceControl = null;
@@ -508,12 +513,20 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @param dc The display this container is on after changes.
*/
void onDisplayChanged(DisplayContent dc) {
+ mDisplayContent = dc;
+ if (dc != null && dc != this) {
+ dc.getPendingTransaction().merge(mPendingTransaction);
+ }
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer child = mChildren.get(i);
child.onDisplayChanged(dc);
}
}
+ DisplayContent getDisplayContent() {
+ return mDisplayContent;
+ }
+
void setWaitingForDrawnIfResizingChanged() {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer wc = mChildren.get(i);
@@ -1180,13 +1193,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
}
- /**
- * TODO: Once we totally eliminate global transaction we will pass transaction in here
- * rather than merging to global.
- */
void prepareSurfaces() {
- SurfaceControl.mergeToGlobalTransaction(getPendingTransaction());
-
// If a leash has been set when the transaction was committed, then the leash reparent has
// been committed.
mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
@@ -1204,8 +1211,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
/**
- * Trigger a call to prepareSurfaces from the animation thread, such that
- * mPendingTransaction will be applied.
+ * Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
+ * will be applied.
*/
void scheduleAnimation() {
if (mParent != null) {
@@ -1224,6 +1231,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
@Override
public Transaction getPendingTransaction() {
+ final DisplayContent displayContent = getDisplayContent();
+ if (displayContent != null && displayContent != this) {
+ return displayContent.getPendingTransaction();
+ }
+ // This WindowContainer has not attached to a display yet or this is a DisplayContent, so we
+ // let the caller to save the surface operations within the local mPendingTransaction.
+ // If this is not a DisplayContent, we will merge it to the pending transaction of its
+ // display once it attaches to it.
return mPendingTransaction;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index dd3c6004dcad..5ef184adc52f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1313,6 +1313,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mOrientationChangeTimedOut = true;
}
+ @Override
DisplayContent getDisplayContent() {
return mToken.getDisplayContent();
}
@@ -4602,7 +4603,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
new WindowAnimationSpec(anim, mSurfacePosition, false /* canSkipFirstFrame */,
0 /* windowCornerRadius */),
mWmService.mSurfaceAnimationRunner);
- startAnimation(mPendingTransaction, adapter);
+ startAnimation(getPendingTransaction(), adapter);
commitPendingTransaction();
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index f0b9c62f2843..8aee0f2a8308 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -82,9 +82,6 @@ class WindowToken extends WindowContainer<WindowState> {
// windows will be put to the bottom of the list.
boolean sendingToBottom;
- // The display this token is on.
- protected DisplayContent mDisplayContent;
-
/** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
final boolean mOwnerCanManageAppTokens;
@@ -249,10 +246,6 @@ class WindowToken extends WindowContainer<WindowState> {
return null;
}
- DisplayContent getDisplayContent() {
- return mDisplayContent;
- }
-
@Override
void removeImmediately() {
if (mDisplayContent != null) {
@@ -266,7 +259,6 @@ class WindowToken extends WindowContainer<WindowState> {
@Override
void onDisplayChanged(DisplayContent dc) {
dc.reParentWindowToken(this);
- mDisplayContent = dc;
// TODO(b/36740756): One day this should perhaps be hooked
// up with goodToGo, so we don't move a window
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c2f699bab9d9..ea5cc211c954 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1051,12 +1051,7 @@ public final class SystemServer {
mDisplayManagerService.windowManagerAndInputReady();
traceEnd();
- // Skip Bluetooth if we have an emulator kernel
- // TODO: Use a more reliable check to see if this product should
- // support Bluetooth - see bug 988521
- if (isEmulator) {
- Slog.i(TAG, "No Bluetooth Service (emulator)");
- } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
+ if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
Slog.i(TAG, "No Bluetooth Service (factory test)");
} else if (!context.getPackageManager().hasSystemFeature
(PackageManager.FEATURE_BLUETOOTH)) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 09e20e04835b..1f5ebe4536d8 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -235,6 +235,10 @@ public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
mPasswordSlotManager.cleanup();
}
+ protected void flushHandlerTasks() {
+ mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler
+ }
+
protected void assertNotEquals(long expected, long actual) {
assertTrue(expected != actual);
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 10fb3ba938d4..f85e2cc10800 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -110,7 +110,7 @@ public class LockSettingsServiceTestable extends LockSettingsService {
}
@Override
- public boolean hasBiometrics() {
+ public boolean hasEnrolledBiometrics() {
return false;
}
@@ -163,5 +163,4 @@ public class LockSettingsServiceTestable extends LockSettingsService {
}
return storedData;
}
-
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 0273f7651207..1cd590c39f49 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -232,7 +232,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
reset(mAuthSecretService);
mService.onUnlockUser(PRIMARY_USER_ID);
- mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
+ flushHandlerTasks();
verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class));
}
@@ -242,7 +242,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
reset(mAuthSecretService);
mService.onUnlockUser(PRIMARY_USER_ID);
- mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
+ flushHandlerTasks();
verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class));
}
@@ -254,7 +254,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
reset(mAuthSecretService);
mService.onUnlockUser(PRIMARY_USER_ID);
- mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
+ flushHandlerTasks();
verify(mAuthSecretService).primaryUserCredential(any(ArrayList.class));
}
@@ -357,7 +357,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
handle, token, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
// Verify DPM gets notified about new device lock
- mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
+ flushHandlerTasks();
final PasswordMetrics metric = PasswordMetrics.computeForCredential(
LockPatternUtils.CREDENTIAL_TYPE_PATTERN, pattern);
verify(mDevicePolicyManager).setActivePasswordState(metric, PRIMARY_USER_ID);
@@ -384,6 +384,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
mLocalService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
handle, token, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ flushHandlerTasks(); // flush the unlockUser() call before changing password again
mLocalService.setLockCredentialWithToken(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
handle, token, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index faf6ee23e208..0f3050f9e3d3 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -120,6 +120,7 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
@Override
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
switch (vol.type) {
+ case VolumeInfo.TYPE_PUBLIC:
case VolumeInfo.TYPE_PRIVATE:
case VolumeInfo.TYPE_EMULATED:
if (newState == VolumeInfo.STATE_MOUNTED) {
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index b5da2eeb4c9c..addd9e0591b0 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -396,6 +396,12 @@ public class SubscriptionManager {
public static final int NAME_SOURCE_USER_INPUT = 2;
/**
+ * The name_source is carrier (carrier app, carrier config, etc.)
+ * @hide
+ */
+ public static final int NAME_SOURCE_CARRIER = 3;
+
+ /**
* TelephonyProvider column name for the color of a SIM.
* <P>Type: INTEGER (int)</P>
*/
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 64c1830c5e5c..2552f045eedf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -209,18 +209,9 @@ public final class TelephonyPermissions {
context.enforcePermission(
android.Manifest.permission.READ_PHONE_STATE, pid, uid, message);
} catch (SecurityException phoneStateException) {
- SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
- Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- int[] activeSubIds = sm.getActiveSubscriptionIdList();
- for (int activeSubId : activeSubIds) {
- // If we don't have the runtime permission, but do have carrier privileges, that
- // suffices for reading phone state.
- if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
- == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
- return true;
- }
- }
- return false;
+ // If we don't have the runtime permission, but do have carrier privileges, that
+ // suffices for reading phone state.
+ return checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid);
}
}
@@ -236,9 +227,9 @@ public final class TelephonyPermissions {
*
* <p>This method behaves in one of the following ways:
* <ul>
- * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the
- * calling package passes a DevicePolicyManager Device Owner / Profile Owner device
- * identifier access check,
+ * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
+ * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
+ * access check, or the calling package has carrier privileges.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
@@ -258,9 +249,9 @@ public final class TelephonyPermissions {
*
* <p>This method behaves in one of the following ways:
* <ul>
- * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the
- * calling package passes a DevicePolicyManager Device Owner / Profile Owner device
- * identifier access check,
+ * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
+ * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
+ * access check, or the calling package has carrier privileges.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission
* or carrier privileges.
@@ -272,23 +263,8 @@ public final class TelephonyPermissions {
*/
public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
String callingPackage, String message) {
- int pid = Binder.getCallingPid();
- int uid = Binder.getCallingUid();
- // if the device identifier check completes successfully then grant access.
- if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
- return true;
- }
- // Calling packages with carrier privileges will also have access to device identifiers, but
- // this may be removed in a future release.
- if (checkCarrierPrivilegeForSubId(subId)) {
- return true;
- }
- // else the calling package is not authorized to access the device identifiers; call
- // a central method to report the failure based on the target SDK and if the calling package
- // has the READ_PHONE_STATE permission or carrier privileges that were previously required
- // to access the identifiers.
- return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
- message);
+ return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId,
+ Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
}
/**
@@ -298,7 +274,7 @@ public final class TelephonyPermissions {
* <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
- * access check, or the calling package has carrier privleges.
+ * access check, or the calling package has carrier privileges.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
@@ -309,19 +285,8 @@ public final class TelephonyPermissions {
*/
public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
String callingPackage, String message) {
- int pid = Binder.getCallingPid();
- int uid = Binder.getCallingUid();
- // if the device identifiers can be read then grant access to the subscriber identifiers
- if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
- return true;
- }
- // If the calling package has carrier privileges then allow access to the subscriber
- // identifiers.
- if (checkCarrierPrivilegeForSubId(subId)) {
- return true;
- }
- return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
- message);
+ return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId,
+ Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
}
/**
@@ -331,8 +296,10 @@ public final class TelephonyPermissions {
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier access
* check.
*/
- private static boolean checkReadDeviceIdentifiers(Context context, int pid, int uid,
- String callingPackage) {
+ @VisibleForTesting
+ public static boolean checkReadDeviceIdentifiers(Context context,
+ Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
+ String callingPackage, String message) {
// Allow system and root access to the device identifiers.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
@@ -343,31 +310,36 @@ public final class TelephonyPermissions {
uid) == PackageManager.PERMISSION_GRANTED) {
return true;
}
- // if the calling package is null then return now as there's no way to perform the
- // DevicePolicyManager device / profile owner and AppOp checks
- if (callingPackage == null) {
- return false;
+ // If the calling package has carrier privileges for any subscription then allow access.
+ if (checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid)) {
+ return true;
}
- // Allow access to an app that has been granted the READ_DEVICE_IDENTIFIERS app op.
- long token = Binder.clearCallingIdentity();
- AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(
- Context.APP_OPS_SERVICE);
- try {
- if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
- callingPackage) == AppOpsManager.MODE_ALLOWED) {
+ // if the calling package is not null then perform the DevicePolicyManager device /
+ // profile owner and Appop checks.
+ if (callingPackage != null) {
+ // Allow access to an app that has been granted the READ_DEVICE_IDENTIFIERS app op.
+ long token = Binder.clearCallingIdentity();
+ AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(
+ Context.APP_OPS_SERVICE);
+ try {
+ if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
+ callingPackage) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ // Allow access to a device / profile owner app.
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) context.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess(
+ callingPackage, pid, uid)) {
return true;
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
- // Allow access to a device / profile owner app.
- DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess(
- callingPackage, pid, uid)) {
- return true;
- }
- return false;
+ return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
+ message);
}
/**
@@ -403,10 +375,12 @@ public final class TelephonyPermissions {
try {
callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
callingPackage, 0, UserHandle.getUserId(uid));
- if (callingPackageInfo.isSystemApp()) {
- isPreinstalled = true;
- if (callingPackageInfo.isPrivilegedApp()) {
- isPrivApp = true;
+ if (callingPackageInfo != null) {
+ if (callingPackageInfo.isSystemApp()) {
+ isPreinstalled = true;
+ if (callingPackageInfo.isPrivilegedApp()) {
+ isPrivApp = true;
+ }
}
}
} catch (PackageManager.NameNotFoundException e) {
@@ -651,6 +625,26 @@ public final class TelephonyPermissions {
}
}
+ /**
+ * Returns whether the provided uid has carrier privileges for any active subscription ID.
+ */
+ private static boolean checkCarrierPrivilegeForAnySubId(Context context,
+ Supplier<ITelephony> telephonySupplier, int uid) {
+ SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ int[] activeSubIds = sm.getActiveSubscriptionIdList();
+ if (activeSubIds != null) {
+ for (int activeSubId : activeSubIds) {
+ if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
private static int getCarrierPrivilegeStatus(
Supplier<ITelephony> telephonySupplier, int subId, int uid) {
ITelephony telephony = telephonySupplier.get();
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index 07525a6ea49c..db1ccb446ce3 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -24,6 +24,7 @@ java_library {
"frameworks-net-testutils",
"junit",
"mockito-target-minus-junit4",
+ "platform-test-annotations",
],
libs: [
"android.test.base.stubs",
diff --git a/tests/net/common/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
index bef66b27df62..38bc744a0a06 100644
--- a/tests/net/common/java/android/net/NetworkTest.java
+++ b/tests/net/common/java/android/net/NetworkTest.java
@@ -25,6 +25,7 @@ import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.Network;
+import android.platform.test.annotations.AppModeFull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -74,6 +75,7 @@ public class NetworkTest {
}
@Test
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void testBindSocketOfConnectedDatagramSocketThrows() throws Exception {
final DatagramSocket mDgramSocket = new DatagramSocket(0, (InetAddress) Inet6Address.ANY);
mDgramSocket.connect((InetAddress) Inet6Address.LOOPBACK, 53);