21.0: more work

Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
Tavi 2024-05-20 17:45:07 -04:00
parent 26f1ce99a9
commit 07951955d3
No known key found for this signature in database
GPG Key ID: E599F62ECBAEAF2E
31 changed files with 3835 additions and 41 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: inthewaves <inthewaves@pm.me>
Date: Sat, 12 Sep 2020 22:28:34 +0300
Subject: [PATCH] support new special runtime permissions
Ported from 12: b294a2ce1d0d185dbc438ac3c06c90386d5f5949
---
.../PermissionManagerServiceImpl.java | 39 ++++++++++++++-----
1 file changed, 30 insertions(+), 9 deletions(-)
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 671e031b546b..8c51fec86a46 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -1406,7 +1406,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
// their permissions as always granted runtime ones since we need
// to keep the review required permission flag per user while an
// install permission's state is shared across all users.
- if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime() &&
+ !isSpecialRuntimePermission(permName)) {
return;
}
@@ -1449,7 +1450,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
+ " for package " + packageName);
}
- if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M &&
+ !isSpecialRuntimePermission(permName)) {
Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
return;
}
@@ -1592,7 +1594,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
// their permissions as always granted runtime ones since we need
// to keep the review required permission flag per user while an
// install permission's state is shared across all users.
- if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime() &&
+ !isSpecialRuntimePermission(permName)) {
return;
}
@@ -1802,7 +1805,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
// permission as requiring a review as this is the initial state.
final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
- final int flags = (targetSdk < Build.VERSION_CODES.M && isRuntimePermission)
+ final int flags = (targetSdk < Build.VERSION_CODES.M && isRuntimePermission
+ && !isSpecialRuntimePermission(permName))
? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
: 0;
@@ -1822,7 +1826,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
// If this permission was granted by default or role, make sure it is.
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
- || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0) {
+ || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0
+ || isSpecialRuntimePermission(permName)) {
// PermissionPolicyService will handle the app op for runtime permissions later.
grantRuntimePermissionInternal(packageName, permName, false,
Process.SYSTEM_UID, userId, delayingPermCallback);
@@ -2471,6 +2476,10 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
}
+ public static boolean isSpecialRuntimePermission(final String permission) {
+ return false;
+ }
+
/**
* Restore the permission state for a package.
*
@@ -2593,6 +2602,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
synchronized (mLock) {
for (final int userId : userIds) {
final UserPermissionState userState = mState.getOrCreateUserState(userId);
+ // "replace" parameter is set to true even when the app is first installed
+ final boolean uidStateWasPresent = userState.getUidState(ps.getAppId()) != null;
final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId());
if (uidState.isMissing()) {
@@ -2609,7 +2620,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
}
- if (uidTargetSdkVersion < Build.VERSION_CODES.M) {
+ if (uidTargetSdkVersion < Build.VERSION_CODES.M && !isSpecialRuntimePermission(permissionName)) {
uidState.updatePermissionFlags(permission,
PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
| PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
@@ -2803,7 +2814,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
boolean restrictionApplied = (origState.getPermissionFlags(
bp.getName()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
- if (appSupportsRuntimePermissions) {
+ if (appSupportsRuntimePermissions || isSpecialRuntimePermission(bp.getName())) {
// If hard restricted we don't allow holding it
if (permissionPolicyInitialized && hardRestricted) {
if (!restrictionExempt) {
@@ -2856,6 +2867,16 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
}
}
+
+ if (isSpecialRuntimePermission(permName) &&
+ origPermState == null &&
+ // don't grant special runtime permission after update,
+ // unless app comes from the system image
+ (!uidStateWasPresent || ps.isSystem())) {
+ if (uidState.grantPermission(bp)) {
+ wasChanged = true;
+ }
+ }
} else {
if (origPermState == null) {
// New permission
@@ -2890,7 +2911,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
if (restrictionApplied) {
flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
// Dropping restriction on a legacy app implies a review
- if (!appSupportsRuntimePermissions) {
+ if (!appSupportsRuntimePermissions && !isSpecialRuntimePermission(bp.getName())) {
flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
}
wasChanged = true;
@@ -3608,7 +3629,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission,
myUid, userId);
if (shouldGrantRuntimePermission) {
- if (supportsRuntimePermissions) {
+ if (supportsRuntimePermissions || isSpecialRuntimePermission(permission)) {
// Installer cannot change immutable permissions.
if ((flags & immutableFlags) == 0) {
grantRuntimePermissionInternal(pkg.getPackageName(), permission, false,

View File

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Fri, 7 Oct 2022 20:12:26 +0300
Subject: [PATCH] srt permissions: don't auto-grant denied ones when
permissions are reset
---
.../server/pm/permission/PermissionManagerServiceImpl.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 9d91fbc0be74..b771b6ba1726 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -1827,7 +1827,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
// If this permission was granted by default or role, make sure it is.
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
|| (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0
- || isSpecialRuntimePermission(permName)) {
+ || (isSpecialRuntimePermission(permName)
+ && checkPermission(packageName, permName, userId) == PERMISSION_GRANTED)
+ ) {
// PermissionPolicyService will handle the app op for runtime permissions later.
grantRuntimePermissionInternal(packageName, permName, false,
Process.SYSTEM_UID, userId, delayingPermCallback);

View File

@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Micay <danielmicay@gmail.com>
Date: Sun, 17 Mar 2019 17:59:15 +0200
Subject: [PATCH] make INTERNET into a special runtime permission
Ported from 12: a980a4c3d6b6906eb0ee5fb07ca4cf0bae052d00
---
core/api/current.txt | 1 +
core/res/AndroidManifest.xml | 10 +++++++++-
core/res/res/values/strings.xml | 5 +++++
.../pm/permission/PermissionManagerServiceImpl.java | 2 +-
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/core/api/current.txt b/core/api/current.txt
index 9b5316fb79b5..ab1becbad01f 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -331,6 +331,7 @@ package android {
field public static final String LOCATION = "android.permission-group.LOCATION";
field public static final String MICROPHONE = "android.permission-group.MICROPHONE";
field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES";
+ field public static final String NETWORK = "android.permission-group.NETWORK";
field public static final String NOTIFICATIONS = "android.permission-group.NOTIFICATIONS";
field public static final String PHONE = "android.permission-group.PHONE";
field public static final String READ_MEDIA_AURAL = "android.permission-group.READ_MEDIA_AURAL";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 22591641cc66..6536d86432b4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2054,13 +2054,21 @@
<!-- ======================================= -->
<eat-comment />
+ <!-- Network access -->
+ <permission-group android:name="android.permission-group.NETWORK"
+ android:icon="@drawable/perm_group_network"
+ android:label="@string/permgrouplab_network"
+ android:description="@string/permgroupdesc_network"
+ android:priority="900" />
+
<!-- Allows applications to open network sockets.
<p>Protection level: normal
-->
<permission android:name="android.permission.INTERNET"
+ android:permissionGroup="android.permission-group.UNDEFINED"
android:description="@string/permdesc_createNetworkSockets"
android:label="@string/permlab_createNetworkSockets"
- android:protectionLevel="normal|instant" />
+ android:protectionLevel="dangerous|instant" />
<!-- Allows applications to access information about networks.
<p>Protection level: normal
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4596ca74bf8f..5fe90e5510f5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -946,6 +946,11 @@
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
<string name="permgroupdesc_notifications">show notifications</string>
+ <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permgrouplab_network">Network</string>
+ <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permgroupdesc_network">access the network</string>
+
<!-- Title for the capability of an accessibility service to retrieve window content. -->
<string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
<!-- Description for the capability of an accessibility service to retrieve window content. -->
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 8c51fec86a46..ad63a2d19779 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2477,7 +2477,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
public static boolean isSpecialRuntimePermission(final String permission) {
- return false;
+ return Manifest.permission.INTERNET.equals(permission);
}
/**

View File

@ -0,0 +1,113 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Micay <danielmicay@gmail.com>
Date: Sat, 7 Oct 2017 22:54:42 +0300
Subject: [PATCH] add special runtime permission for other sensors
Ported from 12: 9d5a62ed573bc3c7be8b19445b372fed13533d0e
---
core/api/current.txt | 2 ++
.../internal/pm/pkg/parsing/ParsingPackageUtils.java | 2 ++
core/res/AndroidManifest.xml | 12 ++++++++++++
core/res/res/values/strings.xml | 12 ++++++++++++
.../pm/permission/PermissionManagerServiceImpl.java | 2 +-
5 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/core/api/current.txt b/core/api/current.txt
index ab1becbad01f..2f251c8a7755 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -220,6 +220,7 @@ package android {
field public static final String NFC = "android.permission.NFC";
field public static final String NFC_PREFERRED_PAYMENT_INFO = "android.permission.NFC_PREFERRED_PAYMENT_INFO";
field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
+ field public static final String OTHER_SENSORS = "android.permission.OTHER_SENSORS";
field public static final String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
field public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
@@ -333,6 +334,7 @@ package android {
field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES";
field public static final String NETWORK = "android.permission-group.NETWORK";
field public static final String NOTIFICATIONS = "android.permission-group.NOTIFICATIONS";
+ field public static final String OTHER_SENSORS = "android.permission-group.OTHER_SENSORS";
field public static final String PHONE = "android.permission-group.PHONE";
field public static final String READ_MEDIA_AURAL = "android.permission-group.READ_MEDIA_AURAL";
field public static final String READ_MEDIA_VISUAL = "android.permission-group.READ_MEDIA_VISUAL";
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index dbe4fba5dfdb..f71bbec1a8ad 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -2321,6 +2321,8 @@ public class ParsingPackageUtils {
setSupportsSizeChanges(pkg);
pkg.setHasDomainUrls(hasDomainURLs(pkg));
+
+ pkg.addUsesPermission(new ParsedUsesPermissionImpl(android.Manifest.permission.OTHER_SENSORS, 0));
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6536d86432b4..84a53173be9f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1815,6 +1815,18 @@
android:protectionLevel="dangerous|instant" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+ <permission-group android:name="android.permission-group.OTHER_SENSORS"
+ android:icon="@drawable/perm_group_location"
+ android:label="@string/permgrouplab_otherSensors"
+ android:description="@string/permgroupdesc_otherSensors"
+ android:priority="1000" />
+
+ <permission android:name="android.permission.OTHER_SENSORS"
+ android:permissionGroup="android.permission-group.UNDEFINED"
+ android:label="@string/permlab_otherSensors"
+ android:description="@string/permdesc_otherSensors"
+ android:protectionLevel="dangerous" />
+
<!-- ====================================================================== -->
<!-- REMOVED PERMISSIONS -->
<!-- ====================================================================== -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5fe90e5510f5..fe69b195ea4c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -946,6 +946,11 @@
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
<string name="permgroupdesc_notifications">show notifications</string>
+ <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permgrouplab_otherSensors">Sensors</string>
+ <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permgroupdesc_otherSensors">access sensor data about orientation, movement, etc.</string>
+
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_network">Network</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1361,6 +1366,13 @@
<!-- Description of the background body sensors permission, listed so the user can decide whether to allow the application to access data from body sensors in the background. [CHAR LIMIT=NONE] -->
<string name="permdesc_bodySensors_background" product="default">Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background.</string>
+ <!-- Title of the sensors permission, listed so the user can decide whether to allow the application to access sensor data. [CHAR LIMIT=80] -->
+ <string name="permlab_otherSensors">access sensors (like the compass)
+ </string>
+ <!-- Description of the sensors permission, listed so the user can decide whether to allow the application to access data from sensors. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_otherSensors" product="default">Allows the app to access data from sensors
+ monitoring orientation, movement, vibration (including low frequency sound) and environmental data</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCalendar">Read calendar events and details</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index ad63a2d19779..9d91fbc0be74 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2477,7 +2477,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
public static boolean isSpecialRuntimePermission(final String permission) {
- return Manifest.permission.INTERNET.equals(permission);
+ return Manifest.permission.INTERNET.equals(permission) || Manifest.permission.OTHER_SENSORS.equals(permission);
}
/**

View File

@ -0,0 +1,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 18:24:34 +0300
Subject: [PATCH] infrastructure for spoofing self permission checks
---
.../app/ApplicationPackageManager.java | 13 ++++++++-
core/java/android/app/ContextImpl.java | 18 ++++++++++--
.../content/pm/AppPermissionUtils.java | 29 +++++++++++++++++++
3 files changed, 57 insertions(+), 3 deletions(-)
create mode 100644 core/java/android/content/pm/AppPermissionUtils.java
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d1694013ae52..d90f463779ef 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -47,6 +47,7 @@ import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApkChecksum;
+import android.content.pm.AppPermissionUtils;
import android.content.pm.ApplicationInfo;
import android.content.pm.ArchivedPackageInfo;
import android.content.pm.ChangedPackages;
@@ -847,8 +848,18 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public int checkPermission(String permName, String pkgName) {
- return PermissionManager.checkPackageNamePermission(permName, pkgName,
+ int res = PermissionManager.checkPackageNamePermission(permName, pkgName,
mContext.getDeviceId(), getUserId());
+
+ if (res != PERMISSION_GRANTED) {
+ if (pkgName.equals(ActivityThread.currentPackageName())
+ && AppPermissionUtils.shouldSpoofSelfCheck(permName))
+ {
+ return PERMISSION_GRANTED;
+ }
+ }
+
+ return res;
}
@Override
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 014ddd41f8d4..f4e5f2959b87 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -48,6 +48,7 @@ import android.content.ReceiverCallNotAllowedException;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
+import android.content.pm.AppPermissionUtils;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -2258,12 +2259,25 @@ class ContextImpl extends Context {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
+
+ final boolean selfCheck = pid == android.os.Process.myPid() && uid == android.os.Process.myUid();
+
if (mParams.isRenouncedPermission(permission)
- && pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) {
+ && selfCheck) {
Log.v(TAG, "Treating renounced permission " + permission + " as denied");
return PERMISSION_DENIED;
}
- return PermissionManager.checkPermission(permission, pid, uid, getDeviceId());
+ int res = PermissionManager.checkPermission(permission, pid, uid, getDeviceId());
+
+ if (res != PERMISSION_GRANTED) {
+ if (selfCheck) {
+ if (AppPermissionUtils.shouldSpoofSelfCheck(permission)) {
+ return PERMISSION_GRANTED;
+ }
+ }
+ }
+
+ return res;
}
/** @hide */
diff --git a/core/java/android/content/pm/AppPermissionUtils.java b/core/java/android/content/pm/AppPermissionUtils.java
new file mode 100644
index 000000000000..7dc20eec8485
--- /dev/null
+++ b/core/java/android/content/pm/AppPermissionUtils.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 GrapheneOS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.Manifest;
+
+/** @hide */
+public class AppPermissionUtils {
+
+ // android.app.ApplicationPackageManager#checkPermission(String permName, String pkgName)
+ // android.app.ContextImpl#checkPermission(String permission, int pid, int uid)
+ public static boolean shouldSpoofSelfCheck(String permName) {
+ return false;
+ }
+}

View File

@ -0,0 +1,191 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 18:10:28 +0300
Subject: [PATCH] app-side infrastructure for special runtime permissions
---
core/api/system-current.txt | 3 ++
.../android/content/pm/IPackageManager.aidl | 2 +
.../pm/SpecialRuntimePermAppUtils.java | 54 +++++++++++++++++++
.../server/pm/PackageManagerService.java | 19 +++++++
.../permission/SpecialRuntimePermUtils.java | 46 ++++++++++++++++
5 files changed, 124 insertions(+)
create mode 100644 core/java/android/content/pm/SpecialRuntimePermAppUtils.java
create mode 100644 services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e92564b5d7c2..38e4b74acc38 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4175,6 +4175,9 @@ package android.content.pm {
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ShortcutManager.ShareShortcutInfo> CREATOR;
}
+ public class SpecialRuntimePermAppUtils {
+ }
+
public final class SuspendDialogInfo implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 6dc8d4738c87..6acfeded7760 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -832,6 +832,8 @@ interface IPackageManager {
boolean[] canPackageQuery(String sourcePackageName, in String[] targetPackageNames, int userId);
+ int getSpecialRuntimePermissionFlags(String packageName);
+
boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler);
void registerPackageMonitorCallback(IRemoteCallback callback, int userId);
diff --git a/core/java/android/content/pm/SpecialRuntimePermAppUtils.java b/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
new file mode 100644
index 000000000000..efd48cb49aa3
--- /dev/null
+++ b/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 GrapheneOS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.Manifest;
+import android.annotation.SystemApi;
+import android.app.AppGlobals;
+import android.os.Binder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.permission.PermissionManager;
+
+/** @hide */
+@SystemApi
+public class SpecialRuntimePermAppUtils {
+ private static final int FLAG_INITED = 1;
+
+ private static volatile int cachedFlags;
+
+ private static int getFlags() {
+ int cache = cachedFlags;
+ if (cache != 0) {
+ return cache;
+ }
+
+ IPackageManager pm = AppGlobals.getPackageManager();
+ String pkgName = AppGlobals.getInitialPackage();
+
+ final long token = Binder.clearCallingIdentity(); // in case this method is called in the system_server
+ try {
+ return (cachedFlags = pm.getSpecialRuntimePermissionFlags(pkgName) | FLAG_INITED);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private SpecialRuntimePermAppUtils() {}
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7798790c1026..7117861d2d16 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -229,6 +229,7 @@ import com.android.server.pm.permission.LegacyPermissionManagerService;
import com.android.server.pm.permission.LegacyPermissionSettings;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.SpecialRuntimePermUtils;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.ArchiveState;
import com.android.server.pm.pkg.PackageState;
@@ -6535,6 +6536,24 @@ public class PackageManagerService implements PackageSender, TestUtilityService
getPerUidReadTimeouts(snapshot), mSnapshotStatistics
).doDump(snapshot, fd, pw, args);
}
+
+ @Override
+ public int getSpecialRuntimePermissionFlags(String packageName) {
+ final int callingUid = Binder.getCallingUid();
+
+ synchronized (mLock) {
+ AndroidPackage pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ throw new IllegalStateException();
+ }
+
+ if (UserHandle.getAppId(callingUid) != pkg.getUid()) { // getUid() confusingly returns appId
+ throw new SecurityException();
+ }
+
+ return SpecialRuntimePermUtils.getFlags(pkg);
+ }
+ }
}
private class PackageManagerInternalImpl extends PackageManagerInternalBase {
diff --git a/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java b/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
new file mode 100644
index 000000000000..fe946ff5d5ca
--- /dev/null
+++ b/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 GrapheneOS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.permission;
+
+import android.Manifest;
+import android.os.Bundle;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.component.ParsedUsesPermission;
+
+import static android.content.pm.SpecialRuntimePermAppUtils.*;
+
+public class SpecialRuntimePermUtils {
+
+ @GuardedBy("PackageManagerService.mLock")
+ public static int getFlags(AndroidPackage pkg) {
+ int flags = 0;
+
+ for (ParsedUsesPermission perm : pkg.getUsesPermissions()) {
+ String name = perm.getName();
+ switch (name) {
+ default:
+ continue;
+ }
+ }
+
+ return flags;
+ }
+
+ private SpecialRuntimePermUtils() {}
+}

View File

@ -0,0 +1,165 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 18:00:35 +0300
Subject: [PATCH] improve compatibility of INTERNET special runtime permission
There are apps that refuse to work when they detect that INTERNET is revoked, usually because of
a library check that reminds the app developer to add INTERNET uses-permission element to app's
AndroidManifest.
Always report that INTERNET is granted unless the app has
<meta-data android:name="android.permission.INTERNET.mode" android:value="runtime" />
declaration inside <application> element in its AndroidManifest, or is a system app.
---
core/api/system-current.txt | 5 +++++
core/java/android/app/DownloadManager.java | 13 ++++++++++++
.../content/pm/AppPermissionUtils.java | 7 +++++++
.../pm/SpecialRuntimePermAppUtils.java | 20 +++++++++++++++++++
.../permission/SpecialRuntimePermUtils.java | 17 ++++++++++++++++
5 files changed, 62 insertions(+)
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 38e4b74acc38..d7461cbb5be3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4176,6 +4176,11 @@ package android.content.pm {
}
public class SpecialRuntimePermAppUtils {
+ method public static boolean awareOfRuntimeInternetPermission();
+ method public static boolean isInternetCompatEnabled();
+ method public static boolean requestsInternetPermission();
+ field public static final int FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION = 4; // 0x4
+ field public static final int FLAG_REQUESTS_INTERNET_PERMISSION = 2; // 0x2
}
public final class SuspendDialogInfo implements android.os.Parcelable {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index de0244f3934f..6285f4745c37 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -34,6 +34,7 @@ import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.DatabaseUtils;
+import android.database.MatrixCursor;
import android.net.ConnectivityManager;
import android.net.NetworkPolicyManager;
import android.net.Uri;
@@ -53,6 +54,8 @@ import android.util.LongSparseArray;
import android.util.Pair;
import android.webkit.MimeTypeMap;
+import android.content.pm.SpecialRuntimePermAppUtils;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -1124,6 +1127,11 @@ public class DownloadManager {
* future calls related to this download. Returns -1 if the operation fails.
*/
public long enqueue(Request request) {
+ if (SpecialRuntimePermAppUtils.isInternetCompatEnabled()) {
+ // invalid id (DownloadProvider uses SQLite and returns a row id)
+ return -1;
+ }
+
ContentValues values = request.toContentValues(mPackageName);
Uri downloadUri = mResolver.insert(Downloads.Impl.CONTENT_URI, values);
if (downloadUri == null) {
@@ -1176,6 +1184,11 @@ public class DownloadManager {
/** @hide */
public Cursor query(Query query, String[] projection) {
+ if (SpecialRuntimePermAppUtils.isInternetCompatEnabled()) {
+ // underlying provider is protected by the INTERNET permission
+ return new MatrixCursor(projection);
+ }
+
Cursor underlyingCursor = query.runQuery(mResolver, projection, mBaseUri);
if (underlyingCursor == null) {
return null;
diff --git a/core/java/android/content/pm/AppPermissionUtils.java b/core/java/android/content/pm/AppPermissionUtils.java
index 7dc20eec8485..6a96f70dcfcf 100644
--- a/core/java/android/content/pm/AppPermissionUtils.java
+++ b/core/java/android/content/pm/AppPermissionUtils.java
@@ -24,6 +24,13 @@ public class AppPermissionUtils {
// android.app.ApplicationPackageManager#checkPermission(String permName, String pkgName)
// android.app.ContextImpl#checkPermission(String permission, int pid, int uid)
public static boolean shouldSpoofSelfCheck(String permName) {
+ if (Manifest.permission.INTERNET.equals(permName)
+ && SpecialRuntimePermAppUtils.requestsInternetPermission()
+ && !SpecialRuntimePermAppUtils.awareOfRuntimeInternetPermission())
+ {
+ return true;
+ }
+
return false;
}
}
diff --git a/core/java/android/content/pm/SpecialRuntimePermAppUtils.java b/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
index efd48cb49aa3..2f973a585d5c 100644
--- a/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
+++ b/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
@@ -28,9 +28,29 @@ import android.permission.PermissionManager;
@SystemApi
public class SpecialRuntimePermAppUtils {
private static final int FLAG_INITED = 1;
+ public static final int FLAG_REQUESTS_INTERNET_PERMISSION = 1 << 1;
+ public static final int FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION = 1 << 2;
private static volatile int cachedFlags;
+ private static boolean hasInternetPermission() {
+ // checkSelfPermission() is spoofed, query the underlying API directly
+ return PermissionManager.checkPermission(Manifest.permission.INTERNET, Process.myPid(), Process.myUid())
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static boolean requestsInternetPermission() {
+ return (getFlags() & FLAG_REQUESTS_INTERNET_PERMISSION) != 0;
+ }
+
+ public static boolean awareOfRuntimeInternetPermission() {
+ return (getFlags() & FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION) != 0;
+ }
+
+ public static boolean isInternetCompatEnabled() {
+ return !hasInternetPermission() && requestsInternetPermission() && !awareOfRuntimeInternetPermission();
+ }
+
private static int getFlags() {
int cache = cachedFlags;
if (cache != 0) {
diff --git a/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java b/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
index fe946ff5d5ca..6f5cabb8a8fc 100644
--- a/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
+++ b/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
@@ -34,11 +34,28 @@ public class SpecialRuntimePermUtils {
for (ParsedUsesPermission perm : pkg.getUsesPermissions()) {
String name = perm.getName();
switch (name) {
+ case Manifest.permission.INTERNET:
+ flags |= FLAG_REQUESTS_INTERNET_PERMISSION;
+ continue;
default:
continue;
}
}
+ if ((flags & FLAG_REQUESTS_INTERNET_PERMISSION) != 0) {
+ if (pkg.isSystem()) {
+ flags |= FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION;
+ } else {
+ Bundle metadata = pkg.getMetaData();
+ if (metadata != null) {
+ String key = Manifest.permission.INTERNET + ".mode";
+ if ("runtime".equals(metadata.getString(key))) {
+ flags |= FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION;
+ }
+ }
+ }
+ }
+
return flags;
}

View File

@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Wed, 17 Aug 2022 10:12:42 +0300
Subject: [PATCH] mark UserHandle#get{Uid, UserId} as module SystemApi
Needed by packages_modules_Connectivity ->
"enforce INTERNET permission per-uid instead of per-appId".
---
core/api/module-lib-current.txt | 5 +++++
core/java/android/os/UserHandle.java | 2 ++
2 files changed, 7 insertions(+)
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 190fe9f31f3c..3156a91765ac 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -467,6 +467,11 @@ package android.os {
field public static final long TRACE_TAG_NETWORK = 2097152L; // 0x200000L
}
+ public final class UserHandle implements android.os.Parcelable {
+ method public static int getUid(int, int);
+ method public static int getUserId(int);
+ }
+
}
package android.os.storage {
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 0644ef1c788f..2804035aef7b 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -281,6 +281,7 @@ public final class UserHandle implements Parcelable {
* Returns the user id for a given uid.
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@UnsupportedAppUsage
@TestApi
public static @UserIdInt int getUserId(int uid) {
@@ -371,6 +372,7 @@ public final class UserHandle implements Parcelable {
* Returns the uid that is composed from the userId and the appId.
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@UnsupportedAppUsage
@TestApi
public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Tue, 30 Aug 2022 12:37:03 +0300
Subject: [PATCH] improve compatibility with revoked INTERNET in
DownloadManager
---
core/java/android/app/DownloadManager.java | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 6285f4745c37..ffc722279da1 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1169,6 +1169,11 @@ public class DownloadManager {
* @return the number of downloads actually removed
*/
public int remove(long... ids) {
+ if (SpecialRuntimePermAppUtils.isInternetCompatEnabled()) {
+ // underlying provider is protected by the INTERNET permission
+ return 0;
+ }
+
return markRowDeleted(ids);
}
@@ -1595,6 +1600,11 @@ public class DownloadManager {
throw new IllegalArgumentException(" invalid value for param: totalBytes");
}
+ if (SpecialRuntimePermAppUtils.isInternetCompatEnabled()) {
+ // underlying provider is protected by the INTERNET permission
+ return -1;
+ }
+
// if there is already an entry with the given path name in downloads.db, return its id
Request request;
if (uri != null) {

View File

@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Thu, 15 Sep 2022 13:58:34 +0300
Subject: [PATCH] ignore pid when spoofing permission checks
Permissions are enforced per-uid, checking pid may break spoofing for multi-process apps.
---
core/java/android/app/ContextImpl.java | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f4e5f2959b87..932c79e5bf7c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2259,18 +2259,16 @@ class ContextImpl extends Context {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
-
- final boolean selfCheck = pid == android.os.Process.myPid() && uid == android.os.Process.myUid();
-
if (mParams.isRenouncedPermission(permission)
- && selfCheck) {
+ && pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) {
Log.v(TAG, "Treating renounced permission " + permission + " as denied");
return PERMISSION_DENIED;
}
+
int res = PermissionManager.checkPermission(permission, pid, uid, getDeviceId());
if (res != PERMISSION_GRANTED) {
- if (selfCheck) {
+ if (uid == android.os.Process.myUid()) {
if (AppPermissionUtils.shouldSpoofSelfCheck(permission)) {
return PERMISSION_GRANTED;
}

View File

@ -0,0 +1,153 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: anupritaisno1 <www.anuprita804@gmail.com>
Date: Mon, 18 Oct 2021 01:35:40 +0300
Subject: [PATCH] automatically reboot device after timeout if set
Signed-off-by: anupritaisno1 <www.anuprita804@gmail.com>
Change-Id: If891bfbcc144c9336ba013260bad2b7c7a59c054
---
core/java/android/provider/Settings.java | 7 ++++
data/etc/com.android.systemui.xml | 1 +
packages/SystemUI/AndroidManifest.xml | 3 ++
.../keyguard/KeyguardViewMediator.java | 35 +++++++++++++++++++
4 files changed, 46 insertions(+)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 64e39f5001f0..ec292016d3db 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -18673,6 +18673,13 @@ public final class Settings {
public static final String REVIEW_PERMISSIONS_NOTIFICATION_STATE =
"review_permissions_notification_state";
+ /**
+ * Whether to automatically reboot the device after a user defined timeout
+ *
+ * @hide
+ */
+ public static final String SETTINGS_REBOOT_AFTER_TIMEOUT = "settings_reboot_after_timeout";
+
/**
* Whether repair mode is active on the device.
* <p>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 43683ffad432..499d39e0c5cf 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -54,6 +54,7 @@
<permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
<permission name="android.permission.READ_WALLPAPER_INTERNAL"/>
<permission name="android.permission.REAL_GET_TASKS"/>
+ <permission name="android.permission.REBOOT"/>
<permission name="android.permission.REQUEST_NETWORK_SCORES"/>
<permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
<permission name="android.permission.SET_WALLPAPER_DIM_AMOUNT"/>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6f86f4e83623..3770d9530d5b 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -348,6 +348,9 @@
<uses-permission android:name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" />
+ <!-- Permission to allow rebooting the device after a user configurable amount of time -->
+ <uses-permission android:name="android.permission.REBOOT" />
+
<uses-permission android:name="android.permission.MONITOR_KEYBOARD_BACKLIGHT" />
<!-- Listen to (dis-)connection of external displays and enable / disable them. -->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 81856ac16575..dafa9bf8a9a3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -238,6 +238,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private final static String TAG = "KeyguardViewMediator";
+ private static final String DELAYED_REBOOT_ACTION =
+ "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_REBOOT";
public static final String DELAYED_KEYGUARD_ACTION =
"com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
private static final String DELAYED_LOCK_PROFILE_ACTION =
@@ -411,6 +413,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
*/
private int mDelayedProfileShowingSequence;
+ /**
+ * Same as {@link #mDelayedProfileShowingSequence}, but used for our reboot implementation
+ */
+ private int mDelayedRebootSequence;
+
private final DismissCallbackRegistry mDismissCallbackRegistry;
// the properties of the keyguard
@@ -1495,6 +1502,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
final IntentFilter delayedActionFilter = new IntentFilter();
delayedActionFilter.addAction(DELAYED_KEYGUARD_ACTION);
delayedActionFilter.addAction(DELAYED_LOCK_PROFILE_ACTION);
+ delayedActionFilter.addAction(DELAYED_REBOOT_ACTION);
delayedActionFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
SYSTEMUI_PERMISSION, null /* scheduler */,
@@ -1866,6 +1874,18 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
}
+ private void doRebootForOwnerAfterTimeoutIfEnabled(long rebootAfterTimeout) {
+ long when = SystemClock.elapsedRealtime() + rebootAfterTimeout;
+ Intent rebootIntent = new Intent(DELAYED_REBOOT_ACTION);
+ rebootIntent.putExtra("seq", mDelayedRebootSequence);
+ rebootIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ PendingIntent sender = PendingIntent.getBroadcast(mContext,
+ 0, rebootIntent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
+ if (DEBUG) Log.d(TAG, "setting alarm to reboot device, timeout = "
+ + String.valueOf(rebootAfterTimeout));
+ }
+
private void doKeyguardForChildProfilesLocked() {
for (UserInfo profile : mUserTracker.getUserProfiles()) {
if (!profile.isEnabled()) continue;
@@ -1884,6 +1904,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mDelayedProfileShowingSequence++;
}
+ private void cancelDoRebootForOwnerAfterTimeoutIfEnabled() {
+ mDelayedRebootSequence++;
+ }
+
/**
* It will let us know when the device is waking up.
*/
@@ -2276,6 +2300,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked(options);
+ final long rebootAfterTimeout = Settings.Global.getLong(mContext.getContentResolver(), Settings.Global.SETTINGS_REBOOT_AFTER_TIMEOUT, 0);
+ if (rebootAfterTimeout >= 1) {
+ doRebootForOwnerAfterTimeoutIfEnabled(rebootAfterTimeout);
+ }
}
private void lockProfile(int userId) {
@@ -2455,6 +2483,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
}
}
+ } else if (DELAYED_REBOOT_ACTION.equals(intent.getAction())) {
+ final int sequence = intent.getIntExtra("seq", 0);
+ if (sequence == mDelayedRebootSequence) {
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ pm.reboot(null);
+ }
}
}
};
@@ -3164,6 +3198,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mHideAnimationRun = false;
adjustStatusBarLocked();
sendUserPresentBroadcast();
+ cancelDoRebootForOwnerAfterTimeoutIfEnabled();
}
private Configuration.Builder createInteractionJankMonitorConf(int cuj) {

View File

@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Tue, 6 Sep 2022 16:48:26 +0300
Subject: [PATCH] bugfix: Bluetooth auto turn off ignored connected BLE devices
Previous attempt at fixing this didn't work properly, because getConnectionStateLeAware() didn't
actually report BLE state.
---
.../android/server/ext/BluetoothAutoOff.java | 20 ++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/services/core/java/com/android/server/ext/BluetoothAutoOff.java b/services/core/java/com/android/server/ext/BluetoothAutoOff.java
index 4e7dbc042f37..a091b006214f 100644
--- a/services/core/java/com/android/server/ext/BluetoothAutoOff.java
+++ b/services/core/java/com/android/server/ext/BluetoothAutoOff.java
@@ -3,6 +3,7 @@ package com.android.server.ext;
import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -12,12 +13,14 @@ import android.provider.Settings;
import android.util.Slog;
class BluetoothAutoOff extends DelayedConditionalAction {
+ private final BluetoothManager manager;
@Nullable
private final BluetoothAdapter adapter;
BluetoothAutoOff(SystemServerExt sse) {
super(sse, sse.bgHandler);
- adapter = sse.context.getSystemService(BluetoothManager.class).getAdapter();
+ manager = sse.context.getSystemService(BluetoothManager.class);
+ adapter = manager.getAdapter();
}
@Override
@@ -51,11 +54,18 @@ class BluetoothAutoOff extends DelayedConditionalAction {
private boolean isAdapterOnAndDisconnected() {
if (adapter != null) {
- int state = adapter.getLeStateSysApi(); // getState() converts BLE states into STATE_OFF
+ if (adapter.isLeEnabled()) {
+ if (adapter.getConnectionState() == BluetoothAdapter.STATE_DISCONNECTED) {
+ // Bluetooth GATT Profile (Bluetooth LE) connection state is ignored
+ // by getConnectionState()
+ return manager.getConnectedDevices(BluetoothProfile.GATT).size() == 0;
+ }
+ }
- if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON) {
- // getConnectionState() converts BLE states into STATE_DISCONNECTED
- return adapter.getConnectionStateLeAware() == BluetoothAdapter.STATE_DISCONNECTED;
+ // isLeEnabled() currently implies isEnabled(), but check again anyway in case
+ // this changes in the future
+ if (adapter.isEnabled()) {
+ return adapter.getConnectionState() == BluetoothAdapter.STATE_DISCONNECTED;
}
}

View File

@ -0,0 +1,120 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 11:19:33 +0300
Subject: [PATCH] Bluetooth auto turn off
Co-authored-by: Pratyush <codelab@pratyush.dev>
---
core/java/android/provider/Settings.java | 6 ++
.../android/server/ext/BluetoothAutoOff.java | 69 +++++++++++++++++++
.../android/server/ext/SystemServerExt.java | 4 ++
3 files changed, 79 insertions(+)
create mode 100644 services/core/java/com/android/server/ext/BluetoothAutoOff.java
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c22d62c0d40c..9fae9911e2fc 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -18686,6 +18686,12 @@ public final class Settings {
*/
public static final String WIFI_OFF_TIMEOUT = "wifi_off_timeout";
+ /**
+ * The amount of time in milliseconds before a disconnected Bluetooth adapter is turned off
+ * @hide
+ */
+ public static final String BLUETOOTH_OFF_TIMEOUT = "bluetooth_off_timeout";
+
/**
* Whether repair mode is active on the device.
* <p>
diff --git a/services/core/java/com/android/server/ext/BluetoothAutoOff.java b/services/core/java/com/android/server/ext/BluetoothAutoOff.java
new file mode 100644
index 000000000000..4e7dbc042f37
--- /dev/null
+++ b/services/core/java/com/android/server/ext/BluetoothAutoOff.java
@@ -0,0 +1,69 @@
+package com.android.server.ext;
+
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+import android.provider.Settings;
+import android.util.Slog;
+
+class BluetoothAutoOff extends DelayedConditionalAction {
+ @Nullable
+ private final BluetoothAdapter adapter;
+
+ BluetoothAutoOff(SystemServerExt sse) {
+ super(sse, sse.bgHandler);
+ adapter = sse.context.getSystemService(BluetoothManager.class).getAdapter();
+ }
+
+ @Override
+ protected boolean shouldScheduleAlarm() {
+ return isAdapterOnAndDisconnected();
+ }
+
+ @Override
+ protected void alarmTriggered() {
+ if (isAdapterOnAndDisconnected()) {
+ adapter.disable();
+ }
+ }
+
+ @Override
+ protected void registerStateListener() {
+ IntentFilter f = new IntentFilter();
+ f.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ f.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
+
+ sse.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context broadcastContext, Intent intent) {
+ if (Build.isDebuggable()) {
+ Slog.d("BtAutoOff", "" + intent + ", extras " + intent.getExtras().deepCopy());
+ }
+ update();
+ }
+ }, f, handler);
+ }
+
+ private boolean isAdapterOnAndDisconnected() {
+ if (adapter != null) {
+ int state = adapter.getLeStateSysApi(); // getState() converts BLE states into STATE_OFF
+
+ if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON) {
+ // getConnectionState() converts BLE states into STATE_DISCONNECTED
+ return adapter.getConnectionStateLeAware() == BluetoothAdapter.STATE_DISCONNECTED;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ protected String getDelayGlobalSettingsKey() {
+ return Settings.Global.BLUETOOTH_OFF_TIMEOUT;
+ }
+}
diff --git a/services/core/java/com/android/server/ext/SystemServerExt.java b/services/core/java/com/android/server/ext/SystemServerExt.java
index 66350e2b7f74..3c341ed25f4e 100644
--- a/services/core/java/com/android/server/ext/SystemServerExt.java
+++ b/services/core/java/com/android/server/ext/SystemServerExt.java
@@ -53,6 +53,10 @@ public final class SystemServerExt {
if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI, 0)) {
new WifiAutoOff(this);
}
+
+ if (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH, 0)) {
+ new BluetoothAutoOff(this);
+ }
}
public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter, Handler handler) {

View File

@ -0,0 +1,231 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 10:06:14 +0300
Subject: [PATCH] infrastructure for system_server extensions
---
.../server/ext/DelayedConditionalAction.java | 135 ++++++++++++++++++
.../android/server/ext/SystemServerExt.java | 58 ++++++++
.../java/com/android/server/SystemServer.java | 2 +
3 files changed, 195 insertions(+)
create mode 100644 services/core/java/com/android/server/ext/DelayedConditionalAction.java
create mode 100644 services/core/java/com/android/server/ext/SystemServerExt.java
diff --git a/services/core/java/com/android/server/ext/DelayedConditionalAction.java b/services/core/java/com/android/server/ext/DelayedConditionalAction.java
new file mode 100644
index 000000000000..d72f302e9d42
--- /dev/null
+++ b/services/core/java/com/android/server/ext/DelayedConditionalAction.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2022 GrapheneOS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.ext;
+
+import android.app.AlarmManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Slog;
+
+/**
+ * Infrastructure for actions that:
+ * - happen after a user-configurable device-wide (Settings.Global) delay
+ * - need to be taken even when the device is in deep sleep
+ * - need to be rescheduled based on some listenable event
+ */
+public abstract class DelayedConditionalAction {
+ private static final String TAG = "DelayedConditionalAction";
+
+ protected final SystemServerExt sse;
+ protected final Thread thread;
+ protected final Handler handler;
+
+ protected final ContentResolver contentResolver;
+ protected final AlarmManager alarmManager;
+ private final AlarmManager.OnAlarmListener alarmListener;
+
+ protected DelayedConditionalAction(SystemServerExt sse, Handler handler) {
+ this.sse = sse;
+
+ Looper looper = handler.getLooper();
+ thread = looper.getThread();
+ this.handler = handler;
+
+ if (Build.isDebuggable()) {
+ if (thread != Thread.currentThread()) {
+ throw new IllegalStateException("all calls should happen on the same thread");
+ }
+ }
+
+ Context ctx = sse.context;
+ contentResolver = ctx.getContentResolver();
+ alarmManager = ctx.getSystemService(AlarmManager.class);
+
+ alarmListener = () -> {
+ if (delayDurationMillis() == 0) {
+ return;
+ }
+
+ alarmTriggered();
+ };
+
+ registerStateListener();
+
+ Uri delaySettingUri = Settings.Global.getUriFor(getDelayGlobalSettingsKey());
+
+ ContentObserver delayChangeListener = new ContentObserver(handler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+ };
+
+ contentResolver.registerContentObserver(delaySettingUri, false, delayChangeListener);
+ }
+
+ private boolean alarmScheduled;
+
+ protected final void update() {
+ final Thread curThread = Thread.currentThread();
+ if (curThread != thread) {
+ String msg = "update() called on an unknown thread " + curThread;
+ if (Build.isDebuggable()) {
+ throw new IllegalStateException(msg);
+ } else {
+ Slog.e(TAG, msg, new Throwable());
+ return;
+ }
+ }
+
+ if (alarmScheduled) {
+ alarmManager.cancel(alarmListener);
+ alarmScheduled = false;
+ }
+
+ if (!shouldScheduleAlarm()) {
+ return;
+ }
+
+ long delayMillis = delayDurationMillis();
+
+ if (delayMillis == 0) {
+ return;
+ }
+
+ final long triggerAt = SystemClock.elapsedRealtime() + delayMillis;
+ alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAt,
+ getClass().getName(), alarmListener, handler);
+ alarmScheduled = true;
+ }
+
+ private long delayDurationMillis() {
+ return Settings.Global.getLong(contentResolver, getDelayGlobalSettingsKey(), 0);
+ }
+
+ // Make sure to use the same Handler that is used for all other callbacks;
+ // call update() to reschedule / cancel the alarm
+ protected abstract void registerStateListener();
+
+ protected abstract boolean shouldScheduleAlarm();
+ protected abstract void alarmTriggered();
+
+ // android.provider.Settings.Global key
+ protected abstract String getDelayGlobalSettingsKey();
+}
diff --git a/services/core/java/com/android/server/ext/SystemServerExt.java b/services/core/java/com/android/server/ext/SystemServerExt.java
new file mode 100644
index 000000000000..83d895650473
--- /dev/null
+++ b/services/core/java/com/android/server/ext/SystemServerExt.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 GrapheneOS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.ext;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.os.Handler;
+
+import com.android.internal.os.BackgroundThread;
+import com.android.server.pm.PackageManagerService;
+
+public final class SystemServerExt {
+
+ public final Context context;
+ public final Handler bgHandler;
+ public final PackageManagerService packageManager;
+
+ private SystemServerExt(Context systemContext, PackageManagerService pm) {
+ context = systemContext;
+ bgHandler = BackgroundThread.getHandler();
+ packageManager = pm;
+ }
+
+ /*
+ Called after system server has completed its initialization,
+ but before any of the apps are started.
+
+ Call from com.android.server.SystemServer#startOtherServices(), at the end of lambda
+ that is passed into mActivityManagerService.systemReady()
+ */
+ public static void init(Context systemContext, PackageManagerService pm) {
+ SystemServerExt sse = new SystemServerExt(systemContext, pm);
+ sse.bgHandler.post(sse::initBgThread);
+ }
+
+ void initBgThread() {
+
+ }
+
+ public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter, Handler handler) {
+ context.registerReceiver(receiver, filter, null, handler);
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index fb36c0168172..308a0fdf7a8a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -3280,6 +3280,8 @@ public final class SystemServer implements Dumpable {
reportWtf("Triggering OdsignStatsLogger", e);
}
t.traceEnd();
+
+ com.android.server.ext.SystemServerExt.init(mSystemContext, mPackageManagerService);
}, t);
t.traceBegin("LockSettingsThirdPartyAppsStarted");

View File

@ -0,0 +1,128 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 10:06:14 +0300
Subject: [PATCH] Wi-Fi auto turn off
Co-authored-by: Pratyush <codelab@pratyush.dev>
---
core/java/android/provider/Settings.java | 6 ++
.../android/server/ext/SystemServerExt.java | 5 +-
.../com/android/server/ext/WifiAutoOff.java | 69 +++++++++++++++++++
3 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 services/core/java/com/android/server/ext/WifiAutoOff.java
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ec292016d3db..c22d62c0d40c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -18680,6 +18680,12 @@ public final class Settings {
*/
public static final String SETTINGS_REBOOT_AFTER_TIMEOUT = "settings_reboot_after_timeout";
+ /**
+ * The amount of time in milliseconds before a disconnected Wi-Fi adapter is turned off
+ * @hide
+ */
+ public static final String WIFI_OFF_TIMEOUT = "wifi_off_timeout";
+
/**
* Whether repair mode is active on the device.
* <p>
diff --git a/services/core/java/com/android/server/ext/SystemServerExt.java b/services/core/java/com/android/server/ext/SystemServerExt.java
index 83d895650473..66350e2b7f74 100644
--- a/services/core/java/com/android/server/ext/SystemServerExt.java
+++ b/services/core/java/com/android/server/ext/SystemServerExt.java
@@ -19,6 +19,7 @@ package com.android.server.ext;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.os.Handler;
import com.android.internal.os.BackgroundThread;
@@ -49,7 +50,9 @@ public final class SystemServerExt {
}
void initBgThread() {
-
+ if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI, 0)) {
+ new WifiAutoOff(this);
+ }
}
public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter, Handler handler) {
diff --git a/services/core/java/com/android/server/ext/WifiAutoOff.java b/services/core/java/com/android/server/ext/WifiAutoOff.java
new file mode 100644
index 000000000000..c7a3c05fe766
--- /dev/null
+++ b/services/core/java/com/android/server/ext/WifiAutoOff.java
@@ -0,0 +1,69 @@
+package com.android.server.ext;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.provider.Settings;
+import android.util.Slog;
+
+class WifiAutoOff extends DelayedConditionalAction {
+ private final WifiManager wifiManager;
+
+ WifiAutoOff(SystemServerExt sse) {
+ super(sse, sse.bgHandler);
+ wifiManager = sse.context.getSystemService(WifiManager.class);
+ }
+
+ @Override
+ protected boolean shouldScheduleAlarm() {
+ return isWifiEnabledAndNotConnected();
+ }
+
+ @Override
+ protected void alarmTriggered() {
+ if (isWifiEnabledAndNotConnected()) {
+ wifiManager.setWifiEnabled(false);
+ }
+ }
+
+ private boolean isWifiEnabledAndNotConnected() {
+ if (wifiManager.isWifiEnabled()) {
+ WifiInfo i = wifiManager.getConnectionInfo();
+ if (i == null) {
+ return true;
+ }
+ return i.getBSSID() == null;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void registerStateListener() {
+ IntentFilter f = new IntentFilter();
+ f.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ f.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ // ConnectivityManager APIs seem unfit for listening to Wi-Fi state specifically, they look
+ // to be higher level than that, eg VPN over Wi-Fi isn't considered to be a Wi-Fi connection
+ // by ConnectivityManager
+
+ sse.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Build.isDebuggable()) {
+ Slog.d("WifiAutoOff", "" + intent + ", extras " + intent.getExtras().deepCopy());
+ }
+ update();
+ }
+ }, f, handler);
+ }
+
+ @Override
+ protected String getDelayGlobalSettingsKey() {
+ return Settings.Global.WIFI_OFF_TIMEOUT;
+ }
+}

View File

@ -156,10 +156,10 @@ index c3b149a1e295..a47b82018377 100644
<Button
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4596ca74bf8f..c52255b62748 100644
index fe69b195ea4c..bca56dba6b76 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6363,4 +6363,6 @@ ul.</string>
@@ -6380,4 +6380,6 @@ ul.</string>
<!-- Communal profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
<string name="profile_label_communal">Communal</string>

View File

@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Fri, 10 Feb 2023 12:54:21 +0200
Subject: [PATCH] add a setting for forcibly disabling SUPL
Change-Id: I5c31c319d198f09ace493e601278f8224a259f05
---
core/java/android/provider/Settings.java | 9 +++++++++
.../server/location/gnss/GnssConfiguration.java | 14 ++++++++++++++
.../location/gnss/GnssLocationProvider.java | 15 +++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9fae9911e2fc..2544b7bcb7c8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -18680,6 +18680,15 @@ public final class Settings {
*/
public static final String SETTINGS_REBOOT_AFTER_TIMEOUT = "settings_reboot_after_timeout";
+ /**
+ * Force disable Secure User Plane Location (SUPL), 0 or 1.
+ * @hide
+ */
+ public static final String FORCE_DISABLE_SUPL = "force_disable_supl";
+
+ /** @hide */
+ public static final int FORCE_DISABLE_SUPL_DEFAULT = 0;
+
/**
* The amount of time in milliseconds before a disconnected Wi-Fi adapter is turned off
* @hide
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index 5ef89ad4269a..0192ed9de15b 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -19,11 +19,13 @@ package com.android.server.location.gnss;
import android.content.Context;
import android.os.PersistableBundle;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Slog;
import com.android.internal.util.FrameworkStatsLog;
@@ -289,6 +291,7 @@ public class GnssConfiguration {
*/
loadPropertiesFromGpsDebugConfig(mProperties, DEBUG_PROPERTIES_VENDOR_FILE);
loadPropertiesFromGpsDebugConfig(mProperties, DEBUG_PROPERTIES_SYSTEM_FILE);
+ applyConfigOverrides(mContext, mProperties);
mEsExtensionSec = getRangeCheckedConfigEsExtensionSec();
logConfigurations();
@@ -489,4 +492,15 @@ public class GnssConfiguration {
private static native boolean native_set_satellite_blocklist(int[] constellations, int[] svIds);
private static native boolean native_set_es_extension_sec(int emergencyExtensionSeconds);
+
+ private static void applyConfigOverrides(Context ctx, Properties props) {
+ String key = Settings.Global.FORCE_DISABLE_SUPL;
+ int def = Settings.Global.FORCE_DISABLE_SUPL_DEFAULT;
+ if (Settings.Global.getInt(ctx.getContentResolver(), key, def) == 1) {
+ props.setProperty(CONFIG_SUPL_MODE, "0");
+ Slog.d(TAG, "SUPL is force disabled");
+ } else {
+ Slog.d(TAG, "SUPL is not force disabled");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index af7dcc7d917a..d4706d9da0a8 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -103,6 +103,7 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
+import android.util.Slog;
import android.util.Pair;
import android.util.TimeUtils;
@@ -489,6 +490,20 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
mGnssNative.setNotificationCallbacks(this);
mGnssNative.setLocationRequestCallbacks(this);
mGnssNative.setTimeCallbacks(this);
+
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.FORCE_DISABLE_SUPL),
+ false, new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ var cr = mContext.getContentResolver();
+ String key = Settings.Global.FORCE_DISABLE_SUPL;
+ int def = Settings.Global.FORCE_DISABLE_SUPL_DEFAULT;
+
+ Slog.d(TAG, "FORCE_DISABLE_SUPL changed, value: " + Settings.Global.getInt(cr, key, def));
+ mGnssConfiguration.reloadGpsProperties();
+ }
+ });
}
/** Called when system is ready. */

View File

@ -1,4 +1,4 @@
From 51fe11d1639de60bafebc32e6b77428eb0b2628e Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Thu, 7 Jul 2022 09:28:40 +0300
Subject: [PATCH] DeviceIdleJobsController: don't ignore whitelisted system
@ -65,7 +65,7 @@ diff --git a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInter
index caf7e7f4a4ed..1b1d2252dae1 100644
--- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
@@ -73,7 +73,7 @@ void addPowerSaveTempWhitelistAppDirect(int uid, long duration,
@@ -73,7 +73,7 @@ public interface DeviceIdleInternal {
boolean isAppOnWhitelist(int appid);
@ -78,7 +78,7 @@ diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleControl
index 6383ed873e59..f5289001cc32 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -2375,14 +2375,14 @@ public boolean isAppOnWhitelist(int appid) {
@@ -2375,14 +2375,14 @@ public class DeviceIdleController extends SystemService
}
/**
@ -100,7 +100,7 @@ diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/D
index d5c9ae615486..9e3ebb9cf6bc 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -90,7 +90,7 @@ public void onReceive(Context context, Intent intent) {
@@ -90,7 +90,7 @@ public final class DeviceIdleJobsController extends StateController {
case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
synchronized (mLock) {
mDeviceIdleWhitelistAppIds =
@ -109,7 +109,7 @@ index d5c9ae615486..9e3ebb9cf6bc 100644
if (DEBUG) {
Slog.d(TAG, "Got whitelist "
+ Arrays.toString(mDeviceIdleWhitelistAppIds));
@@ -133,7 +133,7 @@ public DeviceIdleJobsController(JobSchedulerService service) {
@@ -133,7 +133,7 @@ public final class DeviceIdleJobsController extends StateController {
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mLocalDeviceIdleController =
LocalServices.getService(DeviceIdleInternal.class);
@ -118,7 +118,7 @@ index d5c9ae615486..9e3ebb9cf6bc 100644
mPowerSaveTempWhitelistAppIds =
mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
mDeviceIdleUpdateFunctor = new DeviceIdleUpdateFunctor();
@@ -194,7 +194,7 @@ public void setUidActiveLocked(int uid, boolean active) {
@@ -194,7 +194,7 @@ public final class DeviceIdleJobsController extends StateController {
}
/**

View File

@ -0,0 +1,254 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tad <tad@spotco.us>
Date: Mon, 3 Jul 2023 12:00:12 -0400
Subject: [PATCH] Unprivileged microG handling
- Must be enabled by user
- Must match microG package ID
- Must meet minimum respective targetSdk and versionCode
- Must match official microG build signing key
- Only spoofs the Google package signature
- Sets the packages forceQueryable
- Spoofs apps installed via some sources as Play Store
This is an effective merge + tweak of two existing patches, credits:
Dylanger Daly
https://github.com/dylangerdaly/platform_frameworks_base/commit/b58aa11631fadab3309a1d9268118bd9f2c2a79f
Chirayu Desai of CalyxOS
https://gitlab.com/CalyxOS/platform_frameworks_base/-/commit/76485abb36dc01b65506b010d0458e96e0116369
https://gitlab.com/CalyxOS/platform_frameworks_base/-/commit/97765782f942d0975c383c90fde9140ef3ccf01b
https://gitlab.com/CalyxOS/platform_frameworks_base/-/commit/d81763383588e81353e24ad0a56ae2478752319c
https://gitlab.com/CalyxOS/platform_frameworks_base/-/commit/91c8aeb75ed737b004f6e38b1bc6664a219beb47
Change-Id: I64a252aac9bb196a11ed7b4b5d8c7e59a3413bd4
---
.../android/content/pm/SigningDetails.java | 36 +++++++++-
core/res/res/values/config.xml | 2 +
.../com/android/server/pm/AppsFilterImpl.java | 17 +++++
.../com/android/server/pm/ComputerEngine.java | 70 +++++++++++++++++--
4 files changed, 118 insertions(+), 7 deletions(-)
diff --git a/core/java/android/content/pm/SigningDetails.java b/core/java/android/content/pm/SigningDetails.java
index 8c2197470a8b..03fabcd21ffd 100644
--- a/core/java/android/content/pm/SigningDetails.java
+++ b/core/java/android/content/pm/SigningDetails.java
@@ -798,6 +798,38 @@ public final class SigningDetails implements Parcelable {
return false;
}
+ /**
+ * Return the Cerificate's Digest
+ */
+ public @Nullable String getSha256Certificate() {
+ return getSha256CertificateInternal();
+ }
+
+ private @Nullable String getSha256CertificateInternal() {
+ String digest;
+ if (this == UNKNOWN) {
+ return null;
+ }
+ if (hasPastSigningCertificates()) {
+
+ // check all past certs, except for the last one, which automatically gets all
+ // capabilities, since it is the same as the current signature, and is checked below
+ for (int i = 0; i < mPastSigningCertificates.length - 1; i++) {
+ digest = PackageUtils.computeSha256Digest(
+ mPastSigningCertificates[i].toByteArray());
+ return digest;
+ }
+ }
+
+ // not in previous certs signing history, just check the current signer
+ if (mSignatures.length == 1) {
+ digest =
+ PackageUtils.computeSha256Digest(mSignatures[0].toByteArray());
+ return digest;
+ }
+ return null;
+ }
+
/** Returns true if the signatures in this and other match exactly. */
public boolean signaturesMatchExactly(@NonNull SigningDetails other) {
return Signature.areExactMatch(this, other);
@@ -1003,10 +1035,10 @@ public final class SigningDetails implements Parcelable {
}
@DataClass.Generated(
- time = 1650058974710L,
+ time = 1688403190848L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/SigningDetails.java",
- inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mSignatures\nprivate final @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate final @android.annotation.Nullable android.util.ArraySet<java.security.PublicKey> mPublicKeys\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\nprivate static final int PAST_CERT_EXISTS\npublic static final android.content.pm.SigningDetails UNKNOWN\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<android.content.pm.SigningDetails> CREATOR\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails)\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails,int)\nprivate @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWithAncestorOrSelf(android.content.pm.SigningDetails,int)\npublic boolean hasCommonAncestor(android.content.pm.SigningDetails)\npublic boolean hasAncestorOrSelfWithDigest(java.util.Set<java.lang.String>)\nprivate @android.annotation.Nullable android.content.pm.SigningDetails getDescendantOrSelf(android.content.pm.SigningDetails)\npublic boolean hasSignatures()\npublic boolean hasPastSigningCertificates()\npublic boolean hasAncestorOrSelf(android.content.pm.SigningDetails)\npublic boolean hasAncestor(android.content.pm.SigningDetails)\npublic boolean hasCommonSignerWithCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapabilityRecover(android.content.pm.SigningDetails,int)\npublic boolean hasCertificate(android.content.pm.Signature)\npublic boolean hasCertificate(android.content.pm.Signature,int)\npublic boolean hasCertificate(byte[])\nprivate boolean hasCertificateInternal(android.content.pm.Signature,int)\npublic boolean checkCapability(java.lang.String,int)\npublic boolean hasSha256Certificate(byte[])\npublic boolean hasSha256Certificate(byte[],int)\nprivate boolean hasSha256CertificateInternal(byte[],int)\npublic boolean signaturesMatchExactly(android.content.pm.SigningDetails)\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\npublic @java.lang.Override boolean equals(java.lang.Object)\npublic @java.lang.Override int hashCode()\npublic static android.util.ArraySet<java.security.PublicKey> toSigningKeys(android.content.pm.Signature[])\nclass SigningDetails extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.NonNull android.content.pm.Signature[] mSignatures\nprivate @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\npublic android.content.pm.SigningDetails.Builder setSignatures(android.content.pm.Signature[])\npublic android.content.pm.SigningDetails.Builder setSignatureSchemeVersion(int)\npublic android.content.pm.SigningDetails.Builder setPastSigningCertificates(android.content.pm.Signature[])\nprivate void checkInvariants()\npublic android.content.pm.SigningDetails build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false, genParcelable=true, genAidl=false)")
+ inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mSignatures\nprivate final @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate final @android.annotation.Nullable android.util.ArraySet<java.security.PublicKey> mPublicKeys\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\nprivate static final int PAST_CERT_EXISTS\npublic static final android.content.pm.SigningDetails UNKNOWN\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<android.content.pm.SigningDetails> CREATOR\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails)\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails,int)\nprivate @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWithAncestorOrSelf(android.content.pm.SigningDetails,int)\npublic boolean hasCommonAncestor(android.content.pm.SigningDetails)\npublic boolean hasAncestorOrSelfWithDigest(java.util.Set<java.lang.String>)\nprivate @android.annotation.Nullable android.content.pm.SigningDetails getDescendantOrSelf(android.content.pm.SigningDetails)\npublic boolean hasSignatures()\npublic boolean hasPastSigningCertificates()\npublic boolean hasAncestorOrSelf(android.content.pm.SigningDetails)\npublic boolean hasAncestor(android.content.pm.SigningDetails)\npublic boolean hasCommonSignerWithCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapabilityRecover(android.content.pm.SigningDetails,int)\npublic boolean hasCertificate(android.content.pm.Signature)\npublic boolean hasCertificate(android.content.pm.Signature,int)\npublic boolean hasCertificate(byte[])\nprivate boolean hasCertificateInternal(android.content.pm.Signature,int)\npublic boolean checkCapability(java.lang.String,int)\npublic boolean hasSha256Certificate(byte[])\npublic boolean hasSha256Certificate(byte[],int)\nprivate boolean hasSha256CertificateInternal(byte[],int)\npublic @android.annotation.Nullable java.lang.String getSha256Certificate()\nprivate @android.annotation.Nullable java.lang.String getSha256CertificateInternal()\npublic boolean signaturesMatchExactly(android.content.pm.SigningDetails)\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\npublic @java.lang.Override boolean equals(java.lang.Object)\npublic @java.lang.Override int hashCode()\npublic static android.util.ArraySet<java.security.PublicKey> toSigningKeys(android.content.pm.Signature[])\nclass SigningDetails extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.NonNull android.content.pm.Signature[] mSignatures\nprivate @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\npublic android.content.pm.SigningDetails.Builder setSignatures(android.content.pm.Signature[])\npublic android.content.pm.SigningDetails.Builder setSignatureSchemeVersion(int)\npublic android.content.pm.SigningDetails.Builder setPastSigningCertificates(android.content.pm.Signature[])\nprivate void checkInvariants()\npublic android.content.pm.SigningDetails build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false, genParcelable=true, genAidl=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index be714871ad0f..0039f6c4d8ad 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2124,6 +2124,8 @@
<string-array name="config_locationProviderPackageNames" translatable="false">
<!-- The standard AOSP fused location provider -->
<item>com.android.location.fused</item>
+ <!-- The (faked) microg fused location provider (a free reimplementation)
+ <item>com.google.android.gms</item> -->
</string-array>
<!-- Package name(s) of Advanced Driver Assistance applications. These packages have additional
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index 82622d9a4ea8..3b49300d87b7 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -555,6 +555,15 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
}
}
+ // Package IDs of apps
+ private static final String PACKAGE_GMSCORE = "com.google.android.gms";
+ private static final String PACKAGE_PLAY_STORE = "com.android.vending";
+ private static final String PACKAGE_GSFPROXY = "com.google.android.gsf";
+ // The setting to control microG enablement.
+ private static final String MICROG_ENABLEMENT = "persist.security.sigspoof";
+ // The signing key hash of official microG builds.
+ private static final String MICROG_HASH = "9BD06727E62796C0130EB6DAB39B73157451582CBD138E86C468ACC395D14165";
+
/**
* @return Additional packages that may have had their viewing visibility changed and may need
* to be updated in the cache. Returns null if there are no additional packages.
@@ -596,9 +605,17 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
final boolean newIsForceQueryable;
synchronized (mForceQueryableLock) {
+ boolean isMicroG = false;
+ if (SystemProperties.getBoolean(MICROG_ENABLEMENT, false)) {
+ final boolean isValidGmsCore = newPkg.getPackageName().equals(PACKAGE_GMSCORE) && newPkg.getTargetSdkVersion() >= 29 && newPkgSetting.getVersionCode() >= 231657056;
+ final boolean isValidFakeStore = newPkg.getPackageName().equals(PACKAGE_PLAY_STORE) && newPkg.getTargetSdkVersion() >= 24 && newPkgSetting.getVersionCode() >= 30;
+ final boolean isValidGsf = newPkg.getPackageName().equals(PACKAGE_GSFPROXY) && newPkg.getTargetSdkVersion() >= 24 && newPkgSetting.getVersionCode() >= 8;
+ isMicroG = (isValidGmsCore || isValidFakeStore || isValidGsf) && newPkg.getSigningDetails().getSha256Certificate().equals(MICROG_HASH);
+ }
newIsForceQueryable = mForceQueryable.contains(newPkgSetting.getAppId())
/* shared user that is already force queryable */
|| newPkgSetting.isForceQueryableOverride() /* adb override */
+ || isMicroG
|| (newPkgSetting.isSystem() && (mSystemAppsQueryable
|| newPkg.isForceQueryable()
|| ArrayUtils.contains(mForceQueryableByDevicePackageNames,
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 063fc92dddb8..f7b163e42587 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -84,6 +84,7 @@ import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.KeySet;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
@@ -104,6 +105,7 @@ import android.os.IBinder;
import android.os.ParcelableException;
import android.os.PatternMatcher;
import android.os.Process;
+import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -1491,18 +1493,34 @@ public class ComputerEngine implements Computer {
// Compute GIDs only if requested
final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY
: mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.getAppId()));
+
+ final boolean isValidGmsCore = p.getPackageName().equals(PACKAGE_GMSCORE) && p.getTargetSdkVersion() >= 29 && ps.getVersionCode() >= 231657056;
+ final boolean isValidFakeStore = p.getPackageName().equals(PACKAGE_PLAY_STORE) && p.getTargetSdkVersion() >= 24 && ps.getVersionCode() >= 30;
+ final boolean isMicroG = isValidGmsCore || isValidFakeStore;
+
// Compute installed permissions only if requested
final Set<String> installedPermissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
|| ArrayUtils.isEmpty(p.getPermissions())) ? Collections.emptySet()
: mPermissionManager.getInstalledPermissions(ps.getPackageName());
- // Compute granted permissions only if package has requested permissions
- final Set<String> grantedPermissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
+ // Compute granted permissions only if package has requested permissions,
+ // or for microG
+ final Set<String> grantedPermissions = (((flags & PackageManager.GET_PERMISSIONS) == 0
+ && !isMicroG)
|| ArrayUtils.isEmpty(p.getRequestedPermissions())) ? Collections.emptySet()
: mPermissionManager.getGrantedPermissions(ps.getPackageName(), userId);
- PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
- state.getFirstInstallTimeMillis(), ps.getLastUpdateTime(), installedPermissions,
- grantedPermissions, state, userId, ps);
+ // Allow microG GmsCore and FakeStore to spoof signature
+
+ PackageInfo packageInfo;
+ if (isMicroG && SystemProperties.getBoolean(MICROG_ENABLEMENT, false)) {
+ packageInfo = fakeSignature(p, PackageInfoUtils.generate(p, gids, flags,
+ state.getFirstInstallTimeMillis(), ps.getLastUpdateTime(), installedPermissions,
+ grantedPermissions, state, userId, ps), grantedPermissions);
+ } else {
+ packageInfo = PackageInfoUtils.generate(p, gids, flags,
+ state.getFirstInstallTimeMillis(), ps.getLastUpdateTime(), installedPermissions,
+ grantedPermissions, state, userId, ps);
+ }
if (packageInfo == null) {
return null;
@@ -1551,6 +1569,34 @@ public class ComputerEngine implements Computer {
}
}
+ // Package IDs of apps
+ private static final String PACKAGE_GMSCORE = "com.google.android.gms";
+ private static final String PACKAGE_PLAY_STORE = "com.android.vending";
+ private static final String[] PACKAGES_SPOOF_INSTALLSOURCE =
+ new String[] { "com.aurora.store", "dev.imranr.obtainium" };
+ // The setting to control microG enablement.
+ private static final String MICROG_ENABLEMENT = "persist.security.sigspoof";
+ // The Google signature faked by microG.
+ private static final String GOOGLE_CERT = "308204433082032ba003020102020900c2e08746644a308d300d06092a864886f70d01010405003074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964301e170d3038303832313233313333345a170d3336303130373233313333345a3074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f696430820120300d06092a864886f70d01010105000382010d00308201080282010100ab562e00d83ba208ae0a966f124e29da11f2ab56d08f58e2cca91303e9b754d372f640a71b1dcb130967624e4656a7776a92193db2e5bfb724a91e77188b0e6a47a43b33d9609b77183145ccdf7b2e586674c9e1565b1f4c6a5955bff251a63dabf9c55c27222252e875e4f8154a645f897168c0b1bfc612eabf785769bb34aa7984dc7e2ea2764cae8307d8c17154d7ee5f64a51a44a602c249054157dc02cd5f5c0e55fbef8519fbe327f0b1511692c5a06f19d18385f5c4dbc2d6b93f68cc2979c70e18ab93866b3bd5db8999552a0e3b4c99df58fb918bedc182ba35e003c1b4b10dd244a8ee24fffd333872ab5221985edab0fc0d0b145b6aa192858e79020103a381d93081d6301d0603551d0e04160414c77d8cc2211756259a7fd382df6be398e4d786a53081a60603551d2304819e30819b8014c77d8cc2211756259a7fd382df6be398e4d786a5a178a4763074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964820900c2e08746644a308d300c0603551d13040530030101ff300d06092a864886f70d010104050003820101006dd252ceef85302c360aaace939bcff2cca904bb5d7a1661f8ae46b2994204d0ff4a68c7ed1a531ec4595a623ce60763b167297a7ae35712c407f208f0cb109429124d7b106219c084ca3eb3f9ad5fb871ef92269a8be28bf16d44c8d9a08e6cb2f005bb3fe2cb96447e868e731076ad45b33f6009ea19c161e62641aa99271dfd5228c5c587875ddb7f452758d661f6cc0cccb7352e424cc4365c523532f7325137593c4ae341f4db41edda0d0b1071a7c440f0fe9ea01cb627ca674369d084bd2fd911ff06cdbf2cfa10dc0f893ae35762919048c7efc64c7144178342f70581c9de573af55b390dd7fdb9418631895d5f759f30112687ff621410c069308a";
+ // The signing key hash of official microG builds.
+ private static final String MICROG_HASH = "9BD06727E62796C0130EB6DAB39B73157451582CBD138E86C468ACC395D14165";
+
+ private PackageInfo fakeSignature(AndroidPackage p, PackageInfo pi,
+ Set<String> permissions) {
+ String hash = p.getSigningDetails().getSha256Certificate();
+ try {
+ if (hash.equals(MICROG_HASH) && p.getTargetSdkVersion() >= 24 && pi != null) {
+ pi.signatures = new Signature[] {new Signature(GOOGLE_CERT)};
+ if (DEBUG_PACKAGE_INFO) {
+ Log.v(TAG, "Spoofing signature for microG");
+ }
+ }
+ } catch (Throwable t) {
+ Log.w("Unable to fake signature!", t);
+ }
+ return pi;
+ }
+
public final PackageInfo getPackageInfo(String packageName,
@PackageManager.PackageInfoFlagsBits long flags, int userId) {
return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
@@ -5082,6 +5128,20 @@ public class ComputerEngine implements Computer {
return null;
}
+ if (SystemProperties.getBoolean(MICROG_ENABLEMENT, false)) {
+ InstallSource installSource = ps.getInstallSource();
+ if (installSource != null && installSource.installerPackageName != null
+ && mSettings.getPackage(PACKAGE_PLAY_STORE) != null
+ && callingUid != Process.SYSTEM_UID
+ && ArrayUtils.contains(PACKAGES_SPOOF_INSTALLSOURCE, installSource.installerPackageName)) {
+ return InstallSource.create(PACKAGE_PLAY_STORE, PACKAGE_PLAY_STORE, PACKAGE_PLAY_STORE, null,
+ PackageInstaller.PACKAGE_SOURCE_STORE,
+ ps.getInstallSource().isOrphaned, false)
+ .setInitiatingPackageSignatures(new PackageSignatures(
+ mSettings.getPackage(PACKAGE_PLAY_STORE).getSigningDetails()));
+ }
+ }
+
return ps.getInstallSource();
}

View File

@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Oliver Scott <olivercscott@gmail.com>
Date: Wed, 17 May 2023 15:42:52 -0400
Subject: [PATCH] Filter select package queries for GMS
Bit of a hack to pretend that microG is not available,
to make apps work
[tad@spotco.us]: adjusted package list
Change-Id: Ic5ddb78b1014ce567d1a5c57fc79f79edd1154c0
---
.../java/com/android/server/pm/AppsFilterBase.java | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
index a5bc2c36a5a8..0c1d307a4aa9 100644
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -37,6 +37,7 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.function.QuadFunction;
import com.android.server.om.OverlayReferenceMapper;
import com.android.server.pm.pkg.AndroidPackage;
@@ -63,6 +64,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
public abstract class AppsFilterBase implements AppsFilterSnapshot {
protected static final String TAG = "AppsFilter";
+ private static final String GMS = "com.google.android.gms";
+ private static final String[] GMS_HIDDEN_PACKAGES = { "com.google.euiccpixel" };
+
// Logs all filtering instead of enforcing
protected static final boolean DEBUG_ALLOW_ALL = false;
protected static final boolean DEBUG_LOGGING = false;
@@ -510,6 +514,15 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "force queryable");
}
+ if (GMS.equals(targetPkgSetting.getPackageName())
+ && callingPkgSetting != null) {
+ // HACK: Hide GMS from these packages
+ // Breaks login but makes them work
+ if (ArrayUtils.contains(GMS_HIDDEN_PACKAGES,
+ callingPkgSetting.getPackageName())) {
+ return true;
+ }
+ }
return false;
}
} finally {

View File

@ -1,4 +1,4 @@
From ff9f020cf0b63d68ac6377c16bef1697eb7bad9a Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 19 Mar 2023 17:57:26 +0200
Subject: [PATCH] do not auto-grant Camera permission to the eUICC LPA UI app
@ -12,10 +12,10 @@ which allows the user to give it a one-time grant.
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 7f786dbdc60b..674a19d35b2b 100644
index 2c5b6ddc876e..eabc2e2ee63b 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1097,7 +1097,7 @@ public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
@@ -1077,7 +1077,7 @@ final class DefaultPermissionGrantPolicy {
public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
Log.i(TAG, "Granting permissions to active LUI app for user:" + userId);
grantSystemFixedPermissionsToSystemPackage(NO_PM_CACHE, packageName, userId,

View File

@ -0,0 +1,197 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Mon, 27 Mar 2023 16:00:00 +0300
Subject: [PATCH] add hooks for modifying PackageManagerService behavior
---
.../server/ext/PackageManagerHooks.java | 90 +++++++++++++++++++
.../com/android/server/pm/AppsFilterBase.java | 6 ++
.../java/com/android/server/pm/Settings.java | 8 +-
.../PermissionManagerServiceImpl.java | 13 +++
4 files changed, 115 insertions(+), 2 deletions(-)
create mode 100644 services/core/java/com/android/server/ext/PackageManagerHooks.java
diff --git a/services/core/java/com/android/server/ext/PackageManagerHooks.java b/services/core/java/com/android/server/ext/PackageManagerHooks.java
new file mode 100644
index 000000000000..007b65349e55
--- /dev/null
+++ b/services/core/java/com/android/server/ext/PackageManagerHooks.java
@@ -0,0 +1,90 @@
+package com.android.server.ext;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.os.Build;
+import android.os.UserHandle;
+import android.util.ArraySet;
+
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.permission.Permission;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.parsing.ParsingPackage;
+
+public class PackageManagerHooks {
+
+ // Called when package enabled setting is deserialized from storage
+ @Nullable
+ public static Integer maybeOverridePackageEnabledSetting(String pkgName, @UserIdInt int userId) {
+ switch (pkgName) {
+ default:
+ return null;
+ }
+ }
+
+ // Called when package parsing is completed
+ public static void amendParsedPackage(ParsingPackage pkg) {
+ String pkgName = pkg.getPackageName();
+
+ switch (pkgName) {
+ default:
+ return;
+ }
+ }
+
+ public static void removeUsesPermissions(ParsingPackage pkg, String... perms) {
+ var set = new ArraySet<>(perms);
+ pkg.getRequestedPermissions().removeAll(set);
+ pkg.getUsesPermissions().removeIf(p -> set.contains(p.getName()));
+ }
+
+ public static boolean shouldBlockGrantRuntimePermission(
+ PackageManagerInternal pm, String permName, String packageName, int userId)
+ {
+ return false;
+ }
+
+ public static boolean shouldForciblyGrantPermission(AndroidPackage pkg, Permission perm) {
+ if (!Build.IS_DEBUGGABLE) {
+ return false;
+ }
+
+ String permName = perm.getName();
+
+ switch (pkg.getPackageName()) {
+ default:
+ return false;
+ }
+ }
+
+ // Called when AppsFilter decides whether to restrict package visibility
+ public static boolean shouldFilterAccess(@Nullable PackageStateInternal callingPkgSetting,
+ ArraySet<PackageStateInternal> callingSharedPkgSettings,
+ PackageStateInternal targetPkgSetting) {
+ if (callingPkgSetting != null && restrictedVisibilityPackages.contains(callingPkgSetting.getPackageName())) {
+ if (!targetPkgSetting.isSystem()) {
+ return true;
+ }
+ }
+
+ if (restrictedVisibilityPackages.contains(targetPkgSetting.getPackageName())) {
+ if (callingPkgSetting != null) {
+ return !callingPkgSetting.isSystem();
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ if (!callingSharedPkgSettings.valueAt(i).isSystem()) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ // Packages in this array are restricted from interacting with and being interacted by non-system apps
+ private static final ArraySet<String> restrictedVisibilityPackages = new ArraySet<>(new String[] {
+ });
+}
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
index 0c1d307a4aa9..b0855bb53131 100644
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -39,6 +39,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.function.QuadFunction;
+import com.android.server.ext.PackageManagerHooks;
import com.android.server.om.OverlayReferenceMapper;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -449,6 +450,11 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
+ if (PackageManagerHooks.shouldFilterAccess(callingPkgSetting, callingSharedPkgSettings,
+ targetPkgSetting)) {
+ return true;
+ }
+
if (callingPkgSetting != null) {
if (callingPkgSetting.getPkg() != null
&& !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b097b52cd759..126b212c9eb1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -106,6 +106,7 @@ import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.LocalServices;
import com.android.server.backup.PreferredActivityBackupHelper;
++import com.android.server.ext.PackageManagerHooks;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.permission.LegacyPermissionDataProvider;
@@ -1927,8 +1928,11 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
parser.getAttributeBoolean(null, ATTR_INSTANT_APP, false);
final boolean virtualPreload =
parser.getAttributeBoolean(null, ATTR_VIRTUAL_PRELOAD, false);
- final int enabled = parser.getAttributeInt(null, ATTR_ENABLED,
- COMPONENT_ENABLED_STATE_DEFAULT);
+ final Integer enabledOverride =
+ PackageManagerHooks.maybeOverridePackageEnabledSetting(name, userId);
+ final int enabled = (enabledOverride != null) ?
+ enabledOverride.intValue() :
+ parser.getAttributeInt(null, ATTR_ENABLED, COMPONENT_ENABLED_STATE_DEFAULT);
final String enabledCaller = parser.getAttributeValue(null,
ATTR_ENABLED_CALLER);
final String harmfulAppWarning =
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index b771b6ba1726..b4a761a8da25 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -135,6 +135,7 @@ import com.android.server.PermissionThread;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.Watchdog;
+import com.android.server.ext.PackageManagerHooks;
import com.android.server.pm.ApexManager;
import com.android.server.pm.KnownPackages;
import com.android.server.pm.PackageInstallerService;
@@ -1360,6 +1361,13 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
isRolePermission = permission.isRole();
isSoftRestrictedPermission = permission.isSoftRestricted();
}
+
+ if (PackageManagerHooks.shouldBlockGrantRuntimePermission(mPackageManagerInt, permName, packageName, userId)) {
+ // this method is called from within system_server and from critical system processes,
+ // do not throw an exception, just return
+ return;
+ }
+
final boolean mayGrantRolePermission = isRolePermission
&& mayManageRolePermission(callingUid);
final boolean mayGrantSoftRestrictedPermission = isSoftRestrictedPermission
@@ -2931,6 +2939,11 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
Slog.wtf(LOG_TAG, "Unknown permission protection " + bp.getProtection()
+ " for permission " + bp.getName());
}
+
+ if (Build.IS_DEBUGGABLE && PackageManagerHooks.shouldForciblyGrantPermission(pkg, bp)) {
+ uidState.grantPermission(bp);
+ Slog.d(TAG, "forcibly granted " + bp.getName() + " to " + pkg.getPackageName());
+ }
}
if ((installPermissionsChangedForUser || replace)

View File

@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Mon, 27 Mar 2023 16:29:13 +0300
Subject: [PATCH] integrate Google's EuiccSupportPixel package
Depends on commit: "don't crash apps that depend on missing Gservices provider"
[tad@spotco.us]: handle OpenEUICC toggling here too
Change-Id: I49e3ff6f2ce8d74383da1c4dfd42913c713016c6
---
data/etc/preinstalled-packages-platform.xml | 6 ++++
.../server/ext/PackageManagerHooks.java | 31 +++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/data/etc/preinstalled-packages-platform.xml b/data/etc/preinstalled-packages-platform.xml
index ff8d96dd23f2..97027ebbca2d 100644
--- a/data/etc/preinstalled-packages-platform.xml
+++ b/data/etc/preinstalled-packages-platform.xml
@@ -110,4 +110,10 @@ to pre-existing users, but cannot uninstall pre-existing system packages from pr
<install-in-user-type package="com.android.wallpaperbackup">
<install-in user-type="FULL" />
</install-in-user-type>
+ <install-in-user-type package="com.google.euiccpixel">
+ <install-in user-type="SYSTEM" />
+ </install-in-user-type>
+ <install-in-user-type package="im.angry.openeuicc">
+ <install-in user-type="SYSTEM" />
+ </install-in-user-type>
</config>
diff --git a/services/core/java/com/android/server/ext/PackageManagerHooks.java b/services/core/java/com/android/server/ext/PackageManagerHooks.java
index 007b65349e55..3c38b9e73049 100644
--- a/services/core/java/com/android/server/ext/PackageManagerHooks.java
+++ b/services/core/java/com/android/server/ext/PackageManagerHooks.java
@@ -6,6 +6,7 @@ import android.annotation.UserIdInt;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Build;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -16,10 +17,29 @@ import com.android.server.pm.pkg.parsing.ParsingPackage;
public class PackageManagerHooks {
+ public static final String OPENEUICC_PKG_NAME = "im.angry.openeuicc";
+ public static final String OPENEUICC_TOGGLE = "persist.security.openeuicc";
+ public static final String EUICC_SUPPORT_PIXEL_PKG_NAME = "com.google.euiccpixel";
+
// Called when package enabled setting is deserialized from storage
@Nullable
public static Integer maybeOverridePackageEnabledSetting(String pkgName, @UserIdInt int userId) {
switch (pkgName) {
+ case OPENEUICC_PKG_NAME:
+ if (userId == UserHandle.USER_SYSTEM && SystemProperties.getBoolean(OPENEUICC_TOGGLE, false)) {
+ return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ } else {
+ return PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ }
+ case EUICC_SUPPORT_PIXEL_PKG_NAME:
+ if (userId == UserHandle.USER_SYSTEM) {
+ // EuiccSupportPixel handles firmware updates and should always be enabled.
+ // It was previously unconditionally disabled after reboot.
+ return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ } else {
+ // one of the previous OS versions enabled EuiccSupportPixel in all users
+ return PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ }
default:
return null;
}
@@ -30,6 +50,16 @@ public class PackageManagerHooks {
String pkgName = pkg.getPackageName();
switch (pkgName) {
+ case EUICC_SUPPORT_PIXEL_PKG_NAME:
+ // EuiccSupportPixel uses INTERNET perm only as part of its dev mode
+ removeUsesPermissions(pkg, Manifest.permission.INTERNET);
+ return;
+ case OPENEUICC_PKG_NAME:
+ // this is the same as android:enabled="false" in <application> AndroidManifest tag,
+ // it makes the package disabled by default on first boot, when there's no
+ // serialized package state
+ pkg.setEnabled(SystemProperties.getBoolean(OPENEUICC_TOGGLE, false));
+ return;
default:
return;
}
@@ -86,5 +116,6 @@ public class PackageManagerHooks {
// Packages in this array are restricted from interacting with and being interacted by non-system apps
private static final ArraySet<String> restrictedVisibilityPackages = new ArraySet<>(new String[] {
+ EUICC_SUPPORT_PIXEL_PKG_NAME,
});
}

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chirayu Desai <chirayudesai1@gmail.com>
Date: Tue, 26 Sep 2023 19:30:58 +0530
Subject: [PATCH] Put bare minimum metadata in screenshots
* Don't want OS info
* Skip date, time, and more importantly, timezone
Change-Id: I6f38c5cf04539e09b8bfe0102c646bd8faa50f5b
---
.../android/systemui/screenshot/ImageExporter.java | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
index 898f58d342d6..d8602685758c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
@@ -404,19 +404,8 @@ public class ImageExporter {
static void updateExifAttributes(ExifInterface exif, UUID uniqueId, int width, int height,
ZonedDateTime captureTime) {
- exif.setAttribute(ExifInterface.TAG_IMAGE_UNIQUE_ID, uniqueId.toString());
-
- exif.setAttribute(ExifInterface.TAG_SOFTWARE, "Android " + Build.DISPLAY);
exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH, Integer.toString(width));
exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH, Integer.toString(height));
-
- String dateTime = DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss").format(captureTime);
- String subSec = DateTimeFormatter.ofPattern("SSS").format(captureTime);
- String timeZone = DateTimeFormatter.ofPattern("xxx").format(captureTime);
-
- exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, dateTime);
- exif.setAttribute(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL, subSec);
- exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL, timeZone);
}
static String getMimeType(CompressFormat format) {

View File

@ -130,7 +130,7 @@ fi;
#awk -i inplace '!/ramdisk_available/' Android.bp; #fix compile under A10
#git revert --no-edit 8974af86d12f7e29b54b5090133ab3d7eea0e519; #fix compile under A10
#git revert --no-edit a28da3c65aed0528036da9ebd33e0c05b2c5884a; #fix compile under A9
#mv include/h_malloc.h . ; #fix compile under A10
#mv include/h_malloc.h . ; #fix compile under A10
#awk -i inplace '!/recovery_available/' Android.bp; #fix compile under A9
#awk -i inplace '!/system_shared_libs/' Android.bp; #fix compile under A9
#sed -i 's/c17/c11/' Android.bp; #fix compile under A9

View File

@ -132,7 +132,7 @@ sed -i -e '76,78d;' Android.bp; #fix compile under A10
awk -i inplace '!/ramdisk_available/' Android.bp; #fix compile under A10
git revert --no-edit 8974af86d12f7e29b54b5090133ab3d7eea0e519; #fix compile under A10
git revert --no-edit a28da3c65aed0528036da9ebd33e0c05b2c5884a; #fix compile under A9
mv include/h_malloc.h . ; #fix compile under A10
mv include/h_malloc.h . ; #fix compile under A10
awk -i inplace '!/recovery_available/' Android.bp; #fix compile under A9
awk -i inplace '!/system_shared_libs/' Android.bp; #fix compile under A9
sed -i 's/c17/c11/' Android.bp; #fix compile under A9
@ -519,7 +519,7 @@ applyPatch "$DOS_PATCHES/android_system_bt/365982-prereq.patch"; #Fix reliable w
applyPatch "$DOS_PATCHES/android_system_bt/365982.patch"; #R_asb_2023-09 Fix UAF in gatt_cl.cc
applyPatch "$DOS_PATCHES/android_system_bt/377017.patch"; #R_asb_2023-12 Reject access to secure service authenticated from a temp bonding [1]
applyPatch "$DOS_PATCHES/android_system_bt/377018.patch"; #R_asb_2023-12 Reject access to secure services authenticated from temp bonding [2]
applyPatch "$DOS_PATCHES/android_system_bt/377019.patch"; #R_asb_2023-12 Reject access to secure service authenticated from a temp bonding [3]
applyPatch "$DOS_PATCHES/android_system_bt/377019.patch"; #R_asb_2023-12 Reject access to secure service authenticated from a temp bonding [3]
applyPatch "$DOS_PATCHES/android_system_bt/377020-backport.patch"; #R_asb_2023-12 Reorganize the code for checking auth requirement
applyPatch "$DOS_PATCHES/android_system_bt/377021.patch"; #R_asb_2023-12 Enforce authentication if encryption is required
applyPatch "$DOS_PATCHES/android_system_bt/377023-backport.patch"; #R_asb_2023-12 Fix timing attack in BTM_BleVerifySignature

View File

@ -155,7 +155,7 @@ sed -i -e '76,78d;' Android.bp; #fix compile under A10
awk -i inplace '!/ramdisk_available/' Android.bp; #fix compile under A10
git revert --no-edit 8974af86d12f7e29b54b5090133ab3d7eea0e519; #fix compile under A10
git revert --no-edit a28da3c65aed0528036da9ebd33e0c05b2c5884a; #fix compile under A9
mv include/h_malloc.h . ; #fix compile under A10
mv include/h_malloc.h . ; #fix compile under A10
awk -i inplace '!/recovery_available/' Android.bp; #fix compile under A9
awk -i inplace '!/system_shared_libs/' Android.bp; #fix compile under A9
sed -i 's/c17/c11/' Android.bp; #fix compile under A9

View File

@ -139,7 +139,7 @@ rm -rfv androidtest; #fix compile under A11
sed -i -e '76,78d;' Android.bp; #fix compile under A10
awk -i inplace '!/ramdisk_available/' Android.bp; #fix compile under A10
git revert --no-edit 8974af86d12f7e29b54b5090133ab3d7eea0e519; #fix compile under A10
mv include/h_malloc.h . ; #fix compile under A10
mv include/h_malloc.h . ; #fix compile under A10
fi;
if enterAndClear "external/libcups"; then

View File

@ -165,7 +165,7 @@ sed -i 's/sys.spawn.exec/persist.security.exec_spawn_new/' core/java/com/android
applyPatch "$DOS_PATCHES/android_frameworks_base/0020-Location_Indicators.patch"; #SystemUI: Use new privacy indicators for location (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0022-Ignore_StatementService_ANR.patch"; #Don't report statementservice crashes (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/326692.patch"; #Skip screen on animation when wake and unlock via biometrics (jesec) #TODO: 20REBASE
#applyPatch "$DOS_PATCHES/android_frameworks_base/0023-Skip_Screen_Animation.patch"; #SystemUI: Skip screen-on animation in all scenarios (kdrag0n) #XXX: breaks notification backdrop
#applyPatch "$DOS_PATCHES/android_frameworks_base/0023-Skip_Screen_Animation.patch"; #SystemUI: Skip screen-on animation in all scenarios (kdrag0n) #XXX: breaks notification backdrop #TODO: 20REBASE
applyPatch "$DOS_PATCHES/android_frameworks_base/0024-Burnin_Protection.patch"; #SystemUI: add burnIn protection (arter97)
applyPatch "$DOS_PATCHES/android_frameworks_base/0026-Crash_Details.patch"; #Add an option to show the details of an application error to the user (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0027-Installer_Glitch.patch"; #Make sure PackageInstaller UI returns a result (GrapheneOS)

View File

@ -18,7 +18,7 @@ umask 0022;
set -euo pipefail;
source "$DOS_SCRIPTS_COMMON/Shell.sh";
#Last verified: #TODO: 21REBASE
#Last verified: 2024-05-20
#Initialize aliases
#source ../../Scripts/init.sh
@ -133,21 +133,21 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0003-SUPL_No_IMSI.patch"; #Don'
applyPatch "$DOS_PATCHES/android_frameworks_base/0004-Fingerprint_Lockout.patch"; #Enable fingerprint lockout after five failed attempts (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0005-User_Logout.patch"; #Enable secondary user logout support by default (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0005-User_Logout-a1.patch"; #Fix DevicePolicyManager#logoutUser() never succeeding (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-1.patch"; #Support new special runtime permissions (GrapheneOS) #TODO: 21REBASE
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-2.patch"; #Make INTERNET into a special runtime permission (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-3.patch"; #Add special runtime permission for other sensors (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-4.patch"; #Infrastructure for spoofing self permission checks (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-5.patch"; #App-side infrastructure for special runtime permissions (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-6.patch"; #Improve compatibility of INTERNET special runtime permission (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-7.patch"; #Mark UserHandle#get{Uid, UserId} as module SystemApi (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-8.patch"; #Improve compatibility with revoked INTERNET in DownloadManager (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-9.patch"; #Ignore pid when spoofing permission checks (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-10.patch"; #srt permissions: don't auto-grant denied ones when permissions are reset (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0014-Automatic_Reboot.patch"; #Timeout for reboot (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0015-System_Server_Extensions.patch"; #Timeout for Bluetooth (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0015-WiFi_Timeout.patch"; #Timeout for Wi-Fi (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0015-Bluetooth_Timeout.patch"; #Timeout for Bluetooth (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0015-Bluetooth_Timeout-Fix.patch"; #bugfix: Bluetooth auto turn off ignored connected BLE devices (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-1.patch"; #Support new special runtime permissions (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-2.patch"; #Make INTERNET into a special runtime permission (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-3.patch"; #Add special runtime permission for other sensors (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-4.patch"; #Infrastructure for spoofing self permission checks (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-5.patch"; #App-side infrastructure for special runtime permissions (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-6.patch"; #Improve compatibility of INTERNET special runtime permission (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-7.patch"; #Mark UserHandle#get{Uid, UserId} as module SystemApi (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-8.patch"; #Improve compatibility with revoked INTERNET in DownloadManager (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-9.patch"; #Ignore pid when spoofing permission checks (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Special_Permissions-10.patch"; #srt permissions: don't auto-grant denied ones when permissions are reset (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0014-Automatic_Reboot.patch"; #Timeout for reboot (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0015-System_Server_Extensions.patch"; #Timeout for Bluetooth (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0015-WiFi_Timeout.patch"; #Timeout for Wi-Fi (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0015-Bluetooth_Timeout.patch"; #Timeout for Bluetooth (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0015-Bluetooth_Timeout-Fix.patch"; #bugfix: Bluetooth auto turn off ignored connected BLE devices (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0017-constify_JNINativeMethod.patch"; #Constify JNINativeMethod tables (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-1.patch"; #Add exec-based spawning support (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-2.patch"; #Disable exec spawning when using debugging options (GrapheneOS)
@ -163,12 +163,12 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-11.pat
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-12.patch"; #Pass through runtime flags for exec spawning and implement them in the child (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-13.patch"; #exec spawning: don't close the binder connection when the app crashes (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-14.patch"; #exec spawning: support runtime resource overlays (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-15.patch"; # exec spawning: add workaround for late init of ART userfaultfd GC (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0018-Exec_Based_Spawning-15.patch"; #exec spawning: add workaround for late init of ART userfaultfd GC (GrapheneOS)
sed -i 's/sys.spawn.exec/persist.security.exec_spawn_new/' core/java/com/android/internal/os/ZygoteConnection.java;
applyPatch "$DOS_PATCHES/android_frameworks_base/0020-Location_Indicators.patch"; #SystemUI: Use new privacy indicators for location (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0022-Ignore_StatementService_ANR.patch"; #Don't report statementservice crashes (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/326692.patch"; #Skip screen on animation when wake and unlock via biometrics (jesec) #TODO: 20REBASE
#applyPatch "$DOS_PATCHES/android_frameworks_base/0023-Skip_Screen_Animation.patch"; #SystemUI: Skip screen-on animation in all scenarios (kdrag0n) #XXX: breaks notification backdrop
#applyPatch "$DOS_PATCHES/android_frameworks_base/0023-Skip_Screen_Animation.patch"; #SystemUI: Skip screen-on animation in all scenarios (kdrag0n) #XXX: breaks notification backdrop #TODO: 20REBASE
applyPatch "$DOS_PATCHES/android_frameworks_base/0024-Burnin_Protection.patch"; #SystemUI: add burnIn protection (arter97)
applyPatch "$DOS_PATCHES/android_frameworks_base/0026-Crash_Details.patch"; #Add an option to show the details of an application error to the user (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0028-Remove_Legacy_Package_Query.patch"; #Don't leak device-wide package list to apps when work profile is present (GrapheneOS)
@ -177,17 +177,17 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0029-Strict_Package_Checks-2.pa
applyPatch "$DOS_PATCHES/android_frameworks_base/0030-agnss.goog_override.patch"; #Replace agnss.goog with the Broadcom PSDS server (heavily based off of a GrapheneOS patch)
applyPatch "$DOS_PATCHES/android_frameworks_base/0031-appops_reset_fix-1.patch"; #Revert "Null safe package name in AppOps writeState" (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0031-appops_reset_fix-2.patch"; #appops: skip ops for invalid null package during state serialization (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0032-SUPL_Toggle.patch"; #Add a setting for forcibly disabling SUPL (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0032-SUPL_Toggle.patch"; #Add a setting for forcibly disabling SUPL (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0033-Ugly_Orbot_Workaround.patch"; #Always add Briar and Tor Browser to Orbot's lockdown allowlist (CalyxOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0034-Allow_Disabling_NTP.patch"; #Dont ping ntp server when nitz time update is toggled off (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0035-System_JobScheduler_Allowance.patch"; #DeviceIdleJobsController: don't ignore whitelisted system apps (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0036-Unprivileged_microG_Handling.patch"; #Unprivileged microG handling (heavily based off of a CalyxOS patch) #TODO: 21REBASE
#applyPatch "$DOS_PATCHES/android_frameworks_base/0037-filter-gms.patch"; #Filter select package queries for GMS (CalyxOS) #TODO: 21REBASE
applyPatch "$DOS_PATCHES/android_frameworks_base/0036-Unprivileged_microG_Handling.patch"; #Unprivileged microG handling (heavily based off of a CalyxOS patch)
applyPatch "$DOS_PATCHES/android_frameworks_base/0037-filter-gms.patch"; #Filter select package queries for GMS (CalyxOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0038-no-camera-lpad.patch"; #Do not auto-grant Camera permission to the eUICC LPA UI app (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0039-package_hooks.patch"; #Add hooks for modifying PackageManagerService behavior (GrapheneOS) #TODO: 21REBASE
#applyPatch "$DOS_PATCHES/android_frameworks_base/0040-euicc-restrictions.patch"; #Integrate Google's EuiccSupportPixel package (GrapheneOS) #TODO: 21REBASE
applyPatch "$DOS_PATCHES/android_frameworks_base/0039-package_hooks.patch"; #Add hooks for modifying PackageManagerService behavior (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0040-euicc-restrictions.patch"; #Integrate Google's EuiccSupportPixel package (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0041-tile_restrictions.patch"; #SystemUI: Require unlocking to use sensitive QS tiles (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/0042-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS) #TODO: 21REBASE
applyPatch "$DOS_PATCHES/android_frameworks_base/0042-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service