Merge "Remove AsyncTask from the preload classes blacklist"
diff --git a/api/current.txt b/api/current.txt
index 7c13dc1..e855596 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -52435,6 +52435,7 @@
method public int getId();
method public int getLayer();
method public android.view.accessibility.AccessibilityWindowInfo getParent();
+ method public void getRegionInScreen(@NonNull android.graphics.Region);
method public android.view.accessibility.AccessibilityNodeInfo getRoot();
method @Nullable public CharSequence getTitle();
method public int getType();
diff --git a/api/removed.txt b/api/removed.txt
index 7b1d241..b075f9e 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -73,10 +73,6 @@
package android.content {
- public class ClipData implements android.os.Parcelable {
- method @Deprecated public void addItem(android.content.ClipData.Item, android.content.ContentResolver);
- }
-
public abstract class Context {
method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int);
method public abstract java.io.File getSharedPreferencesPath(String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 48804b6..eef6b3f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5179,7 +5179,8 @@
method @NonNull public static java.io.File getOdmDirectory();
method @NonNull public static java.io.File getOemDirectory();
method @NonNull public static java.io.File getProductDirectory();
- method @NonNull public static java.io.File getProductServicesDirectory();
+ method @Deprecated @NonNull public static java.io.File getProductServicesDirectory();
+ method @NonNull public static java.io.File getSystemExtDirectory();
method @NonNull public static java.io.File getVendorDirectory();
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 050ec52..d2179d3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -54,6 +54,7 @@
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
method public long getTotalRam();
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
+ method public static boolean isHighEndGfx();
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
method public static void resumeAppSwitches() throws android.os.RemoteException;
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
@@ -3492,11 +3493,6 @@
method public boolean isInputMethodPickerShown();
}
- public class InputMethodSystemProperty {
- ctor public InputMethodSystemProperty();
- field public static final boolean MULTI_CLIENT_IME_ENABLED;
- }
-
}
package android.view.inspector {
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 680ccfc..76b905d 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -64,6 +64,10 @@
private static final String BMGR_NOT_RUNNING_ERR =
"Error: Could not access the Backup Manager. Is the system running?";
+ private static final String BMGR_NOT_ACTIVATED_FOR_USER =
+ "Error: Backup Manager is not activated for user ";
+ private static final String BMGR_ERR_NO_RESTORESESSION_FOR_USER =
+ "Error: Could not get restore session for user ";
private static final String TRANSPORT_NOT_RUNNING_ERR =
"Error: Could not access the backup transport. Is the system running?";
private static final String PM_NOT_RUNNING_ERR =
@@ -190,15 +194,19 @@
showUsage();
}
- boolean isBackupActive(@UserIdInt int userId) {
+ private void handleRemoteException(RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ }
+
+ private boolean isBackupActive(@UserIdInt int userId) {
try {
if (!mBmgr.isBackupServiceActive(userId)) {
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ System.err.println(BMGR_NOT_ACTIVATED_FOR_USER + userId);
return false;
}
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
return false;
}
@@ -214,8 +222,7 @@
System.out.println("Backup Manager currently "
+ activatedToString(mBmgr.isBackupServiceActive(userId)));
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -230,8 +237,7 @@
System.out.println("Backup Manager currently "
+ enableToString(isEnabled));
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -250,8 +256,7 @@
showUsage();
return;
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -259,8 +264,7 @@
try {
mBmgr.backupNowForUser(userId);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -274,8 +278,7 @@
try {
mBmgr.dataChangedForUser(userId, pkg);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -292,8 +295,7 @@
mBmgr.fullTransportBackupForUser(
userId, allPkgs.toArray(new String[allPkgs.size()]));
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
}
@@ -421,8 +423,7 @@
try {
filteredPackages = mBmgr.filterAppsEligibleForBackupForUser(userId, packages);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
backupNowPackages(userId, Arrays.asList(filteredPackages), nonIncrementalBackup,
monitorState);
@@ -455,8 +456,7 @@
System.err.println("Unable to run backup");
}
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -506,8 +506,7 @@
try {
mBmgr.cancelBackupsForUser(userId);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
return;
}
@@ -537,8 +536,7 @@
}
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -569,8 +567,7 @@
}
});
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
return;
}
@@ -598,8 +595,7 @@
mBmgr.clearBackupDataForUser(userId, transport, pkg);
System.out.println("Wiped backup data for " + pkg + " on " + transport);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -632,8 +628,7 @@
observer.waitForCompletion(30*1000L);
System.out.println("Initialization result: " + observer.result);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -648,7 +643,7 @@
try {
mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
if (mRestore == null) {
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
return;
}
@@ -658,8 +653,7 @@
mRestore.endRestoreSession();
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -686,8 +680,7 @@
System.out.println(pad + t);
}
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -805,7 +798,7 @@
boolean didRestore = false;
mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
if (mRestore == null) {
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
return;
}
RestoreSet[] sets = null;
@@ -851,8 +844,7 @@
System.out.println("done");
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -865,8 +857,7 @@
}
}
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
@@ -886,8 +877,7 @@
+ " for user "
+ userId);
} catch (RemoteException e) {
- System.err.println(e.toString());
- System.err.println(BMGR_NOT_RUNNING_ERR);
+ handleRemoteException(e);
}
}
diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp
index 31bd612..c1f8654 100644
--- a/cmds/bootanimation/Android.bp
+++ b/cmds/bootanimation/Android.bp
@@ -79,7 +79,6 @@
"libEGL",
"libGLESv1_CM",
"libgui",
- "libtinyalsa",
],
product_variables: {
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index cfac5f3..0b349e1 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -103,6 +103,7 @@
{"/oem/", kPolicyOem},
{"/product/", kPolicyProduct},
{"/system/", kPolicySystem},
+ {"/system_ext/", kPolicySystem},
{"/vendor/", kPolicyVendor},
};
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 17368b7..cb99a3a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -925,7 +925,7 @@
* (which tends to consume a lot more RAM).
* @hide
*/
- @UnsupportedAppUsage
+ @TestApi
static public boolean isHighEndGfx() {
return !isLowRamDeviceStatic()
&& !RoSystemProperties.CONFIG_AVOID_GFX_ACCEL
@@ -1822,7 +1822,8 @@
* @hide
*/
public static class TaskSnapshot implements Parcelable {
-
+ // Identifier of this snapshot
+ private final long mId;
// Top activity in task when snapshot was taken
private final ComponentName mTopActivityComponent;
private final GraphicBuffer mSnapshot;
@@ -1841,10 +1842,12 @@
// Must be one of the named color spaces, otherwise, always use SRGB color space.
private final ColorSpace mColorSpace;
- public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
+ public TaskSnapshot(long id,
+ @NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
@NonNull ColorSpace colorSpace, int orientation, Rect contentInsets,
boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
int systemUiVisibility, boolean isTranslucent) {
+ mId = id;
mTopActivityComponent = topActivityComponent;
mSnapshot = snapshot;
mColorSpace = colorSpace.getId() < 0
@@ -1860,6 +1863,7 @@
}
private TaskSnapshot(Parcel source) {
+ mId = source.readLong();
mTopActivityComponent = ComponentName.readFromParcel(source);
mSnapshot = source.readParcelable(null /* classLoader */);
int colorSpaceId = source.readInt();
@@ -1877,6 +1881,13 @@
}
/**
+ * @return Identifier of this snapshot.
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
* @return The top activity component for the task at the point this snapshot was taken.
*/
public ComponentName getTopActivityComponent() {
@@ -1970,6 +1981,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mId);
ComponentName.writeToParcel(mTopActivityComponent, dest);
dest.writeParcelable(mSnapshot, 0);
dest.writeInt(mColorSpace.getId());
@@ -1988,6 +2000,7 @@
final int width = mSnapshot != null ? mSnapshot.getWidth() : 0;
final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
return "TaskSnapshot{"
+ + " mId=" + mId
+ " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
+ " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
+ " mColorSpace=" + mColorSpace.toString()
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f8e6ae5..69e7118 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -26,6 +26,7 @@
import android.content.pm.ActivityPresentationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.UserInfo;
+import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.TransactionTooLargeException;
@@ -52,6 +53,12 @@
*/
public abstract String checkContentProviderAccess(String authority, int userId);
+ /**
+ * Verify that calling UID has access to the given provider.
+ */
+ public abstract int checkContentProviderUriPermission(Uri uri, int userId,
+ int callingUid, int modeFlags);
+
// Called by the power manager.
public abstract void onWakefulnessChanged(int wakefulness);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d741b61..2b4d4f8b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -791,6 +791,8 @@
@Nullable
ContentCaptureOptions contentCaptureOptions;
+ long[] disabledCompatChanges;
+
@Override
public String toString() {
return "AppBindData{appInfo=" + appInfo + "}";
@@ -1003,7 +1005,7 @@
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
- ContentCaptureOptions contentCaptureOptions) {
+ ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
if (services != null) {
if (false) {
// Test code to make sure the app could see the passed-in services.
@@ -1051,6 +1053,7 @@
data.buildSerial = buildSerial;
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
+ data.disabledCompatChanges = disabledCompatChanges;
sendMessage(H.BIND_APPLICATION, data);
}
@@ -6144,10 +6147,10 @@
if (data.trackAllocation) {
DdmVmInternal.enableRecentAllocations(true);
}
-
// Note when this process has started.
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
+ AppCompatCallbacks.install(data.disabledCompatChanges);
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
new file mode 100644
index 0000000..17697db
--- /dev/null
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.compat.Compatibility;
+import android.os.Process;
+import android.util.Log;
+
+import java.util.Arrays;
+
+/**
+ * App process implementation of the {@link Compatibility} API.
+ *
+ * @hide
+ */
+public final class AppCompatCallbacks extends Compatibility.Callbacks {
+
+ private static final String TAG = "Compatibility";
+
+ private final long[] mDisabledChanges;
+
+ /**
+ * Install this class into the current process.
+ *
+ * @param disabledChanges Set of compatibility changes that are disabled for this process.
+ */
+ public static void install(long[] disabledChanges) {
+ Compatibility.setCallbacks(new AppCompatCallbacks(disabledChanges));
+ }
+
+ private AppCompatCallbacks(long[] disabledChanges) {
+ mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length);
+ Arrays.sort(mDisabledChanges);
+ }
+
+ protected void reportChange(long changeId) {
+ Log.d(TAG, "Compat change reported: " + changeId + "; UID " + Process.myUid());
+ // TODO log via StatsLog
+ }
+
+ protected boolean isChangeEnabled(long changeId) {
+ if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) {
+ // Not present in the disabled array
+ reportChange(changeId);
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 416aaa3..0478ac8 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -635,7 +635,7 @@
@Override
public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
try {
- return mPM.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
+ return mPermissionManager.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -795,10 +795,11 @@
@Override
@UnsupportedAppUsage
- public boolean shouldShowRequestPermissionRationale(String permission) {
+ public boolean shouldShowRequestPermissionRationale(String permName) {
try {
- return mPM.shouldShowRequestPermissionRationale(permission,
- mContext.getPackageName(), getUserId());
+ final String packageName = mContext.getPackageName();
+ return mPermissionManager
+ .shouldShowRequestPermissionRationale(permName, packageName, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2049,7 +2050,7 @@
@Override
public String getDefaultBrowserPackageNameAsUser(int userId) {
try {
- return mPM.getDefaultBrowserPackageName(userId);
+ return mPermissionManager.getDefaultBrowser(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2058,7 +2059,7 @@
@Override
public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
try {
- return mPM.setDefaultBrowserPackageName(packageName, userId);
+ return mPermissionManager.setDefaultBrowser(packageName, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 66c4383..cfa065b 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -73,7 +73,7 @@
boolean restrictedBackupMode, boolean persistent, in Configuration config,
in CompatibilityInfo compatInfo, in Map services,
in Bundle coreSettings, in String buildSerial, in AutofillOptions autofillOptions,
- in ContentCaptureOptions contentCaptureOptions);
+ in ContentCaptureOptions contentCaptureOptions, in long[] disabledCompatChanges);
void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs);
void scheduleExit();
void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 88e2c22..fdef2a1 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -892,12 +892,6 @@
mItems.add(item);
}
- /** @removed use #addItem(ContentResolver, Item) instead */
- @Deprecated
- public void addItem(Item item, ContentResolver resolver) {
- addItem(resolver, item);
- }
-
/**
* Add a new Item to the overall ClipData container.
* <p> Unlike {@link #addItem(Item)}, this method will update the list of available MIME types
diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java
index d41d8d9..197de97 100644
--- a/core/java/android/content/ContentInterface.java
+++ b/core/java/android/content/ContentInterface.java
@@ -56,6 +56,9 @@
public boolean refresh(@NonNull Uri uri, @Nullable Bundle args,
@Nullable CancellationSignal cancellationSignal) throws RemoteException;
+ public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+ throws RemoteException;
+
public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
throws RemoteException;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 7cdd268..3c79991 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -28,6 +28,7 @@
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.app.AppOpsManager;
+import android.content.pm.PackageManager;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
@@ -582,6 +583,22 @@
}
}
+ @Override
+ public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+ uri = validateIncomingUri(uri);
+ uri = maybeGetUriWithoutUserId(uri);
+ Trace.traceBegin(TRACE_TAG_DATABASE, "checkUriPermission");
+ final String original = setCallingPackage(callingPkg);
+ try {
+ return mInterface.checkUriPermission(uri, uid, modeFlags);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ } finally {
+ setCallingPackage(original);
+ Trace.traceEnd(TRACE_TAG_DATABASE);
+ }
+ }
+
private void enforceFilePermission(String callingPkg, Uri uri, String mode,
IBinder callerToken) throws FileNotFoundException, SecurityException {
if (mode != null && mode.indexOf('w') != -1) {
@@ -1416,6 +1433,12 @@
return false;
}
+ /** {@hide} */
+ @Override
+ public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+
/**
* @hide
* Implementation when a caller has performed an insert on the content
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 93bf518..8a4330e 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -307,6 +307,25 @@
}
}
+ /** {@hide} */
+ @Override
+ public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+ throws RemoteException {
+ Preconditions.checkNotNull(uri, "uri");
+
+ beforeRemote();
+ try {
+ return mContentProvider.checkUriPermission(mPackageName, uri, uid, modeFlags);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ } finally {
+ afterRemote();
+ }
+ }
+
/** See {@link ContentProvider#insert ContentProvider.insert} */
@Override
public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues)
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 9948338..cd735d4 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -363,6 +363,19 @@
reply.writeInt(out ? 0 : -1);
return true;
}
+
+ case CHECK_URI_PERMISSION_TRANSACTION: {
+ data.enforceInterface(IContentProvider.descriptor);
+ String callingPkg = data.readString();
+ Uri uri = Uri.CREATOR.createFromParcel(data);
+ int uid = data.readInt();
+ int modeFlags = data.readInt();
+
+ int out = checkUriPermission(callingPkg, uri, uid, modeFlags);
+ reply.writeNoException();
+ reply.writeInt(out);
+ return true;
+ }
}
} catch (Exception e) {
DatabaseUtils.writeExceptionToParcel(reply, e);
@@ -800,6 +813,29 @@
}
}
+ @Override
+ public int checkUriPermission(String callingPkg, Uri url, int uid, int modeFlags)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
+
+ data.writeString(callingPkg);
+ url.writeToParcel(data, 0);
+ data.writeInt(uid);
+ data.writeInt(modeFlags);
+
+ mRemote.transact(IContentProvider.CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
+
+ DatabaseUtils.readExceptionFromParcel(reply);
+ return reply.readInt();
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
+ }
+
@UnsupportedAppUsage
private IBinder mRemote;
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0a1bc85..9c86359 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -31,6 +31,7 @@
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.UriGrantsManager;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
@@ -1146,6 +1147,24 @@
}
}
+ /** {@hide} */
+ @Override
+ public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+ Preconditions.checkNotNull(uri, "uri");
+
+ try {
+ if (mWrapped != null) return mWrapped.checkUriPermission(uri, uid, modeFlags);
+ } catch (RemoteException e) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+
+ try (ContentProviderClient client = acquireUnstableContentProviderClient(uri)) {
+ return client.checkUriPermission(uri, uid, modeFlags);
+ } catch (RemoteException e) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ }
+
/**
* Open a stream on to the content associated with a content URI. If there
* is no data associated with the URI, FileNotFoundException is thrown.
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 0427c2f..fade0ab 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -16,6 +16,7 @@
package android.content;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
@@ -82,6 +83,9 @@
public Bundle call(String callingPkg, String authority, String method,
@Nullable String arg, @Nullable Bundle extras) throws RemoteException;
+ public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags)
+ throws RemoteException;
+
public ICancellationSignal createCancellationSignal() throws RemoteException;
public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException;
@@ -116,4 +120,5 @@
static final int CANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 24;
static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25;
static final int REFRESH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 26;
+ static final int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 27;
}
diff --git a/core/java/android/content/LoggingContentInterface.java b/core/java/android/content/LoggingContentInterface.java
index 83c0c91..1df1c4f 100644
--- a/core/java/android/content/LoggingContentInterface.java
+++ b/core/java/android/content/LoggingContentInterface.java
@@ -165,6 +165,19 @@
}
@Override
+ public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+ throws RemoteException {
+ try (Logger l = new Logger("checkUriPermission", uri, uid, modeFlags)) {
+ try {
+ return l.setResult(delegate.checkUriPermission(uri, uid, modeFlags));
+ } catch (Exception res) {
+ l.setResult(res);
+ throw res;
+ }
+ }
+ }
+
+ @Override
public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
throws RemoteException {
try (Logger l = new Logger("insert", uri, initialValues)) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index f75cd23..d0a61eb 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -614,10 +614,10 @@
/**
* Value for {@link #privateFlags}: whether this app is pre-installed on the
- * google partition of the system image.
+ * system_ext partition of the system image.
* @hide
*/
- public static final int PRIVATE_FLAG_PRODUCT_SERVICES = 1 << 21;
+ public static final int PRIVATE_FLAG_SYSTEM_EXT = 1 << 21;
/**
* Indicates whether this package requires access to non-SDK APIs.
@@ -713,7 +713,7 @@
PRIVATE_FLAG_USE_EMBEDDED_DEX,
PRIVATE_FLAG_PRIVILEGED,
PRIVATE_FLAG_PRODUCT,
- PRIVATE_FLAG_PRODUCT_SERVICES,
+ PRIVATE_FLAG_SYSTEM_EXT,
PRIVATE_FLAG_PROFILEABLE_BY_SHELL,
PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
@@ -2046,8 +2046,8 @@
}
/** @hide */
- public boolean isProductServices() {
- return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+ public boolean isSystemExt() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
}
/** @hide */
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 904bd16..c6beee2 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -94,8 +94,6 @@
@UnsupportedAppUsage
ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId);
- boolean shouldShowRequestPermissionRationale(String permName,
- String packageName, int userId);
boolean isProtectedBroadcast(String actionName);
@@ -594,18 +592,12 @@
ParceledListSlice getIntentFilterVerifications(String packageName);
ParceledListSlice getAllIntentFilters(String packageName);
- boolean setDefaultBrowserPackageName(String packageName, int userId);
- String getDefaultBrowserPackageName(int userId);
-
VerifierDeviceIdentity getVerifierDeviceIdentity();
boolean isFirstBoot();
boolean isOnlyCoreApps();
boolean isDeviceUpgrading();
- void setPermissionEnforced(String permission, boolean enforced);
- boolean isPermissionEnforced(String permission);
-
/** Reflects current DeviceStorageMonitorService state */
@UnsupportedAppUsage
boolean isStorageLow();
@@ -629,17 +621,6 @@
boolean isPackageSignedByKeySet(String packageName, in KeySet ks);
boolean isPackageSignedByKeySetExactly(String packageName, in KeySet ks);
- void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
- void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
- void grantDefaultPermissionsToEnabledTelephonyDataServices(
- in String[] packageNames, int userId);
- void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
- in String[] packageNames, int userId);
- void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
- void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
-
- boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
-
@UnsupportedAppUsage
String getPermissionControllerPackageName();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b845a37..4d8a0c4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3571,7 +3571,7 @@
/**
* Retrieve all of the information we know about a particular permission.
*
- * @param permissionName The fully qualified name (i.e. com.google.permission.LOGIN)
+ * @param permName The fully qualified name (i.e. com.google.permission.LOGIN)
* of the permission you are interested in.
* @param flags Additional option flags to modify the data returned.
* @return Returns a {@link PermissionInfo} containing information about the
@@ -3579,7 +3579,7 @@
* @throws NameNotFoundException if a package with the given name cannot be
* found on the system.
*/
- public abstract PermissionInfo getPermissionInfo(@NonNull String permissionName,
+ public abstract PermissionInfo getPermissionInfo(@NonNull String permName,
@PermissionInfoFlags int flags) throws NameNotFoundException;
/**
@@ -3620,7 +3620,7 @@
* Retrieve all of the information we know about a particular group of
* permissions.
*
- * @param permissionName The fully qualified name (i.e.
+ * @param permName The fully qualified name (i.e.
* com.google.permission_group.APPS) of the permission you are
* interested in.
* @param flags Additional option flags to modify the data returned.
@@ -3630,7 +3630,7 @@
* found on the system.
*/
@NonNull
- public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permissionName,
+ public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permName,
@PermissionGroupInfoFlags int flags) throws NameNotFoundException;
/**
@@ -3858,7 +3858,7 @@
* Check whether a particular package has been granted a particular
* permission.
*
- * @param permissionName The name of the permission you are checking for.
+ * @param permName The name of the permission you are checking for.
* @param packageName The name of the package you are checking against.
*
* @return If the package has the permission, PERMISSION_GRANTED is
@@ -3870,7 +3870,7 @@
*/
@CheckResult
@PermissionResult
- public abstract int checkPermission(@NonNull String permissionName,
+ public abstract int checkPermission(@NonNull String permName,
@NonNull String packageName);
/**
@@ -3880,13 +3880,13 @@
* permissions, hence the only way for an app to get such a permission
* is by a policy change.
*
- * @param permissionName The name of the permission you are checking for.
+ * @param permName The name of the permission you are checking for.
* @param packageName The name of the package you are checking against.
*
* @return Whether the permission is restricted by policy.
*/
@CheckResult
- public abstract boolean isPermissionRevokedByPolicy(@NonNull String permissionName,
+ public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName,
@NonNull String packageName);
/**
@@ -3949,14 +3949,14 @@
* -- you are only allowed to remove permissions that you are allowed
* to add.
*
- * @param permissionName The name of the permission to remove.
+ * @param permName The name of the permission to remove.
*
* @throws SecurityException if you are not allowed to remove the
* given permission name.
*
* @see #addPermission(PermissionInfo)
*/
- public abstract void removePermission(@NonNull String permissionName);
+ public abstract void removePermission(@NonNull String permName);
/**
* Permission flags set when granting or revoking a permission.
@@ -3998,7 +3998,7 @@
* </p>
*
* @param packageName The package to which to grant the permission.
- * @param permissionName The permission name to grant.
+ * @param permName The permission name to grant.
* @param user The user for which to grant the permission.
*
* @see #revokeRuntimePermission(String, String, android.os.UserHandle)
@@ -4009,7 +4009,7 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
public abstract void grantRuntimePermission(@NonNull String packageName,
- @NonNull String permissionName, @NonNull UserHandle user);
+ @NonNull String permName, @NonNull UserHandle user);
/**
* Revoke a runtime permission that was previously granted by {@link
@@ -4025,7 +4025,7 @@
* </p>
*
* @param packageName The package from which to revoke the permission.
- * @param permissionName The permission name to revoke.
+ * @param permName The permission name to revoke.
* @param user The user for which to revoke the permission.
*
* @see #grantRuntimePermission(String, String, android.os.UserHandle)
@@ -4036,12 +4036,12 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
public abstract void revokeRuntimePermission(@NonNull String packageName,
- @NonNull String permissionName, @NonNull UserHandle user);
+ @NonNull String permName, @NonNull UserHandle user);
/**
* Gets the state flags associated with a permission.
*
- * @param permissionName The permission for which to get the flags.
+ * @param permName The permission for which to get the flags.
* @param packageName The package name for which to get the flags.
* @param user The user for which to get permission flags.
* @return The permission flags.
@@ -4056,14 +4056,14 @@
android.Manifest.permission.GET_RUNTIME_PERMISSIONS
})
@PermissionFlags
- public abstract int getPermissionFlags(@NonNull String permissionName,
+ public abstract int getPermissionFlags(@NonNull String permName,
@NonNull String packageName, @NonNull UserHandle user);
/**
* Updates the flags associated with a permission by replacing the flags in
* the specified mask with the provided flag values.
*
- * @param permissionName The permission for which to update the flags.
+ * @param permName The permission for which to update the flags.
* @param packageName The package name for which to update the flags.
* @param flagMask The flags which to replace.
* @param flagValues The flags with which to replace.
@@ -4077,7 +4077,7 @@
android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
})
- public abstract void updatePermissionFlags(@NonNull String permissionName,
+ public abstract void updatePermissionFlags(@NonNull String permName,
@NonNull String packageName, @PermissionFlags int flagMask,
@PermissionFlags int flagValues, @NonNull UserHandle user);
@@ -4164,7 +4164,7 @@
* provided ones.
*
* @param packageName The app for which to get whitelisted permissions.
- * @param permission The whitelisted permission to add.
+ * @param permName The whitelisted permission to add.
* @param whitelistFlags The whitelists to which to add. Passing multiple flags
* updates all specified whitelists.
* @return Whether the permission was added to the whitelist.
@@ -4180,7 +4180,7 @@
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
- @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+ @NonNull String permName, @PermissionWhitelistFlags int whitelistFlags) {
return false;
}
@@ -4218,7 +4218,7 @@
* provided ones.
*
* @param packageName The app for which to get whitelisted permissions.
- * @param permission The whitelisted permission to remove.
+ * @param permName The whitelisted permission to remove.
* @param whitelistFlags The whitelists from which to remove. Passing multiple flags
* updates all specified whitelists.
* @return Whether the permission was removed from the whitelist.
@@ -4234,7 +4234,7 @@
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
- @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+ @NonNull String permName, @PermissionWhitelistFlags int whitelistFlags) {
return false;
}
@@ -4244,13 +4244,13 @@
* which the permission is requested does not clearly communicate to the user
* what would be the benefit from grating this permission.
*
- * @param permissionName A permission your app wants to request.
+ * @param permName A permission your app wants to request.
* @return Whether you can show permission rationale UI.
*
* @hide
*/
@UnsupportedAppUsage
- public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permissionName);
+ public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permName);
/**
* Returns an {@link android.content.Intent} suitable for passing to
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index e21d4c41..2f198ac 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -84,139 +84,6 @@
}
/**
- * Provider for package names.
- */
- public interface PackagesProvider {
-
- /**
- * Gets the packages for a given user.
- * @param userId The user id.
- * @return The package names.
- */
- public String[] getPackages(int userId);
- }
-
- /**
- * Provider for package names.
- */
- public interface SyncAdapterPackagesProvider {
-
- /**
- * Gets the sync adapter packages for given authority and user.
- * @param authority The authority.
- * @param userId The user id.
- * @return The package names.
- */
- public String[] getPackages(String authority, int userId);
- }
-
- /**
- * Provider for default browser
- */
- public interface DefaultBrowserProvider {
-
- /**
- * Get the package name of the default browser.
- *
- * @param userId the user id
- *
- * @return the package name of the default browser, or {@code null} if none
- */
- @Nullable
- String getDefaultBrowser(@UserIdInt int userId);
-
- /**
- * Set the package name of the default browser.
- *
- * @param packageName package name of the default browser, or {@code null} to remove
- * @param userId the user id
- *
- * @return whether the default browser was successfully set.
- */
- boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
-
- /**
- * Set the package name of the default browser asynchronously.
- *
- * @param packageName package name of the default browser, or {@code null} to remove
- * @param userId the user id
- */
- void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
- }
-
- /**
- * Provider for default dialer
- */
- public interface DefaultDialerProvider {
-
- /**
- * Get the package name of the default dialer.
- *
- * @param userId the user id
- *
- * @return the package name of the default dialer, or {@code null} if none
- */
- @Nullable
- String getDefaultDialer(@UserIdInt int userId);
- }
-
- /**
- * Provider for default home
- */
- public interface DefaultHomeProvider {
-
- /**
- * Get the package name of the default home.
- *
- * @param userId the user id
- *
- * @return the package name of the default home, or {@code null} if none
- */
- @Nullable
- String getDefaultHome(@UserIdInt int userId);
-
- /**
- * Set the package name of the default home.
- *
- * @param packageName package name of the default home, or {@code null} to remove
- * @param userId the user id
- * @param callback the callback made after the default home as been updated
- */
- void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
- @NonNull Consumer<Boolean> callback);
- }
-
- /**
- * Sets the location provider packages provider.
- * @param provider The packages provider.
- */
- public abstract void setLocationPackagesProvider(PackagesProvider provider);
-
- /**
- * Set the location extra packages provider.
- * @param provider The packages provider.
- */
- public abstract void setLocationExtraPackagesProvider(PackagesProvider provider);
-
- /**
- * Sets the voice interaction packages provider.
- * @param provider The packages provider.
- */
- public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
-
- /**
- * Sets the Use Open Wifi packages provider.
- * @param provider The packages provider.
- */
- public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
-
- /**
- * Sets the sync adapter packages provider.
- * @param provider The provider.
- */
- public abstract void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider);
-
- /**
* Called when the package for the default SMS handler changed
*
* @param packageName the new sms package
@@ -233,14 +100,6 @@
public void onDefaultSimCallManagerAppChanged(String packageName, int userId) {}
/**
- * Requests granting of the default permissions to the current default Use Open Wifi app.
- * @param packageName The default use open wifi package name.
- * @param userId The user for which to grant the permissions.
- */
- public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName,
- int userId);
-
- /**
* Sets a list of apps to keep in PM's internal data structures and as APKs even if no user has
* currently installed it. The apps are not preloaded.
* @param packageList List of package names to keep cached.
@@ -697,7 +556,15 @@
* @see #canAccessInstantApps
*/
public abstract boolean filterAppAccess(
- @Nullable PackageParser.Package pkg, int callingUid, int userId);
+ @NonNull PackageParser.Package pkg, int callingUid, int userId);
+
+ /**
+ * Returns whether or not access to the application should be filtered.
+ *
+ * @see #filterAppAccess(android.content.pm.PackageParser.Package, int, int)
+ */
+ public abstract boolean filterAppAccess(
+ @NonNull String packageName, int callingUid, int userId);
/** Returns whether the given package was signed by the platform */
public abstract boolean isPlatformSigned(String pkg);
@@ -872,27 +739,6 @@
public abstract String removeLegacyDefaultBrowserPackageName(int userId);
/**
- * Sets the default browser provider.
- *
- * @param provider the provider
- */
- public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
-
- /**
- * Sets the default dialer provider.
- *
- * @param provider the provider
- */
- public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
-
- /**
- * Sets the default home provider.
- *
- * @param provider the provider
- */
- public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
-
- /**
* Returns {@code true} if given {@code packageName} is an apex package.
*/
public abstract boolean isApexPackage(String packageName);
@@ -910,15 +756,6 @@
IntentSender intentSender);
/**
- * Whether default permission grants have been performed for a user
- * since the device booted.
- *
- * @param userId The user id.
- * @return true if default permissions
- */
- public abstract boolean wereDefaultPermissionsGrantedSinceBoot(int userId);
-
- /**
* Get fingerprint of build that updated the runtime permissions for a user.
*
* @param userId The user to update
@@ -960,4 +797,10 @@
*/
public abstract boolean isCallerInstallerOfRecord(
@NonNull PackageParser.Package pkg, int callingUid);
+
+ /** Returns whether or not default runtime permissions are granted for the given user */
+ public abstract boolean areDefaultRuntimePermissionsGranted(@UserIdInt int userId);
+
+ /** Sets the enforcement of reading external storage */
+ public abstract void setReadExternalStorageEnforced(boolean enforced);
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a74c34f..e690a7f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -254,6 +254,8 @@
/** @hide */
public static final String APK_FILE_EXTENSION = ".apk";
+ /** @hide */
+ public static final String APEX_FILE_EXTENSION = ".apex";
/** @hide */
public static class NewPermissionInfo {
@@ -6897,8 +6899,8 @@
}
/** @hide */
- public boolean isProductServices() {
- return applicationInfo.isProductServices();
+ public boolean isSystemExt() {
+ return applicationInfo.isSystemExt();
}
/** @hide */
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 2b1b32e..30d87f4 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -19,10 +19,11 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import com.android.internal.os.RoSystemProperties;
+
/**
* Per-user information.
* @hide
@@ -232,7 +233,9 @@
if (isManagedProfile() || isGuest() || isRestricted()) {
return false;
}
- if (UserManager.isSplitSystemUser()) {
+ boolean splitOrHeadlessSystemUser = UserManager.isSplitSystemUser()
+ || RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER;
+ if (splitOrHeadlessSystemUser) {
return id != UserHandle.USER_SYSTEM;
} else {
return id == UserHandle.USER_SYSTEM;
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index a99a0b5..f3b7553 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -32,8 +32,8 @@
import android.view.WindowManager.LayoutParams;
/**
- * CompatibilityInfo class keeps the information about compatibility mode that the application is
- * running under.
+ * CompatibilityInfo class keeps the information about the screen compatibility mode that the
+ * application is running under.
*
* {@hide}
*/
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9f4118e..b3125d8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1191,7 +1191,7 @@
ArrayList<Partition> partitions = new ArrayList();
String[] names = new String[] {
- "bootimage", "odm", "product", "product_services", Partition.PARTITION_NAME_SYSTEM,
+ "bootimage", "odm", "product", "system_ext", Partition.PARTITION_NAME_SYSTEM,
"vendor"
};
for (String name : names) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0ee9a11..3462d1f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -54,7 +54,7 @@
private static final String ENV_ODM_ROOT = "ODM_ROOT";
private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
- private static final String ENV_PRODUCT_SERVICES_ROOT = "PRODUCT_SERVICES_ROOT";
+ private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
/** {@hide} */
public static final String DIR_ANDROID = "Android";
@@ -77,8 +77,8 @@
private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
- private static final File DIR_PRODUCT_SERVICES_ROOT = getDirectory(ENV_PRODUCT_SERVICES_ROOT,
- "/product_services");
+ private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
+ "/system_ext");
@UnsupportedAppUsage
private static UserEnvironment sCurrentUser;
@@ -222,11 +222,26 @@
* Return root directory of the "product_services" partition holding middleware
* services if any. If present, the partition is mounted read-only.
*
+ * @deprecated This directory is not guaranteed to exist.
+ * Its name is changed to "system_ext" because the partition's purpose is changed.
+ * {@link #getSystemExtDirectory()}
* @hide
*/
@SystemApi
+ @Deprecated
public static @NonNull File getProductServicesDirectory() {
- return DIR_PRODUCT_SERVICES_ROOT;
+ return getDirectory("PRODUCT_SERVICES_ROOT", "/product_services");
+ }
+
+ /**
+ * Return root directory of the "system_ext" partition holding system partition's extension
+ * If present, the partition is mounted read-only.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static @NonNull File getSystemExtDirectory() {
+ return DIR_SYSTEM_EXT_ROOT;
}
/**
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index d31cee0..9fa5f16 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -70,4 +70,31 @@
void revokeRuntimePermission(String packageName, String permName, int userId);
void resetRuntimePermissions();
+
+ boolean setDefaultBrowser(String packageName, int userId);
+
+ String getDefaultBrowser(int userId);
+
+ void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
+
+ void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
+
+ void grantDefaultPermissionsToEnabledTelephonyDataServices(
+ in String[] packageNames, int userId);
+
+ void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+ in String[] packageNames, int userId);
+
+ void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
+
+ void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
+
+ void setPermissionEnforced(String permName, boolean enforced);
+
+ boolean isPermissionEnforced(String permName);
+
+ boolean shouldShowRequestPermissionRationale(String permName,
+ String packageName, int userId);
+
+ boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 4bfd138..f73f28a 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -308,7 +308,7 @@
/**
* Called when the system gesture exclusion has changed.
*/
- void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
+ oneway void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
/**
* Request the server to call setInputWindowInfo on a given Surface, and return
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index abf5e3f..57dfc62 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -16,7 +16,7 @@
package android.view;
-import android.graphics.Rect;
+import android.graphics.Region;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -44,7 +44,7 @@
public IBinder parentToken;
public IBinder activityToken;
public boolean focused;
- public final Rect boundsInScreen = new Rect();
+ public Region regionInScreen = new Region();
public List<IBinder> childTokens;
public CharSequence title;
public long accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -73,7 +73,7 @@
window.parentToken = other.parentToken;
window.activityToken = other.activityToken;
window.focused = other.focused;
- window.boundsInScreen.set(other.boundsInScreen);
+ window.regionInScreen.set(other.regionInScreen);
window.title = other.title;
window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor;
window.inPictureInPicture = other.inPictureInPicture;
@@ -109,7 +109,7 @@
parcel.writeStrongBinder(parentToken);
parcel.writeStrongBinder(activityToken);
parcel.writeInt(focused ? 1 : 0);
- boundsInScreen.writeToParcel(parcel, flags);
+ regionInScreen.writeToParcel(parcel, flags);
parcel.writeCharSequence(title);
parcel.writeLong(accessibilityIdOfAnchor);
parcel.writeInt(inPictureInPicture ? 1 : 0);
@@ -132,7 +132,8 @@
builder.append(", type=").append(type);
builder.append(", layer=").append(layer);
builder.append(", token=").append(token);
- builder.append(", bounds=").append(boundsInScreen);
+ builder.append(", region=").append(regionInScreen);
+ builder.append(", bounds=").append(regionInScreen.getBounds());
builder.append(", parent=").append(parentToken);
builder.append(", focused=").append(focused);
builder.append(", children=").append(childTokens);
@@ -151,7 +152,7 @@
parentToken = parcel.readStrongBinder();
activityToken = parcel.readStrongBinder();
focused = (parcel.readInt() == 1);
- boundsInScreen.readFromParcel(parcel);
+ regionInScreen = Region.CREATOR.createFromParcel(parcel);
title = parcel.readCharSequence();
accessibilityIdOfAnchor = parcel.readLong();
inPictureInPicture = (parcel.readInt() == 1);
@@ -174,7 +175,7 @@
parentToken = null;
activityToken = null;
focused = false;
- boundsInScreen.setEmpty();
+ regionInScreen.setEmpty();
if (childTokens != null) {
childTokens.clear();
}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 985effb..fd09a87 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -622,6 +622,10 @@
/**
* Change type for {@link #TYPE_WINDOWS_CHANGED} event:
* The window's bounds changed.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#R R}, this event implies the window's
+ * region changed. It's also possible that region changed but bounds doesn't.
+ * </p>
*/
public static final int WINDOWS_CHANGE_BOUNDS = 0x00000008;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index ea61ef8..6a3af34 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -16,9 +16,11 @@
package android.view.accessibility;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.graphics.Rect;
+import android.graphics.Region;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -107,7 +109,7 @@
private int mBooleanProperties;
private int mId = UNDEFINED_WINDOW_ID;
private int mParentId = UNDEFINED_WINDOW_ID;
- private final Rect mBoundsInScreen = new Rect();
+ private Region mRegionInScreen = new Region();
private LongArray mChildIds;
private CharSequence mTitle;
private long mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -305,23 +307,33 @@
}
/**
- * Gets the bounds of this window in the screen.
+ * Gets the touchable region of this window in the screen.
+ *
+ * @param outRegion The out window region.
+ */
+ public void getRegionInScreen(@NonNull Region outRegion) {
+ outRegion.set(mRegionInScreen);
+ }
+
+ /**
+ * Sets the touchable region of this window in the screen.
+ *
+ * @param region The window region.
+ *
+ * @hide
+ */
+ public void setRegionInScreen(Region region) {
+ mRegionInScreen.set(region);
+ }
+
+ /**
+ * Gets the bounds of this window in the screen. This is equivalent to get the bounds of the
+ * Region from {@link #getRegionInScreen(Region)}.
*
* @param outBounds The out window bounds.
*/
public void getBoundsInScreen(Rect outBounds) {
- outBounds.set(mBoundsInScreen);
- }
-
- /**
- * Sets the bounds of this window in the screen.
- *
- * @param bounds The out window bounds.
- *
- * @hide
- */
- public void setBoundsInScreen(Rect bounds) {
- mBoundsInScreen.set(bounds);
+ outBounds.set(mRegionInScreen.getBounds());
}
/**
@@ -522,7 +534,7 @@
parcel.writeInt(mBooleanProperties);
parcel.writeInt(mId);
parcel.writeInt(mParentId);
- mBoundsInScreen.writeToParcel(parcel, flags);
+ mRegionInScreen.writeToParcel(parcel, flags);
parcel.writeCharSequence(mTitle);
parcel.writeLong(mAnchorId);
@@ -552,7 +564,7 @@
mBooleanProperties = other.mBooleanProperties;
mId = other.mId;
mParentId = other.mParentId;
- mBoundsInScreen.set(other.mBoundsInScreen);
+ mRegionInScreen.set(other.mRegionInScreen);
mTitle = other.mTitle;
mAnchorId = other.mAnchorId;
@@ -574,7 +586,7 @@
mBooleanProperties = parcel.readInt();
mId = parcel.readInt();
mParentId = parcel.readInt();
- mBoundsInScreen.readFromParcel(parcel);
+ mRegionInScreen = Region.CREATOR.createFromParcel(parcel);
mTitle = parcel.readCharSequence();
mAnchorId = parcel.readLong();
@@ -621,7 +633,8 @@
builder.append(", id=").append(mId);
builder.append(", type=").append(typeToString(mType));
builder.append(", layer=").append(mLayer);
- builder.append(", bounds=").append(mBoundsInScreen);
+ builder.append(", region=").append(mRegionInScreen);
+ builder.append(", bounds=").append(mRegionInScreen.getBounds());
builder.append(", focused=").append(isFocused());
builder.append(", active=").append(isActive());
builder.append(", pictureInPicture=").append(isInPictureInPictureMode());
@@ -661,7 +674,7 @@
mBooleanProperties = 0;
mId = UNDEFINED_WINDOW_ID;
mParentId = UNDEFINED_WINDOW_ID;
- mBoundsInScreen.setEmpty();
+ mRegionInScreen.setEmpty();
mChildIds = null;
mConnectionId = UNDEFINED_WINDOW_ID;
mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -716,7 +729,6 @@
}
}
-
/**
* Reports how this window differs from a possibly different state of the same window. The
* argument must have the same id and type as neither of those properties may change.
@@ -739,8 +751,7 @@
if (!TextUtils.equals(mTitle, other.mTitle)) {
changes |= AccessibilityEvent.WINDOWS_CHANGE_TITLE;
}
-
- if (!mBoundsInScreen.equals(other.mBoundsInScreen)) {
+ if (!mRegionInScreen.equals(other.mRegionInScreen)) {
changes |= AccessibilityEvent.WINDOWS_CHANGE_BOUNDS;
}
if (mLayer != other.mLayer) {
diff --git a/core/java/android/view/inputmethod/InputMethodSystemProperty.java b/core/java/android/view/inputmethod/InputMethodSystemProperty.java
index 0689806..e20c2fd 100644
--- a/core/java/android/view/inputmethod/InputMethodSystemProperty.java
+++ b/core/java/android/view/inputmethod/InputMethodSystemProperty.java
@@ -17,7 +17,6 @@
package android.view.inputmethod;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.content.ComponentName;
import android.os.Build;
import android.os.SystemProperties;
@@ -27,7 +26,6 @@
*
* @hide
*/
-@TestApi
public class InputMethodSystemProperty {
/**
* System property key for the production use. The value must be either empty or a valid
@@ -78,6 +76,5 @@
*
* @hide
*/
- @TestApi
public static final boolean MULTI_CLIENT_IME_ENABLED = (sMultiClientImeComponentName != null);
}
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 9fc79cb..364278d 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -194,9 +194,8 @@
final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
- final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppPermissions = new ArrayMap<>();
- final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppDenyPermissions =
- new ArrayMap<>();
+ final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>();
+ final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>();
final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
@@ -321,12 +320,20 @@
return mProductPrivAppDenyPermissions.get(packageName);
}
- public ArraySet<String> getProductServicesPrivAppPermissions(String packageName) {
- return mProductServicesPrivAppPermissions.get(packageName);
+ /**
+ * Read from "permission" tags in /system_ext/etc/permissions/*.xml
+ * @return Set of privileged permissions that are explicitly granted.
+ */
+ public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) {
+ return mSystemExtPrivAppPermissions.get(packageName);
}
- public ArraySet<String> getProductServicesPrivAppDenyPermissions(String packageName) {
- return mProductServicesPrivAppDenyPermissions.get(packageName);
+ /**
+ * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml
+ * @return Set of privileged permissions that are explicitly denied.
+ */
+ public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) {
+ return mSystemExtPrivAppDenyPermissions.get(packageName);
}
public Map<String, Boolean> getOemPermissions(String packageName) {
@@ -398,11 +405,11 @@
readPermissions(Environment.buildPath(
Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
- // Allow /product_services to customize all system configs
+ // Allow /system_ext to customize all system configs
readPermissions(Environment.buildPath(
- Environment.getProductServicesDirectory(), "etc", "sysconfig"), ALLOW_ALL);
+ Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
readPermissions(Environment.buildPath(
- Environment.getProductServicesDirectory(), "etc", "permissions"), ALLOW_ALL);
+ Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
}
void readPermissions(File libraryDir, int permissionFlag) {
@@ -848,7 +855,7 @@
} break;
case "privapp-permissions": {
if (allowPrivappPermissions) {
- // privapp permissions from system, vendor, product and product_services
+ // privapp permissions from system, vendor, product and system_ext
// partitions are stored separately. This is to prevent xml files in
// the vendor partition from granting permissions to priv apps in the
// system partition and vice versa.
@@ -858,17 +865,17 @@
Environment.getOdmDirectory().toPath() + "/");
boolean product = permFile.toPath().startsWith(
Environment.getProductDirectory().toPath() + "/");
- boolean productServices = permFile.toPath().startsWith(
- Environment.getProductServicesDirectory().toPath() + "/");
+ boolean systemExt = permFile.toPath().startsWith(
+ Environment.getSystemExtDirectory().toPath() + "/");
if (vendor) {
readPrivAppPermissions(parser, mVendorPrivAppPermissions,
mVendorPrivAppDenyPermissions);
} else if (product) {
readPrivAppPermissions(parser, mProductPrivAppPermissions,
mProductPrivAppDenyPermissions);
- } else if (productServices) {
- readPrivAppPermissions(parser, mProductServicesPrivAppPermissions,
- mProductServicesPrivAppDenyPermissions);
+ } else if (systemExt) {
+ readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
+ mSystemExtPrivAppDenyPermissions);
} else {
readPrivAppPermissions(parser, mPrivAppPermissions,
mPrivAppDenyPermissions);
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index 6934d26..06e31a1 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -18,8 +18,9 @@
#include <jni.h>
#include <android/bitmap.h>
-#include <SkBitmap.h>
-#include <SkImageInfo.h>
+
+class SkBitmap;
+struct SkImageInfo;
namespace android {
@@ -34,8 +35,8 @@
};
jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
- int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL,
- jobject ninePatchInsets = NULL, int density = -1);
+ int bitmapCreateFlags, jbyteArray ninePatchChunk = nullptr,
+ jobject ninePatchInsets = nullptr, int density = -1);
void toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap);
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 55abc93..58c5871 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -16,7 +16,6 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
-#include "GraphicsJNI.h"
#include <math.h>
#include <stdio.h>
@@ -33,6 +32,7 @@
#include <SkBitmap.h>
#include "core_jni_helpers.h"
+#include "android/graphics/Bitmap.h"
#undef LOG_TAG
#define LOG_TAG "OpenGLUtil"
@@ -43,6 +43,10 @@
namespace android {
+static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
static inline
void mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
@@ -706,7 +710,7 @@
jlong bitmapPtr)
{
SkBitmap nativeBitmap;
- bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
+ bitmap::toSkBitmap(bitmapPtr, &nativeBitmap);
return getInternalFormat(nativeBitmap.colorType());
}
@@ -714,7 +718,7 @@
jlong bitmapPtr)
{
SkBitmap nativeBitmap;
- bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
+ bitmap::toSkBitmap(bitmapPtr, &nativeBitmap);
return getType(nativeBitmap.colorType());
}
@@ -723,7 +727,7 @@
jlong bitmapPtr, jint type, jint border)
{
SkBitmap bitmap;
- bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
+ bitmap::toSkBitmap(bitmapPtr, &bitmap);
SkColorType colorType = bitmap.colorType();
if (internalformat < 0) {
internalformat = getInternalFormat(colorType);
@@ -751,7 +755,7 @@
jlong bitmapPtr, jint format, jint type)
{
SkBitmap bitmap;
- bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
+ bitmap::toSkBitmap(bitmapPtr, &bitmap);
SkColorType colorType = bitmap.colorType();
int internalFormat = getInternalFormat(colorType);
if (format < 0) {
diff --git a/core/jni/android_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp
index 93f2525..3a08148 100644
--- a/core/jni/android_app_ActivityThread.cpp
+++ b/core/jni/android_app_ActivityThread.cpp
@@ -15,7 +15,6 @@
*/
#include "jni.h"
-#include "GraphicsJNI.h"
#include <nativehelper/JNIHelp.h>
#include <minikin/Layout.h>
diff --git a/core/jni/android_nio_utils.h b/core/jni/android_nio_utils.h
index aa75dd0..4aaa0a7 100644
--- a/core/jni/android_nio_utils.h
+++ b/core/jni/android_nio_utils.h
@@ -17,7 +17,7 @@
#ifndef _ANDROID_NIO_UTILS_H_
#define _ANDROID_NIO_UTILS_H_
-#include <android_runtime/AndroidRuntime.h>
+#include <nativehelper/JNIHelp.h>
namespace android {
@@ -68,12 +68,12 @@
AutoBufferPointer() = delete;
AutoBufferPointer(AutoBufferPointer&) = delete;
AutoBufferPointer& operator=(AutoBufferPointer&) = delete;
- static void* operator new(std::size_t);
- static void* operator new[](std::size_t);
- static void* operator new(std::size_t, void*);
- static void* operator new[](std::size_t, void*);
- static void operator delete(void*, std::size_t);
- static void operator delete[](void*, std::size_t);
+ static void* operator new(size_t);
+ static void* operator new[](size_t);
+ static void* operator new(size_t, void*);
+ static void* operator new[](size_t, void*);
+ static void operator delete(void*, size_t);
+ static void operator delete[](void*, size_t);
};
} /* namespace android */
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d6d9391..bf4ffc7 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -161,7 +161,7 @@
}
// Generic idmap parameters
- const char* argv[10];
+ const char* argv[11];
int argc = 0;
struct stat st;
@@ -193,8 +193,8 @@
argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR;
}
- if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
- argv[argc++] = AssetManager::PRODUCT_SERVICES_OVERLAY_DIR;
+ if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+ argv[argc++] = AssetManager::SYSTEM_EXT_OVERLAY_DIR;
}
if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
@@ -235,8 +235,8 @@
input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR);
}
- if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
- input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR);
+ if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+ input_dirs.push_back(AssetManager::SYSTEM_EXT_OVERLAY_DIR);
}
if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index c9eac79..ca32b00 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -17,7 +17,6 @@
#define LOG_TAG "OpenGLRenderer"
#include "jni.h"
-#include "GraphicsJNI.h"
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 78dd1aa..a579229 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -21,10 +21,10 @@
#include "android_util_Binder.h"
#include "android_hardware_input_InputWindowHandle.h"
#include "android/graphics/Bitmap.h"
-#include "android/graphics/GraphicsJNI.h"
#include "android/graphics/Region.h"
#include "core_jni_helpers.h"
+#include <android_runtime/AndroidRuntime.h>
#include <android-base/chrono_utils.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
@@ -50,6 +50,14 @@
namespace android {
+static void doThrowNPE(JNIEnv* env) {
+ jniThrowNullPointerException(env, NULL);
+}
+
+static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
static const char* const OutOfResourcesException =
"android/view/Surface$OutOfResourcesException";
diff --git a/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp b/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
index d20bae2..d629d63 100644
--- a/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
+++ b/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include "jni.h"
#include <nativehelper/JNIHelp.h>
+#include <utils/LightRefBase.h>
#include "core_jni_helpers.h"
namespace android {
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 940ac22..5aea848 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -30,10 +30,6 @@
#include <gui/GLConsumer.h>
#include <gui/Surface.h>
-#include <GraphicsJNI.h>
-#include <SkBitmap.h>
-#include <SkPixelRef.h>
-
#include <ui/ANativeObjectBase.h>
namespace android {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index e5d6393..ea4b252 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -100,8 +100,8 @@
static const char* kVendorOverlaySubdir = "/system/vendor/overlay-subdir/";
static const char* kSystemProductOverlayDir = "/system/product/overlay/";
static const char* kProductOverlayDir = "/product/overlay";
- static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/";
- static const char* kProductServicesOverlayDir = "/product_services/overlay";
+ static const char* kSystemSystemExtOverlayDir = "/system/system_ext/overlay/";
+ static const char* kSystemExtOverlayDir = "/system_ext/overlay";
static const char* kSystemOdmOverlayDir = "/system/odm/overlay";
static const char* kOdmOverlayDir = "/odm/overlay";
static const char* kSystemOemOverlayDir = "/system/oem/overlay";
@@ -113,8 +113,8 @@
|| android::base::StartsWith(path, kVendorOverlayDir)
|| android::base::StartsWith(path, kSystemProductOverlayDir)
|| android::base::StartsWith(path, kProductOverlayDir)
- || android::base::StartsWith(path, kSystemProductServicesOverlayDir)
- || android::base::StartsWith(path, kProductServicesOverlayDir)
+ || android::base::StartsWith(path, kSystemSystemExtOverlayDir)
+ || android::base::StartsWith(path, kSystemExtOverlayDir)
|| android::base::StartsWith(path, kSystemOdmOverlayDir)
|| android::base::StartsWith(path, kOdmOverlayDir)
|| android::base::StartsWith(path, kSystemOemOverlayDir)
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ebf5b93..40acebc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4981,6 +4981,7 @@
<service
android:name="com.android.server.autofill.AutofillCompatAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
+ android:visibleToInstantApps="true"
android:exported="true">
<meta-data
android:name="android.accessibilityservice"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5ea7f5b..3b12753 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1115,6 +1115,22 @@
regularly selected color mode will be used if this value is negative. -->
<integer name="config_accessibilityColorMode">-1</integer>
+ <!-- The following two arrays specify which color space to use for display composition when a
+ certain color mode is active.
+ Composition color spaces are defined in android.view.Display.COLOR_MODE_xxx, and color
+ modes are defined in ColorDisplayManager.COLOR_MODE_xxx and
+ ColorDisplayManager.VENDOR_COLOR_MODE_xxx.
+ The color space COLOR_MODE_DEFAULT (0) lets the system select the most appropriate
+ composition color space for currently displayed content. Other values (e.g.,
+ COLOR_MODE_SRGB) override system selection; these other color spaces must be supported by
+ the device for for display composition.
+ If a color mode does not have a corresponding color space specified in this array, the
+ currently set composition color space will not be modified.-->
+ <integer-array name="config_displayCompositionColorModes">
+ </integer-array>
+ <integer-array name="config_displayCompositionColorSpaces">
+ </integer-array>
+
<!-- Indicate whether to allow the device to suspend when the screen is off
due to the proximity sensor. This resource should only be set to true
if the sensor HAL correctly handles the proximity sensor as a wake-up source.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c4dbde8..c49092e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3196,6 +3196,8 @@
<java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" />
<java-symbol type="array" name="config_availableColorModes" />
<java-symbol type="integer" name="config_accessibilityColorMode" />
+ <java-symbol type="array" name="config_displayCompositionColorModes" />
+ <java-symbol type="array" name="config_displayCompositionColorSpaces" />
<java-symbol type="bool" name="config_displayWhiteBalanceAvailable" />
<java-symbol type="bool" name="config_displayWhiteBalanceEnabledDefault" />
<java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMin" />
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index d2b18cb..51da0c8 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -416,7 +416,8 @@
IUiAutomationConnection iUiAutomationConnection, int i, boolean b, boolean b1,
boolean b2, boolean b3, Configuration configuration,
CompatibilityInfo compatibilityInfo, Map map, Bundle bundle1, String s1,
- AutofillOptions ao, ContentCaptureOptions co) throws RemoteException {
+ AutofillOptions ao, ContentCaptureOptions co, long[] disableCompatChanges)
+ throws RemoteException {
}
@Override
diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java
index 037a0d9..05e8bd8 100644
--- a/core/tests/coretests/src/android/view/WindowInfoTest.java
+++ b/core/tests/coretests/src/android/view/WindowInfoTest.java
@@ -91,7 +91,7 @@
assertFalse(w.focused);
assertFalse(w.inPictureInPicture);
assertFalse(w.hasFlagWatchOutsideTouch);
- assertTrue(w.boundsInScreen.isEmpty());
+ assertTrue(w.regionInScreen.isEmpty());
}
@SmallTest
@@ -114,7 +114,7 @@
equality &= w1.childTokens.equals(w2.childTokens);
equality &= w1.parentToken == w2.parentToken;
equality &= w1.activityToken == w2.activityToken;
- equality &= w1.boundsInScreen.equals(w2.boundsInScreen);
+ equality &= w1.regionInScreen.equals(w2.regionInScreen);
return equality;
}
@@ -132,6 +132,6 @@
windowInfo.focused = true;
windowInfo.inPictureInPicture = true;
windowInfo.hasFlagWatchOutsideTouch = true;
- windowInfo.boundsInScreen.set(0, 0, 1080, 1080);
+ windowInfo.regionInScreen.set(0, 0, 1080, 1080);
}
}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index aadfcbc..abee1da2 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -71,7 +71,7 @@
import com.android.internal.accessibility.AccessibilityShortcutController.FrameworkObjectProvider;
import com.android.internal.util.test.FakeSettingsProvider;
-import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -136,6 +136,7 @@
mContentResolver = new MockContentResolver(mContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ FakeSettingsProvider.clearSettingsProvider();
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(anyInt()))
@@ -193,8 +194,9 @@
when(mTextToSpeech.getVoice()).thenReturn(mVoice);
}
- @After
- public void tearDown() {
+ @AfterClass
+ public static void cleanUpSettingsProvider() {
+ FakeSettingsProvider.clearSettingsProvider();
}
@Test
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 4755cb8..f7c8337 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -74,7 +74,7 @@
const char* AssetManager::IDMAP_BIN = "/system/bin/idmap";
const char* AssetManager::VENDOR_OVERLAY_DIR = "/vendor/overlay";
const char* AssetManager::PRODUCT_OVERLAY_DIR = "/product/overlay";
-const char* AssetManager::PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+const char* AssetManager::SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
const char* AssetManager::ODM_OVERLAY_DIR = "/odm/overlay";
const char* AssetManager::OEM_OVERLAY_DIR = "/oem/overlay";
const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
@@ -575,7 +575,7 @@
mZipSet.setZipResourceTableAsset(ap.path, ass);
}
}
-
+
if (nextEntryIdx == 0 && ass != NULL) {
// If this is the first resource table in the asset
// manager, then we are going to cache it so that we
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index 66fba26b..ce0985b 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -61,7 +61,7 @@
static const char* IDMAP_BIN;
static const char* VENDOR_OVERLAY_DIR;
static const char* PRODUCT_OVERLAY_DIR;
- static const char* PRODUCT_SERVICES_OVERLAY_DIR;
+ static const char* SYSTEM_EXT_OVERLAY_DIR;
static const char* ODM_OVERLAY_DIR;
static const char* OEM_OVERLAY_DIR;
/*
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 7269bca..16ec877 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -29,7 +29,6 @@
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRect.h"
-#include "SkTDArray.h"
#include "SkTemplates.h"
#include <vector>
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index e50428b..40fbdff 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -16,6 +16,8 @@
#include "RenderProxy.h"
+#include <gui/Surface.h>
+
#include "DeferredLayerUpdater.h"
#include "DisplayList.h"
#include "Properties.h"
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index a0f08cb..c3eb6ed 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -19,7 +19,6 @@
#include <SkBitmap.h>
#include <cutils/compiler.h>
-#include <gui/Surface.h>
#include <utils/Functor.h>
#include "../FrameMetricsObserver.h"
@@ -30,6 +29,7 @@
namespace android {
class GraphicBuffer;
+class Surface;
namespace uirenderer {
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index 5fa860a..5717bb3 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -17,6 +17,7 @@
#include <system/graphics.h>
#include <system/window.h>
+#include <ui/BufferQueueDefs.h>
#include <vulkan/vulkan.h>
#include <SkRefCnt.h>
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index f13a64c..5dcbb05 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -23,6 +23,9 @@
import android.os.Parcelable;
import android.text.TextUtils;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import java.util.Objects;
/**
@@ -53,6 +56,8 @@
final String mDescription;
@Nullable
final String mClientPackageName;
+ @NonNull
+ final List<String> mSupportedCategories;
@Nullable
final Bundle mExtras;
@@ -62,6 +67,7 @@
mName = builder.mName;
mDescription = builder.mDescription;
mClientPackageName = builder.mClientPackageName;
+ mSupportedCategories = builder.mSupportedCategories;
mExtras = builder.mExtras;
}
@@ -71,6 +77,7 @@
mName = in.readString();
mDescription = in.readString();
mClientPackageName = in.readString();
+ mSupportedCategories = in.createStringArrayList();
mExtras = in.readBundle();
}
@@ -103,13 +110,14 @@
&& Objects.equals(mName, other.mName)
&& Objects.equals(mDescription, other.mDescription)
&& Objects.equals(mClientPackageName, other.mClientPackageName)
+ && Objects.equals(mSupportedCategories, other.mSupportedCategories)
//TODO: This will be evaluated as false in most cases. Try not to.
&& Objects.equals(mExtras, other.mExtras);
}
@Override
public int hashCode() {
- return Objects.hash(mId, mName, mDescription);
+ return Objects.hash(mId, mName, mDescription, mSupportedCategories);
}
@NonNull
@@ -146,11 +154,38 @@
return mClientPackageName;
}
+ /**
+ * Gets the supported categories of the route.
+ */
+ @NonNull
+ public List<String> getSupportedCategories() {
+ return mSupportedCategories;
+ }
+
@Nullable
public Bundle getExtras() {
return mExtras;
}
+ //TODO: Move this if we re-define control category / selector things.
+ /**
+ * Returns true if the route supports at least one of the specified control categories
+ *
+ * @param controlCategories the list of control categories to consider
+ * @return true if the route supports at least one category
+ */
+ public boolean supportsControlCategory(@NonNull Collection<String> controlCategories) {
+ Objects.requireNonNull(controlCategories, "control categories must not be null");
+ for (String controlCategory : controlCategories) {
+ for (String supportedCategory : getSupportedCategories()) {
+ if (TextUtils.equals(controlCategory, supportedCategory)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -163,6 +198,7 @@
dest.writeString(mName);
dest.writeString(mDescription);
dest.writeString(mClientPackageName);
+ dest.writeStringList(mSupportedCategories);
dest.writeBundle(mExtras);
}
@@ -187,6 +223,7 @@
String mName;
String mDescription;
String mClientPackageName;
+ List<String> mSupportedCategories;
Bundle mExtras;
public Builder(@NonNull String id, @NonNull String name) {
@@ -198,6 +235,7 @@
}
setId(id);
setName(name);
+ mSupportedCategories = new ArrayList<>();
}
public Builder(@NonNull MediaRoute2Info routeInfo) {
@@ -212,6 +250,7 @@
setName(routeInfo.mName);
mDescription = routeInfo.mDescription;
setClientPackageName(routeInfo.mClientPackageName);
+ setSupportedCategories(routeInfo.mSupportedCategories);
if (routeInfo.mExtras != null) {
mExtras = new Bundle(routeInfo.mExtras);
}
@@ -273,6 +312,39 @@
}
/**
+ * Sets the supported categories of the route.
+ */
+ @NonNull
+ public Builder setSupportedCategories(@NonNull Collection<String> categories) {
+ mSupportedCategories = new ArrayList<>();
+ return addSupportedCategories(categories);
+ }
+
+ /**
+ * Adds supported categories for the route.
+ */
+ @NonNull
+ public Builder addSupportedCategories(@NonNull Collection<String> categories) {
+ Objects.requireNonNull(categories, "categories must not be null");
+ for (String category: categories) {
+ addSupportedCategory(category);
+ }
+ return this;
+ }
+
+ /**
+ * Add a supported category for the route.
+ */
+ @NonNull
+ public Builder addSupportedCategory(@NonNull String category) {
+ if (TextUtils.isEmpty(category)) {
+ throw new IllegalArgumentException("category must not be null or empty");
+ }
+ mSupportedCategories.add(category);
+ return this;
+ }
+
+ /**
* Sets a bundle of extras for the route.
*/
@NonNull
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 5fc37a5..85105e0 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -38,6 +38,8 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
@@ -66,6 +68,8 @@
List<MediaRoute2ProviderInfo> mProviders = Collections.emptyList();
@NonNull
List<MediaRoute2Info> mRoutes = Collections.emptyList();
+ @NonNull
+ ConcurrentMap<String, List<String>> mControlCategoryMap = new ConcurrentHashMap<>();
/**
* Gets an instance of media router manager that controls media route of other applications.
@@ -160,6 +164,8 @@
return -1;
}
+ //TODO: Use cache not to create array. For now, it's unclear when to purge the cache.
+ //Do this when we finalize how to set control categories.
/**
* Gets available routes for an application.
*
@@ -167,8 +173,17 @@
*/
@NonNull
public List<MediaRoute2Info> getAvailableRoutes(@NonNull String packageName) {
- //TODO: filter irrelevant routes.
- return Collections.unmodifiableList(mRoutes);
+ List<String> controlCategories = mControlCategoryMap.get(packageName);
+ if (controlCategories == null) {
+ return Collections.emptyList();
+ }
+ List<MediaRoute2Info> routes = new ArrayList<>();
+ for (MediaRoute2Info route : mRoutes) {
+ if (route.supportsControlCategory(controlCategories)) {
+ routes.add(route);
+ }
+ }
+ return routes;
}
/**
@@ -310,11 +325,8 @@
}
}
- void notifyControlCategoriesChanged(String packageName, List<String> categories) {
- for (CallbackRecord record : mCallbacks) {
- record.mExecutor.execute(
- () -> record.mCallback.onControlCategoriesChanged(packageName, categories));
- }
+ void updateControlCategories(String packageName, List<String> categories) {
+ mControlCategoryMap.put(packageName, categories);
}
/**
@@ -346,15 +358,6 @@
public void onRouteSelected(@NonNull String packageName, @Nullable MediaRoute2Info route) {}
/**
- * Called when the control categories of an application is changed.
- *
- * @param packageName the package name of the app that changed control categories
- * @param categories the changed categories
- */
- public void onControlCategoriesChanged(@NonNull String packageName,
- @NonNull List<String> categories) {}
-
- /**
* Called when the list of routes are changed.
* A client may refresh available routes for each application.
*/
@@ -389,7 +392,7 @@
@Override
public void notifyControlCategoriesChanged(String packageName, List<String> categories) {
- mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
+ mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updateControlCategories,
MediaRouter2Manager.this, packageName, categories));
}
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
index 2cdc6a8..1267aa8 100644
--- a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
@@ -32,19 +32,35 @@
public static final String ROUTE_NAME1 = "Sample Route 1";
public static final String ROUTE_ID2 = "route_id2";
public static final String ROUTE_NAME2 = "Sample Route 2";
+
+ public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
+ public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";
+
public static final String ACTION_REMOVE_ROUTE =
"com.android.mediarouteprovider.action_remove_route";
+ public static final String CATEGORY_SAMPLE =
+ "com.android.mediarouteprovider.CATEGORY_SAMPLE";
+ public static final String CATEGORY_SPECIAL =
+ "com.android.mediarouteprovider.CATEGORY_SPECIAL";
+
Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
private void initializeRoutes() {
MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
+ .addSupportedCategory(CATEGORY_SAMPLE)
.build();
MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2)
+ .addSupportedCategory(CATEGORY_SAMPLE)
.build();
-
+ MediaRoute2Info routeSpecial =
+ new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_CATEGORY, ROUTE_NAME_SPECIAL_CATEGORY)
+ .addSupportedCategory(CATEGORY_SAMPLE)
+ .addSupportedCategory(CATEGORY_SPECIAL)
+ .build();
mRoutes.put(route1.getId(), route1);
mRoutes.put(route2.getId(), route2);
+ mRoutes.put(routeSpecial.getId(), routeSpecial);
}
@Override
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 03b43e2..4282a5bc 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -58,9 +58,18 @@
public static final String ROUTE_NAME1 = "Sample Route 1";
public static final String ROUTE_ID2 = "route_id2";
public static final String ROUTE_NAME2 = "Sample Route 2";
+
+ public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
+ public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";
+
public static final String ACTION_REMOVE_ROUTE =
"com.android.mediarouteprovider.action_remove_route";
+ public static final String CATEGORY_SAMPLE =
+ "com.android.mediarouteprovider.CATEGORY_SAMPLE";
+ public static final String CATEGORY_SPECIAL =
+ "com.android.mediarouteprovider.CATEGORY_SPECIAL";
+
private static final int TIMEOUT_MS = 5000;
private Context mContext;
@@ -69,12 +78,13 @@
private Executor mExecutor;
private String mPackageName;
- private static final List<String> TEST_CONTROL_CATEGORIES = new ArrayList();
- private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1";
- private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2";
+ private static final List<String> CONTROL_CATEGORIES_ALL = new ArrayList();
+ private static final List<String> CONTROL_CATEGORIES_SPECIAL = new ArrayList();
static {
- TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
- TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
+ CONTROL_CATEGORIES_ALL.add(CATEGORY_SAMPLE);
+ CONTROL_CATEGORIES_ALL.add(CATEGORY_SPECIAL);
+
+ CONTROL_CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL);
}
@Before
@@ -125,7 +135,7 @@
// (Control requests shouldn't be used in this way.)
InstrumentationRegistry.getInstrumentation().runOnMainSync(
(Runnable) () -> {
- mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+ mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, mockRouterCallback);
mRouter.sendControlRequest(
new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2).build(),
new Intent(ACTION_REMOVE_ROUTE));
@@ -138,8 +148,11 @@
mManager.removeCallback(mockCallback);
}
+ /**
+ * Tests if we get proper routes for application that has special control category.
+ */
@Test
- public void controlCategoryTest() throws Exception {
+ public void testControlCategory() throws Exception {
MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
mManager.addCallback(mExecutor, mockCallback);
@@ -147,12 +160,19 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync(
() -> {
- mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+ mRouter.addCallback(CONTROL_CATEGORIES_SPECIAL,
+ mExecutor, mockRouterCallback);
mRouter.removeCallback(mockRouterCallback);
}
);
- verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
- .onControlCategoriesChanged(mPackageName, TEST_CONTROL_CATEGORIES);
+ verify(mockCallback, timeout(TIMEOUT_MS))
+ .onRouteListChanged(argThat(routes -> routes.size() > 0));
+
+ Map<String, MediaRoute2Info> routes =
+ createRouteMap(mManager.getAvailableRoutes(mPackageName));
+
+ Assert.assertEquals(1, routes.size());
+ Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
mManager.removeCallback(mockCallback);
}
@@ -164,7 +184,7 @@
MediaRouter2.Callback mockRouterCallback = mock(MediaRouter2.Callback.class);
InstrumentationRegistry.getInstrumentation().runOnMainSync(
() -> {
- mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+ mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, mockRouterCallback);
}
);
@@ -197,10 +217,10 @@
mManager.removeCallback(managerCallback);
}
- @Test
/**
* Tests selecting and unselecting routes of a single provider.
*/
+ @Test
public void testSingleProviderSelect() {
MediaRouter2Manager.Callback managerCallback = mock(MediaRouter2Manager.Callback.class);
MediaRouter2.Callback routerCallback = mock(MediaRouter2.Callback.class);
@@ -208,7 +228,7 @@
mManager.addCallback(mExecutor, managerCallback);
InstrumentationRegistry.getInstrumentation().runOnMainSync(
() -> {
- mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, routerCallback);
+ mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, routerCallback);
}
);
verify(managerCallback, timeout(TIMEOUT_MS))
@@ -218,7 +238,8 @@
createRouteMap(mManager.getAvailableRoutes(mPackageName));
mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1));
- verify(managerCallback, timeout(TIMEOUT_MS))
+ verify(managerCallback, timeout(TIMEOUT_MS)
+ )
.onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID1, routeInfo.getId())
&& TextUtils.equals(routeInfo.getClientPackageName(), mPackageName)));
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index fc5e791..c0dcbbc 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -70,13 +70,9 @@
R.styleable.CarNavigationButton_unselectedAlpha, mUnselectedAlpha);
mSelectedIconResourceId = typedArray.getResourceId(
R.styleable.CarNavigationButton_selectedIcon, mIconResourceId);
+ mIconResourceId = typedArray.getResourceId(
+ R.styleable.CarNavigationButton_icon, 0);
typedArray.recycle();
-
- // ImageView attrs
- TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.ImageView);
- mIconResourceId = a.getResourceId(com.android.internal.R.styleable.ImageView_src, 0);
- a.recycle();
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index a452bae..b1f9797 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -1073,9 +1073,10 @@
// shade is visible to the user. When the notification shade is completely open then
// alpha value will be 1.
float alpha = (float) height / mNotificationView.getHeight();
- Drawable background = mNotificationView.getBackground();
+ Drawable background = mNotificationView.getBackground().mutate();
background.setAlpha((int) (alpha * 255));
+ mNotificationView.setBackground(background);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 9a41f1d..9672fea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -663,7 +663,8 @@
final SpannableStringBuilder sb = new SpannableStringBuilder(textView.getText());
removeExistingRestrictedSpans(sb);
if (disabled) {
- final int disabledColor = context.getColor(R.color.disabled_text_color);
+ final int disabledColor = Utils.getDisabled(context,
+ textView.getCurrentTextColor());
sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setCompoundDrawables(null, null, getRestrictedPadlock(context), null);
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index d32e85f..eb5ca46 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -218,6 +218,13 @@
return list.getDefaultColor();
}
+ /**
+ * This method computes disabled color from normal color
+ *
+ * @param context
+ * @param inputColor normal color.
+ * @return disabled color.
+ */
@ColorInt
public static int getDisabled(Context context, int inputColor) {
return applyAlphaAttr(context, android.R.attr.disabledAlpha, inputColor);
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java
new file mode 100644
index 0000000..c54b471
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.utils;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+
+/** Utility class for getting color attribute **/
+public class ColorUtil {
+
+ /**
+ * Returns android:disabledAlpha value in context
+ */
+ public static float getDisabledAlpha(Context context) {
+ final TypedArray ta = context.obtainStyledAttributes(
+ new int[]{android.R.attr.disabledAlpha});
+ final float alpha = ta.getFloat(0, 0);
+ ta.recycle();
+ return alpha;
+ }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 9d398b5..b11df48 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,7 +16,6 @@
package com.android.providers.settings;
-import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.backup.BackupAgentHelper;
import android.app.backup.BackupDataInput;
@@ -41,6 +40,7 @@
import android.util.BackupUtils;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import java.io.BufferedOutputStream;
@@ -586,15 +586,15 @@
final String[] whitelist;
Map<String, Validator> validators = null;
if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
- whitelist = concat(Settings.Secure.SETTINGS_TO_BACKUP,
+ whitelist = ArrayUtils.concatElements(String.class, Settings.Secure.SETTINGS_TO_BACKUP,
Settings.Secure.LEGACY_RESTORE_SETTINGS);
validators = Settings.Secure.VALIDATORS;
} else if (contentUri.equals(Settings.System.CONTENT_URI)) {
- whitelist = concat(Settings.System.SETTINGS_TO_BACKUP,
+ whitelist = ArrayUtils.concatElements(String.class, Settings.System.SETTINGS_TO_BACKUP,
Settings.System.LEGACY_RESTORE_SETTINGS);
validators = Settings.System.VALIDATORS;
} else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
- whitelist = concat(Settings.Global.SETTINGS_TO_BACKUP,
+ whitelist = ArrayUtils.concatElements(String.class, Settings.Global.SETTINGS_TO_BACKUP,
Settings.Global.LEGACY_RESTORE_SETTINGS);
validators = Settings.Global.VALIDATORS;
} else {
@@ -672,18 +672,6 @@
return (validator != null) && validator.validate(value);
}
- private final String[] concat(String[] first, @Nullable String[] second) {
- if (second == null || second.length == 0) {
- return first;
- }
- final int firstLen = first.length;
- final int secondLen = second.length;
- String[] both = new String[firstLen + secondLen];
- System.arraycopy(first, 0, both, 0, firstLen);
- System.arraycopy(second, 0, both, firstLen, secondLen);
- return both;
- }
-
/**
* Restores the owner info enabled and other settings in LockSettings.
*
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index 28d5402..52ec1f0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -30,7 +30,7 @@
*/
@ProvidesInterface(version = FalsingManager.VERSION)
public interface FalsingManager {
- int VERSION = 1;
+ int VERSION = 2;
void onSucccessfulUnlock();
@@ -103,4 +103,6 @@
void onTouchEvent(MotionEvent ev, int width, int height);
void dump(PrintWriter pw);
+
+ void cleanup();
}
diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml
index c560d7e..e687cdf 100644
--- a/packages/SystemUI/res/layout/biometric_dialog.xml
+++ b/packages/SystemUI/res/layout/biometric_dialog.xml
@@ -55,7 +55,8 @@
android:id="@+id/left_space"
android:layout_weight="1"
android:layout_width="0dp"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:contentDescription="@string/biometric_dialog_empty_space_description"/>
<LinearLayout
android:id="@+id/dialog"
@@ -177,7 +178,8 @@
android:id="@+id/right_space"
android:layout_weight="1"
android:layout_width="0dp"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:contentDescription="@string/biometric_dialog_empty_space_description"/>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/attrs_car.xml b/packages/SystemUI/res/values/attrs_car.xml
index ced26c9..49b87f3 100644
--- a/packages/SystemUI/res/values/attrs_car.xml
+++ b/packages/SystemUI/res/values/attrs_car.xml
@@ -62,6 +62,8 @@
<attr name="unselectedAlpha" />
<!-- icon to be rendered when in selected state -->
<attr name="selectedIcon" />
+ <!-- icon to be rendered (drawable) -->
+ <attr name="icon"/>
</declare-styleable>
<!-- Custom attributes to configure hvac values -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 7c24130..861187f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -154,12 +154,8 @@
<!-- The number of milliseconds before the heads up notification accepts touches. -->
<integer name="touch_acceptance_delay">700</integer>
- <!-- The number of milliseconds before the ambient notification auto-dismisses. This will
- override the default pulse length. -->
- <integer name="heads_up_notification_decay_dozing">10000</integer>
-
<!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
- <integer name="ambient_notification_extension_time">6000</integer>
+ <integer name="ambient_notification_extension_time">10000</integer>
<!-- In multi-window, determines whether the stack where recents lives should grow from
the smallest position when being launched. -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
index 98a8110..98b7e24 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
@@ -38,6 +38,7 @@
public int windowingMode;
public int systemUiVisibility;
public float scale;
+ public long snapshotId;
public ThumbnailData() {
thumbnail = null;
@@ -49,6 +50,7 @@
isTranslucent = false;
windowingMode = WINDOWING_MODE_UNDEFINED;
systemUiVisibility = 0;
+ snapshotId = 0;
}
public ThumbnailData(TaskSnapshot snapshot) {
@@ -61,5 +63,6 @@
isTranslucent = snapshot.isTranslucent();
windowingMode = snapshot.getWindowingMode();
systemUiVisibility = snapshot.getSystemUiVisibility();
+ snapshotId = snapshot.getId();
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 69630c4..4ad262f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -237,6 +237,7 @@
MIN_DRAG_SIZE, getResources().getDisplayMetrics())
&& !mUpdateMonitor.isFaceDetectionRunning()) {
mUpdateMonitor.requestFaceAuth();
+ mCallback.userActivity();
showMessage(null, null);
}
}
@@ -512,7 +513,7 @@
case SimPuk:
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
- if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
+ if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser())) {
finish = true;
eventSubtype = BOUNCER_DISMISS_SIM;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
index 0041b0c..ea175ed 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -239,4 +239,8 @@
public void dump(PrintWriter pw) {
}
+
+ @Override
+ public void cleanup() {
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
index 67dfdca..fba0d50 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
@@ -168,6 +168,7 @@
.append("enabled=").append(isEnabled() ? 1 : 0)
.append(" mScreenOn=").append(mScreenOn ? 1 : 0)
.append(" mState=").append(StatusBarState.toShortString(mState))
+ .append(" mShowingAod=").append(mShowingAod ? 1 : 0)
.toString()
);
}
@@ -550,6 +551,14 @@
pw.println();
}
+ @Override
+ public void cleanup() {
+ mSensorManager.unregisterListener(mSensorEventListener);
+ mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
+ Dependency.get(StatusBarStateController.class).removeCallback(mStatusBarStateListener);
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mKeyguardUpdateCallback);
+ }
+
public Uri reportRejectedTouch() {
if (mDataCollector.isEnabled()) {
return mDataCollector.reportRejectedTouch();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 3cc8ec9a..8210951 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -65,6 +65,7 @@
public void onPluginConnected(FalsingPlugin plugin, Context context) {
FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
if (pluginFalsingManager != null) {
+ mInternalFalsingManager.cleanup();
mInternalFalsingManager = pluginFalsingManager;
}
}
@@ -290,4 +291,9 @@
public void dump(PrintWriter pw) {
mInternalFalsingManager.dump(pw);
}
+
+ @Override
+ public void cleanup() {
+ mInternalFalsingManager.cleanup();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index 00f35aa..cee01a4 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -324,6 +324,11 @@
public void dump(PrintWriter printWriter) {
}
+ @Override
+ public void cleanup() {
+ unregisterSensors();
+ }
+
static void logDebug(String msg) {
logDebug(msg, null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 0e93f42..d3e8b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -77,7 +77,7 @@
protected void extractWallpaperColors() {
super.extractWallpaperColors();
// mTonal is final but this method will be invoked by the base class during its ctor.
- if (mTonal == null) {
+ if (mTonal == null || mNeutralColorsLock == null) {
return;
}
mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 537c09e..1bc7e63 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -30,6 +30,7 @@
import com.android.systemui.SystemUIApplication;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.AsyncSensorManager;
import com.android.systemui.util.wakelock.DelayedWakeLock;
@@ -70,7 +71,7 @@
new DozeScreenState(wrappedService, handler, params, wakeLock),
createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
handler),
- new DozeWallpaperState(context),
+ new DozeWallpaperState(context, getBiometricUnlockController(dozeService)),
new DozeDockHandler(context, machine, host, config, handler, dockManager),
new DozeAuthRemover(dozeService)
});
@@ -108,4 +109,10 @@
final SystemUIApplication app = (SystemUIApplication) appCandidate;
return app.getComponent(DozeHost.class);
}
+
+ public static BiometricUnlockController getBiometricUnlockController(DozeService service) {
+ Application appCandidate = service.getApplication();
+ final SystemUIApplication app = (SystemUIApplication) appCandidate;
+ return app.getComponent(BiometricUnlockController.class);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 3c9d4a9..ae6dac5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -50,9 +50,23 @@
*/
void onSlpiTap(float x, float y);
+ /**
+ * Artificially dim down the the display by changing scrim opacities.
+ * @param scrimOpacity opacity from 0 to 1.
+ */
default void setAodDimmingScrim(float scrimOpacity) {}
+
+ /**
+ * Sets the actual display brightness.
+ * @param value from 0 to 255.
+ */
void setDozeScreenBrightness(int value);
+ /**
+ * Makes scrims black and changes animation durations.
+ */
+ default void prepareForGentleWakeUp() {}
+
void onIgnoreTouchWhilePulsing(boolean ignore);
/**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index 5be097c..38ee2fe 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -82,7 +82,10 @@
boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState);
boolean pulseEnding = oldState == DozeMachine.State.DOZE_PULSE_DONE
&& newState == DozeMachine.State.DOZE_AOD;
- if (messagePending || oldState == DozeMachine.State.INITIALIZED || pulseEnding) {
+ boolean turningOn = (oldState == DozeMachine.State.DOZE_AOD_PAUSED
+ || oldState == DozeMachine.State.DOZE) && newState == DozeMachine.State.DOZE_AOD;
+ boolean justInitialized = oldState == DozeMachine.State.INITIALIZED;
+ if (messagePending || justInitialized || pulseEnding || turningOn) {
// During initialization, we hide the navigation bar. That is however only applied after
// a traversal; setting the screen state here is immediate however, so it can happen
// that the screen turns on again before the navigation bar is hidden. To work around
@@ -91,7 +94,7 @@
// Delay screen state transitions even longer while animations are running.
boolean shouldDelayTransition = newState == DozeMachine.State.DOZE_AOD
- && mParameters.shouldControlScreenOff();
+ && mParameters.shouldControlScreenOff() && !turningOn;
if (shouldDelayTransition) {
mWakeLock.setAcquired(true);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index cf04b7f..6918501 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -198,7 +198,10 @@
updateListening();
}
- private void updateListening() {
+ /**
+ * Registers/unregisters sensors based on internal state.
+ */
+ public void updateListening() {
boolean anyListening = false;
for (TriggerSensor s : mSensors) {
// We don't want to be listening while we're PAUSED (prox sensor is covered)
@@ -231,7 +234,7 @@
public void onUserSwitched() {
for (TriggerSensor s : mSensors) {
- s.updateListener();
+ s.updateListening();
}
}
@@ -246,7 +249,7 @@
return;
}
for (TriggerSensor s : mSensors) {
- s.updateListener();
+ s.updateListening();
}
}
};
@@ -409,22 +412,22 @@
public void setListening(boolean listen) {
if (mRequested == listen) return;
mRequested = listen;
- updateListener();
+ updateListening();
}
public void setDisabled(boolean disabled) {
if (mDisabled == disabled) return;
mDisabled = disabled;
- updateListener();
+ updateListening();
}
public void ignoreSetting(boolean ignored) {
if (mIgnoresSetting == ignored) return;
mIgnoresSetting = ignored;
- updateListener();
+ updateListening();
}
- public void updateListener() {
+ public void updateListening() {
if (!mConfigured || mSensor == null) return;
if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
&& !mRegistered) {
@@ -480,7 +483,7 @@
mCallback.onSensorPulse(mPulseReason, mSensorPerformsProxCheck, screenX, screenY,
event.values);
if (!mRegistered) {
- updateListener(); // reregister, this sensor only fires once
+ updateListening(); // reregister, this sensor only fires once
}
}));
}
@@ -541,7 +544,7 @@
}
@Override
- public void updateListener() {
+ public void updateListening() {
if (!mConfigured) return;
AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 97b08d5..8ef01e8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -201,7 +201,7 @@
// Let's prepare the display to wake-up by drawing black.
// This will cover the hardware wake-up sequence, where the display
// becomes black for a few frames.
- mDozeHost.setAodDimmingScrim(255f);
+ mDozeHost.setAodDimmingScrim(1f);
}
mMachine.wakeUp();
}
@@ -314,6 +314,9 @@
break;
case DOZE_PULSE_DONE:
mDozeSensors.requestTemporaryDisable();
+ // A pulse will temporarily disable sensors that require a touch screen.
+ // Let's make sure that they are re-enabled when the pulse is over.
+ mDozeSensors.updateListening();
break;
case FINISH:
mBroadcastReceiver.unregister(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 51e96d2..e877d44 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -130,6 +130,7 @@
break;
case DOZE:
case DOZE_AOD_PAUSED:
+ mHost.prepareForGentleWakeUp();
unscheduleTimeTick();
break;
case DOZE_REQUEST_PULSE:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
index 1b3cd88..35c8b74 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -24,6 +24,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
import java.io.PrintWriter;
@@ -38,18 +39,22 @@
private final IWallpaperManager mWallpaperManagerService;
private final DozeParameters mDozeParameters;
+ private final BiometricUnlockController mBiometricUnlockController;
private boolean mIsAmbientMode;
- public DozeWallpaperState(Context context) {
+ public DozeWallpaperState(Context context,
+ BiometricUnlockController biometricUnlockController) {
this(IWallpaperManager.Stub.asInterface(
ServiceManager.getService(Context.WALLPAPER_SERVICE)),
+ biometricUnlockController,
DozeParameters.getInstance(context));
}
@VisibleForTesting
DozeWallpaperState(IWallpaperManager wallpaperManagerService,
- DozeParameters parameters) {
+ BiometricUnlockController biometricUnlockController, DozeParameters parameters) {
mWallpaperManagerService = wallpaperManagerService;
+ mBiometricUnlockController = biometricUnlockController;
mDozeParameters = parameters;
}
@@ -76,7 +81,9 @@
} else {
boolean wakingUpFromPulse = oldState == DozeMachine.State.DOZE_PULSING
&& newState == DozeMachine.State.FINISH;
- animated = !mDozeParameters.getDisplayNeedsBlanking() || wakingUpFromPulse;
+ boolean fastDisplay = !mDozeParameters.getDisplayNeedsBlanking();
+ animated = (fastDisplay && !mBiometricUnlockController.unlockedByWakeAndUnlock())
+ || wakingUpFromPulse;
}
if (isAmbientMode != mIsAmbientMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index bc7174d..94cd2cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -141,6 +141,7 @@
private BiometricSourceType mPendingAuthenticatedBioSourceType = null;
private boolean mPendingShowBouncer;
private boolean mHasScreenTurnedOnSinceAuthenticating;
+ private boolean mFadedAwayAfterWakeAndUnlock;
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
@@ -260,6 +261,7 @@
boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated(
biometricSourceType);
if (unlockAllowed) {
+ mKeyguardViewMediator.userActivity();
startWakeAndUnlock(biometricSourceType);
} else {
Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
@@ -367,6 +369,7 @@
@Override
public void onStartedGoingToSleep(int why) {
resetMode();
+ mFadedAwayAfterWakeAndUnlock = false;
mPendingAuthenticatedUserId = -1;
mPendingAuthenticatedBioSourceType = null;
}
@@ -466,8 +469,11 @@
}
if (mStatusBarKeyguardViewManager.isShowing()) {
if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
- return bypass && !mKeyguardBypassController.canPlaySubtleWindowAnimations()
- ? MODE_UNLOCK_COLLAPSING : MODE_UNLOCK_FADING;
+ if (bypass && mKeyguardBypassController.canPlaySubtleWindowAnimations()) {
+ return MODE_UNLOCK_FADING;
+ } else {
+ return MODE_DISMISS_BOUNCER;
+ }
} else if (unlockingAllowed) {
return bypass ? MODE_UNLOCK_FADING : MODE_NONE;
} else {
@@ -509,6 +515,9 @@
}
public void finishKeyguardFadingAway() {
+ if (isWakeAndUnlock()) {
+ mFadedAwayAfterWakeAndUnlock = true;
+ }
resetMode();
}
@@ -559,6 +568,14 @@
}
/**
+ * Successful authentication with fingerprint, face, or iris that wakes up the device.
+ * This will return {@code true} even after the keyguard fades away.
+ */
+ public boolean unlockedByWakeAndUnlock() {
+ return isWakeAndUnlock() || mFadedAwayAfterWakeAndUnlock;
+ }
+
+ /**
* Successful authentication with fingerprint, face, or iris when the screen was either
* on or off.
*/
@@ -567,6 +584,13 @@
}
/**
+ * Successful authentication with fingerprint, face, or iris when the lockscreen fades away
+ */
+ public boolean isUnlockFading() {
+ return mMode == MODE_UNLOCK_FADING;
+ }
+
+ /**
* Translates biometric source type for logging purpose.
*/
private int toSubtype(BiometricSourceType biometricSourceType) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index cbaf85c..680e522 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -72,8 +72,6 @@
private NotificationGroupManager mGroupManager;
private VisualStabilityManager mVisualStabilityManager;
private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
- @VisibleForTesting
- int mAutoDismissNotificationDecayDozing;
private boolean mReleaseOnExpandFinish;
private int mStatusBarHeight;
@@ -120,8 +118,6 @@
KeyguardBypassController bypassController) {
super(context);
Resources resources = mContext.getResources();
- mAutoDismissNotificationDecayDozing = resources.getInteger(
- R.integer.heads_up_notification_decay_dozing);
mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
mAutoHeadsUpNotificationDecay = resources.getInteger(
R.integer.auto_heads_up_notification_decay);
@@ -612,9 +608,7 @@
}
private int getDecayDuration() {
- if (mStatusBarStateController.isDozing()) {
- return mAutoDismissNotificationDecayDozing;
- } else if (isAutoHeadsUp()) {
+ if (isAutoHeadsUp()) {
return getRecommendedHeadsUpTimeoutMs(mAutoHeadsUpNotificationDecay);
} else {
return getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index c88b22b..0aec2b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -167,4 +167,8 @@
pw.print(" qSExpanded: "); pw.println(qSExpanded)
pw.print(" bouncerShowing: "); pw.println(bouncerShowing)
}
+
+ companion object {
+ const val BYPASS_PANEL_FADE_DURATION = 67
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 49afae7..1360a08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -102,6 +102,7 @@
private boolean mWakeAndUnlockRunning;
private boolean mKeyguardShowing;
private boolean mShowingLaunchAffordance;
+ private boolean mKeyguardJustShown;
private boolean mUpdatePending;
private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
@@ -115,6 +116,9 @@
mBlockUpdates = false;
force = true;
}
+ if (!wasShowing && mKeyguardShowing) {
+ mKeyguardJustShown = true;
+ }
update(force);
}
@@ -273,8 +277,10 @@
int state = getState();
int lastState = mLastState;
+ boolean keyguardJustShown = mKeyguardJustShown;
mIsFaceUnlockState = state == STATE_SCANNING_FACE;
mLastState = state;
+ mKeyguardJustShown = false;
boolean shouldUpdate = lastState != state || mForceUpdate;
if (mBlockUpdates && canBlockUpdates()) {
@@ -283,7 +289,7 @@
if (shouldUpdate) {
mForceUpdate = false;
@LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState,
- state, mPulsing, mDozing);
+ state, mPulsing, mDozing, keyguardJustShown);
boolean isAnim = lockAnimIndex != -1;
int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state);
@@ -412,7 +418,7 @@
}
private static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing,
- boolean dozing) {
+ boolean dozing, boolean keyguardJustShown) {
// Never animate when screen is off
if (dozing && !pulsing) {
@@ -423,7 +429,7 @@
return ERROR;
} else if (oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN) {
return UNLOCK;
- } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED) {
+ } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED && !keyguardJustShown) {
return LOCK;
} else if (newState == STATE_SCANNING_FACE) {
return SCANNING;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 0bbfbef..195870b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -464,7 +464,7 @@
if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
return false;
}
- if (!mHeadsUpManager.isAlerting(entry.key)) {
+ if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.key)) {
return false;
}
return (sbn.getNotification().fullScreenIntent != null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3f38c04..1aec5e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -487,6 +487,20 @@
}
/**
+ * Set front scrim to black, cancelling animations, in order to prepare to fade them
+ * away once the display turns on.
+ */
+ public void prepareForGentleWakeUp() {
+ if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
+ mCurrentInFrontAlpha = 1f;
+ mAnimateChange = false;
+ updateScrims();
+ mAnimateChange = true;
+ mAnimationDuration = ANIMATION_DURATION_LONG;
+ }
+ }
+
+ /**
* If the lock screen sensor is active.
*/
public void setWakeLockScreenSensorActive(boolean active) {
@@ -932,6 +946,12 @@
}
}
+ public void setUnlockIsFading(boolean unlockFading) {
+ for (ScrimState state : ScrimState.values()) {
+ state.setUnlockIsFading(unlockFading);
+ }
+ }
+
public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
for (ScrimState state : ScrimState.values()) {
state.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index d152ecd..763e0d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -147,7 +147,9 @@
public void prepare(ScrimState previousState) {
mCurrentBehindAlpha = 0;
mCurrentInFrontAlpha = 0;
- mAnimationDuration = StatusBar.FADE_KEYGUARD_DURATION;
+ mAnimationDuration = mUnlockIsFading
+ ? KeyguardBypassController.BYPASS_PANEL_FADE_DURATION
+ : StatusBar.FADE_KEYGUARD_DURATION;
mAnimateChange = !mLaunchingAffordanceWithPreview;
if (previousState == ScrimState.AOD) {
@@ -198,6 +200,7 @@
boolean mHasBackdrop;
boolean mLaunchingAffordanceWithPreview;
boolean mWakeLockScreenSensorActive;
+ boolean mUnlockIsFading;
ScrimState(int index) {
mIndex = index;
@@ -285,4 +288,8 @@
public void setWakeLockScreenSensorActive(boolean active) {
mWakeLockScreenSensorActive = active;
}
+
+ public void setUnlockIsFading(boolean unlockIsFading) {
+ mUnlockIsFading = unlockIsFading;
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 40ebe58..f8e6aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1229,6 +1229,7 @@
mDozeScrimController, keyguardViewMediator,
mScrimController, this, UnlockMethodCache.getInstance(mContext),
new Handler(), mKeyguardUpdateMonitor, mKeyguardBypassController);
+ putComponent(BiometricUnlockController.class, mBiometricUnlockController);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
@@ -3839,6 +3840,7 @@
public void notifyBiometricAuthModeChanged() {
updateDozing();
+ mScrimController.setUnlockIsFading(mBiometricUnlockController.isUnlockFading());
updateScrimController();
mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(),
mBiometricUnlockController.isBiometricUnlock());
@@ -3850,7 +3852,8 @@
// We don't want to end up in KEYGUARD state when we're unlocking with
// fingerprint from doze. We should cross fade directly from black.
- boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
+ boolean unlocking = mBiometricUnlockController.isWakeAndUnlock()
+ || mKeyguardMonitor.isKeyguardFadingAway();
// Do not animate the scrim expansion when triggered by the fingerprint sensor.
mScrimController.setExpansionAffectsAlpha(
@@ -3875,9 +3878,9 @@
} else if (isPulsing()) {
mScrimController.transitionTo(ScrimState.PULSING,
mDozeScrimController.getScrimCallback());
- } else if (mDozing && !wakeAndUnlocking) {
+ } else if (mDozing && !unlocking) {
mScrimController.transitionTo(ScrimState.AOD);
- } else if (mIsKeyguard && !wakeAndUnlocking) {
+ } else if (mIsKeyguard && !unlocking) {
mScrimController.transitionTo(ScrimState.KEYGUARD);
} else if (mBubbleController.isStackExpanded()) {
mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
@@ -4118,6 +4121,11 @@
mScrimController.setAodFrontScrimAlpha(scrimOpacity);
}
+ @Override
+ public void prepareForGentleWakeUp() {
+ mScrimController.prepareForGentleWakeUp();
+ }
+
private void dispatchTap(View view, float x, float y) {
long now = SystemClock.elapsedRealtime();
dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_DOWN);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 65be708..5ce1329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -85,7 +85,6 @@
// make everything a bit slower to bridge a gap until the user is unlocked and home screen has
// dranw its first frame.
private static final long KEYGUARD_DISMISS_DURATION_LOCKED = 2000;
- private static final long BYPASS_PANEL_FADE_DURATION = 67;
private static String TAG = "StatusBarKeyguardViewManager";
@@ -270,7 +269,7 @@
boolean keyguardWithoutQs = mStatusBarStateController.getState() == StatusBarState.KEYGUARD
&& !mNotificationPanelView.isQsExpanded();
boolean lockVisible = (mBouncer.isShowing() || keyguardWithoutQs)
- && !mBouncer.isAnimatingAway();
+ && !mBouncer.isAnimatingAway() && !mKeyguardMonitor.isKeyguardFadingAway();
if (mLastLockVisible != lockVisible) {
mLastLockVisible = lockVisible;
@@ -279,8 +278,14 @@
AppearAnimationUtils.DEFAULT_APPEAR_DURATION /* duration */,
0 /* delay */);
} else {
+ final long duration;
+ if (needsBypassFading()) {
+ duration = KeyguardBypassController.BYPASS_PANEL_FADE_DURATION;
+ } else {
+ duration = AppearAnimationUtils.DEFAULT_APPEAR_DURATION / 2;
+ }
CrossFadeHelper.fadeOut(mLockIconContainer,
- AppearAnimationUtils.DEFAULT_APPEAR_DURATION / 2 /* duration */,
+ duration /* duration */,
0 /* delay */, null /* runnable */);
}
}
@@ -567,7 +572,7 @@
if (needsBypassFading()) {
ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
mNotificationContainer,
- BYPASS_PANEL_FADE_DURATION,
+ KeyguardBypassController.BYPASS_PANEL_FADE_DURATION,
() -> {
mStatusBar.hideKeyguard();
onKeyguardFadedAway();
@@ -583,7 +588,7 @@
if (needsBypassFading()) {
ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
mNotificationContainer,
- BYPASS_PANEL_FADE_DURATION,
+ KeyguardBypassController.BYPASS_PANEL_FADE_DURATION,
() -> {
mStatusBar.hideKeyguard();
});
@@ -602,6 +607,7 @@
mBiometricUnlockController.finishKeyguardFadingAway();
}
}
+ updateLockIcon();
updateStates();
mStatusBarWindowController.setKeyguardShowing(false);
mViewMediatorCallback.keyguardGone();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 2d6ae26..2ed0970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.withSettings;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.utils.hardware.FakeSensorManager;
import org.mockito.Answers;
import org.mockito.MockSettings;
@@ -39,6 +40,7 @@
when(params.getPickupPerformsProxCheck()).thenReturn(true);
when(params.getPolicy()).thenReturn(mock(AlwaysOnDisplayPolicy.class));
when(params.doubleTapReportsTouchCoordinates()).thenReturn(false);
+ when(params.getDisplayNeedsBlanking()).thenReturn(false);
doneHolder[0] = true;
return params;
@@ -52,11 +54,17 @@
when(config.pickupGestureEnabled(anyInt())).thenReturn(false);
when(config.pulseOnNotificationEnabled(anyInt())).thenReturn(true);
when(config.alwaysOnEnabled(anyInt())).thenReturn(false);
+ when(config.enabled(anyInt())).thenReturn(true);
+ when(config.getWakeLockScreenDebounce()).thenReturn(0L);
when(config.doubleTapSensorType()).thenReturn(null);
when(config.tapSensorType()).thenReturn(null);
when(config.longPressSensorType()).thenReturn(null);
+ when(config.tapGestureEnabled(anyInt())).thenReturn(true);
+ when(config.tapSensorAvailable()).thenReturn(true);
+ when(config.tapSensorType()).thenReturn(FakeSensorManager.TAP_SENSOR_TYPE);
+
when(config.dozePickupSensorAvailable()).thenReturn(false);
when(config.wakeScreenGestureAvailable()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 6979fd8..eb8ef09 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -19,6 +19,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -27,18 +28,17 @@
import static org.mockito.Mockito.when;
import android.app.AlarmManager;
-import android.app.Instrumentation;
+import android.hardware.Sensor;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.wakelock.WakeLock;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -46,14 +46,12 @@
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@Ignore("failing")
@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
public class DozeTriggersTest extends SysuiTestCase {
private DozeTriggers mTriggers;
private DozeMachine mMachine;
@@ -61,10 +59,10 @@
private AmbientDisplayConfiguration mConfig;
private DozeParameters mParameters;
private FakeSensorManager mSensors;
+ private Sensor mTapSensor;
private WakeLock mWakeLock;
- private Instrumentation mInstrumentation;
private AlarmManager mAlarmManager;
- private DockManagerFake mDockManagerFake;
+ private DockManager mDockManagerFake;
@BeforeClass
public static void setupSuite() {
@@ -74,15 +72,15 @@
@Before
public void setUp() throws Exception {
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
mMachine = mock(DozeMachine.class);
mAlarmManager = mock(AlarmManager.class);
- mHost = new DozeHostFake();
+ mHost = spy(new DozeHostFake());
mConfig = DozeConfigurationUtil.createMockConfig();
mParameters = DozeConfigurationUtil.createMockParameters();
- mSensors = new FakeSensorManager(mContext);
+ mSensors = spy(new FakeSensorManager(mContext));
+ mTapSensor = mSensors.getFakeTapSensor().getSensor();
mWakeLock = new WakeLockFake();
- mDockManagerFake = spy(new DockManagerFake());
+ mDockManagerFake = mock(DockManager.class);
mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, mConfig, mParameters,
mSensors, Handler.createAsync(Looper.myLooper()), mWakeLock, true,
@@ -95,29 +93,45 @@
mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+ clearInvocations(mMachine);
mHost.callback.onNotificationAlerted();
-
mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
verify(mMachine, never()).requestState(any());
verify(mMachine, never()).requestPulse(anyInt());
mHost.callback.onNotificationAlerted();
-
mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
verify(mMachine).requestPulse(anyInt());
}
@Test
+ public void testTransitionTo_disablesAndEnablesTouchSensors() {
+ when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
+
+ mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+ verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
+
+ clearInvocations(mSensors);
+ mTriggers.transitionTo(DozeMachine.State.DOZE,
+ DozeMachine.State.DOZE_REQUEST_PULSE);
+ mTriggers.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
+ DozeMachine.State.DOZE_PULSING);
+ verify(mSensors).cancelTriggerSensor(any(), eq(mTapSensor));
+
+ clearInvocations(mSensors);
+ mTriggers.transitionTo(DozeMachine.State.DOZE_PULSING, DozeMachine.State.DOZE_PULSE_DONE);
+ verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
+ }
+
+ @Test
public void testDockEventListener_registerAndUnregister() {
mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
-
verify(mDockManagerFake).addListener(any());
mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH);
-
verify(mDockManagerFake).removeListener(any());
}
@@ -128,7 +142,6 @@
mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP,
false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */,
null /* rawValues */);
-
verify(mMachine, never()).wakeUp();
}
@@ -142,7 +155,7 @@
false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */,
null /* rawValues */);
- verify(mHost).setAodDimmingScrim(eq(255));
+ verify(mHost).setAodDimmingScrim(eq(1f));
verify(mMachine).wakeUp();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
index 87ae85f..f07edf3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -29,6 +30,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
import org.junit.Before;
@@ -44,12 +46,14 @@
private DozeWallpaperState mDozeWallpaperState;
@Mock IWallpaperManager mIWallpaperManager;
+ @Mock BiometricUnlockController mBiometricUnlockController;
@Mock DozeParameters mDozeParameters;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters);
+ mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mBiometricUnlockController,
+ mDozeParameters);
}
@Test
@@ -102,6 +106,20 @@
}
@Test
+ public void testDoesNotAnimate_whenWakeAndUnlock() throws RemoteException {
+ // Pre-conditions
+ when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+ when(mBiometricUnlockController.unlockedByWakeAndUnlock()).thenReturn(true);
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+ DozeMachine.State.DOZE_AOD);
+ clearInvocations(mIWallpaperManager);
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+ verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(0L));
+ }
+
+ @Test
public void testTransitionTo_requestPulseIsAmbientMode() throws RemoteException {
mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE,
DozeMachine.State.DOZE_REQUEST_PULSE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 5c1f473..881cc39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -64,7 +64,7 @@
protected static final int TEST_AUTO_DISMISS_TIME = 500;
// Number of notifications to use in tests requiring multiple notifications
private static final int TEST_NUM_NOTIFICATIONS = 4;
- protected static final int TEST_TIMEOUT_TIME = 10000;
+ protected static final int TEST_TIMEOUT_TIME = 15000;
protected final Runnable TEST_TIMEOUT_RUNNABLE = () -> mTimedOut = true;
private AlertingNotificationManager mAlertingNotificationManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index a99dc7f..7d9920d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
@@ -192,6 +194,34 @@
}
@Test
+ public void onBiometricAuthenticated_whenBypassOnBouncer_dismissBouncer() {
+ reset(mKeyguardBypassController);
+ when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+ when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+ when(mKeyguardBypassController.onBiometricAuthenticated(any())).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
+ mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+ BiometricSourceType.FACE);
+
+ verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+ assertThat(mBiometricUnlockController.getMode())
+ .isEqualTo(BiometricUnlockController.MODE_DISMISS_BOUNCER);
+ }
+
+ @Test
+ public void onBiometricAuthenticated_whenBypassOnBouncer_respectsCanPlaySubtleAnim() {
+ when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+ when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
+ mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+ BiometricSourceType.FACE);
+
+ verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+ assertThat(mBiometricUnlockController.getMode())
+ .isEqualTo(BiometricUnlockController.MODE_UNLOCK_FADING);
+ }
+
+ @Test
public void onBiometricAuthenticated_whenFaceAndPulsing_dontDismissKeyguard() {
reset(mUpdateMonitor);
reset(mStatusBarKeyguardViewManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index f8b9e68..48934da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -70,7 +70,6 @@
setUp(statusBarWindowView, groupManager, bar, vsManager);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
- mAutoDismissNotificationDecayDozing = TEST_AUTO_DISMISS_TIME;
}
}
@@ -134,13 +133,11 @@
@Test
public void testExtendHeadsUp() {
- when(mStatusBarStateController.isDozing()).thenReturn(true);
mHeadsUpManager.showNotification(mEntry);
Runnable pastNormalTimeRunnable =
() -> mLivesPastNormalTime = mHeadsUpManager.isAlerting(mEntry.key);
mTestHandler.postDelayed(pastNormalTimeRunnable,
- mHeadsUpManager.mAutoDismissNotificationDecayDozing +
- mHeadsUpManager.mExtensionTime / 2);
+ TEST_AUTO_DISMISS_TIME + mHeadsUpManager.mExtensionTime / 2);
mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
mHeadsUpManager.extendHeadsUp();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
index a4ae166..29b8ab60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
@@ -40,18 +40,23 @@
import java.util.List;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+
/**
* Rudimentary fake for SensorManager
*
- * Currently only supports the proximity sensor.
+ * Currently only supports proximity, light and tap sensors.
*
* Note that this class ignores the "Handler" argument, so the test is responsible for calling the
* listener on the right thread.
*/
public class FakeSensorManager extends SensorManager {
+ public static final String TAP_SENSOR_TYPE = "tapSensorType";
+
private final MockProximitySensor mMockProximitySensor;
private final FakeGenericSensor mFakeLightSensor;
+ private final FakeGenericSensor mFakeTapSensor;
private final FakeGenericSensor[] mSensors;
public FakeSensorManager(Context context) throws Exception {
@@ -59,12 +64,13 @@
.getDefaultSensor(Sensor.TYPE_PROXIMITY);
if (proxSensor == null) {
// No prox? Let's create a fake one!
- proxSensor = createSensor(Sensor.TYPE_PROXIMITY);
+ proxSensor = createSensor(Sensor.TYPE_PROXIMITY, null);
}
mSensors = new FakeGenericSensor[]{
mMockProximitySensor = new MockProximitySensor(proxSensor),
- mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT)),
+ mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)),
+ mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE))
};
}
@@ -76,6 +82,10 @@
return mFakeLightSensor;
}
+ public FakeGenericSensor getFakeTapSensor() {
+ return mFakeTapSensor;
+ }
+
@Override
public Sensor getDefaultSensor(int type) {
Sensor s = super.getDefaultSensor(type);
@@ -160,13 +170,13 @@
@Override
protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
- return false;
+ return true;
}
@Override
protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
boolean disable) {
- return false;
+ return true;
}
@Override
@@ -185,12 +195,15 @@
return false;
}
- private Sensor createSensor(int type) throws Exception {
+ private Sensor createSensor(int type, @Nullable String stringType) throws Exception {
Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
constr.setAccessible(true);
Sensor sensor = constr.newInstance();
setSensorType(sensor, type);
+ if (stringType != null) {
+ setSensorField(sensor, "mStringType", stringType);
+ }
setSensorField(sensor, "mName", "Mock " + sensor.getStringType() + "/" + type);
setSensorField(sensor, "mVendor", "Mock Vendor");
setSensorField(sensor, "mVersion", 1);
diff --git a/proto/src/task_snapshot.proto b/proto/src/task_snapshot.proto
index 381d983..821db86 100644
--- a/proto/src/task_snapshot.proto
+++ b/proto/src/task_snapshot.proto
@@ -33,4 +33,5 @@
bool is_translucent = 9;
string top_activity_component = 10;
float scale = 11;
- }
\ No newline at end of file
+ int64 id = 12;
+ }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 8415272..1dea2f2 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -23,7 +23,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.graphics.Rect;
import android.graphics.Region;
import android.os.Binder;
import android.os.Handler;
@@ -277,7 +276,7 @@
} else if (!oldWindow.activityToken.equals(newWindow.activityToken)) {
return true;
}
- if (!oldWindow.boundsInScreen.equals(newWindow.boundsInScreen)) {
+ if (!oldWindow.regionInScreen.equals(newWindow.regionInScreen)) {
return true;
}
if (oldWindow.childTokens != null && newWindow.childTokens != null
@@ -755,20 +754,20 @@
boolean windowInteractiveRegionChanged = false;
final int windowCount = mWindows.size();
- final Rect currentWindowBounds = new Rect();
+ final Region currentWindowRegions = new Region();
for (int i = windowCount - 1; i >= 0; i--) {
AccessibilityWindowInfo currentWindow = mWindows.get(i);
if (windowInteractiveRegion == null) {
if (currentWindow.getId() == windowId) {
- currentWindow.getBoundsInScreen(currentWindowBounds);
- outRegion.set(currentWindowBounds);
+ currentWindow.getRegionInScreen(currentWindowRegions);
+ outRegion.set(currentWindowRegions);
windowInteractiveRegion = outRegion;
continue;
}
} else if (currentWindow.getType()
!= AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
- currentWindow.getBoundsInScreen(currentWindowBounds);
- if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
+ currentWindow.getRegionInScreen(currentWindowRegions);
+ if (windowInteractiveRegion.op(currentWindowRegions, Region.Op.DIFFERENCE)) {
windowInteractiveRegionChanged = true;
}
}
@@ -1115,7 +1114,7 @@
reportedWindow.setType(getTypeForWindowManagerWindowType(window.type));
reportedWindow.setLayer(window.layer);
reportedWindow.setFocused(window.focused);
- reportedWindow.setBoundsInScreen(window.boundsInScreen);
+ reportedWindow.setRegionInScreen(window.regionInScreen);
reportedWindow.setTitle(window.title);
reportedWindow.setAnchorId(window.accessibilityIdOfAnchor);
reportedWindow.setPictureInPicture(window.inPictureInPicture);
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 18ee7a4..18c38dc 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -128,7 +128,7 @@
private static final String TAG = "PFTBT";
- private UserBackupManagerService backupManagerService;
+ private UserBackupManagerService mUserBackupManagerService;
private final Object mCancelLock = new Object();
ArrayList<PackageInfo> mPackages;
@@ -159,7 +159,7 @@
@Nullable IBackupManagerMonitor monitor, @Nullable OnTaskFinishedListener listener,
boolean userInitiated) {
super(observer);
- this.backupManagerService = backupManagerService;
+ this.mUserBackupManagerService = backupManagerService;
mTransportClient = transportClient;
mUpdateSchedule = updateSchedule;
mLatch = latch;
@@ -252,16 +252,16 @@
}
private void registerTask() {
- synchronized (backupManagerService.getCurrentOpLock()) {
+ synchronized (mUserBackupManagerService.getCurrentOpLock()) {
Slog.d(TAG, "backupmanager pftbt token=" + Integer.toHexString(mCurrentOpToken));
- backupManagerService.getCurrentOperations().put(
+ mUserBackupManagerService.getCurrentOperations().put(
mCurrentOpToken,
new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
}
}
public void unregisterTask() {
- backupManagerService.removeOperation(mCurrentOpToken);
+ mUserBackupManagerService.removeOperation(mCurrentOpToken);
}
@Override
@@ -288,7 +288,7 @@
mCancelAll = true;
if (mIsDoingBackup) {
- backupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
+ mUserBackupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
try {
// If we're running a backup we should be connected to a transport
IBackupTransport transport =
@@ -320,16 +320,17 @@
int backupRunStatus = BackupManager.SUCCESS;
try {
- if (!backupManagerService.isEnabled() || !backupManagerService.isSetupComplete()) {
+ if (!mUserBackupManagerService.isEnabled()
+ || !mUserBackupManagerService.isSetupComplete()) {
// Backups are globally disabled, so don't proceed.
if (DEBUG) {
- Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
+ Slog.i(TAG, "full backup requested but enabled=" + mUserBackupManagerService
.isEnabled()
- + " setupComplete=" + backupManagerService.isSetupComplete()
+ + " setupComplete=" + mUserBackupManagerService.isSetupComplete()
+ "; ignoring");
}
int monitoringEvent;
- if (backupManagerService.isSetupComplete()) {
+ if (mUserBackupManagerService.isSetupComplete()) {
monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED;
} else {
monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
@@ -532,7 +533,8 @@
// Roll this package to the end of the backup queue if we're
// in a queue-driven mode (regardless of success/failure)
if (mUpdateSchedule) {
- backupManagerService.enqueueFullBackup(packageName, System.currentTimeMillis());
+ mUserBackupManagerService.enqueueFullBackup(
+ packageName, System.currentTimeMillis());
}
if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
@@ -549,7 +551,8 @@
// from the preflight pass. If we got as far as preflight, we now need
// to tear down the target process.
if (mBackupRunner != null) {
- backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+ mUserBackupManagerService.tearDownAgentAndKill(
+ currentPackage.applicationInfo);
}
// ... and continue looping.
} else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
@@ -561,7 +564,7 @@
EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
packageName);
}
- backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+ mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
// Do nothing, clean up, and continue looping.
} else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
BackupObserverUtils
@@ -569,7 +572,7 @@
BackupManager.ERROR_AGENT_FAILURE);
Slog.w(TAG, "Application failure for package: " + packageName);
EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
- backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+ mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
// Do nothing, clean up, and continue looping.
} else if (backupPackageStatus == BackupManager.ERROR_BACKUP_CANCELLED) {
BackupObserverUtils
@@ -578,7 +581,7 @@
Slog.w(TAG, "Backup cancelled. package=" + packageName +
", cancelAll=" + mCancelAll);
EventLog.writeEvent(EventLogTags.FULL_BACKUP_CANCELLED, packageName);
- backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+ mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
// Do nothing, clean up, and continue looping.
} else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
BackupObserverUtils
@@ -588,7 +591,7 @@
EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
// Abort entire backup pass.
backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
- backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+ mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
return;
} else {
// Success!
@@ -596,14 +599,14 @@
.sendBackupOnPackageResult(mBackupObserver, packageName,
BackupManager.SUCCESS);
EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
- backupManagerService.logBackupComplete(packageName);
+ mUserBackupManagerService.logBackupComplete(packageName);
}
cleanUpPipes(transportPipes);
cleanUpPipes(enginePipes);
if (currentPackage.applicationInfo != null) {
Slog.i(TAG, "Unbinding agent in " + packageName);
try {
- backupManagerService.getActivityManager().unbindBackupAgent(
+ mUserBackupManagerService.getActivityManager().unbindBackupAgent(
currentPackage.applicationInfo);
} catch (RemoteException e) { /* can't happen; activity manager is local */ }
}
@@ -639,8 +642,8 @@
mJob.finishBackupPass(mUserId);
}
- synchronized (backupManagerService.getQueueLock()) {
- backupManagerService.setRunningFullBackupTask(null);
+ synchronized (mUserBackupManagerService.getQueueLock()) {
+ mUserBackupManagerService.setRunningFullBackupTask(null);
}
mListener.onFinished("PFTBT.run()");
@@ -650,11 +653,11 @@
// Now that we're actually done with schedule-driven work, reschedule
// the next pass based on the new queue state.
if (mUpdateSchedule) {
- backupManagerService.scheduleNextFullBackupJob(backoff);
+ mUserBackupManagerService.scheduleNextFullBackupJob(backoff);
}
Slog.i(TAG, "Full data backup pass finished.");
- backupManagerService.getWakelock().release();
+ mUserBackupManagerService.getWakelock().release();
}
}
@@ -709,13 +712,13 @@
long fullBackupAgentTimeoutMillis =
mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
try {
- backupManagerService.prepareOperationTimeout(
+ mUserBackupManagerService.prepareOperationTimeout(
mCurrentOpToken, fullBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
if (MORE_DEBUG) {
Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
}
agent.doMeasureFullBackup(mQuota, mCurrentOpToken,
- backupManagerService.getBackupManagerBinder(), mTransportFlags);
+ mUserBackupManagerService.getBackupManagerBinder(), mTransportFlags);
// Now wait to get our result back. If this backstop timeout is reached without
// the latch being thrown, flow will continue as though a result or "normal"
@@ -765,7 +768,7 @@
}
mResult.set(result);
mLatch.countDown();
- backupManagerService.removeOperation(mCurrentOpToken);
+ mUserBackupManagerService.removeOperation(mCurrentOpToken);
}
@Override
@@ -775,7 +778,7 @@
}
mResult.set(BackupTransport.AGENT_ERROR);
mLatch.countDown();
- backupManagerService.removeOperation(mCurrentOpToken);
+ mUserBackupManagerService.removeOperation(mCurrentOpToken);
}
@Override
@@ -812,7 +815,7 @@
mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
mTarget = target;
mCurrentOpToken = currentOpToken;
- mEphemeralToken = backupManagerService.generateRandomIntegerToken();
+ mEphemeralToken = mUserBackupManagerService.generateRandomIntegerToken();
mPreflight = new SinglePackageBackupPreflight(
transportClient, quota, mEphemeralToken, transportFlags);
mPreflightLatch = new CountDownLatch(1);
@@ -825,23 +828,32 @@
}
void registerTask() {
- synchronized (backupManagerService.getCurrentOpLock()) {
- backupManagerService.getCurrentOperations().put(
+ synchronized (mUserBackupManagerService.getCurrentOpLock()) {
+ mUserBackupManagerService.getCurrentOperations().put(
mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP_WAIT));
}
}
void unregisterTask() {
- synchronized (backupManagerService.getCurrentOpLock()) {
- backupManagerService.getCurrentOperations().remove(mCurrentOpToken);
+ synchronized (mUserBackupManagerService.getCurrentOpLock()) {
+ mUserBackupManagerService.getCurrentOperations().remove(mCurrentOpToken);
}
}
@Override
public void run() {
FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
- mEngine = new FullBackupEngine(backupManagerService, out, mPreflight, mTarget, false,
- this, mQuota, mCurrentOpToken, mTransportFlags);
+ mEngine =
+ new FullBackupEngine(
+ mUserBackupManagerService,
+ out,
+ mPreflight,
+ mTarget,
+ false,
+ this,
+ mQuota,
+ mCurrentOpToken,
+ mTransportFlags);
try {
try {
if (!mIsCancelled) {
@@ -928,13 +940,13 @@
mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
mIsCancelled = true;
// Cancel tasks spun off by this task.
- backupManagerService.handleCancel(mEphemeralToken, cancelAll);
- backupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
+ mUserBackupManagerService.handleCancel(mEphemeralToken, cancelAll);
+ mUserBackupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
// Free up everyone waiting on this task and its children.
mPreflightLatch.countDown();
mBackupLatch.countDown();
// We are done with this operation.
- backupManagerService.removeOperation(mCurrentOpToken);
+ mUserBackupManagerService.removeOperation(mCurrentOpToken);
}
}
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 930cf9e..5089ee0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -42,7 +42,6 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.res.Resources;
@@ -121,6 +120,7 @@
import com.android.server.location.MockProvider;
import com.android.server.location.PassiveProvider;
import com.android.server.location.RemoteListenerHelper;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
@@ -282,12 +282,12 @@
// Let the package manager query which are the default location
// providers as they get certain permissions granted by default.
- PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
- packageManagerInternal.setLocationPackagesProvider(
+ PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
+ PermissionManagerServiceInternal.class);
+ permissionManagerInternal.setLocationPackagesProvider(
userId -> mContext.getResources().getStringArray(
com.android.internal.R.array.config_locationProviderPackageNames));
- packageManagerInternal.setLocationExtraPackagesProvider(
+ permissionManagerInternal.setLocationExtraPackagesProvider(
userId -> mContext.getResources().getStringArray(
com.android.internal.R.array.config_locationExtraPackageNames));
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 80d7ac9..df5005e 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -26,7 +26,6 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
import android.location.LocationManager;
import android.net.INetworkRecommendationProvider;
@@ -54,15 +53,14 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.IntArray;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.TransferPipe;
-import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.DumpUtils;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -294,7 +292,7 @@
String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
Global.USE_OPEN_WIFI_PACKAGE);
if (!TextUtils.isEmpty(useOpenWifiPackage)) {
- LocalServices.getService(PackageManagerInternal.class)
+ LocalServices.getService(PermissionManagerServiceInternal.class)
.grantDefaultPermissionsToDefaultUseOpenWifiApp(useOpenWifiPackage,
userId);
}
@@ -306,17 +304,14 @@
false /*notifyForDescendants*/,
mUseOpenWifiPackageObserver);
// Set a callback for the package manager to query the use open wifi app.
- LocalServices.getService(PackageManagerInternal.class).setUseOpenWifiAppPackagesProvider(
- new PackageManagerInternal.PackagesProvider() {
- @Override
- public String[] getPackages(int userId) {
- String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
- Global.USE_OPEN_WIFI_PACKAGE);
- if (!TextUtils.isEmpty(useOpenWifiPackage)) {
- return new String[]{useOpenWifiPackage};
- }
- return null;
+ LocalServices.getService(PermissionManagerServiceInternal.class)
+ .setUseOpenWifiAppPackagesProvider((userId) -> {
+ String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
+ Global.USE_OPEN_WIFI_PACKAGE);
+ if (!TextUtils.isEmpty(useOpenWifiPackage)) {
+ return new String[]{useOpenWifiPackage};
}
+ return null;
});
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index adb0909..ff8c3e9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -347,6 +347,7 @@
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
import com.android.server.appop.AppOpsService;
+import com.android.server.compat.CompatConfig;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.firewall.IntentFirewall;
import com.android.server.job.JobSchedulerInternal;
@@ -392,7 +393,9 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -5027,6 +5030,7 @@
bindApplicationTimeMillis = SystemClock.elapsedRealtime();
mAtmInternal.preBindApplication(app.getWindowProcessController());
final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
+ long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info);
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
@@ -5042,7 +5046,8 @@
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
- buildSerial, autofillOptions, contentCaptureOptions);
+ buildSerial, autofillOptions, contentCaptureOptions,
+ disabledCompatChanges);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
@@ -5051,7 +5056,8 @@
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
- buildSerial, autofillOptions, contentCaptureOptions);
+ buildSerial, autofillOptions, contentCaptureOptions,
+ disabledCompatChanges);
}
if (profilerInfo != null) {
profilerInfo.closeFd();
@@ -7706,6 +7712,34 @@
return null;
}
+ int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) {
+ final String name = uri.getAuthority();
+ final long ident = Binder.clearCallingIdentity();
+ ContentProviderHolder holder = null;
+ try {
+ holder = getContentProviderExternalUnchecked(name, null, callingUid,
+ "*checkContentProviderUriPermission*", userId);
+ if (holder != null) {
+ return holder.provider.checkUriPermission(null, uri, callingUid, modeFlags);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Content provider dead retrieving " + uri, e);
+ return PackageManager.PERMISSION_DENIED;
+ } catch (Exception e) {
+ Log.w(TAG, "Exception while determining type of " + uri, e);
+ return PackageManager.PERMISSION_DENIED;
+ } finally {
+ try {
+ if (holder != null) {
+ removeContentProviderExternalUnchecked(name, null, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ return PackageManager.PERMISSION_DENIED;
+ }
+
private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
if (UserHandle.getUserId(callingUid) == userId) {
return true;
@@ -17826,6 +17860,35 @@
}
@Override
+ public int checkContentProviderUriPermission(Uri uri, int userId,
+ int callingUid, int modeFlags) {
+ // We can find ourselves needing to check Uri permissions while
+ // already holding the WM lock, which means reaching back here for
+ // the AM lock would cause an inversion. The WM team has requested
+ // that we use the strategy below instead of shifting where Uri
+ // grants are calculated.
+
+ // Since we could also arrive here while holding the AM lock, we
+ // can't always delegate the call through the handler, and we need
+ // to delicately dance between the deadlocks.
+ if (Thread.currentThread().holdsLock(ActivityManagerService.this)) {
+ return ActivityManagerService.this.checkContentProviderUriPermission(uri,
+ userId, callingUid, modeFlags);
+ } else {
+ final CompletableFuture<Integer> res = new CompletableFuture<>();
+ mHandler.post(() -> {
+ res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri,
+ userId, callingUid, modeFlags));
+ });
+ try {
+ return res.get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
public void onWakefulnessChanged(int wakefulness) {
ActivityManagerService.this.onWakefulnessChanged(wakefulness);
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 7824a0a..3e1817b 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -40,7 +40,6 @@
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.ProviderInfo;
import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
@@ -71,6 +70,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -280,15 +280,11 @@
// Let the package manager query for the sync adapters for a given authority
// as we grant default permissions to sync adapters for specific authorities.
- PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
- packageManagerInternal.setSyncAdapterPackagesprovider(
- new PackageManagerInternal.SyncAdapterPackagesProvider() {
- @Override
- public String[] getPackages(String authority, int userId) {
- return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
- }
- });
+ final PermissionManagerServiceInternal permissionManagerInternal =
+ LocalServices.getService(PermissionManagerServiceInternal.class);
+ permissionManagerInternal.setSyncAdapterPackagesProvider((authority, userId) -> {
+ return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+ });
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 2e5aafe..7fb5b19 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -63,6 +63,8 @@
import android.provider.Settings.System;
import android.util.MathUtils;
import android.util.Slog;
+import android.util.SparseIntArray;
+import android.view.Display;
import android.view.SurfaceControl;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AnimationUtils;
@@ -171,6 +173,11 @@
private NightDisplayAutoMode mNightDisplayAutoMode;
+ /**
+ * Map of color modes -> display composition colorspace
+ */
+ private SparseIntArray mColorModeCompositionColorSpaces = null;
+
public ColorDisplayService(Context context) {
super(context);
mHandler = new TintHandler(DisplayThread.get().getLooper());
@@ -267,6 +274,30 @@
return Secure.getIntForUser(cr, Secure.USER_SETUP_COMPLETE, 0, userHandle) == 1;
}
+ private void setUpDisplayCompositionColorSpaces(Resources res) {
+ mColorModeCompositionColorSpaces = null;
+
+ final int[] colorModes = res.getIntArray(R.array.config_displayCompositionColorModes);
+ if (colorModes == null) {
+ return;
+ }
+
+ final int[] compSpaces = res.getIntArray(R.array.config_displayCompositionColorSpaces);
+ if (compSpaces == null) {
+ return;
+ }
+
+ if (colorModes.length != compSpaces.length) {
+ Slog.e(TAG, "Number of composition color spaces doesn't match specified color modes");
+ return;
+ }
+
+ mColorModeCompositionColorSpaces = new SparseIntArray(colorModes.length);
+ for (int i = 0; i < colorModes.length; i++) {
+ mColorModeCompositionColorSpaces.put(colorModes[i], compSpaces[i]);
+ }
+ }
+
private void setUp() {
Slog.d(TAG, "setUp: currentUser=" + mCurrentUser);
@@ -359,6 +390,8 @@
onAccessibilityInversionChanged();
onAccessibilityDaltonizerChanged();
+ setUpDisplayCompositionColorSpaces(getContext().getResources());
+
// Set the color mode, if valid, and immediately apply the updated tint matrix based on the
// existing activated state. This ensures consistency of tint across the color mode change.
onDisplayColorModeChanged(getColorModeInternal());
@@ -450,6 +483,14 @@
}
}
+ private int getCompositionColorSpace(int mode) {
+ if (mColorModeCompositionColorSpaces == null) {
+ return Display.COLOR_MODE_INVALID;
+ }
+
+ return mColorModeCompositionColorSpaces.get(mode, Display.COLOR_MODE_INVALID);
+ }
+
private void onDisplayColorModeChanged(int mode) {
if (mode == NOT_SET) {
return;
@@ -470,7 +511,8 @@
// DisplayTransformManager.needsLinearColorMatrix(), therefore it is dependent
// on the state of DisplayTransformManager.
final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
- dtm.setColorMode(mode, mNightDisplayTintController.getMatrix());
+ dtm.setColorMode(mode, mNightDisplayTintController.getMatrix(),
+ getCompositionColorSpace(mode));
if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) {
updateDisplayWhiteBalanceStatus();
diff --git a/services/core/java/com/android/server/display/color/DisplayTransformManager.java b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
index 5ff45a9..d5706a5 100644
--- a/services/core/java/com/android/server/display/color/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
@@ -26,6 +26,7 @@
import android.os.SystemProperties;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -77,6 +78,8 @@
@VisibleForTesting
static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
@VisibleForTesting
+ static final String PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE = "persist.sys.sf.color_mode";
+ @VisibleForTesting
static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
private static final float COLOR_SATURATION_NATURAL = 1.0f;
@@ -251,23 +254,24 @@
/**
* Sets color mode and updates night display transform values.
*/
- public boolean setColorMode(int colorMode, float[] nightDisplayMatrix) {
+ public boolean setColorMode(int colorMode, float[] nightDisplayMatrix,
+ int compositionColorMode) {
if (colorMode == ColorDisplayManager.COLOR_MODE_NATURAL) {
applySaturation(COLOR_SATURATION_NATURAL);
- setDisplayColor(DISPLAY_COLOR_MANAGED);
+ setDisplayColor(DISPLAY_COLOR_MANAGED, compositionColorMode);
} else if (colorMode == ColorDisplayManager.COLOR_MODE_BOOSTED) {
applySaturation(COLOR_SATURATION_BOOSTED);
- setDisplayColor(DISPLAY_COLOR_MANAGED);
+ setDisplayColor(DISPLAY_COLOR_MANAGED, compositionColorMode);
} else if (colorMode == ColorDisplayManager.COLOR_MODE_SATURATED) {
applySaturation(COLOR_SATURATION_NATURAL);
- setDisplayColor(DISPLAY_COLOR_UNMANAGED);
+ setDisplayColor(DISPLAY_COLOR_UNMANAGED, compositionColorMode);
} else if (colorMode == ColorDisplayManager.COLOR_MODE_AUTOMATIC) {
applySaturation(COLOR_SATURATION_NATURAL);
- setDisplayColor(DISPLAY_COLOR_ENHANCED);
+ setDisplayColor(DISPLAY_COLOR_ENHANCED, compositionColorMode);
} else if (colorMode >= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN
&& colorMode <= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX) {
applySaturation(COLOR_SATURATION_NATURAL);
- setDisplayColor(colorMode);
+ setDisplayColor(colorMode, compositionColorMode);
}
setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, nightDisplayMatrix);
@@ -323,13 +327,21 @@
/**
* Toggles native mode on/off in SurfaceFlinger.
*/
- private void setDisplayColor(int color) {
+ private void setDisplayColor(int color, int compositionColorMode) {
SystemProperties.set(PERSISTENT_PROPERTY_DISPLAY_COLOR, Integer.toString(color));
+ if (compositionColorMode != Display.COLOR_MODE_INVALID) {
+ SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE,
+ Integer.toString(compositionColorMode));
+ }
+
final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
if (flinger != null) {
final Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
data.writeInt(color);
+ if (compositionColorMode != Display.COLOR_MODE_INVALID) {
+ data.writeInt(compositionColorMode);
+ }
try {
flinger.transact(SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR, data, null, 0);
} catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 07fd322..d30895e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -401,7 +401,7 @@
// for enabling and disabling notification pulse behavior
boolean mScreenOn = true;
- protected boolean mInCall = false;
+ protected boolean mInCallStateOffHook = false;
boolean mNotificationPulseEnabled;
private Uri mInCallNotificationUri;
@@ -1299,7 +1299,7 @@
mScreenOn = false;
updateNotificationPulse();
} else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
- mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
+ mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
updateNotificationPulse();
} else if (action.equals(Intent.ACTION_USER_STOPPED)) {
@@ -5824,7 +5824,7 @@
}
if (DBG) Slog.v(TAG, "Interrupting!");
if (hasValidSound) {
- if (mInCall) {
+ if (isInCall()) {
playInCallNotification();
beep = true;
} else {
@@ -5838,7 +5838,7 @@
final boolean ringerModeSilent =
mAudioManager.getRingerModeInternal()
== AudioManager.RINGER_MODE_SILENT;
- if (!mInCall && hasValidVibrate && !ringerModeSilent) {
+ if (!isInCall() && hasValidVibrate && !ringerModeSilent) {
buzz = playVibration(record, vibration, hasValidSound);
if(buzz) {
mVibrateNotificationKey = key;
@@ -5926,7 +5926,7 @@
return false;
}
// not if in call or the screen's on
- if (mInCall || mScreenOn) {
+ if (isInCall() || mScreenOn) {
return false;
}
@@ -7027,7 +7027,7 @@
}
// Don't flash while we are in a call or screen is on
- if (ledNotification == null || mInCall || mScreenOn) {
+ if (ledNotification == null || isInCall() || mScreenOn) {
mNotificationLight.turnOff();
} else {
NotificationRecord.Light light = ledNotification.getLight();
@@ -7495,6 +7495,18 @@
}
}
+ private boolean isInCall() {
+ if (mInCallStateOffHook) {
+ return true;
+ }
+ int audioMode = mAudioManager.getMode();
+ if (audioMode == AudioManager.MODE_IN_CALL
+ || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
+ return true;
+ }
+ return false;
+ }
+
public class NotificationAssistants extends ManagedServices {
static final String TAG_ENABLED_NOTIFICATION_ASSISTANTS = "enabled_assistants";
diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java
new file mode 100644
index 0000000..55fbcb4
--- /dev/null
+++ b/services/core/java/com/android/server/om/IdmapDaemon.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import static android.content.Context.IDMAP_SERVICE;
+
+import static com.android.server.om.OverlayManagerService.DEBUG;
+import static com.android.server.om.OverlayManagerService.TAG;
+
+import android.os.IBinder;
+import android.os.IIdmap2;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.util.Slog;
+
+import com.android.server.IoThread;
+
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * To prevent idmap2d from continuously running, the idmap daemon will terminate after 10
+ * seconds without a transaction.
+ **/
+class IdmapDaemon {
+ // The amount of time in milliseconds to wait after a transaction to the idmap service is made
+ // before stopping the service.
+ private static final int SERVICE_TIMEOUT_MS = 10000;
+
+ // The amount of time in milliseconds to wait when attempting to connect to idmap service.
+ private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000;
+
+ private static final Object IDMAP_TOKEN = new Object();
+ private static final String IDMAP_DAEMON = "idmap2d";
+
+ private static IdmapDaemon sInstance;
+ private volatile IIdmap2 mService;
+ private final AtomicInteger mOpenedCount = new AtomicInteger();
+
+ /**
+ * An {@link AutoCloseable} connection to the idmap service. When the connection is closed or
+ * finalized, the idmap service will be stopped after a period of time unless another connection
+ * to the service is open.
+ **/
+ private class Connection implements AutoCloseable {
+ private boolean mOpened = true;
+
+ private Connection() {
+ synchronized (IDMAP_TOKEN) {
+ mOpenedCount.incrementAndGet();
+ }
+ }
+
+ @Override
+ public void close() {
+ synchronized (IDMAP_TOKEN) {
+ if (!mOpened) {
+ return;
+ }
+
+ mOpened = false;
+ if (mOpenedCount.decrementAndGet() != 0) {
+ // Only post the callback to stop the service if the service does not have an
+ // open connection.
+ return;
+ }
+
+ IoThread.getHandler().postDelayed(() -> {
+ synchronized (IDMAP_TOKEN) {
+ // Only stop the service if the service does not have an open connection.
+ if (mService == null || mOpenedCount.get() != 0) {
+ return;
+ }
+
+ stopIdmapService();
+ mService = null;
+ }
+ }, IDMAP_TOKEN, SERVICE_TIMEOUT_MS);
+ }
+ }
+ }
+
+ static IdmapDaemon getInstance() {
+ if (sInstance == null) {
+ sInstance = new IdmapDaemon();
+ }
+ return sInstance;
+ }
+
+ String createIdmap(String targetPath, String overlayPath, int policies, boolean enforce,
+ int userId) throws Exception {
+ try (Connection connection = connect()) {
+ return mService.createIdmap(targetPath, overlayPath, policies, enforce, userId);
+ }
+ }
+
+ boolean removeIdmap(String overlayPath, int userId) throws Exception {
+ try (Connection connection = connect()) {
+ return mService.removeIdmap(overlayPath, userId);
+ }
+ }
+
+ boolean verifyIdmap(String overlayPath, int policies, boolean enforce, int userId)
+ throws Exception {
+ try (Connection connection = connect()) {
+ return mService.verifyIdmap(overlayPath, policies, enforce, userId);
+ }
+ }
+
+ String getIdmapPath(String overlayPath, int userId) throws Exception {
+ try (Connection connection = connect()) {
+ return mService.getIdmapPath(overlayPath, userId);
+ }
+ }
+
+ static void startIdmapService() {
+ SystemProperties.set("ctl.start", IDMAP_DAEMON);
+ }
+
+ static void stopIdmapService() {
+ SystemProperties.set("ctl.stop", IDMAP_DAEMON);
+ }
+
+ private Connection connect() throws Exception {
+ synchronized (IDMAP_TOKEN) {
+ IoThread.getHandler().removeCallbacksAndMessages(IDMAP_TOKEN);
+ if (mService != null) {
+ // Not enough time has passed to stop the idmap service. Reuse the existing
+ // interface.
+ return new Connection();
+ }
+
+ // Start the idmap service if it is not currently running.
+ startIdmapService();
+
+ // Block until the service is found.
+ FutureTask<IBinder> bindIdmap = new FutureTask<>(() -> {
+ IBinder binder = null;
+ while (binder == null) {
+ try {
+ binder = ServiceManager.getService(IDMAP_SERVICE);
+ Thread.sleep(100);
+ } catch (Exception e) {
+ Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not retrieved; "
+ + e.getMessage());
+ }
+ }
+ return binder;
+ });
+
+ IBinder binder;
+ try {
+ IoThread.getHandler().postAtFrontOfQueue(bindIdmap);
+ binder = bindIdmap.get(SERVICE_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (Exception rethrow) {
+ Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not found;");
+ throw rethrow;
+ }
+
+ try {
+ binder.linkToDeath(() -> {
+ Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died");
+ }, 0);
+ } catch (RemoteException rethrow) {
+ Slog.e(TAG, "service '" + IDMAP_SERVICE + "' failed to be bound");
+ throw rethrow;
+ }
+
+ mService = IIdmap2.Stub.asInterface(binder);
+ if (DEBUG) {
+ Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected");
+ }
+
+ return new Connection();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index b604aa8..288ef0e 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -16,9 +16,6 @@
package com.android.server.om;
-import static android.content.Context.IDMAP_SERVICE;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
import static com.android.server.om.OverlayManagerService.DEBUG;
import static com.android.server.om.OverlayManagerService.TAG;
@@ -27,15 +24,11 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Build.VERSION_CODES;
-import android.os.IBinder;
import android.os.IIdmap2;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Slog;
-import com.android.internal.os.BackgroundThread;
import com.android.server.om.OverlayManagerServiceImpl.PackageManagerHelper;
import com.android.server.pm.Installer;
@@ -51,11 +44,6 @@
*/
class IdmapManager {
private static final boolean FEATURE_FLAG_IDMAP2 = true;
-
- private final Installer mInstaller;
- private final PackageManagerHelper mPackageManager;
- private IIdmap2 mIdmap2Service;
-
private static final boolean VENDOR_IS_Q_OR_LATER;
static {
final String value = SystemProperties.get("ro.vndk.version", "29");
@@ -70,12 +58,14 @@
VENDOR_IS_Q_OR_LATER = isQOrLater;
}
+ private final Installer mInstaller;
+ private final PackageManagerHelper mPackageManager;
+ private final IdmapDaemon mIdmapDaemon;
+
IdmapManager(final Installer installer, final PackageManagerHelper packageManager) {
mInstaller = installer;
mPackageManager = packageManager;
- if (FEATURE_FLAG_IDMAP2) {
- connectToIdmap2d();
- }
+ mIdmapDaemon = IdmapDaemon.getInstance();
}
boolean createIdmap(@NonNull final PackageInfo targetPackage,
@@ -91,11 +81,11 @@
if (FEATURE_FLAG_IDMAP2) {
int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
boolean enforce = enforceOverlayable(overlayPackage);
- if (mIdmap2Service.verifyIdmap(overlayPath, policies, enforce, userId)) {
+ if (mIdmapDaemon.verifyIdmap(overlayPath, policies, enforce, userId)) {
return true;
}
- return mIdmap2Service.createIdmap(targetPath, overlayPath, policies, enforce,
- userId) != null;
+ return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
+ enforce, userId) != null;
} else {
mInstaller.idmap(targetPath, overlayPath, sharedGid);
return true;
@@ -113,7 +103,7 @@
}
try {
if (FEATURE_FLAG_IDMAP2) {
- return mIdmap2Service.removeIdmap(oi.baseCodePath, userId);
+ return mIdmapDaemon.removeIdmap(oi.baseCodePath, userId);
} else {
mInstaller.removeIdmap(oi.baseCodePath);
return true;
@@ -137,7 +127,7 @@
final int userId) {
if (FEATURE_FLAG_IDMAP2) {
try {
- return mIdmap2Service.getIdmapPath(overlayPackagePath, userId);
+ return mIdmapDaemon.getIdmapPath(overlayPackagePath, userId);
} catch (Exception e) {
Slog.w(TAG, "failed to get idmap path for " + overlayPackagePath + ": "
+ e.getMessage());
@@ -151,35 +141,6 @@
}
}
- private void connectToIdmap2d() {
- IBinder binder = ServiceManager.getService(IDMAP_SERVICE);
- if (binder != null) {
- try {
- binder.linkToDeath(new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died; reconnecting...");
- connectToIdmap2d();
- }
-
- }, 0);
- } catch (RemoteException e) {
- binder = null;
- }
- }
- if (binder != null) {
- mIdmap2Service = IIdmap2.Stub.asInterface(binder);
- if (DEBUG) {
- Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected");
- }
- } else {
- Slog.w(TAG, "service '" + IDMAP_SERVICE + "' not found; trying again...");
- BackgroundThread.getHandler().postDelayed(() -> {
- connectToIdmap2d();
- }, SECOND_IN_MILLIS);
- }
- }
-
/**
* Checks if overlayable and policies should be enforced on the specified overlay for backwards
* compatibility with pre-Q overlays.
@@ -237,14 +198,9 @@
return fulfilledPolicies | IIdmap2.POLICY_OEM_PARTITION;
}
- // Check partitions for which there exists no policy so overlays on these partitions will
- // not fulfill the system policy.
- if (ai.isProductServices()) {
- return fulfilledPolicies;
- }
-
+ // System_ext partition (/system_ext) is considered as system
// Check this last since every partition except for data is scanned as system in the PMS.
- if (ai.isSystemApp()) {
+ if (ai.isSystemApp() || ai.isSystemExt()) {
return fulfilledPolicies | IIdmap2.POLICY_SYSTEM_PARTITION;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index da69986..ce95181 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -262,6 +262,7 @@
initIfNeeded();
onSwitchUser(UserHandle.USER_SYSTEM);
+ IdmapDaemon.stopIdmapService();
publishBinderService(Context.OVERLAY_SERVICE, mService);
publishLocalService(OverlayManagerService.class, this);
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 9094e1b..e5a2e77 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -376,12 +376,12 @@
continue;
}
- // If the path is in /system, /vendor, /product or /product_services, ignore. It will
+ // If the path is in /system, /vendor, /product or /system_ext, ignore. It will
// have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
if (pkg.codePath.startsWith("/system")
|| pkg.codePath.startsWith("/vendor")
|| pkg.codePath.startsWith("/product")
- || pkg.codePath.startsWith("/product_services")) {
+ || pkg.codePath.startsWith("/system_ext")) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 6f9a918..4eddb930 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -23,6 +23,7 @@
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
+import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
@@ -1484,7 +1485,29 @@
"Too many files for apex install");
}
- mResolvedBaseFile = addedFiles[0];
+ try {
+ resolveStageDirLocked();
+ } catch (IOException e) {
+ throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
+ "Failed to resolve stage location", e);
+ }
+
+ File addedFile = addedFiles[0]; // there is only one file
+
+ // Ensure file name has proper suffix
+ final String sourceName = addedFile.getName();
+ final String targetName = sourceName.endsWith(APEX_FILE_EXTENSION)
+ ? sourceName
+ : sourceName + APEX_FILE_EXTENSION;
+ if (!FileUtils.isValidExtFilename(targetName)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Invalid filename: " + targetName);
+ }
+
+ final File targetFile = new File(mResolvedStageDir, targetName);
+ resolveAndStageFile(addedFile, targetFile);
+
+ mResolvedBaseFile = targetFile;
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8660d19..6a672c3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -311,7 +311,6 @@
import com.android.server.pm.dex.PackageDexUsage;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.permission.BasePermission;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.permission.PermissionsState;
@@ -472,7 +471,7 @@
static final int SCAN_AS_OEM = 1 << 19;
static final int SCAN_AS_VENDOR = 1 << 20;
static final int SCAN_AS_PRODUCT = 1 << 21;
- static final int SCAN_AS_PRODUCT_SERVICES = 1 << 22;
+ static final int SCAN_AS_SYSTEM_EXT = 1 << 22;
static final int SCAN_AS_ODM = 1 << 23;
@IntDef(flag = true, prefix = { "SCAN_" }, value = {
@@ -584,7 +583,7 @@
private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
- private static final String PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+ private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
private static final String ODM_OVERLAY_DIR = "/odm/overlay";
@@ -948,8 +947,6 @@
final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
= new SparseArray<>();
- // TODO remove this and go through mPermissonManager directly
- final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
// Internal interface for permission manager
private final PermissionManagerServiceInternal mPermissionManager;
// Public interface for permission manager
@@ -992,15 +989,6 @@
void receiveVerificationResponse(int verificationId);
}
- @GuardedBy("mPackages")
- private PackageManagerInternal.DefaultBrowserProvider mDefaultBrowserProvider;
-
- @GuardedBy("mPackages")
- private PackageManagerInternal.DefaultDialerProvider mDefaultDialerProvider;
-
- @GuardedBy("mPackages")
- private PackageManagerInternal.DefaultHomeProvider mDefaultHomeProvider;
-
private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
private Context mContext;
private ComponentName mIntentFilterVerifierComponent;
@@ -1966,7 +1954,7 @@
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting.getInstallReason(userId)
!= PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
- setDefaultBrowserAsyncLPw(null, userId);
+ mPermissionManager.setDefaultBrowser(null, true, true, userId);
}
}
}
@@ -2348,7 +2336,6 @@
mPackages /*externalLock*/);
mPermissionManagerService =
(IPermissionManager) ServiceManager.getService("permissionmgr");
- mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
mSettings = new Settings(Environment.getDataDirectory(),
mPermissionManager.getPermissionSettings(), mPackages);
}
@@ -2540,7 +2527,7 @@
scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
}
- // Collect vendor/product/product_services overlay packages. (Do this before scanning
+ // Collect vendor/product/system_ext overlay packages. (Do this before scanning
// any apps.)
// For security and version matching reason, only consider overlay packages if they
// reside in the right directory.
@@ -2558,12 +2545,12 @@
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT,
0);
- scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
+ scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT_SERVICES,
+ | SCAN_AS_SYSTEM_EXT,
0);
scanDirTracedLI(new File(ODM_OVERLAY_DIR),
mDefParseFlags
@@ -2721,37 +2708,37 @@
| SCAN_AS_PRODUCT,
0);
- // Collected privileged /product_services packages.
- File privilegedProductServicesAppDir =
- new File(Environment.getProductServicesDirectory(), "priv-app");
+ // Collected privileged /system_ext packages.
+ File privilegedSystemExtAppDir =
+ new File(Environment.getSystemExtDirectory(), "priv-app");
try {
- privilegedProductServicesAppDir =
- privilegedProductServicesAppDir.getCanonicalFile();
+ privilegedSystemExtAppDir =
+ privilegedSystemExtAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
- scanDirTracedLI(privilegedProductServicesAppDir,
+ scanDirTracedLI(privilegedSystemExtAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT_SERVICES
+ | SCAN_AS_SYSTEM_EXT
| SCAN_AS_PRIVILEGED,
0);
- // Collect ordinary /product_services packages.
- File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
+ // Collect ordinary /system_ext packages.
+ File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
try {
- productServicesAppDir = productServicesAppDir.getCanonicalFile();
+ systemExtAppDir = systemExtAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
- scanDirTracedLI(productServicesAppDir,
+ scanDirTracedLI(systemExtAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT_SERVICES,
+ | SCAN_AS_SYSTEM_EXT,
0);
// Prune any system packages that no longer exist.
@@ -2981,23 +2968,23 @@
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT;
- } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
+ } else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT_SERVICES
+ | SCAN_AS_SYSTEM_EXT
| SCAN_AS_PRIVILEGED;
- } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
+ } else if (FileUtils.contains(systemExtAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT_SERVICES;
+ | SCAN_AS_SYSTEM_EXT;
} else {
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
continue;
@@ -5499,40 +5486,6 @@
}
@Override
- public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
- if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- "isPermissionRevokedByPolicy for user " + userId);
- }
-
- if (checkPermission(permission, packageName, userId)
- == PackageManager.PERMISSION_GRANTED) {
- return false;
- }
-
- final int callingUid = Binder.getCallingUid();
- if (getInstantAppPackageName(callingUid) != null) {
- if (!isCallerSameApp(packageName, callingUid)) {
- return false;
- }
- } else {
- if (isInstantApp(packageName, userId)) {
- return false;
- }
- }
-
- final long identity = Binder.clearCallingIdentity();
- try {
- final int flags = mPermissionManager
- .getPermissionFlags(permission, packageName, Binder.getCallingUid(), userId);
- return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
public String getPermissionControllerPackageName() {
synchronized (mPackages) {
return mRequiredPermissionControllerPackage;
@@ -5588,46 +5541,6 @@
}
@Override
- public boolean shouldShowRequestPermissionRationale(String permName,
- String packageName, int userId) {
- if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- "canShowRequestPermissionRationale for user " + userId);
- }
-
- final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
- if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
- return false;
- }
-
- if (checkPermission(permName, packageName, userId)
- == PackageManager.PERMISSION_GRANTED) {
- return false;
- }
-
- final int flags;
-
- final long identity = Binder.clearCallingIdentity();
- try {
- flags = mPermissionManager
- .getPermissionFlags(permName, packageName, Binder.getCallingUid(), userId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
-
- final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
- | PackageManager.FLAG_PERMISSION_POLICY_FIXED
- | PackageManager.FLAG_PERMISSION_USER_FIXED;
-
- if ((flags & fixedFlags) != 0) {
- return false;
- }
-
- return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
- }
-
- @Override
public boolean isProtectedBroadcast(String actionName) {
// allow instant applications
synchronized (mProtectedBroadcasts) {
@@ -7286,7 +7199,8 @@
} else {
// Browser/generic handling case. If there's a default browser, go straight
// to that (but only if there is no other higher-priority match).
- final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+ final String defaultBrowserPackageName =
+ mPermissionManager.getDefaultBrowser(userId);
int maxMatchPrio = 0;
ResolveInfo defaultBrowserMatch = null;
final int numCandidates = matchAllList.size();
@@ -10340,7 +10254,7 @@
* <li>{@link #SCAN_AS_OEM}</li>
* <li>{@link #SCAN_AS_VENDOR}</li>
* <li>{@link #SCAN_AS_PRODUCT}</li>
- * <li>{@link #SCAN_AS_PRODUCT_SERVICES}</li>
+ * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
* <li>{@link #SCAN_AS_INSTANT_APP}</li>
* <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
* <li>{@link #SCAN_AS_ODM}</li>
@@ -10377,8 +10291,8 @@
scanFlags |= SCAN_AS_PRODUCT;
}
if ((systemPkgSetting.pkgPrivateFlags
- & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0) {
- scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+ & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
+ scanFlags |= SCAN_AS_SYSTEM_EXT;
}
if ((systemPkgSetting.pkgPrivateFlags
& ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
@@ -11156,8 +11070,8 @@
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
}
- if ((scanFlags & SCAN_AS_PRODUCT_SERVICES) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+ if ((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) {
+ pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
}
if ((scanFlags & SCAN_AS_ODM) != 0) {
@@ -12121,8 +12035,8 @@
codeRoot = Environment.getOdmDirectory();
} else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
codeRoot = Environment.getProductDirectory();
- } else if (FileUtils.contains(Environment.getProductServicesDirectory(), codePath)) {
- codeRoot = Environment.getProductServicesDirectory();
+ } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+ codeRoot = Environment.getSystemExtDirectory();
} else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
codeRoot = Environment.getOdmDirectory();
} else {
@@ -12826,7 +12740,9 @@
@Override
public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
- enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils
+ .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null || !pkgSetting.isSystem()) {
@@ -12849,7 +12765,9 @@
@Override
public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
- enforceSystemOrPhoneCaller("setSystemAppInstallState");
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils
+ .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
// The target app should always be in system
@@ -13421,7 +13339,7 @@
final long callingId = Binder.clearCallingIdentity();
try {
final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
- final String dialerPackageName = getDefaultDialerPackageName(userId);
+ final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
for (int i = 0; i < packageNames.length; i++) {
canSuspend[i] = false;
final String packageName = packageNames[i];
@@ -13503,19 +13421,6 @@
return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
}
- @Nullable
- private String getDefaultDialerPackageName(@UserIdInt int userId) {
- PackageManagerInternal.DefaultDialerProvider provider;
- synchronized (mPackages) {
- provider = mDefaultDialerProvider;
- }
- if (provider == null) {
- Slog.e(TAG, "mDefaultDialerProvider is null");
- return null;
- }
- return provider.getDefaultDialer(userId);
- }
-
@Override
public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
mContext.enforceCallingOrSelfPermission(
@@ -13874,75 +13779,6 @@
}
}
- @Override
- public boolean setDefaultBrowserPackageName(String packageName, int userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
- if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
- }
- if (userId == UserHandle.USER_ALL) {
- return false;
- }
- PackageManagerInternal.DefaultBrowserProvider provider;
- synchronized (mPackages) {
- provider = mDefaultBrowserProvider;
- }
- if (provider == null) {
- Slog.e(TAG, "mDefaultBrowserProvider is null");
- return false;
- }
- boolean successful = provider.setDefaultBrowser(packageName, userId);
- if (!successful) {
- return false;
- }
- if (packageName != null) {
- synchronized (mPackages) {
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
- userId);
- }
- }
- return true;
- }
-
- private void setDefaultBrowserAsyncLPw(@Nullable String packageName, @UserIdInt int userId) {
- if (userId == UserHandle.USER_ALL) {
- return;
- }
- if (mDefaultBrowserProvider == null) {
- Slog.e(TAG, "mDefaultBrowserProvider is null");
- return;
- }
- mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
- if (packageName != null) {
- synchronized (mPackages) {
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
- userId);
- }
- }
- }
-
- @Override
- public String getDefaultBrowserPackageName(int userId) {
- if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
- }
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return null;
- }
- PackageManagerInternal.DefaultBrowserProvider provider;
- synchronized (mPackages) {
- provider = mDefaultBrowserProvider;
- }
- if (provider == null) {
- Slog.e(TAG, "mDefaultBrowserProvider is null");
- return null;
- }
- return provider.getDefaultBrowser(userId);
- }
-
/**
* Get the "allow unknown sources" setting.
*
@@ -17678,9 +17514,9 @@
return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
}
- private static boolean isProductServicesApp(PackageParser.Package pkg) {
+ private static boolean isSystemExtApp(PackageParser.Package pkg) {
return (pkg.applicationInfo.privateFlags
- & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+ & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
}
private static boolean isOdmApp(PackageParser.Package pkg) {
@@ -18445,13 +18281,13 @@
final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
- final File privilegedProductServicesAppDir =
- new File(Environment.getProductServicesDirectory(), "priv-app");
+ final File privilegedSystemExtAppDir =
+ new File(Environment.getSystemExtDirectory(), "priv-app");
return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
|| path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
|| path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
|| path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
- || path.startsWith(privilegedProductServicesAppDir.getCanonicalPath() + "/");
+ || path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
} catch (IOException e) {
Slog.e(TAG, "Unable to access code path " + path);
}
@@ -18486,10 +18322,10 @@
return false;
}
- static boolean locationIsProductServices(String path) {
+ static boolean locationIsSystemExt(String path) {
try {
return path.startsWith(
- Environment.getProductServicesDirectory().getCanonicalPath() + "/");
+ Environment.getSystemExtDirectory().getCanonicalPath() + "/");
} catch (IOException e) {
Slog.e(TAG, "Unable to access code path " + path);
}
@@ -18622,8 +18458,8 @@
if (locationIsProduct(codePathString)) {
scanFlags |= SCAN_AS_PRODUCT;
}
- if (locationIsProductServices(codePathString)) {
- scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+ if (locationIsSystemExt(codePathString)) {
+ scanFlags |= SCAN_AS_SYSTEM_EXT;
}
if (locationIsOdm(codePathString)) {
scanFlags |= SCAN_AS_ODM;
@@ -19688,10 +19524,10 @@
}
private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
- final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+ final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
if (packageName.equals(defaultBrowserPackageName)) {
- setDefaultBrowserPackageName(null, userId);
+ mPermissionManager.setDefaultBrowser(null, true, true, userId);
}
}
}
@@ -19719,7 +19555,7 @@
// significant refactoring to keep all default apps in the package
// manager (cleaner but more work) or have the services provide
// callbacks to the package manager to request a default app reset.
- setDefaultBrowserPackageName(null, userId);
+ mPermissionManager.setDefaultBrowser(null, true, true, userId);
resetNetworkPolicies(userId);
synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
@@ -19972,17 +19808,14 @@
parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
(parser1, userId1) -> {
- String defaultBrowser;
+ final String defaultBrowser;
synchronized (mPackages) {
mSettings.readDefaultAppsLPw(parser1, userId1);
defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
}
if (defaultBrowser != null) {
- PackageManagerInternal.DefaultBrowserProvider provider;
- synchronized (mPackages) {
- provider = mDefaultBrowserProvider;
- }
- provider.setDefaultBrowser(defaultBrowser, userId1);
+ mPermissionManager
+ .setDefaultBrowser(defaultBrowser, false, false, userId1);
}
});
} catch (Exception e) {
@@ -20219,15 +20052,7 @@
}
allHomeCandidates.addAll(resolveInfos);
- PackageManagerInternal.DefaultHomeProvider provider;
- synchronized (mPackages) {
- provider = mDefaultHomeProvider;
- }
- if (provider == null) {
- Slog.e(TAG, "mDefaultHomeProvider is null");
- return null;
- }
- String packageName = provider.getDefaultHome(userId);
+ final String packageName = mPermissionManager.getDefaultHome(userId);
if (packageName == null) {
return null;
}
@@ -20280,15 +20105,7 @@
final String packageName = preferredResolveInfo != null
&& preferredResolveInfo.activityInfo != null
? preferredResolveInfo.activityInfo.packageName : null;
- final PackageManagerInternal.DefaultHomeProvider provider;
- synchronized (mPackages) {
- provider = mDefaultHomeProvider;
- }
- if (provider == null) {
- Slog.e(TAG, "Default home provider has not been set");
- return false;
- }
- final String currentPackageName = provider.getDefaultHome(userId);
+ final String currentPackageName = mPermissionManager.getDefaultHome(userId);
if (TextUtils.equals(currentPackageName, packageName)) {
return false;
}
@@ -20298,7 +20115,7 @@
// PermissionController manages default home directly.
return false;
}
- provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
+ mPermissionManager.setDefaultHome(currentPackageName, userId, (successful) -> {
if (successful) {
postPreferredActivityChangedBroadcast(userId);
}
@@ -20854,7 +20671,8 @@
// Disable any carrier apps. We do this very early in boot to prevent the apps from being
// disabled after already being started.
CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
- mContext.getContentResolver(), UserHandle.USER_SYSTEM);
+ mPermissionManagerService, mContext.getContentResolver(),
+ UserHandle.USER_SYSTEM);
disableSkuSpecificApps();
@@ -20868,8 +20686,6 @@
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
}
- int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
-
synchronized (mPackages) {
// Verify that all of the preferred activity components actually
// exist. It is possible for applications to be updated and at
@@ -20899,27 +20715,9 @@
mSettings.mPreferredActivities.keyAt(i));
}
}
-
- for (int userId : UserManagerService.getInstance().getUserIds()) {
- if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
- grantPermissionsUserIds = ArrayUtils.appendInt(
- grantPermissionsUserIds, userId);
- }
- }
}
sUserManager.systemReady();
- // If we upgraded grant all default permissions before kicking off.
- for (int userId : grantPermissionsUserIds) {
- mDefaultPermissionPolicy.grantDefaultPermissions(userId);
- }
-
- if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
- // If we did not grant default permissions, we preload from this the
- // default permission exceptions lazily to ensure we don't hit the
- // disk on a new user creation.
- mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
- }
// Now that we've scanned all packages, and granted any default
// permissions, ensure permissions are updated. Beware of dragons if you
@@ -22943,11 +22741,7 @@
}
void onNewUserCreated(final int userId) {
- mDefaultPermissionPolicy.grantDefaultPermissions(userId);
- synchronized(mPackages) {
- // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
- mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, true);
- }
+ mPermissionManager.onNewUserCreated(userId);
}
@Override
@@ -22962,44 +22756,6 @@
}
@Override
- public void setPermissionEnforced(String permission, boolean enforced) {
- // TODO: Now that we no longer change GID for storage, this should to away.
- mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
- "setPermissionEnforced");
- if (READ_EXTERNAL_STORAGE.equals(permission)) {
- synchronized (mPackages) {
- if (mSettings.mReadExternalStorageEnforced == null
- || mSettings.mReadExternalStorageEnforced != enforced) {
- mSettings.mReadExternalStorageEnforced =
- enforced ? Boolean.TRUE : Boolean.FALSE;
- mSettings.writeLPr();
- }
- }
- // kill any non-foreground processes so we restart them and
- // grant/revoke the GID.
- final IActivityManager am = ActivityManager.getService();
- if (am != null) {
- final long token = Binder.clearCallingIdentity();
- try {
- am.killProcessesBelowForeground("setPermissionEnforcement");
- } catch (RemoteException e) {
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- } else {
- throw new IllegalArgumentException("No selective enforcement for " + permission);
- }
- }
-
- @Override
- @Deprecated
- public boolean isPermissionEnforced(String permission) {
- // allow instant applications
- return true;
- }
-
- @Override
public boolean isStorageLow() {
// allow instant applications
final long token = Binder.clearCallingIdentity();
@@ -23463,8 +23219,20 @@
@Override
public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
synchronized (mPackages) {
- return PackageManagerService.this.filterAppAccessLPr(
- (PackageSetting) pkg.mExtras, callingUid, userId);
+ return PackageManagerService.this
+ .filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid, userId);
+ }
+ }
+
+ @Override
+ public boolean filterAppAccess(String packageName, int callingUid, int userId) {
+ synchronized (mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ return false;
+ }
+ return PackageManagerService.this
+ .filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid, userId);
}
}
@@ -23531,7 +23299,7 @@
public String getKnownPackageName(int knownPackage, int userId) {
switch(knownPackage) {
case PackageManagerInternal.PACKAGE_BROWSER:
- return getDefaultBrowserPackageName(userId);
+ return mPermissionManager.getDefaultBrowser(userId);
case PackageManagerInternal.PACKAGE_INSTALLER:
return mRequiredInstallerPackage;
case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
@@ -23565,37 +23333,6 @@
}
@Override
- public void setLocationPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
- }
-
- @Override
- public void setLocationExtraPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setLocationExtraPackagesProvider(provider);
- }
-
- @Override
- public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
- }
-
- @Override
- public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
- }
-
- @Override
- public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
- mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
- }
-
- @Override
- public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
- packageName, userId);
- }
-
- @Override
public void setKeepUninstalledPackages(final List<String> packageList) {
Preconditions.checkNotNull(packageList);
List<String> removedFromList = null;
@@ -24108,27 +23845,6 @@
}
@Override
- public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
- synchronized (mPackages) {
- mDefaultBrowserProvider = provider;
- }
- }
-
- @Override
- public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
- synchronized (mPackages) {
- mDefaultDialerProvider = provider;
- }
- }
-
- @Override
- public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
- synchronized (mPackages) {
- mDefaultHomeProvider = provider;
- }
- }
-
- @Override
public boolean isApexPackage(String packageName) {
return PackageManagerService.this.mApexManager.isApexPackage(packageName);
}
@@ -24174,13 +23890,6 @@
}
@Override
- public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
- synchronized (mPackages) {
- return mDefaultPermissionPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
- }
- }
-
- @Override
public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
@UserIdInt int userId) {
synchronized (mPackages) {
@@ -24266,6 +23975,25 @@
&& UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
}
}
+
+ @Override
+ public boolean areDefaultRuntimePermissionsGranted(int userId) {
+ synchronized (mPackages) {
+ return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
+ }
+ }
+
+ @Override
+ public void setReadExternalStorageEnforced(boolean enforced) {
+ synchronized (mPackages) {
+ if (mSettings.mReadExternalStorageEnforced != null
+ && mSettings.mReadExternalStorageEnforced == enforced) {
+ return;
+ }
+ mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
+ mSettings.writeLPr();
+ }
+ }
}
@GuardedBy("mPackages")
@@ -24334,83 +24062,6 @@
}
}
- @Override
- public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
- enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
- synchronized (mPackages) {
- final long identity = Binder.clearCallingIdentity();
- try {
- mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
- packageNames, userId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- @Override
- public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
- enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
- synchronized (mPackages) {
- final long identity = Binder.clearCallingIdentity();
- try {
- mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
- packageNames, userId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- @Override
- public void grantDefaultPermissionsToEnabledTelephonyDataServices(
- String[] packageNames, int userId) {
- enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledTelephonyDataServices");
- synchronized (mPackages) {
- Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
- grantDefaultPermissionsToEnabledTelephonyDataServices(
- packageNames, userId));
- }
- }
-
- @Override
- public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
- String[] packageNames, int userId) {
- enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromDisabledTelephonyDataServices");
- synchronized (mPackages) {
- Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
- revokeDefaultPermissionsFromDisabledTelephonyDataServices(
- packageNames, userId));
- }
- }
-
- @Override
- public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
- enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp");
- synchronized (mPackages) {
- final long identity = Binder.clearCallingIdentity();
- try {
- mDefaultPermissionPolicy.grantDefaultPermissionsToActiveLuiApp(
- packageName, userId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- @Override
- public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
- enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps");
- synchronized (mPackages) {
- final long identity = Binder.clearCallingIdentity();
- try {
- mDefaultPermissionPolicy.revokeDefaultPermissionsFromLuiApps(packageNames, userId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
synchronized (mPackages) {
int numPackages = mPackages.size();
@@ -24435,14 +24086,6 @@
}
}
- private static void enforceSystemOrPhoneCaller(String tag) {
- int callingUid = Binder.getCallingUid();
- if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
- throw new SecurityException(
- "Cannot call " + tag + " from UID " + callingUid);
- }
- }
-
boolean isHistoricalPackageUsageAvailable() {
return mPackageUsage.isHistoricalPackageUsageAvailable();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index f56e1ef..4c7db9a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -390,6 +390,17 @@
}
/**
+ * Enforces that the caller must be either the system process or the phone process.
+ * If not, throws a {@link SecurityException}.
+ */
+ public static void enforceSystemOrPhoneCaller(String methodName, int callingUid) {
+ if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
+ throw new SecurityException(
+ "Cannot call " + methodName + " from UID " + callingUid);
+ }
+ }
+
+ /**
* Derive the value of the {@code cpuAbiOverride} based on the provided
* value and an optional stored value from the package settings.
*/
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 53c1c1f..85bc9f3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2020,7 +2020,7 @@
getErrPrintWriter().println("Error: no enforcement specified");
return 1;
}
- mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
+ mPermissionManager.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
return 0;
}
@@ -2042,10 +2042,10 @@
}
}
- private boolean isProductServicesApp(String pkg) {
+ private boolean isSystemExtApp(String pkg) {
try {
final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
- return info != null && info.applicationInfo.isProductServices();
+ return info != null && info.applicationInfo.isSystemExt();
} catch (RemoteException e) {
return false;
}
@@ -2063,9 +2063,9 @@
privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
} else if (isProductApp(pkg)) {
privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
- } else if (isProductServicesApp(pkg)) {
+ } else if (isSystemExtApp(pkg)) {
privAppPermissions = SystemConfig.getInstance()
- .getProductServicesPrivAppPermissions(pkg);
+ .getSystemExtPrivAppPermissions(pkg);
} else {
privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
}
@@ -2087,9 +2087,9 @@
privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
} else if (isProductApp(pkg)) {
privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
- } else if (isProductServicesApp(pkg)) {
+ } else if (isSystemExtApp(pkg)) {
privAppPermissions = SystemConfig.getInstance()
- .getProductServicesPrivAppDenyPermissions(pkg);
+ .getSystemExtPrivAppDenyPermissions(pkg);
} else {
privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
}
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index e859893..4ea8a30 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -148,8 +148,8 @@
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
}
- public boolean isProductServices() {
- return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+ public boolean isSystemExt() {
+ return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
}
public boolean isOdm() {
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index a24818f..ec9746d 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -63,7 +63,7 @@
| ApplicationInfo.PRIVATE_FLAG_OEM
| ApplicationInfo.PRIVATE_FLAG_VENDOR
| ApplicationInfo.PRIVATE_FLAG_PRODUCT
- | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+ | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
| ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER
| ApplicationInfo.PRIVATE_FLAG_ODM);
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 11a8f4b..3bc2236 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -774,7 +774,7 @@
| ApplicationInfo.PRIVATE_FLAG_OEM
| ApplicationInfo.PRIVATE_FLAG_VENDOR
| ApplicationInfo.PRIVATE_FLAG_PRODUCT
- | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+ | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
| ApplicationInfo.PRIVATE_FLAG_ODM);
pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
pkgSetting.pkgPrivateFlags |=
@@ -786,7 +786,7 @@
pkgSetting.pkgPrivateFlags |=
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT;
pkgSetting.pkgPrivateFlags |=
- pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+ pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
pkgSetting.pkgPrivateFlags |=
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
pkgSetting.primaryCpuAbiString = primaryCpuAbi;
@@ -4413,7 +4413,7 @@
ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
- ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES, "PRODUCT_SERVICES",
+ ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT, "SYSTEM_EXT",
ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
};
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 db01d77..fe0b3a3 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -34,8 +34,6 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManagerInternal.PackagesProvider;
-import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
@@ -69,6 +67,8 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.PackagesProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.SyncAdapterPackagesProvider;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -1388,8 +1388,7 @@
if (dir.isDirectory() && dir.canRead()) {
Collections.addAll(ret, dir.listFiles());
}
- dir = new File(Environment.getProductServicesDirectory(),
- "etc/default-permissions");
+ dir = new File(Environment.getSystemExtDirectory(), "etc/default-permissions");
if (dir.isDirectory() && dir.canRead()) {
Collections.addAll(ret, dir.listFiles());
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 9d0b427..673ab6c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -33,6 +33,7 @@
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
+import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
@@ -118,6 +119,9 @@
import com.android.server.pm.PackageSetting;
import com.android.server.pm.SharedUserSetting;
import com.android.server.pm.UserManagerService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
import com.android.server.pm.permission.PermissionsState.PermissionState;
import com.android.server.policy.SoftRestrictedPermissionPolicy;
@@ -250,6 +254,15 @@
@GuardedBy("mLock")
private final OnPermissionChangeListeners mOnPermissionChangeListeners;
+ @GuardedBy("mLock")
+ private DefaultBrowserProvider mDefaultBrowserProvider;
+
+ @GuardedBy("mLock")
+ private DefaultDialerProvider mDefaultDialerProvider;
+
+ @GuardedBy("mLock")
+ private DefaultHomeProvider mDefaultHomeProvider;
+
// TODO: Take a look at the methods defined in the callback.
// The callback was initially created to support the split between permission
// manager and the package manager. However, it's started to be used for other
@@ -1609,6 +1622,226 @@
mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
}
+ @Override
+ public String getDefaultBrowser(int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (UserHandle.getUserId(callingUid) != userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
+ if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+ return null;
+ }
+ synchronized (mLock) {
+ return mDefaultBrowserProvider == null
+ ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
+ }
+ }
+
+ @Override
+ public boolean setDefaultBrowser(String packageName, int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
+ return setDefaultBrowserInternal(packageName, false, true, userId);
+ }
+
+ private boolean setDefaultBrowserInternal(String packageName, boolean async,
+ boolean doGrant, int userId) {
+ synchronized (mLock) {
+ if (userId == UserHandle.USER_ALL) {
+ return false;
+ }
+ if (mDefaultBrowserProvider == null) {
+ return false;
+ }
+ if (async) {
+ mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
+ } else {
+ if (!mDefaultBrowserProvider.setDefaultBrowser(packageName, userId)) {
+ return false;
+ }
+ }
+ if (doGrant && packageName != null) {
+ mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils
+ .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
+ synchronized (mLock) {
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+ "grantDefaultPermissionsToEnabledImsServices", callingUid);
+ synchronized (mLock) {
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToEnabledTelephonyDataServices(
+ String[] packageNames, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+ "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
+ synchronized (mLock) {
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToEnabledTelephonyDataServices(
+ packageNames, userId));
+ }
+ }
+
+ @Override
+ public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+ String[] packageNames, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+ "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
+ synchronized (mLock) {
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+ packageNames, userId));
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils
+ .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
+ synchronized (mLock) {
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
+ }
+ }
+
+ @Override
+ public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ PackageManagerServiceUtils
+ .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
+ synchronized (mLock) {
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
+ }
+ }
+
+ @Override
+ public void setPermissionEnforced(String permName, boolean enforced) {
+ // TODO: Now that we no longer change GID for storage, this should to away.
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
+ "setPermissionEnforced");
+ if (READ_EXTERNAL_STORAGE.equals(permName)) {
+ mPackageManagerInt.setReadExternalStorageEnforced(enforced);
+ // kill any non-foreground processes so we restart them and
+ // grant/revoke the GID.
+ final IActivityManager am = ActivityManager.getService();
+ if (am != null) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ am.killProcessesBelowForeground("setPermissionEnforcement");
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("No selective enforcement for " + permName);
+ }
+ }
+
+ /** @deprecated */
+ @Override
+ @Deprecated
+ public boolean isPermissionEnforced(String permName) {
+ // allow instant applications
+ return true;
+ }
+
+ @Override
+ public boolean shouldShowRequestPermissionRationale(String permName,
+ String packageName, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "canShowRequestPermissionRationale for user " + userId);
+ }
+
+ final int uid =
+ mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
+ if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
+ return false;
+ }
+
+ if (checkPermission(permName, packageName, userId)
+ == PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+
+ final int flags;
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+
+ final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+ | PackageManager.FLAG_PERMISSION_POLICY_FIXED
+ | PackageManager.FLAG_PERMISSION_USER_FIXED;
+
+ if ((flags & fixedFlags) != 0) {
+ return false;
+ }
+
+ return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
+ }
+
+ @Override
+ public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "isPermissionRevokedByPolicy for user " + userId);
+ }
+
+ if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+
+ final int callingUid = Binder.getCallingUid();
+ if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
+ return false;
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+ return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
/**
* Get the state of the runtime permissions as xml file.
*
@@ -2746,9 +2979,9 @@
} else if (pkg.isProduct()) {
wlPermissions =
SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
- } else if (pkg.isProductServices()) {
+ } else if (pkg.isSystemExt()) {
wlPermissions =
- SystemConfig.getInstance().getProductServicesPrivAppPermissions(
+ SystemConfig.getInstance().getSystemExtPrivAppPermissions(
pkg.packageName);
} else {
wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
@@ -2782,9 +3015,9 @@
} else if (pkg.isProduct()) {
deniedPermissions = SystemConfig.getInstance()
.getProductPrivAppDenyPermissions(pkg.packageName);
- } else if (pkg.isProductServices()) {
+ } else if (pkg.isSystemExt()) {
deniedPermissions = SystemConfig.getInstance()
- .getProductServicesPrivAppDenyPermissions(pkg.packageName);
+ .getSystemExtPrivAppDenyPermissions(pkg.packageName);
} else {
deniedPermissions = SystemConfig.getInstance()
.getPrivAppDenyPermissions(pkg.packageName);
@@ -2793,13 +3026,15 @@
deniedPermissions == null || !deniedPermissions.contains(perm);
if (permissionViolation) {
Slog.w(TAG, "Privileged permission " + perm + " for package "
- + pkg.packageName + " - not in privapp-permissions whitelist");
+ + pkg.packageName + " (" + pkg.codePath
+ + ") not in privapp-permissions whitelist");
if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
if (mPrivappPermissionsViolations == null) {
mPrivappPermissionsViolations = new ArraySet<>();
}
- mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
+ mPrivappPermissionsViolations.add(
+ pkg.packageName + " (" + pkg.codePath + "): " + perm);
}
} else {
return false;
@@ -3714,6 +3949,24 @@
}
mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
+
+ int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ if (!mPackageManagerInt.areDefaultRuntimePermissionsGranted(userId)) {
+ grantPermissionsUserIds = ArrayUtils.appendInt(
+ grantPermissionsUserIds, userId);
+ }
+ }
+ // If we upgraded grant all default permissions before kicking off.
+ for (int userId : grantPermissionsUserIds) {
+ mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+ }
+ if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
+ // If we did not grant default permissions, we preload from this the
+ // default permission exceptions lazily to ensure we don't hit the
+ // disk on a new user creation.
+ mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
+ }
}
private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
@@ -3847,20 +4100,6 @@
.getAppOpPermissionPackagesInternal(permName, callingUid);
}
@Override
- public int getPermissionFlags(String permName, String packageName, int callingUid,
- int userId) {
- return PermissionManagerService.this
- .getPermissionFlagsInternal(permName, packageName, callingUid, userId);
- }
- @Override
- public void updatePermissionFlags(String permName, String packageName, int flagMask,
- int flagValues, int callingUid, int userId, boolean overridePolicy,
- PermissionCallback callback) {
- PermissionManagerService.this.updatePermissionFlagsInternal(
- permName, packageName, flagMask, flagValues, callingUid, userId,
- overridePolicy, callback);
- }
- @Override
public void enforceCrossUserPermission(int callingUid, int userId,
boolean requireFullPermission, boolean checkShell, String message) {
PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
@@ -3882,10 +4121,6 @@
return mSettings;
}
@Override
- public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
- return mDefaultPermissionGrantPolicy;
- }
- @Override
public BasePermission getPermissionTEMP(String permName) {
synchronized (PermissionManagerService.this.mLock) {
return mSettings.getPermissionLocked(permName);
@@ -3956,9 +4191,166 @@
mCheckPermissionDelegate = delegate;
}
}
+
@Override
- public void notifyPermissionsChangedTEMP(int uid) {
- mOnPermissionChangeListeners.onPermissionsChanged(uid);
+ public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
+ synchronized (mLock) {
+ mDefaultBrowserProvider = provider;
+ }
+ }
+
+ @Override
+ public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
+ int userId) {
+ setDefaultBrowserInternal(packageName, async, doGrant, userId);
+ }
+
+ @Override
+ public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
+ synchronized (mLock) {
+ mDefaultDialerProvider = provider;
+ }
+ }
+
+ @Override
+ public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
+ synchronized (mLock) {
+ mDefaultHomeProvider = provider;
+ }
+ }
+
+ @Override
+ public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
+ synchronized (mLock) {
+ if (userId == UserHandle.USER_ALL) {
+ return;
+ }
+ if (mDefaultHomeProvider == null) {
+ return;
+ }
+ mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, callback);
+ }
+ }
+
+ @Override
+ public void setDialerAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setLocationExtraPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setLocationPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setSmsAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
+ }
+ }
+
+ @Override
+ public String getDefaultBrowser(int userId) {
+ synchronized (mLock) {
+ return mDefaultBrowserProvider == null
+ ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
+ }
+ }
+
+ @Override
+ public String getDefaultDialer(int userId) {
+ synchronized (mLock) {
+ return mDefaultDialerProvider == null
+ ? null : mDefaultDialerProvider.getDefaultDialer(userId);
+ }
+ }
+
+ @Override
+ public String getDefaultHome(int userId) {
+ synchronized (mLock) {
+ return mDefaultHomeProvider == null
+ ? null : mDefaultHomeProvider.getDefaultHome(userId);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
+ }
+ }
+
+ @Override
+ public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
+ synchronized (mLock) {
+ return mDefaultPermissionGrantPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
+ }
+ }
+
+ @Override
+ public void onNewUserCreated(int userId) {
+ synchronized (mLock) {
+ mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+ // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
+ PermissionManagerService.this.updateAllPermissions(
+ StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 2fdab4d..04ec5ba 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Consumer;
/**
* Internal interfaces services.
@@ -35,6 +36,109 @@
*/
public abstract class PermissionManagerServiceInternal extends PermissionManagerInternal {
/**
+ * Provider for package names.
+ */
+ public interface PackagesProvider {
+
+ /**
+ * Gets the packages for a given user.
+ * @param userId The user id.
+ * @return The package names.
+ */
+ String[] getPackages(int userId);
+ }
+
+ /**
+ * Provider for package names.
+ */
+ public interface SyncAdapterPackagesProvider {
+
+ /**
+ * Gets the sync adapter packages for given authority and user.
+ * @param authority The authority.
+ * @param userId The user id.
+ * @return The package names.
+ */
+ String[] getPackages(String authority, int userId);
+ }
+
+ /**
+ * Provider for default browser
+ */
+ public interface DefaultBrowserProvider {
+
+ /**
+ * Get the package name of the default browser.
+ *
+ * @param userId the user id
+ *
+ * @return the package name of the default browser, or {@code null} if none
+ */
+ @Nullable
+ String getDefaultBrowser(@UserIdInt int userId);
+
+ /**
+ * Set the package name of the default browser.
+ *
+ * @param packageName package name of the default browser, or {@code null} to remove
+ * @param userId the user id
+ *
+ * @return whether the default browser was successfully set.
+ */
+ boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
+
+ /**
+ * Set the package name of the default browser asynchronously.
+ *
+ * @param packageName package name of the default browser, or {@code null} to remove
+ * @param userId the user id
+ */
+ void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
+ }
+
+ /**
+ * Provider for default dialer
+ */
+ public interface DefaultDialerProvider {
+
+ /**
+ * Get the package name of the default dialer.
+ *
+ * @param userId the user id
+ *
+ * @return the package name of the default dialer, or {@code null} if none
+ */
+ @Nullable
+ String getDefaultDialer(@UserIdInt int userId);
+ }
+
+ /**
+ * Provider for default home
+ */
+ public interface DefaultHomeProvider {
+
+ /**
+ * Get the package name of the default home.
+ *
+ * @param userId the user id
+ *
+ * @return the package name of the default home, or {@code null} if none
+ */
+ @Nullable
+ String getDefaultHome(@UserIdInt int userId);
+
+ /**
+ * Set the package name of the default home.
+ *
+ * @param packageName package name of the default home, or {@code null} to remove
+ * @param userId the user id
+ * @param callback the callback made after the default home as been updated
+ */
+ void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
+ @NonNull Consumer<Boolean> callback);
+ }
+
+ /**
* Callbacks invoked when interesting actions have been taken on a permission.
* <p>
* NOTE: The current arguments are merely to support the existing use cases. This
@@ -159,17 +263,6 @@
public abstract @Nullable String[] getAppOpPermissionPackages(
@NonNull String permName, int callingUid);
- public abstract int getPermissionFlags(@NonNull String permName,
- @NonNull String packageName, int callingUid, int userId);
-
- /**
- * Updates the flags associated with a permission by replacing the flags in
- * the specified mask with the provided flag values.
- */
- public abstract void updatePermissionFlags(@NonNull String permName,
- @NonNull String packageName, int flagMask, int flagValues, int callingUid, int userId,
- boolean overridePolicy, @Nullable PermissionCallback callback);
-
/**
* Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
* or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userid} is not for the caller.
@@ -189,13 +282,13 @@
public abstract void enforceGrantRevokeRuntimePermissionPermissions(@NonNull String message);
public abstract @NonNull PermissionSettings getPermissionSettings();
- public abstract @NonNull DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy();
+
+ /** Grants default browser permissions to the given package */
+ public abstract void grantDefaultPermissionsToDefaultBrowser(
+ @NonNull String packageName, @UserIdInt int userId);
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
- /** HACK HACK notify the permission listener; this shouldn't be needed after permissions
- * are fully removed from the package manager */
- public abstract void notifyPermissionsChangedTEMP(int uid);
/** Get all permission that have a certain protection level */
public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
@@ -214,4 +307,142 @@
* @param delegate A delegate instance or {@code null} to clear.
*/
public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate);
+
+ /**
+ * Sets the dialer application packages provider.
+ * @param provider The provider.
+ */
+ public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Set the location extra packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setLocationExtraPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the location provider packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setLocationPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the SIM call manager packages provider.
+ * @param provider The provider.
+ */
+ public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the SMS application packages provider.
+ * @param provider The provider.
+ */
+ public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the sync adapter packages provider.
+ * @param provider The provider.
+ */
+ public abstract void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider);
+
+ /**
+ * Sets the Use Open Wifi packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the voice interaction packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the default browser provider.
+ *
+ * @param provider the provider
+ */
+ public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
+
+ /**
+ * Sets the package name of the default browser provider for the given user.
+ *
+ * @param packageName The package name of the default browser or {@code null}
+ * to clear the default browser
+ * @param async If {@code true}, set the default browser asynchronously,
+ * otherwise set it synchronously
+ * @param doGrant If {@code true} and if {@code packageName} is not {@code null},
+ * perform default permission grants on the browser, otherwise skip the
+ * default permission grants.
+ * @param userId The user to set the default browser for.
+ */
+ public abstract void setDefaultBrowser(@Nullable String packageName, boolean async,
+ boolean doGrant, @UserIdInt int userId);
+
+ /**
+ * Sets the default dialer provider.
+ *
+ * @param provider the provider
+ */
+ public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
+
+ /**
+ * Sets the default home provider.
+ *
+ * @param provider the provider
+ */
+ public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
+
+ /**
+ * Asynchronously sets the package name of the default home provider for the given user.
+ *
+ * @param packageName The package name of the default home or {@code null}
+ * to clear the default browser
+ * @param userId The user to set the default browser for
+ * @param callback Invoked after the default home has been set
+ */
+ public abstract void setDefaultHome(@Nullable String packageName, @UserIdInt int userId,
+ @NonNull Consumer<Boolean> callback);
+
+ /**
+ * Returns the default browser package name for the given user.
+ */
+ @Nullable
+ public abstract String getDefaultBrowser(@UserIdInt int userId);
+
+ /**
+ * Returns the default dialer package name for the given user.
+ */
+ @Nullable
+ public abstract String getDefaultDialer(@UserIdInt int userId);
+
+ /**
+ * Returns the default home package name for the given user.
+ */
+ @Nullable
+ public abstract String getDefaultHome(@UserIdInt int userId);
+
+ /**
+ * Requests granting of the default permissions to the current default Use Open Wifi app.
+ * @param packageName The default use open wifi package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultSimCallManager(
+ @NonNull String packageName, @UserIdInt int userId);
+
+ /**
+ * Requests granting of the default permissions to the current default Use Open Wifi app.
+ * @param packageName The default use open wifi package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(
+ @NonNull String packageName, @UserIdInt int userId);
+
+ /**
+ * Returns whether or not default permission grants have been performed for the given
+ * user since the device booted.
+ */
+ public abstract boolean wereDefaultPermissionsGrantedSinceBoot(@UserIdInt int userId);
+
+ /** Called when a new user has been created. */
+ public abstract void onNewUserCreated(@UserIdInt int userId);
}
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index a569bff..8da7f7b 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -260,9 +260,11 @@
private void grantOrUpgradeDefaultRuntimePermissionsIfNeeded(@UserIdInt int userId) {
if (DEBUG) Slog.i(LOG_TAG, "grantOrUpgradeDefaultPermsIfNeeded(" + userId + ")");
- final PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
- if (packageManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
+ final PackageManagerInternal packageManagerInternal =
+ LocalServices.getService(PackageManagerInternal.class);
+ final PermissionManagerServiceInternal permissionManagerInternal =
+ LocalServices.getService(PermissionManagerServiceInternal.class);
+ if (permissionManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
if (DEBUG) Slog.i(LOG_TAG, "defaultPermsWereGrantedSinceBoot(" + userId + ")");
// Now call into the permission controller to apply policy around permissions
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index d53f685..c1a6dbd 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -28,11 +28,14 @@
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+import static java.lang.Integer.min;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.UserHandle;
@@ -73,6 +76,41 @@
};
/**
+ * TargetSDK is per package. To make sure two apps int the same shared UID do not fight over
+ * what to set, always compute the combined targetSDK.
+ *
+ * @param context A context
+ * @param appInfo The app that is changed
+ * @param user The user the app belongs to
+ *
+ * @return The minimum targetSDK of all apps sharing the uid of the app
+ */
+ private static int getMinimumTargetSDK(@NonNull Context context,
+ @NonNull ApplicationInfo appInfo, @NonNull UserHandle user) {
+ PackageManager pm = context.getPackageManager();
+
+ int minimumTargetSDK = appInfo.targetSdkVersion;
+
+ String[] uidPkgs = pm.getPackagesForUid(appInfo.uid);
+ if (uidPkgs != null) {
+ for (String uidPkg : uidPkgs) {
+ if (!uidPkg.equals(appInfo.packageName)) {
+ ApplicationInfo uidPkgInfo;
+ try {
+ uidPkgInfo = pm.getApplicationInfoAsUser(uidPkg, 0, user);
+ } catch (PackageManager.NameNotFoundException e) {
+ continue;
+ }
+
+ minimumTargetSDK = min(minimumTargetSDK, uidPkgInfo.targetSdkVersion);
+ }
+ }
+ }
+
+ return minimumTargetSDK;
+ }
+
+ /**
* Get the policy for a soft restricted permission.
*
* @param context A context to use
@@ -99,12 +137,36 @@
final int targetSDK;
if (appInfo != null) {
- flags = context.getPackageManager().getPermissionFlags(permission,
- appInfo.packageName, user);
+ PackageManager pm = context.getPackageManager();
+ flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
- hasRequestedLegacyExternalStorage = appInfo.hasRequestedLegacyExternalStorage();
- targetSDK = appInfo.targetSdkVersion;
+ targetSDK = getMinimumTargetSDK(context, appInfo, user);
+
+ boolean hasAnyRequestedLegacyExternalStorage =
+ appInfo.hasRequestedLegacyExternalStorage();
+
+ // hasRequestedLegacyExternalStorage is per package. To make sure two apps in
+ // the same shared UID do not fight over what to set, always compute the
+ // combined hasRequestedLegacyExternalStorage
+ String[] uidPkgs = pm.getPackagesForUid(appInfo.uid);
+ if (uidPkgs != null) {
+ for (String uidPkg : uidPkgs) {
+ if (!uidPkg.equals(appInfo.packageName)) {
+ ApplicationInfo uidPkgInfo;
+ try {
+ uidPkgInfo = pm.getApplicationInfoAsUser(uidPkg, 0, user);
+ } catch (PackageManager.NameNotFoundException e) {
+ continue;
+ }
+
+ hasAnyRequestedLegacyExternalStorage |=
+ uidPkgInfo.hasRequestedLegacyExternalStorage();
+ }
+ }
+ }
+
+ hasRequestedLegacyExternalStorage = hasAnyRequestedLegacyExternalStorage;
} else {
flags = 0;
applyRestriction = false;
@@ -155,7 +217,7 @@
final int flags = context.getPackageManager().getPermissionFlags(permission,
appInfo.packageName, user);
isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
- targetSDK = appInfo.targetSdkVersion;
+ targetSDK = getMinimumTargetSDK(context, appInfo, user);
} else {
isWhiteListed = false;
targetSDK = 0;
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 9f64039..484017b 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -33,6 +33,9 @@
"options": [
{
"include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+ },
+ {
+ "include-filter": "android.permission2.cts.RestrictedStoragePermissionSharedUidTest"
}
]
},
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b503ce8..1948b20 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -76,6 +76,7 @@
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
@@ -166,11 +167,11 @@
LocalServices.addService(RoleManagerInternal.class, new Internal());
- PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
- packageManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
- packageManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
- packageManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
+ PermissionManagerServiceInternal permissionManagerInternal =
+ LocalServices.getService(PermissionManagerServiceInternal.class);
+ permissionManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
+ permissionManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
+ permissionManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
registerUserRemovedReceiver();
}
@@ -755,7 +756,8 @@
}
}
- private class DefaultBrowserProvider implements PackageManagerInternal.DefaultBrowserProvider {
+ private class DefaultBrowserProvider implements
+ PermissionManagerServiceInternal.DefaultBrowserProvider {
@Nullable
@Override
@@ -809,7 +811,8 @@
}
}
- private class DefaultDialerProvider implements PackageManagerInternal.DefaultDialerProvider {
+ private class DefaultDialerProvider implements
+ PermissionManagerServiceInternal.DefaultDialerProvider {
@Nullable
@Override
@@ -819,7 +822,8 @@
}
}
- private class DefaultHomeProvider implements PackageManagerInternal.DefaultHomeProvider {
+ private class DefaultHomeProvider implements
+ PermissionManagerServiceInternal.DefaultHomeProvider {
@Nullable
@Override
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 54369ca..a853529 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -39,7 +39,6 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerService;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
/**
@@ -66,9 +65,9 @@
ServiceManager.addService(Context.TELECOM_SERVICE, service);
synchronized (mLock) {
+ final PermissionManagerServiceInternal permissionManager =
+ LocalServices.getService(PermissionManagerServiceInternal.class);
if (mDefaultSimCallManagerRequests != null) {
- final DefaultPermissionGrantPolicy permissionPolicy =
- getDefaultPermissionGrantPolicy();
if (mDefaultSimCallManagerRequests != null) {
TelecomManager telecomManager =
(TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
@@ -80,7 +79,7 @@
for (int i = requestCount - 1; i >= 0; i--) {
final int userId = mDefaultSimCallManagerRequests.get(i);
mDefaultSimCallManagerRequests.remove(i);
- permissionPolicy
+ permissionManager
.grantDefaultPermissionsToDefaultSimCallManager(
packageName, userId);
}
@@ -99,11 +98,6 @@
}
}
- private DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
- return LocalServices.getService(PermissionManagerServiceInternal.class)
- .getDefaultPermissionGrantPolicy();
- }
-
private static final ComponentName SERVICE_COMPONENT = new ComponentName(
"com.android.server.telecom",
"com.android.server.telecom.components.TelecomService");
@@ -162,10 +156,11 @@
private void registerDefaultAppProviders() {
- final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
+ final PermissionManagerServiceInternal permissionManager =
+ LocalServices.getService(PermissionManagerServiceInternal.class);
// Set a callback for the permission grant policy to query the default sms app.
- permissionPolicy.setSmsAppPackagesProvider(userId -> {
+ permissionManager.setSmsAppPackagesProvider(userId -> {
synchronized (mLock) {
if (mServiceConnection == null) {
return null;
@@ -180,7 +175,7 @@
});
// Set a callback for the permission grant policy to query the default dialer app.
- permissionPolicy.setDialerAppPackagesProvider(userId -> {
+ permissionManager.setDialerAppPackagesProvider(userId -> {
synchronized (mLock) {
if (mServiceConnection == null) {
return null;
@@ -194,7 +189,7 @@
});
// Set a callback for the permission grant policy to query the default sim call manager.
- permissionPolicy.setSimCallManagerPackagesProvider(userId -> {
+ permissionManager.setSimCallManagerPackagesProvider(userId -> {
synchronized (mLock) {
if (mServiceConnection == null) {
if (mDefaultSimCallManagerRequests == null) {
@@ -215,12 +210,11 @@
}
private void registerDefaultAppNotifier() {
- final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
// Notify the package manager on default app changes
final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
- (roleName, user) -> updateSimCallManagerPermissions(permissionPolicy,
- user.getIdentifier()), UserHandle.ALL);
+ (roleName, user) -> updateSimCallManagerPermissions(user.getIdentifier()),
+ UserHandle.ALL);
}
@@ -230,7 +224,7 @@
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
for (int userId : UserManagerService.getInstance().getUserIds()) {
- updateSimCallManagerPermissions(getDefaultPermissionGrantPolicy(), userId);
+ updateSimCallManagerPermissions(userId);
}
}
}
@@ -240,16 +234,16 @@
new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null);
}
- private void updateSimCallManagerPermissions(
- DefaultPermissionGrantPolicy permissionGrantPolicy, int userId) {
+ private void updateSimCallManagerPermissions(int userId) {
+ final PermissionManagerServiceInternal permissionManager =
+ LocalServices.getService(PermissionManagerServiceInternal.class);
TelecomManager telecomManager =
(TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
if (phoneAccount != null) {
Slog.i(TAG, "updating sim call manager permissions for userId:" + userId);
String packageName = phoneAccount.getComponentName().getPackageName();
- permissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
- packageName, userId);
+ permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
}
}
}
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 55f062b..b2f1153 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -949,7 +949,25 @@
return false;
}
- return readMet && writeMet;
+ // If this provider says that grants are always required, we need to
+ // consult it directly to determine if the UID has permission
+ final boolean forceMet;
+ if (pi.forceUriPermissions) {
+ final int providerUserId = UserHandle.getUserId(pi.applicationInfo.uid);
+ final int clientUserId = UserHandle.getUserId(uid);
+ if (providerUserId == clientUserId) {
+ forceMet = (mAmInternal.checkContentProviderUriPermission(grantUri.uri,
+ providerUserId, uid, modeFlags) == PackageManager.PERMISSION_GRANTED);
+ } else {
+ // The provider can't track cross-user permissions, so we have
+ // to assume they're always denied
+ forceMet = false;
+ }
+ } else {
+ forceMet = true;
+ }
+
+ return readMet && writeMet && forceMet;
}
private void removeUriPermissionIfNeeded(UriPermission perm) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index bace7e3..8abfde2 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -22,6 +22,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.utils.RegionUtils.forEachRect;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -1126,14 +1127,13 @@
// Iterate until we figure out what is touchable for the entire screen.
for (int i = visibleWindowCount - 1; i >= 0; i--) {
final WindowState windowState = visibleWindows.valueAt(i);
+ final Region regionInScreen = new Region();
+ computeWindowRegionInScreen(windowState, regionInScreen);
- final Rect boundsInScreen = mTempRect;
- computeWindowBoundsInScreen(windowState, boundsInScreen);
-
- if (windowMattersToAccessibility(windowState, boundsInScreen, unaccountedSpace,
+ if (windowMattersToAccessibility(windowState, regionInScreen, unaccountedSpace,
skipRemainingWindowsForTasks)) {
- addPopulatedWindowInfo(windowState, boundsInScreen, windows, addedWindows);
- updateUnaccountedSpace(windowState, boundsInScreen, unaccountedSpace,
+ addPopulatedWindowInfo(windowState, regionInScreen, windows, addedWindows);
+ updateUnaccountedSpace(windowState, regionInScreen, unaccountedSpace,
skipRemainingWindowsForTasks);
focusedWindowAdded |= windowState.isFocused();
}
@@ -1171,8 +1171,9 @@
clearAndRecycleWindows(windows);
}
- private boolean windowMattersToAccessibility(WindowState windowState, Rect boundsInScreen,
- Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) {
+ private boolean windowMattersToAccessibility(WindowState windowState,
+ Region regionInScreen, Region unaccountedSpace,
+ HashSet<Integer> skipRemainingWindowsForTasks) {
if (windowState.isFocused()) {
return true;
}
@@ -1192,7 +1193,7 @@
}
// If the window is completely covered by other windows - ignore.
- if (unaccountedSpace.quickReject(boundsInScreen)) {
+ if (unaccountedSpace.quickReject(regionInScreen)) {
return false;
}
@@ -1204,7 +1205,7 @@
return false;
}
- private void updateUnaccountedSpace(WindowState windowState, Rect boundsInScreen,
+ private void updateUnaccountedSpace(WindowState windowState, Region regionInScreen,
Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) {
if (windowState.mAttrs.type
!= WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
@@ -1212,59 +1213,71 @@
// Account for the space this window takes if the window
// is not an accessibility overlay which does not change
// the reported windows.
- unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+ unaccountedSpace.op(regionInScreen, unaccountedSpace,
Region.Op.REVERSE_DIFFERENCE);
// If a window is modal it prevents other windows from being touched
if ((windowState.mAttrs.flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)) == 0) {
- // Account for all space in the task, whether the windows in it are
- // touchable or not. The modal window blocks all touches from the task's
- // area.
- unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
- Region.Op.REVERSE_DIFFERENCE);
+ if (!windowState.hasTapExcludeRegion()) {
+ // Account for all space in the task, whether the windows in it are
+ // touchable or not. The modal window blocks all touches from the task's
+ // area.
+ unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
+ Region.Op.REVERSE_DIFFERENCE);
+ } else {
+ // If a window has tap exclude region, we need to account it.
+ final Region displayRegion = new Region(windowState.getDisplayFrameLw());
+ final Region tapExcludeRegion = new Region();
+ windowState.amendTapExcludeRegion(tapExcludeRegion);
+ displayRegion.op(tapExcludeRegion, displayRegion,
+ Region.Op.REVERSE_DIFFERENCE);
+ unaccountedSpace.op(displayRegion, unaccountedSpace,
+ Region.Op.REVERSE_DIFFERENCE);
+ }
final Task task = windowState.getTask();
if (task != null) {
// If the window is associated with a particular task, we can skip the
// rest of the windows for that task.
skipRemainingWindowsForTasks.add(task.mTaskId);
- } else {
+ } else if (!windowState.hasTapExcludeRegion()) {
// If the window is not associated with a particular task, then it is
- // globally modal. In this case we can skip all remaining windows.
+ // globally modal. In this case we can skip all remaining windows when
+ // it doesn't has tap exclude region.
unaccountedSpace.setEmpty();
}
}
}
}
- private void computeWindowBoundsInScreen(WindowState windowState, Rect outBounds) {
+ private void computeWindowRegionInScreen(WindowState windowState, Region outRegion) {
// Get the touchable frame.
Region touchableRegion = mTempRegion1;
windowState.getTouchableRegion(touchableRegion);
- Rect touchableFrame = mTempRect;
- touchableRegion.getBounds(touchableFrame);
-
- // Move to origin as all transforms are captured by the matrix.
- RectF windowFrame = mTempRectF;
- windowFrame.set(touchableFrame);
- windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
// Map the frame to get what appears on the screen.
Matrix matrix = mTempMatrix;
populateTransformationMatrixLocked(windowState, matrix);
- matrix.mapRect(windowFrame);
- // Got the bounds.
- outBounds.set((int) windowFrame.left, (int) windowFrame.top,
- (int) windowFrame.right, (int) windowFrame.bottom);
+ forEachRect(touchableRegion, rect -> {
+ // Move to origin as all transforms are captured by the matrix.
+ RectF windowFrame = mTempRectF;
+ windowFrame.set(rect);
+ windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
+
+ matrix.mapRect(windowFrame);
+
+ // Union all rects.
+ outRegion.union(new Rect((int) windowFrame.left, (int) windowFrame.top,
+ (int) windowFrame.right, (int) windowFrame.bottom));
+ });
}
- private static void addPopulatedWindowInfo(
- WindowState windowState, Rect boundsInScreen,
+ private static void addPopulatedWindowInfo(WindowState windowState, Region regionInScreen,
List<WindowInfo> out, Set<IBinder> tokenOut) {
final WindowInfo window = windowState.getWindowInfo();
- window.boundsInScreen.set(boundsInScreen);
+ window.regionInScreen.set(regionInScreen);
window.layer = tokenOut.size();
out.add(window);
tokenOut.add(window.token);
@@ -1293,7 +1306,7 @@
private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
final List<WindowState> tempWindowStatesList = new ArrayList<>();
final DisplayContent dc = mService.getDefaultDisplayContentLocked();
- dc.forAllWindows((w) -> {
+ dc.forAllWindows(w -> {
if (w.isVisibleLw()) {
tempWindowStatesList.add(w);
}
@@ -1306,17 +1319,11 @@
return;
}
- // TODO: Use Region instead to get rid of this complicated logic.
- // Check the tap exclude region of the parent window. If the tap exclude region
- // is empty, it means there is another can-receive-pointer-event view on top of
- // the region. Hence, we don't count the window as visible.
if (w.isVisibleLw() && parentWindow.getDisplayContent().isDefaultDisplay
- && parentWindow.hasTapExcludeRegion()
&& tempWindowStatesList.contains(parentWindow)) {
- tempWindowStatesList.add(
- tempWindowStatesList.lastIndexOf(parentWindow) + 1, w);
+ tempWindowStatesList.add(tempWindowStatesList.lastIndexOf(parentWindow), w);
}
- }, true /* traverseTopToBottom */);
+ }, false /* traverseTopToBottom */);
for (int i = 0; i < tempWindowStatesList.size(); i++) {
outWindows.put(i, tempWindowStatesList.get(i));
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 9c87ce8..99d2903 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -916,8 +916,9 @@
return ResolverActivity.class.getName().equals(className);
}
- boolean isResolverActivity() {
- return isResolverActivity(mActivityComponent.getClassName());
+ boolean isResolverOrDelegateActivity() {
+ return isResolverActivity(mActivityComponent.getClassName()) || Objects.equals(
+ mActivityComponent, mAtmService.mStackSupervisor.getSystemChooserActivity());
}
boolean isResolverOrChildActivity() {
@@ -1247,7 +1248,8 @@
&& intent.getType() == null;
}
- private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
+ @VisibleForTesting
+ boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
if (uid == Process.myUid() || uid == 0) {
// System process can launch home activity.
return true;
@@ -1257,8 +1259,8 @@
if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
return true;
}
- // Resolver activity can launch home activity.
- return sourceRecord != null && sourceRecord.isResolverActivity();
+ // Resolver or system chooser activity can launch home activity.
+ return sourceRecord != null && sourceRecord.isResolverOrDelegateActivity();
}
/**
@@ -1277,7 +1279,7 @@
ActivityOptions options, ActivityRecord sourceRecord) {
int activityType = ACTIVITY_TYPE_UNDEFINED;
if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
- && isHomeIntent(intent) && !isResolverActivity()) {
+ && isHomeIntent(intent) && !isResolverOrDelegateActivity()) {
// This sure looks like a home activity!
activityType = ACTIVITY_TYPE_HOME;
@@ -1523,7 +1525,6 @@
stack.moveToFront(reason, task);
// Report top activity change to tracking services and WM
if (mRootActivityContainer.getTopResumedActivity() == this) {
- // TODO(b/111361570): Support multiple focused apps in WM
mAtmService.setResumedActivityUncheckLocked(this, reason);
}
return true;
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 18a57ae..79098f1 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -565,7 +565,6 @@
+ reason);
setResumedActivity(record, reason + " - onActivityStateChanged");
if (record == mRootActivityContainer.getTopResumedActivity()) {
- // TODO(b/111361570): Support multiple focused apps in WM
mService.setResumedActivityUncheckLocked(record, reason);
}
mStackSupervisor.mRecentTasks.add(record.getTaskRecord());
@@ -3711,9 +3710,6 @@
if (nextFocusableStack != null) {
final ActivityRecord top = nextFocusableStack.topRunningActivityLocked();
if (top != null && top == mRootActivityContainer.getTopResumedActivity()) {
- // TODO(b/111361570): Remove this and update focused app per-display in
- // WindowManager every time an activity becomes resumed in
- // ActivityTaskManagerService#setResumedActivityUncheckLocked().
mService.setResumedActivityUncheckLocked(top, reason);
}
return;
@@ -5651,7 +5647,6 @@
// If the original state is resumed, there is no state change to update focused app.
// So here makes sure the activity focus is set if it is the top.
if (origState == RESUMED && r == mRootActivityContainer.getTopResumedActivity()) {
- // TODO(b/111361570): Support multiple focused apps in WM
mService.setResumedActivityUncheckLocked(r, reason);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index feb4a36..eb170bd 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -130,6 +130,7 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.ReferrerIntent;
@@ -323,6 +324,12 @@
boolean mUserLeaving = false;
/**
+ * The system chooser activity which worked as a delegate of
+ * {@link com.android.internal.app.ResolverActivity}.
+ */
+ private ComponentName mSystemChooserActivity;
+
+ /**
* We don't want to allow the device to go to sleep while in the process
* of launching an activity. This is primarily to allow alarm intent
* receivers to launch an activity and get that to run before the device
@@ -469,6 +476,14 @@
return mKeyguardController;
}
+ ComponentName getSystemChooserActivity() {
+ if (mSystemChooserActivity == null) {
+ mSystemChooserActivity = ComponentName.unflattenFromString(
+ mService.mContext.getResources().getString(R.string.config_chooserActivity));
+ }
+ return mSystemChooserActivity;
+ }
+
void setRecentTasks(RecentTasks recentTasks) {
mRecentTasks = recentTasks;
mRecentTasks.registerCallback(this);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 54eb07f..6fd2ebc 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1980,8 +1980,8 @@
// Also put noDisplay activities in the source task. These by itself can be placed
// in any task/stack, however it could launch other activities like ResolverActivity,
// and we want those to stay in the original task.
- if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
- && mSourceRecord.inFreeformWindowingMode()) {
+ if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
+ && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
mAddingToTask = true;
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ed7790c..c37ced5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4928,6 +4928,9 @@
* - the cmd arg isn't the flattened component name of an existing activity:
* dump all activity whose component contains the cmd as a substring
* - A hex number of the ActivityRecord object instance.
+ * <p>
+ * The caller should not hold lock when calling this method because it will wait for the
+ * activities to complete the dump.
*
* @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
* @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
@@ -4980,29 +4983,28 @@
private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
final ActivityRecord r, String[] args, boolean dumpAll) {
String innerPrefix = prefix + " ";
+ IApplicationThread appThread = null;
synchronized (mGlobalLock) {
pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
pw.print(" pid=");
- if (r.hasProcess()) pw.println(r.app.getPid());
- else pw.println("(not running)");
+ if (r.hasProcess()) {
+ pw.println(r.app.getPid());
+ appThread = r.app.getThread();
+ } else {
+ pw.println("(not running)");
+ }
if (dumpAll) {
r.dump(pw, innerPrefix);
}
}
- if (r.attachedToProcess()) {
+ if (appThread != null) {
// flush anything that is already in the PrintWriter since the thread is going
// to write to the file descriptor directly
pw.flush();
- try {
- TransferPipe tp = new TransferPipe();
- try {
- r.app.getThread().dumpActivity(tp.getWriteFd(),
- r.appToken, innerPrefix, args);
- tp.go(fd);
- } finally {
- tp.kill();
- }
+ try (TransferPipe tp = new TransferPipe()) {
+ appThread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args);
+ tp.go(fd);
} catch (IOException e) {
pw.println(innerPrefix + "Failure while dumping the activity: " + e);
} catch (RemoteException e) {
@@ -7063,10 +7065,8 @@
public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
boolean dumpFocusedStackOnly) {
- synchronized (mGlobalLock) {
- return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
- dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
- }
+ return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti, dumpAll,
+ dumpVisibleStacksOnly, dumpFocusedStackOnly);
}
@Override
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 8007c0f..d15081c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -260,9 +260,9 @@
ActivityRecord mActivityRecord;
/**
- * See {@link #canTurnScreenOn()}
+ * @see #currentLaunchCanTurnScreenOn()
*/
- private boolean mCanTurnScreenOn = true;
+ private boolean mCurrentLaunchCanTurnScreenOn = true;
/**
* If we are running an animation, this determines the transition type. Must be one of
@@ -1002,7 +1002,7 @@
+ " " + this);
mAppStopped = false;
// Allow the window to turn the screen on once the app is resumed again.
- setCanTurnScreenOn(true);
+ setCurrentLaunchCanTurnScreenOn(true);
if (!wasStopped) {
destroySurfaces(true /*cleanupOnResume*/);
}
@@ -2420,21 +2420,25 @@
}
/**
- * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
+ * Sets whether the current launch can turn the screen on.
+ * @see #currentLaunchCanTurnScreenOn()
*/
- void setCanTurnScreenOn(boolean canTurnScreenOn) {
- mCanTurnScreenOn = canTurnScreenOn;
+ void setCurrentLaunchCanTurnScreenOn(boolean currentLaunchCanTurnScreenOn) {
+ mCurrentLaunchCanTurnScreenOn = currentLaunchCanTurnScreenOn;
}
/**
* Indicates whether the current launch can turn the screen on. This is to prevent multiple
* relayouts from turning the screen back on. The screen should only turn on at most
* once per activity resume.
+ * <p>
+ * Note this flag is only meaningful when {@link WindowManager.LayoutParams#FLAG_TURN_SCREEN_ON}
+ * or {@link ActivityRecord#canTurnScreenOn} is set.
*
- * @return true if the screen can be turned on.
+ * @return {@code true} if the activity is ready to turn on the screen.
*/
- boolean canTurnScreenOn() {
- return mCanTurnScreenOn;
+ boolean currentLaunchCanTurnScreenOn() {
+ return mCurrentLaunchCanTurnScreenOn;
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index cf87203..61ba69f 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -284,6 +284,8 @@
/** See {@link #getNavigationBarFrameHeight} */
private int[] mNavigationBarFrameHeightForRotationDefault = new int[4];
+ private boolean mIsFreeformWindowOverlappingWithNavBar;
+
/** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */
@Px private int mWindowOutsetBottom;
@@ -2379,6 +2381,7 @@
mAllowLockscreenWhenOn = false;
mShowingDream = false;
mWindowSleepTokenNeeded = false;
+ mIsFreeformWindowOverlappingWithNavBar = false;
}
/**
@@ -2478,6 +2481,13 @@
}
}
+ // Check if the freeform window overlaps with the navigation bar area.
+ final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null;
+ if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()
+ && isOverlappingWithNavBar(win, navBarWin)) {
+ mIsFreeformWindowOverlappingWithNavBar = true;
+ }
+
// Also keep track of any windows that are dimming but not necessarily fullscreen in the
// docked stack.
if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
@@ -3458,7 +3468,11 @@
}
} else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
- visibility = setNavBarOpaqueFlag(visibility);
+ if (mIsFreeformWindowOverlappingWithNavBar) {
+ visibility = setNavBarTranslucentFlag(visibility);
+ } else {
+ visibility = setNavBarOpaqueFlag(visibility);
+ }
} else if (fullscreenDrawsBackground) {
visibility = setNavBarTransparentFlag(visibility);
}
@@ -3747,4 +3761,14 @@
wm.removeView(mPointerLocationView);
mPointerLocationView = null;
}
+
+ @VisibleForTesting
+ static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
+ if (navBarWindow == null || !navBarWindow.isVisibleLw()
+ || targetWindow.mAppToken == null || !targetWindow.isVisibleLw()) {
+ return false;
+ }
+
+ return Rect.intersects(targetWindow.getFrameLw(), navBarWindow.getFrameLw());
+ }
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index bd114d9..f9a6fe7 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -310,6 +310,7 @@
}
final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
return new TaskSnapshot(
+ System.currentTimeMillis() /* id */,
appWindowToken.mActivityComponent, screenshotBuffer.getGraphicBuffer(),
screenshotBuffer.getColorSpace(),
appWindowToken.getTask().getConfiguration().orientation,
@@ -404,7 +405,9 @@
// Note, the app theme snapshot is never translucent because we enforce a non-translucent
// color above
- return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
+ return new TaskSnapshot(
+ System.currentTimeMillis() /* id */,
+ topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
hwBitmap.getColorSpace(), topChild.getTask().getConfiguration().orientation,
getInsets(mainWindow), ActivityManager.isLowRamDeviceStatic() /* reduced */,
mFullSnapshotScale, false /* isRealSnapshot */, task.getWindowingMode(),
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index fcd97c1..696e1c3 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -92,7 +92,7 @@
// For legacy snapshots, restore the scale based on the reduced resolution state
final float legacyScale = reducedResolution ? mPersister.getReducedScale() : 1f;
final float scale = Float.compare(proto.scale, 0f) != 0 ? proto.scale : legacyScale;
- return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
+ return new TaskSnapshot(proto.id, topActivityComponent, buffer, bitmap.getColorSpace(),
proto.orientation,
new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
reducedResolution, scale, proto.isRealSnapshot, proto.windowingMode,
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 72fc189..32a1d90 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -343,6 +343,7 @@
proto.isTranslucent = mSnapshot.isTranslucent();
proto.topActivityComponent = mSnapshot.getTopActivityComponent().flattenToString();
proto.scale = mSnapshot.getScale();
+ proto.id = mSnapshot.getId();
final byte[] bytes = TaskSnapshotProto.toByteArray(proto);
final File file = getProtoFile(mTaskId, mUserId);
final AtomicFile atomicFile = new AtomicFile(file);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8b1baeb..14df806 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1633,7 +1633,7 @@
|| !mRelayoutCalled
|| (atoken == null && mToken.isHidden())
|| (atoken != null && atoken.hiddenRequested)
- || isParentWindowHidden()
+ || isParentWindowGoneForLayout()
|| (mAnimatingExit && !isAnimatingLw())
|| mDestroying;
}
@@ -2393,10 +2393,11 @@
void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
// We need to turn on screen regardless of visibility.
- boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0;
+ final boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0
+ || (mAppToken != null && mAppToken.mActivityRecord.canTurnScreenOn());
// The screen will turn on if the following conditions are met
- // 1. The window has the flag FLAG_TURN_SCREEN_ON
+ // 1. The window has the flag FLAG_TURN_SCREEN_ON or ActivityRecord#canTurnScreenOn.
// 2. The WMS allows theater mode.
// 3. No AWT or the AWT allows the screen to be turned on. This should only be true once
// per resume to prevent the screen getting getting turned on for each relayout. Set
@@ -2410,7 +2411,7 @@
boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout
|| Settings.Global.getInt(mWmService.mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 0;
- boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn();
+ boolean canTurnScreenOn = mAppToken == null || mAppToken.currentLaunchCanTurnScreenOn();
if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) {
if (DEBUG_VISIBILITY || DEBUG_POWER) {
@@ -2421,7 +2422,7 @@
}
if (mAppToken != null) {
- mAppToken.setCanTurnScreenOn(false);
+ mAppToken.setCurrentLaunchCanTurnScreenOn(false);
}
}
@@ -3847,6 +3848,11 @@
return parent != null && parent.mHidden;
}
+ private boolean isParentWindowGoneForLayout() {
+ final WindowState parent = getParentWindow();
+ return parent != null && parent.isGoneForLayoutLw();
+ }
+
void setWillReplaceWindow(boolean animate) {
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState c = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 73344ac..3ba3280 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1508,6 +1508,12 @@
}
void detachChildren() {
+
+ // Do not detach children of starting windows, as their lifecycle is well under control and
+ // it may lead to issues in case we relaunch when we just added the starting window.
+ if (mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
+ return;
+ }
if (mSurfaceController != null) {
mSurfaceController.detachChildren();
}
diff --git a/services/core/java/com/android/server/wm/utils/RegionUtils.java b/services/core/java/com/android/server/wm/utils/RegionUtils.java
index b1b3070..ce7776f 100644
--- a/services/core/java/com/android/server/wm/utils/RegionUtils.java
+++ b/services/core/java/com/android/server/wm/utils/RegionUtils.java
@@ -50,6 +50,20 @@
/**
* Applies actions on each rect contained within a {@code Region}.
*
+ * @param region the given region.
+ * @param rectConsumer the action holder.
+ */
+ public static void forEachRect(Region region, Consumer<Rect> rectConsumer) {
+ final RegionIterator it = new RegionIterator(region);
+ final Rect rect = new Rect();
+ while (it.next(rect)) {
+ rectConsumer.accept(rect);
+ }
+ }
+
+ /**
+ * Applies actions on each rect contained within a {@code Region}.
+ *
* Order is bottom to top, then right to left.
*
* @param region the given region.
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
index 73b3b8b..a785300 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
@@ -19,6 +19,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
+import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE;
import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_DISPLAY_COLOR;
import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_SATURATION;
@@ -28,6 +29,7 @@
import android.hardware.display.ColorDisplayManager;
import android.os.SystemProperties;
+import android.view.Display;
import androidx.test.runner.AndroidJUnit4;
@@ -79,7 +81,7 @@
@Test
public void setColorMode_natural() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, -1);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("0" /* managed */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -88,7 +90,7 @@
@Test
public void setColorMode_boosted() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix, -1);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("0" /* managed */);
@@ -98,7 +100,7 @@
@Test
public void setColorMode_saturated() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix, -1);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("1" /* unmanaged */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -107,7 +109,7 @@
@Test
public void setColorMode_automatic() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix, -1);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("2" /* enhanced */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -116,7 +118,7 @@
@Test
public void setColorMode_vendor() {
- mDtm.setColorMode(0x100, mNightDisplayMatrix);
+ mDtm.setColorMode(0x100, mNightDisplayMatrix, -1);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo(Integer.toString(0x100) /* pass-through */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -125,10 +127,38 @@
@Test
public void setColorMode_outOfBounds() {
- mDtm.setColorMode(0x50, mNightDisplayMatrix);
+ mDtm.setColorMode(0x50, mNightDisplayMatrix, -1);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo(null);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
.isEqualTo(null);
}
+
+ @Test
+ public void setColorMode_withoutColorSpace() {
+ String magicPropertyValue = "magic";
+
+ // Start with a known state, which we expect to remain unmodified
+ SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
+
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+ Display.COLOR_MODE_INVALID);
+ assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
+ .isEqualTo(magicPropertyValue);
+ }
+
+ @Test
+ public void setColorMode_withColorSpace() {
+ String magicPropertyValue = "magic";
+ int testPropertyValue = Display.COLOR_MODE_SRGB;
+
+ // Start with a known state, which we expect to get modified
+ SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
+
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+ testPropertyValue);
+ assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
+ .isEqualTo(Integer.toString(testPropertyValue));
+ }
+
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e9e96c9..1ad7b6e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -72,6 +72,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.server.devicepolicy.MockUtils;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.google.android.collect.Lists;
@@ -132,9 +133,10 @@
@Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter;
@Mock private WifiInfo mWifiInfo;
@Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection;
- @Mock private PackageManagerInternal mPackageManagerInternal;
+ @Mock private PermissionManagerServiceInternal mPermissionManagerInternal;
@Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
- @Captor private ArgumentCaptor<PackageManagerInternal.PackagesProvider> mPackagesProviderCaptor;
+ @Captor private
+ ArgumentCaptor<PermissionManagerServiceInternal.PackagesProvider> mPackagesProviderCaptor;
private ContentResolver mContentResolver;
private NetworkScoreService mNetworkScoreService;
@@ -162,7 +164,8 @@
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
mHandlerThread.start();
- LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
+ LocalServices.addService(
+ PermissionManagerServiceInternal.class, mPermissionManagerInternal);
mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper());
WifiConfiguration configuration = new WifiConfiguration();
@@ -196,7 +199,7 @@
Settings.Global.putString(mContentResolver,
Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.app");
- verify(mPackageManagerInternal)
+ verify(mPermissionManagerInternal)
.setUseOpenWifiAppPackagesProvider(mPackagesProviderCaptor.capture());
String[] packages = mPackagesProviderCaptor.getValue().getPackages(0);
@@ -209,7 +212,7 @@
Settings.Global.putString(mContentResolver,
Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.other.app");
- verify(mPackageManagerInternal, timeout(500))
+ verify(mPermissionManagerInternal, timeout(500))
.grantDefaultPermissionsToDefaultUseOpenWifiApp("com.some.other.app", 0);
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 22408cc..e125329 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -238,7 +238,7 @@
windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
windowInfo.token = token.asBinder();
windowInfo.layer = 0;
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
mWindowInfos.set(0, windowInfo);
mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
@@ -305,67 +305,73 @@
}
@Test
- public void computePartialInteractiveRegionForWindow_wholeWindowVisible_returnWholeRegion() {
+ public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
// Updates top 2 z-order WindowInfo are whole visible.
WindowInfo windowInfo = mWindowInfos.get(0);
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
+ windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
windowInfo = mWindowInfos.get(1);
- windowInfo.boundsInScreen.set(0, SCREEN_HEIGHT / 2,
- SCREEN_WIDTH, SCREEN_HEIGHT);
+ windowInfo.regionInScreen.set(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT);
mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
final Region outBounds = new Region();
int windowId = a11yWindows.get(0).getId();
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
- windowId, outBounds);
+ mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
windowId = a11yWindows.get(1).getId();
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
- windowId, outBounds);
+ mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
}
@Test
- public void computePartialInteractiveRegionForWindow_halfWindowVisible_returnHalfRegion() {
+ public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
// Updates z-order #1 WindowInfo is half visible
WindowInfo windowInfo = mWindowInfos.get(0);
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
- windowInfo = mWindowInfos.get(1);
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
final Region outBounds = new Region();
int windowId = a11yWindows.get(1).getId();
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
- windowId, outBounds);
+ mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
}
@Test
- public void computePartialInteractiveRegionForWindow_windowNotVisible_returnEmptyRegion() {
- // Updates z-order #1 WindowInfo is not visible
+ public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
+ // Since z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+ final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
+ final Region outBounds = new Region();
+ int windowId = a11yWindows.get(1).getId();
+
+ mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
+ assertTrue(outBounds.getBounds().isEmpty());
+ }
+
+ @Test
+ public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
+ // Updates z-order #0 WindowInfo to have two interact-able areas.
+ Region region = new Region(0, 0, SCREEN_WIDTH, 200);
+ region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
WindowInfo windowInfo = mWindowInfos.get(0);
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- windowInfo = mWindowInfos.get(1);
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ windowInfo.regionInScreen.set(region);
mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
final Region outBounds = new Region();
int windowId = a11yWindows.get(1).getId();
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
- windowId, outBounds);
- assertTrue(outBounds.getBounds().isEmpty());
+ mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
+ assertFalse(outBounds.getBounds().isEmpty());
+ assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
+ assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT - 400));
}
@Test
@@ -588,7 +594,7 @@
windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
windowInfo.token = windowToken.asBinder();
windowInfo.layer = layer;
- windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
mWindowInfos.add(windowInfo);
}
diff --git a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index fb2913b..a19b387 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -18,13 +18,19 @@
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.Resources;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.Time;
import android.os.Handler;
@@ -33,6 +39,7 @@
import android.provider.Settings.Secure;
import android.provider.Settings.System;
import android.test.mock.MockContentResolver;
+import android.view.Display;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -73,6 +80,8 @@
private ColorDisplayService mCds;
private ColorDisplayService.BinderService mBinderService;
+ private Resources mResourcesSpy;
+
@BeforeClass
public static void setDtm() {
final DisplayTransformManager dtm = Mockito.mock(DisplayTransformManager.class);
@@ -84,6 +93,9 @@
mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
doReturn(mContext).when(mContext).getApplicationContext();
+ mResourcesSpy = Mockito.spy(mContext.getResources());
+ when(mContext.getResources()).thenReturn(mResourcesSpy);
+
mUserId = ActivityManager.getCurrentUser();
final MockContentResolver cr = new MockContentResolver(mContext);
@@ -1050,6 +1062,80 @@
assertDwbActive(true);
}
+ @Test
+ public void compositionColorSpaces_noResources() {
+ final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+ reset(dtm);
+
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+ .thenReturn(new int[] {});
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+ .thenReturn(new int[] {});
+ setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+ startService();
+ verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+ eq(Display.COLOR_MODE_INVALID));
+ }
+
+ @Test
+ public void compositionColorSpaces_invalidResources() {
+ final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+ reset(dtm);
+
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+ .thenReturn(new int[] {
+ ColorDisplayManager.COLOR_MODE_NATURAL,
+ // Missing second color mode
+ });
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+ .thenReturn(new int[] {
+ Display.COLOR_MODE_SRGB,
+ Display.COLOR_MODE_DISPLAY_P3
+ });
+ setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+ startService();
+ verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+ eq(Display.COLOR_MODE_INVALID));
+ }
+
+ @Test
+ public void compositionColorSpaces_validResources_validColorMode() {
+ final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+ reset(dtm);
+
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+ .thenReturn(new int[] {
+ ColorDisplayManager.COLOR_MODE_NATURAL
+ });
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+ .thenReturn(new int[] {
+ Display.COLOR_MODE_SRGB,
+ });
+ setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+ startService();
+ verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+ eq(Display.COLOR_MODE_SRGB));
+ }
+
+ @Test
+ public void compositionColorSpaces_validResources_invalidColorMode() {
+ final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+ reset(dtm);
+
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+ .thenReturn(new int[] {
+ ColorDisplayManager.COLOR_MODE_NATURAL
+ });
+ when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+ .thenReturn(new int[] {
+ Display.COLOR_MODE_SRGB,
+ });
+ setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
+ startService();
+ verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(),
+ eq(Display.COLOR_MODE_INVALID));
+ }
+
/**
* Configures Night display to use a custom schedule.
*
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 95ec3d9..fc7cfec 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -115,7 +115,7 @@
@Test
public void testPartitions() throws Exception {
- String[] partitions = { "system", "vendor", "odm", "oem", "product", "product_services" };
+ String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
String[] appdir = { "app", "priv-app" };
for (int i = 0; i < partitions.length; i++) {
for (int j = 0; j < appdir.length; j++) {
@@ -128,7 +128,7 @@
Assert.assertEquals(i == 1 || i == 2, PackageManagerService.locationIsVendor(path));
Assert.assertEquals(i == 3, PackageManagerService.locationIsOem(path));
Assert.assertEquals(i == 4, PackageManagerService.locationIsProduct(path));
- Assert.assertEquals(i == 5, PackageManagerService.locationIsProductServices(path));
+ Assert.assertEquals(i == 5, PackageManagerService.locationIsSystemExt(path));
}
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 6061d51..8c3373f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -156,7 +156,7 @@
mService.setUsageStats(mUsageStats);
mService.setAccessibilityManager(accessibilityManager);
mService.mScreenOn = false;
- mService.mInCall = false;
+ mService.mInCallStateOffHook = false;
mService.mNotificationPulseEnabled = true;
}
@@ -681,7 +681,7 @@
mService.buzzBeepBlinkLocked(r);
Mockito.reset(mRingtonePlayer);
- mService.mInCall = true;
+ mService.mInCallStateOffHook = true;
mService.buzzBeepBlinkLocked(r);
verify(mService, times(1)).playInCallNotification();
@@ -1137,7 +1137,7 @@
@Test
public void testLightsInCall() {
- mService.mInCall = true;
+ mService.mInCallStateOffHook = true;
NotificationRecord r = getLightsNotification();
mService.buzzBeepBlinkLocked(r);
verifyNeverLights();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index efbae2b..deca57e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.os.Process.NOBODY_UID;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
@@ -40,6 +41,8 @@
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -54,8 +57,10 @@
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.PauseActivityItem;
+import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.util.MergedConfiguration;
@@ -67,6 +72,7 @@
import androidx.test.filters.MediumTest;
+import com.android.internal.R;
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Before;
@@ -611,6 +617,15 @@
assertNull(mActivity.pendingOptions);
}
+ @Test
+ public void testCanLaunchHomeActivityFromChooser() {
+ ComponentName chooserComponent = ComponentName.unflattenFromString(
+ Resources.getSystem().getString(R.string.config_chooserActivity));
+ ActivityRecord chooserActivity = new ActivityBuilder(mService).setComponent(
+ chooserComponent).build();
+ assertThat(mActivity.canLaunchHomeActivity(NOBODY_UID, chooserActivity)).isTrue();
+ }
+
/** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */
private void prepareFixedAspectRatioUnresizableActivity() {
setupDisplayContentForCompatDisplayInsets();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 1684f97..6a3c81a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -32,6 +32,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -49,10 +50,12 @@
import static org.mockito.Mockito.when;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;
import android.view.WindowManager;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -273,4 +276,37 @@
win.mHasSurface = true;
return win;
}
+
+ @Test
+ @FlakyTest(bugId = 131005232)
+ public void testOverlappingWithNavBar() {
+ final WindowState targetWin = createApplicationWindow();
+ final WindowFrames winFrame = targetWin.getWindowFrames();
+ winFrame.mFrame.set(new Rect(100, 100, 200, 200));
+
+ final WindowState navigationBar = createNavigationBarWindow();
+
+ navigationBar.getFrameLw().set(new Rect(100, 200, 200, 300));
+
+ assertFalse("Freeform is overlapping with navigation bar",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+ winFrame.mFrame.set(new Rect(100, 101, 200, 201));
+ assertTrue("Freeform should be overlapping with navigation bar (bottom)",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+ winFrame.mFrame.set(new Rect(99, 200, 199, 300));
+ assertTrue("Freeform should be overlapping with navigation bar (right)",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+ winFrame.mFrame.set(new Rect(199, 200, 299, 300));
+ assertTrue("Freeform should be overlapping with navigation bar (left)",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+ }
+
+ private WindowState createNavigationBarWindow() {
+ final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
+ win.mHasSurface = true;
+ return win;
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index f958867..b29453a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -64,6 +64,7 @@
assertTrueForFiles(files, File::exists, " must exist");
final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* reduced */);
assertNotNull(snapshot);
+ assertEquals(MOCK_SNAPSHOT_ID, snapshot.getId());
assertEquals(TEST_INSETS, snapshot.getContentInsets());
assertNotNull(snapshot.getSnapshot());
assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index e004cd3..f749622 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -45,6 +45,7 @@
private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
static final File FILES_DIR = getInstrumentation().getTargetContext().getFilesDir();
+ static final long MOCK_SNAPSHOT_ID = 12345678;
TaskSnapshotPersister mPersister;
TaskSnapshotLoader mLoader;
@@ -129,7 +130,7 @@
Canvas c = buffer.lockCanvas();
c.drawColor(Color.RED);
buffer.unlockCanvasAndPost(c);
- return new TaskSnapshot(new ComponentName("", ""), buffer,
+ return new TaskSnapshot(MOCK_SNAPSHOT_ID, new ComponentName("", ""), buffer,
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS,
mReducedResolution, mScale, mIsRealSnapshot,
mWindowingMode, mSystemUiVisibility, mIsTranslucent);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 4ca01ec..74db820 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -64,7 +64,9 @@
int windowFlags, Rect taskBounds) {
final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
- final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer,
+ final TaskSnapshot snapshot = new TaskSnapshot(
+ System.currentTimeMillis(),
+ new ComponentName("", ""), buffer,
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, contentInsets, false,
1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
0 /* systemUiVisibility */, false /* isTranslucent */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 1b57c79..36698ea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -302,43 +302,38 @@
@Test
public void testPrepareWindowToDisplayDuringRelayout() {
- testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
-
- // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON
- // before calling prepareWindowToDisplayDuringRelayout for windows with flag in the same
- // appWindowToken.
+ // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
+ // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same appWindowToken.
final AppWindowToken appWindowToken = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final WindowState first = createWindow(null, TYPE_APPLICATION, appWindowToken, "first");
final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second");
second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- reset(sPowerManagerWrapper);
- first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
- assertTrue(appWindowToken.canTurnScreenOn());
-
- reset(sPowerManagerWrapper);
- second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
- assertFalse(appWindowToken.canTurnScreenOn());
+ testPrepareWindowToDisplayDuringRelayout(first, false /* expectedWakeupCalled */,
+ true /* expectedCurrentLaunchCanTurnScreenOn */);
+ testPrepareWindowToDisplayDuringRelayout(second, true /* expectedWakeupCalled */,
+ false /* expectedCurrentLaunchCanTurnScreenOn */);
// Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
// from the same appWindowToken. Only one should trigger the wakeup.
- appWindowToken.setCanTurnScreenOn(true);
+ appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- reset(sPowerManagerWrapper);
- first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
- assertFalse(appWindowToken.canTurnScreenOn());
+ testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
+ false /* expectedCurrentLaunchCanTurnScreenOn */);
+ testPrepareWindowToDisplayDuringRelayout(second, false /* expectedWakeupCalled */,
+ false /* expectedCurrentLaunchCanTurnScreenOn */);
- reset(sPowerManagerWrapper);
- second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
- assertFalse(appWindowToken.canTurnScreenOn());
+ // Without window flags, the state of ActivityRecord.canTurnScreenOn should still be able to
+ // turn on the screen.
+ appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
+ first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+ doReturn(true).when(appWindowToken.mActivityRecord).canTurnScreenOn();
+
+ testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
+ false /* expectedCurrentLaunchCanTurnScreenOn */);
// Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
// appWindowToken. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup
@@ -360,6 +355,22 @@
verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
}
+ private void testPrepareWindowToDisplayDuringRelayout(WindowState appWindow,
+ boolean expectedWakeupCalled, boolean expectedCurrentLaunchCanTurnScreenOn) {
+ reset(sPowerManagerWrapper);
+ appWindow.prepareWindowToDisplayDuringRelayout(false /* wasVisible */);
+
+ if (expectedWakeupCalled) {
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
+ } else {
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
+ }
+ // If wakeup is expected to be called, the currentLaunchCanTurnScreenOn should be false
+ // because the state will be consumed.
+ assertThat(appWindow.mAppToken.currentLaunchCanTurnScreenOn(),
+ is(expectedCurrentLaunchCanTurnScreenOn));
+ }
+
@Test
public void testCanAffectSystemUiFlags() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
@@ -487,15 +498,6 @@
assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
}
- private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
- reset(sPowerManagerWrapper);
- final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
- root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
-
- root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
- }
-
@Test
public void testVisibilityChangeSwitchUser() {
final WindowState window = createWindow(null, TYPE_APPLICATION, "app");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index e1ffb0f..b2fde54 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -33,7 +33,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.ShortcutServiceInternal;
@@ -79,6 +78,7 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.soundtrigger.SoundTriggerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -120,10 +120,10 @@
mUserManager = Preconditions.checkNotNull(
context.getSystemService(UserManager.class));
- PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
- packageManagerInternal.setVoiceInteractionPackagesProvider(
- new PackageManagerInternal.PackagesProvider() {
+ PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
+ PermissionManagerServiceInternal.class);
+ permissionManagerInternal.setVoiceInteractionPackagesProvider(
+ new PermissionManagerServiceInternal.PackagesProvider() {
@Override
public String[] getPackages(int userId) {
mServiceStub.initForUser(userId);
diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py
index 8a9135b..464742d 100644
--- a/startop/scripts/app_startup/run_app_with_prefetch.py
+++ b/startop/scripts/app_startup/run_app_with_prefetch.py
@@ -101,7 +101,7 @@
return parser.parse_args(argv)
-def validate_options(args: argparse.Namespace) -> Tuple[bool, RunCommandArgs]:
+def validate_options(args: RunCommandArgs) -> Tuple[bool, RunCommandArgs]:
"""Validates the activity and trace file if needed.
Returns:
diff --git a/startop/scripts/app_startup/run_app_with_prefetch_test.py b/startop/scripts/app_startup/run_app_with_prefetch_test.py
index a642385..8536ce5 100644
--- a/startop/scripts/app_startup/run_app_with_prefetch_test.py
+++ b/startop/scripts/app_startup/run_app_with_prefetch_test.py
@@ -156,7 +156,8 @@
args = '--package com.fake.package --activity act -s'
opts = run.parse_options(shlex.split(args))
- result = run.run_test(opts)
+ args = run.get_args_from_opts(opts)
+ result = run.run_test(args)
assert result == [('TotalTime', '123')]
def test_set_up_adb_env():
diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py
index 7914960..3126137 100755
--- a/startop/scripts/iorap/compiler.py
+++ b/startop/scripts/iorap/compiler.py
@@ -23,20 +23,18 @@
# $> pip3 install --user protobuf sqlalchemy sqlite3
#
-import collections
import optparse
import os
import re
import sys
+from typing import Iterable, Optional
-from typing import Iterable
-
-from lib.inode2filename import Inode2Filename
from generated.TraceFile_pb2 import *
+from lib.inode2filename import Inode2Filename
parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(parent_dir_name + "/trace_analyzer")
-from lib.trace2db import Trace2Db, MmFilemapAddToPageCache
+from lib.trace2db import Trace2Db, MmFilemapAddToPageCache, RawFtraceEntry
_PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes.
@@ -165,9 +163,32 @@
return trace_file
-def query_add_to_page_cache(trace2db: Trace2Db):
+def calc_trace_end_time(trace2db: Trace2Db,
+ trace_duration: Optional[int]) -> float:
+ """
+ Calculates the end time based on the trace duration.
+ The start time is the first receiving mm file map event.
+ The end time is the start time plus the trace duration.
+ All of them are in milliseconds.
+ """
+ # If the duration is not set, assume all time is acceptable.
+ if trace_duration is None:
+ # float('inf')
+ return RawFtraceEntry.__table__.c.timestamp.type.python_type('inf')
+
+ first_event = trace2db.session.query(MmFilemapAddToPageCache).join(
+ MmFilemapAddToPageCache.raw_ftrace_entry).order_by(
+ RawFtraceEntry.timestamp).first()
+
+ return first_event.raw_ftrace_entry.timestamp + trace_duration
+
+def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[int]):
+ end_time = calc_trace_end_time(trace2db, trace_duration)
# SELECT * FROM tbl ORDER BY id;
- return trace2db.session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).all()
+ return trace2db.session.query(MmFilemapAddToPageCache).join(
+ MmFilemapAddToPageCache.raw_ftrace_entry).filter(
+ RawFtraceEntry.timestamp <= end_time).order_by(
+ MmFilemapAddToPageCache.id).all()
def main(argv):
parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb")
@@ -188,6 +209,9 @@
parser.add_option('-o', dest='output_file', metavar='FILE',
help='Output protobuf file')
+ parser.add_option('--duration', dest='trace_duration', action="store",
+ type=int, help='The duration of trace in milliseconds.')
+
options, categories = parser.parse_args(argv[1:])
# TODO: OptionParser should have some flags to make these mandatory.
@@ -217,7 +241,8 @@
# TODO: parse multiple trace files here.
parse_count = trace2db.parse_file_into_db(options.trace_file)
- mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db)
+ mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
+ options.trace_duration)
print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
diff --git a/startop/scripts/trace_analyzer/lib/trace2db.py b/startop/scripts/trace_analyzer/lib/trace2db.py
index f60d6ab..42a33af 100644
--- a/startop/scripts/trace_analyzer/lib/trace2db.py
+++ b/startop/scripts/trace_analyzer/lib/trace2db.py
@@ -19,6 +19,7 @@
from sqlalchemy import create_engine
from sqlalchemy import Column, Date, Integer, Float, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
from sqlalchemy.orm import sessionmaker
@@ -43,6 +44,10 @@
function = Column(String, nullable=False)
function_args = Column(String, nullable=False)
+ # 1:1 relation with MmFilemapAddToPageCache.
+ mm_filemap_add_to_page_cache = relationship("MmFilemapAddToPageCache",
+ back_populates="raw_ftrace_entry")
+
@staticmethod
def parse_dict(line):
# ' <...>-5521 (-----) [003] ...1 17148.446877: tracing_mark_write: trace_event_clock_sync: parent_ts=17148.447266'
@@ -155,6 +160,9 @@
pfn = Column(Integer, nullable=False)
ofs = Column(Integer, nullable=False)
+ # 1:1 relation with RawFtraceEntry.
+ raw_ftrace_entry = relationship("RawFtraceEntry", uselist=False)
+
@staticmethod
def parse_dict(function_args, id = None):
# dev 253:6 ino b2c7 page=00000000ec787cd9 pfn=1478539 ofs=4096
@@ -251,6 +259,8 @@
def parse_file_buf(filebuf, session, engine, raw_ftrace_entry_filter, limit=None) -> int:
global _FLUSH_LIMIT
count = 0
+ # count and id are not equal, because count still increases for invalid lines.
+ id = 0
pending_entries = []
pending_sched_switch = []
@@ -305,9 +315,10 @@
continue
pending_entries.append(raw_ftrace_entry)
+ id = id + 1
if raw_ftrace_entry['function'] == 'sched_switch':
- sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], count)
+ sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], id)
if not sched_switch:
print("WARNING: Failed to parse sched_switch: " + l)
@@ -315,7 +326,7 @@
pending_sched_switch.append(sched_switch)
elif raw_ftrace_entry['function'] == 'sched_blocked_reason':
- sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], count)
+ sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], id)
if not sbr:
print("WARNING: Failed to parse sched_blocked_reason: " + l)
@@ -323,7 +334,8 @@
pending_sched_blocked_reasons.append(sbr)
elif raw_ftrace_entry['function'] == 'mm_filemap_add_to_page_cache':
- d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'], count)
+ d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'],
+ id)
if not d:
print("WARNING: Failed to parse mm_filemap_add_to_page_cache: " + l)
else:
diff --git a/startop/scripts/trace_analyzer/lib/trace2db_test.py b/startop/scripts/trace_analyzer/lib/trace2db_test.py
index b67cffa..3b326f0 100755
--- a/startop/scripts/trace_analyzer/lib/trace2db_test.py
+++ b/startop/scripts/trace_analyzer/lib/trace2db_test.py
@@ -32,17 +32,10 @@
"""
# global imports
-from contextlib import contextmanager
import io
-import shlex
-import sys
-import typing
-
from copy import deepcopy
# pip imports
-import pytest
-
# local imports
from trace2db import *
@@ -197,6 +190,33 @@
assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
+def test_timestamp_filter():
+ test_contents = """
+ MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+ NonUserFacing6-5246 ( 1322) [005] .... 16139.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+ MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
+ """
+
+ t2d = parse_trace_file_to_db(test_contents)
+ session = t2d.session
+
+ end_time = 16137.0
+
+ results = session.query(MmFilemapAddToPageCache).join(
+ MmFilemapAddToPageCache.raw_ftrace_entry).filter(
+ RawFtraceEntry.timestamp <= end_time).order_by(
+ MmFilemapAddToPageCache.id).all()
+
+ assert len(results) == 2
+ assert_eq_ignore_id(
+ MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+ ino=0x7580, page=0x0000000060e990c7, pfn=677646,
+ ofs=159744), results[0])
+ assert_eq_ignore_id(
+ MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+ ino=0xb1d8, page=0x0000000098d4d2e2, pfn=829676,
+ ofs=0), results[1])
+
if __name__ == '__main__':
pytest.main()
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index a1bea4d..6498e49 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -22,6 +22,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.os.RemoteException;
+import android.permission.IPermissionManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
@@ -71,8 +72,8 @@
* privileged apps may have changed.
*/
public synchronized static void disableCarrierAppsUntilPrivileged(String callingPackage,
- IPackageManager packageManager, TelephonyManager telephonyManager,
- ContentResolver contentResolver, int userId) {
+ IPackageManager packageManager, IPermissionManager permissionManager,
+ TelephonyManager telephonyManager, ContentResolver contentResolver, int userId) {
if (DEBUG) {
Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
}
@@ -81,8 +82,8 @@
config.getDisabledUntilUsedPreinstalledCarrierApps();
ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
- disableCarrierAppsUntilPrivileged(callingPackage, packageManager, telephonyManager,
- contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
+ disableCarrierAppsUntilPrivileged(callingPackage, packageManager, permissionManager,
+ telephonyManager, contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
systemCarrierAssociatedAppsDisabledUntilUsed);
}
@@ -98,7 +99,8 @@
* Manager can kill it, and this can lead to crashes as the app is in an unexpected state.
*/
public synchronized static void disableCarrierAppsUntilPrivileged(String callingPackage,
- IPackageManager packageManager, ContentResolver contentResolver, int userId) {
+ IPackageManager packageManager, IPermissionManager permissionManager,
+ ContentResolver contentResolver, int userId) {
if (DEBUG) {
Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
}
@@ -109,7 +111,7 @@
ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
- disableCarrierAppsUntilPrivileged(callingPackage, packageManager,
+ disableCarrierAppsUntilPrivileged(callingPackage, packageManager, permissionManager,
null /* telephonyManager */, contentResolver, userId,
systemCarrierAppsDisabledUntilUsed, systemCarrierAssociatedAppsDisabledUntilUsed);
}
@@ -117,7 +119,8 @@
// Must be public b/c framework unit tests can't access package-private methods.
@VisibleForTesting
public static void disableCarrierAppsUntilPrivileged(String callingPackage,
- IPackageManager packageManager, @Nullable TelephonyManager telephonyManager,
+ IPackageManager packageManager, IPermissionManager permissionManager,
+ @Nullable TelephonyManager telephonyManager,
ContentResolver contentResolver, int userId,
ArraySet<String> systemCarrierAppsDisabledUntilUsed,
ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
@@ -256,7 +259,7 @@
// apps.
String[] packageNames = new String[enabledCarrierPackages.size()];
enabledCarrierPackages.toArray(packageNames);
- packageManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
+ permissionManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
}
} catch (RemoteException e) {
Slog.w(TAG, "Could not reach PackageManager", e);
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index e9a5ff7..4d8c7d9 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -16,6 +16,7 @@
package android.test.mock;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
@@ -23,6 +24,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.IContentProvider;
+import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
@@ -154,6 +156,11 @@
ICancellationSignal cancellationSignal) throws RemoteException {
return MockContentProvider.this.refresh(url, args);
}
+
+ @Override
+ public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+ return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
+ }
}
private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
@@ -266,6 +273,12 @@
throw new UnsupportedOperationException("unimplemented mock method call");
}
+ /** {@hide} */
+ @Override
+ public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+ throw new UnsupportedOperationException("unimplemented mock method call");
+ }
+
/**
* Returns IContentProvider which calls back same methods in this class.
* By overriding this class, we avoid the mechanism hidden behind ContentProvider
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index fc2a464..b072d74 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -16,12 +16,14 @@
package android.test.mock;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.EntityIterator;
import android.content.IContentProvider;
+import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
@@ -144,4 +146,10 @@
ICancellationSignal cancellationSignal) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
+
+ /** {@hide} */
+ @Override
+ public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+ throw new UnsupportedOperationException("unimplemented mock method call");
+ }
}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
similarity index 100%
rename from tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
rename to tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
diff --git a/tests/libs-permissions/Android.bp b/tests/libs-permissions/Android.bp
index c7c4b10..330bfc9 100644
--- a/tests/libs-permissions/Android.bp
+++ b/tests/libs-permissions/Android.bp
@@ -14,16 +14,16 @@
}
java_library {
- name: "com.android.test.libs.product_services",
+ name: "com.android.test.libs.system_ext",
installable: true,
- product_services_specific: true,
- srcs: ["product_services/java/**/*.java"],
- required: ["com.android.test.libs.product_services.xml"],
+ system_ext_specific: true,
+ srcs: ["system_ext/java/**/*.java"],
+ required: ["com.android.test.libs.system_ext.xml"],
}
prebuilt_etc {
- name: "com.android.test.libs.product_services.xml",
- src: "product_services/com.android.test.libs.product_services.xml",
+ name: "com.android.test.libs.system_ext.xml",
+ src: "system_ext/com.android.test.libs.system_ext.xml",
sub_dir: "permissions",
- product_services_specific: true,
+ system_ext_specific: true,
}
diff --git a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
similarity index 81%
rename from tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
rename to tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
index 082a9be..fa56004 100644
--- a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
+++ b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
@@ -15,6 +15,6 @@
-->
<permissions>
- <library name="com.android.test.libs.product_services"
- file="/product_services/framework/com.android.test.libs.product_services.jar" />
+ <library name="com.android.test.libs.system_ext"
+ file="/system_ext/framework/com.android.test.libs.system_ext.jar" />
</permissions>
diff --git a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
similarity index 84%
rename from tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
rename to tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
index dcbdae8..9999aba 100644
--- a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
+++ b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.test.libs.product_services;
+package com.android.test.libs.system_ext;
/**
- * Test class for product_services libs.
+ * Test class for system_ext libs.
*/
-public class LibsProductServicesTest {
+public class LibsSystemExtTest {
/**
* Dummy method for testing.
diff --git a/tests/privapp-permissions/Android.bp b/tests/privapp-permissions/Android.bp
index ca7864f..b661850 100644
--- a/tests/privapp-permissions/Android.bp
+++ b/tests/privapp-permissions/Android.bp
@@ -45,17 +45,17 @@
}
android_app {
- name: "ProductServicesPrivAppPermissionTest",
+ name: "SystemExtPrivAppPermissionTest",
sdk_version: "current",
privileged: true,
- manifest: "product_services/AndroidManifest.xml",
- product_services_specific: true,
- required: ["product_servicesprivapp-permissions-test.xml"],
+ manifest: "system_ext/AndroidManifest.xml",
+ system_ext_specific: true,
+ required: ["system_extprivapp-permissions-test.xml"],
}
prebuilt_etc {
- name: "product_servicesprivapp-permissions-test.xml",
- src: "product_services/privapp-permissions-test.xml",
+ name: "system_extprivapp-permissions-test.xml",
+ src: "system_ext/privapp-permissions-test.xml",
sub_dir: "permissions",
- product_services_specific: true,
+ system_ext_specific: true,
}
diff --git a/tests/privapp-permissions/product_services/AndroidManifest.xml b/tests/privapp-permissions/system_ext/AndroidManifest.xml
similarity index 97%
rename from tests/privapp-permissions/product_services/AndroidManifest.xml
rename to tests/privapp-permissions/system_ext/AndroidManifest.xml
index 511ddee..4a0e82f 100644
--- a/tests/privapp-permissions/product_services/AndroidManifest.xml
+++ b/tests/privapp-permissions/system_ext/AndroidManifest.xml
@@ -16,7 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.framework.permission.privapp.tests.product_services">
+ package="com.android.framework.permission.privapp.tests.system_ext">
<!-- MANAGE_USB is signature|privileged -->
<uses-permission android:name="android.permission.MANAGE_USB"/>
diff --git a/tests/privapp-permissions/product_services/privapp-permissions-test.xml b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
similarity index 85%
rename from tests/privapp-permissions/product_services/privapp-permissions-test.xml
rename to tests/privapp-permissions/system_ext/privapp-permissions-test.xml
index 43baebb..ad63e86 100644
--- a/tests/privapp-permissions/product_services/privapp-permissions-test.xml
+++ b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<permissions>
- <privapp-permissions package="com.android.framework.permission.privapp.tests.product_services">
+ <privapp-permissions package="com.android.framework.permission.privapp.tests.system_ext">
<permission name="android.permission.MANAGE_USB"/>
</privapp-permissions>
</permissions>
diff --git a/tools/lock_agent/Android.bp b/tools/lock_agent/Android.bp
index 408946b..79dce4a 100644
--- a/tools/lock_agent/Android.bp
+++ b/tools/lock_agent/Android.bp
@@ -12,13 +12,9 @@
],
sdk_version: "current",
stl: "c++_static",
- include_dirs: [
- // NDK headers aren't available in platform NDK builds.
- "libnativehelper/include_jni",
- // Use ScopedUtfChars.
- "libnativehelper/header_only_include",
- ],
header_libs: [
+ // Use ScopedUtfChars.
+ "libnativehelper_header_only",
"libopenjdkjvmti_headers",
],
compile_multilib: "both",
@@ -32,13 +28,9 @@
"libz",
"slicer",
],
- include_dirs: [
- // NDK headers aren't available in platform NDK builds.
- "libnativehelper/include_jni",
- // Use ScopedUtfChars.
- "libnativehelper/header_only_include",
- ],
header_libs: [
+ // Use ScopedUtfChars.
+ "libnativehelper_header_only",
"libopenjdkjvmti_headers",
],
}