Merge "Cleanup setIsAllowSearch in Gallery"
diff --git a/core/api/current.txt b/core/api/current.txt
index fc319ce..d4c461c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -12982,6 +12982,14 @@
package android.credentials {
+ public final class ClearCredentialStateRequest implements android.os.Parcelable {
+ ctor public ClearCredentialStateRequest(@NonNull android.os.Bundle);
+ method public int describeContents();
+ method @NonNull public android.os.Bundle getData();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.credentials.ClearCredentialStateRequest> CREATOR;
+ }
+
public final class CreateCredentialRequest implements android.os.Parcelable {
ctor public CreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle);
method public int describeContents();
@@ -13009,6 +13017,7 @@
}
public final class CredentialManager {
+ method public void clearCredentialState(@NonNull android.credentials.ClearCredentialStateRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.CredentialManagerException>);
method public void executeCreateCredential(@NonNull android.credentials.CreateCredentialRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CredentialManagerException>);
method public void executeGetCredential(@NonNull android.credentials.GetCredentialRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.CredentialManagerException>);
}
diff --git a/core/java/android/credentials/IClearCredentialSessionCallback.aidl b/core/java/android/credentials/ClearCredentialStateRequest.aidl
similarity index 76%
copy from core/java/android/credentials/IClearCredentialSessionCallback.aidl
copy to core/java/android/credentials/ClearCredentialStateRequest.aidl
index 903e7f5..2679ee4 100644
--- a/core/java/android/credentials/IClearCredentialSessionCallback.aidl
+++ b/core/java/android/credentials/ClearCredentialStateRequest.aidl
@@ -16,12 +16,4 @@
package android.credentials;
-/**
- * Listener for clearCredentialSession request.
- *
- * @hide
- */
-interface IClearCredentialSessionCallback {
- oneway void onSuccess();
- oneway void onError(int errorCode, String message);
-}
\ No newline at end of file
+parcelable ClearCredentialStateRequest;
\ No newline at end of file
diff --git a/core/java/android/credentials/ClearCredentialStateRequest.java b/core/java/android/credentials/ClearCredentialStateRequest.java
new file mode 100644
index 0000000..33afbed
--- /dev/null
+++ b/core/java/android/credentials/ClearCredentialStateRequest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2022 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.credentials;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.AnnotationValidations;
+
+/**
+ * A request class for clearing a user's credential state from the credential providers.
+ */
+public final class ClearCredentialStateRequest implements Parcelable {
+
+ /** The request data. */
+ @NonNull
+ private final Bundle mData;
+
+ /** Returns the request data. */
+ @NonNull
+ public Bundle getData() {
+ return mData;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeBundle(mData);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "ClearCredentialStateRequest {data=" + mData + "}";
+ }
+
+ /**
+ * Constructs a {@link ClearCredentialStateRequest}.
+ *
+ * @param data the request data
+ */
+ public ClearCredentialStateRequest(@NonNull Bundle data) {
+ mData = requireNonNull(data, "data must not be null");
+ }
+
+ private ClearCredentialStateRequest(@NonNull Parcel in) {
+ Bundle data = in.readBundle();
+ mData = data;
+ AnnotationValidations.validate(NonNull.class, null, mData);
+ }
+
+ public static final @NonNull Creator<ClearCredentialStateRequest> CREATOR =
+ new Creator<ClearCredentialStateRequest>() {
+ @Override
+ public ClearCredentialStateRequest[] newArray(int size) {
+ return new ClearCredentialStateRequest[size];
+ }
+
+ @Override
+ public ClearCredentialStateRequest createFromParcel(@NonNull Parcel in) {
+ return new ClearCredentialStateRequest(in);
+ }
+ };
+}
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 04d57ad..f9973a2 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -142,18 +142,24 @@
}
/**
- * Clears the current user credential session from all credential providers.
+ * Clears the current user credential state from all credential providers.
*
- * <p>Usually invoked after your user signs out of your app so that they will not be
- * automatically signed in the next time.
+ * You should invoked this api after your user signs out of your app to notify all credential
+ * providers that any stored credential session for the given app should be cleared.
*
+ * A credential provider may have stored an active credential session and use it to limit
+ * sign-in options for future get-credential calls. For example, it may prioritize the active
+ * credential over any other available credential. When your user explicitly signs out of your
+ * app and in order to get the holistic sign-in options the next time, you should call this API
+ * to let the provider clear any stored credential session.
+ *
+ * @param request the request data
* @param cancellationSignal an optional signal that allows for cancelling this call
* @param executor the callback will take place on this {@link Executor}
* @param callback the callback invoked when the request succeeds or fails
- *
- * @hide
*/
- public void clearCredentialSession(
+ public void clearCredentialState(
+ @NonNull ClearCredentialStateRequest request,
@Nullable CancellationSignal cancellationSignal,
@CallbackExecutor @NonNull Executor executor,
@NonNull OutcomeReceiver<Void, CredentialManagerException> callback) {
@@ -167,8 +173,8 @@
ICancellationSignal cancelRemote = null;
try {
- cancelRemote = mService.clearCredentialSession(
- new ClearCredentialSessionTransport(executor, callback),
+ cancelRemote = mService.clearCredentialState(request,
+ new ClearCredentialStateTransport(executor, callback),
mContext.getOpPackageName());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
@@ -255,14 +261,14 @@
}
}
- private static class ClearCredentialSessionTransport
- extends IClearCredentialSessionCallback.Stub {
+ private static class ClearCredentialStateTransport
+ extends IClearCredentialStateCallback.Stub {
// TODO: listen for cancellation to release callback.
private final Executor mExecutor;
private final OutcomeReceiver<Void, CredentialManagerException> mCallback;
- private ClearCredentialSessionTransport(Executor executor,
+ private ClearCredentialStateTransport(Executor executor,
OutcomeReceiver<Void, CredentialManagerException> callback) {
mExecutor = executor;
mCallback = callback;
diff --git a/core/java/android/credentials/IClearCredentialSessionCallback.aidl b/core/java/android/credentials/IClearCredentialStateCallback.aidl
similarity index 88%
rename from core/java/android/credentials/IClearCredentialSessionCallback.aidl
rename to core/java/android/credentials/IClearCredentialStateCallback.aidl
index 903e7f5..f8b7ae44 100644
--- a/core/java/android/credentials/IClearCredentialSessionCallback.aidl
+++ b/core/java/android/credentials/IClearCredentialStateCallback.aidl
@@ -17,11 +17,11 @@
package android.credentials;
/**
- * Listener for clearCredentialSession request.
+ * Listener for clearCredentialState request.
*
* @hide
*/
-interface IClearCredentialSessionCallback {
+interface IClearCredentialStateCallback {
oneway void onSuccess();
oneway void onError(int errorCode, String message);
}
\ No newline at end of file
diff --git a/core/java/android/credentials/ICredentialManager.aidl b/core/java/android/credentials/ICredentialManager.aidl
index 35688d7..c5497bd 100644
--- a/core/java/android/credentials/ICredentialManager.aidl
+++ b/core/java/android/credentials/ICredentialManager.aidl
@@ -16,9 +16,10 @@
package android.credentials;
+import android.credentials.ClearCredentialStateRequest;
import android.credentials.CreateCredentialRequest;
import android.credentials.GetCredentialRequest;
-import android.credentials.IClearCredentialSessionCallback;
+import android.credentials.IClearCredentialStateCallback;
import android.credentials.ICreateCredentialCallback;
import android.credentials.IGetCredentialCallback;
import android.os.ICancellationSignal;
@@ -34,5 +35,5 @@
@nullable ICancellationSignal executeCreateCredential(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage);
- @nullable ICancellationSignal clearCredentialSession(in IClearCredentialSessionCallback callback, String callingPackage);
+ @nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage);
}
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index d77e499..03b25c2 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -29,6 +29,7 @@
import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT;
import static android.view.WindowInsets.Type.all;
+import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.indexOf;
import static android.view.WindowInsets.Type.systemBars;
@@ -597,7 +598,10 @@
return new WindowInsets(null, null,
mTypeVisibilityMap,
mIsRound, mAlwaysConsumeSystemBars,
- displayCutoutCopyConstructorArgument(this),
+ // If the system window insets types contain displayCutout, we should also consume
+ // it.
+ (mCompatInsetsTypes & displayCutout()) != 0
+ ? null : displayCutoutCopyConstructorArgument(this),
mRoundedCorners, mPrivacyIndicatorBounds, mCompatInsetsTypes,
mCompatIgnoreVisibility);
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index e4bdab8..88c1036 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -28,7 +28,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
-import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
@@ -104,10 +103,9 @@
Intent.EXTRA_INSTALLER_PACKAGE_NAME);
if (installerPackageNameFromIntent != null) {
final String callingPkgName = getLaunchedFromPackage();
- if (installerPackageNameFromIntent.length() >= SessionParams.MAX_PACKAGE_NAME_LENGTH
- || (!TextUtils.equals(installerPackageNameFromIntent, callingPkgName)
+ if (!TextUtils.equals(installerPackageNameFromIntent, callingPkgName)
&& mPackageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES,
- callingPkgName) != PackageManager.PERMISSION_GRANTED)) {
+ callingPkgName) != PackageManager.PERMISSION_GRANTED) {
Log.e(LOG_TAG, "The given installer package name " + installerPackageNameFromIntent
+ " is invalid. Remove it.");
EventLog.writeEvent(0x534e4554, "236687884", getLaunchedFromUid(),
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt
index bb1cd6e..76f6611 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt
@@ -16,6 +16,7 @@
package com.android.settingslib.spaprivileged.framework.common
+import android.app.ActivityManager
import android.app.AlarmManager
import android.app.AppOpsManager
import android.app.admin.DevicePolicyManager
@@ -28,6 +29,9 @@
import android.os.UserManager
import android.permission.PermissionControllerManager
+/** The [ActivityManager] instance. */
+val Context.activityManager get() = getSystemService(ActivityManager::class.java)!!
+
/** The [AlarmManager] instance. */
val Context.alarmManager get() = getSystemService(AlarmManager::class.java)!!
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 2e0155b..caaa88d 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1105,6 +1105,8 @@
<string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> left until full</string>
<!-- [CHAR_LIMIT=80] Label for battery level chart when charge been limited -->
<string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Charging is paused</string>
+ <!-- [CHAR_LIMIT=80] Label for battery charging future pause -->
+ <string name="power_charging_future_paused"><xliff:g id="level">%1$s</xliff:g> - Charging to <xliff:g id="dock_defender_threshold">%2$s</xliff:g></string>
<!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
<string name="battery_info_status_unknown">Unknown</string>
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index b2a2a67..b962cc4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -107,6 +107,8 @@
if (shouldAnimateForTransition(lastState, newState)) {
iconView.playAnimation()
iconViewOverlay.playAnimation()
+ } else if (lastState == STATE_IDLE && newState == STATE_AUTHENTICATING_ANIMATING_IN) {
+ iconView.playAnimation()
}
LottieColorUtils.applyDynamicColors(context, iconView)
LottieColorUtils.applyDynamicColors(context, iconViewOverlay)
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index bbaf47d..aa6c619 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -391,7 +391,7 @@
// 1600 - accessibility
@JvmField
val A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS =
- unreleasedFlag(1600, "a11y_floating_menu_fling_spring_animations")
+ unreleasedFlag(1600, "a11y_floating_menu_fling_spring_animations", teamfood = true)
// 1700 - clipboard
@JvmField val CLIPBOARD_OVERLAY_REFACTOR = releasedFlag(1700, "clipboard_overlay_refactor")
diff --git a/services/OWNERS b/services/OWNERS
index 495c0737..eace906 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -3,7 +3,7 @@
# art-team@ manages the system server profile
per-file art-profile* = calin@google.com, ngeoffray@google.com, vmarko@google.com
-per-file java/com/android/server/* = toddke@google.com,patb@google.com
+per-file java/com/android/server/* = patb@google.com #{LAST_RESORT_SUGGESTION}
per-file tests/servicestests/src/com/android/server/systemconfig/* = patb@google.com
per-file proguard.flags = jdduke@google.com
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 2669d21..8d247f6 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -140,9 +140,7 @@
import com.android.server.location.provider.proxy.ProxyLocationProvider;
import com.android.server.location.settings.LocationSettings;
import com.android.server.location.settings.LocationUserSettings;
-import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
-import com.android.server.utils.Slogf;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -310,10 +308,6 @@
permissionManagerInternal.setLocationExtraPackagesProvider(
userId -> mContext.getResources().getStringArray(
com.android.internal.R.array.config_locationExtraPackageNames));
-
- // TODO(b/241604546): properly handle this callback
- LocalServices.getService(UserManagerInternal.class).addUserVisibilityListener(
- (u, v) -> Slogf.i(TAG, "onUserVisibilityChanged(): %d -> %b", u, v));
}
@Nullable
@@ -1702,7 +1696,7 @@
private final Context mContext;
- private final UserInfoHelper mUserInfoHelper;
+ private final SystemUserInfoHelper mUserInfoHelper;
private final LocationSettings mLocationSettings;
private final AlarmHelper mAlarmHelper;
private final SystemAppOpsHelper mAppOpsHelper;
@@ -1725,7 +1719,7 @@
@GuardedBy("this")
private boolean mSystemReady;
- SystemInjector(Context context, UserInfoHelper userInfoHelper) {
+ SystemInjector(Context context, SystemUserInfoHelper userInfoHelper) {
mContext = context;
mUserInfoHelper = userInfoHelper;
@@ -1745,6 +1739,7 @@
}
synchronized void onSystemReady() {
+ mUserInfoHelper.onSystemReady();
mAppOpsHelper.onSystemReady();
mLocationPermissionsHelper.onSystemReady();
mSettingsHelper.onSystemReady();
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index 45436e7..cb952ed 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -110,6 +110,11 @@
addLog(new UserSwitchedEvent(userIdFrom, userIdTo));
}
+ /** Logs a user visibility changed event. */
+ public void logUserVisibilityChanged(int userId, boolean visible) {
+ addLog(new UserVisibilityChangedEvent(userId, visible));
+ }
+
/** Logs a location enabled/disabled event. */
public void logLocationEnabled(int userId, boolean enabled) {
addLog(new LocationEnabledEvent(userId, enabled));
@@ -475,6 +480,22 @@
}
}
+ private static final class UserVisibilityChangedEvent {
+
+ private final int mUserId;
+ private final boolean mVisible;
+
+ UserVisibilityChangedEvent(int userId, boolean visible) {
+ mUserId = userId;
+ mVisible = visible;
+ }
+
+ @Override
+ public String toString() {
+ return "[u" + mUserId + "] " + (mVisible ? "visible" : "invisible");
+ }
+ }
+
private static final class LocationEnabledEvent {
private final int mUserId;
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
index 0f5e3d4..d3ceddd 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
@@ -387,7 +387,7 @@
if (!mSettingsHelper.isLocationEnabled(identity.getUserId())) {
return false;
}
- if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) {
+ if (!mUserInfoHelper.isVisibleUserId(identity.getUserId())) {
return false;
}
if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(),
@@ -534,7 +534,10 @@
}
void onUserChanged(int userId, int change) {
- if (change == UserListener.CURRENT_USER_CHANGED) {
+ // current user changes affect whether system server location requests are allowed to access
+ // location, and visibility changes affect whether any given user may access location.
+ if (change == UserListener.CURRENT_USER_CHANGED
+ || change == UserListener.USER_VISIBILITY_CHANGED) {
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
index 349b94b..567d8ac 100644
--- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
+++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
@@ -317,7 +317,7 @@
identity.getUserId())) {
return false;
}
- if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) {
+ if (!mUserInfoHelper.isVisibleUserId(identity.getUserId())) {
return false;
}
if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(),
@@ -394,7 +394,10 @@
}
private void onUserChanged(int userId, int change) {
- if (change == UserListener.CURRENT_USER_CHANGED) {
+ // current user changes affect whether system server location requests are allowed to access
+ // location, and visibility changes affect whether any given user may access location.
+ if (change == UserListener.CURRENT_USER_CHANGED
+ || change == UserListener.USER_VISIBILITY_CHANGED) {
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
}
}
diff --git a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
index ed1e654..40dd979 100644
--- a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
@@ -33,9 +33,11 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
+import com.android.server.pm.UserManagerInternal;
import java.io.FileDescriptor;
import java.util.Arrays;
+import java.util.Objects;
/**
* Provides accessors and listeners for all user info.
@@ -50,11 +52,21 @@
@Nullable private IActivityManager mActivityManager;
@GuardedBy("this")
@Nullable private UserManager mUserManager;
+ @GuardedBy("this")
+ @Nullable private UserManagerInternal mUserManagerInternal;
public SystemUserInfoHelper(Context context) {
mContext = context;
}
+ /** The function should be called when PHASE_SYSTEM_SERVICES_READY. */
+ public synchronized void onSystemReady() {
+ mUserManagerInternal =
+ Objects.requireNonNull(LocalServices.getService(UserManagerInternal.class));
+ mUserManagerInternal.addUserVisibilityListener(
+ (userId, visible) -> dispatchOnVisibleUserChanged(userId, visible));
+ }
+
@Nullable
protected final ActivityManagerInternal getActivityManagerInternal() {
synchronized (this) {
@@ -136,6 +148,24 @@
}
@Override
+ public boolean isVisibleUserId(@UserIdInt int userId) {
+ synchronized (this) {
+ // if you're hitting this precondition then you are invoking this before the system is
+ // ready
+ Preconditions.checkState(mUserManagerInternal != null);
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ return mUserManagerInternal.isUserVisible(userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
protected int[] getProfileIds(@UserIdInt int userId) {
UserManager userManager = getUserManager();
diff --git a/services/core/java/com/android/server/location/injector/UserInfoHelper.java b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
index c835370..2b9db1c 100644
--- a/services/core/java/com/android/server/location/injector/UserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
@@ -22,6 +22,7 @@
import static com.android.server.location.injector.UserInfoHelper.UserListener.CURRENT_USER_CHANGED;
import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STARTED;
import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STOPPED;
+import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_VISIBILITY_CHANGED;
import android.annotation.IntDef;
import android.annotation.UserIdInt;
@@ -47,8 +48,9 @@
int CURRENT_USER_CHANGED = 1;
int USER_STARTED = 2;
int USER_STOPPED = 3;
+ int USER_VISIBILITY_CHANGED = 4;
- @IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED})
+ @IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED, USER_VISIBILITY_CHANGED})
@Retention(RetentionPolicy.SOURCE)
@interface UserChange {}
@@ -121,6 +123,18 @@
}
}
+ protected final void dispatchOnVisibleUserChanged(@UserIdInt int userId, boolean visible) {
+ if (D) {
+ Log.d(TAG, "visibility of u" + userId + " changed to "
+ + (visible ? "visible" : "invisible"));
+ }
+ EVENT_LOG.logUserVisibilityChanged(userId, visible);
+
+ for (UserListener listener : mListeners) {
+ listener.onUserChanged(userId, USER_VISIBILITY_CHANGED);
+ }
+ }
+
/**
* Returns an array of running user ids. This will include all running users, and will also
* include any profiles of the running users. The caller must never mutate the returned
@@ -129,8 +143,8 @@
public abstract int[] getRunningUserIds();
/**
- * Returns true if the given user id is either the current user or a profile of the current
- * user.
+ * Returns {@code true} if the given user id is either the current user or a profile of the
+ * current user.
*/
public abstract boolean isCurrentUserId(@UserIdInt int userId);
@@ -140,6 +154,13 @@
*/
public abstract @UserIdInt int getCurrentUserId();
+ /**
+ * Returns {@code true} if the user is visible.
+ *
+ * <p>The visibility of a user is defined by {@link android.os.UserManager#isUserVisible()}.
+ */
+ public abstract boolean isVisibleUserId(@UserIdInt int userId);
+
protected abstract int[] getProfileIds(@UserIdInt int userId);
/**
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 338a995..7063cb8 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -661,6 +661,8 @@
if (!GPS_PROVIDER.equals(mName)) {
Log.e(TAG, "adas gnss bypass request received in non-gps provider");
adasGnssBypass = false;
+ } else if (!mUserHelper.isCurrentUserId(getIdentity().getUserId())) {
+ adasGnssBypass = false;
} else if (!mLocationSettings.getUserSettings(
getIdentity().getUserId()).isAdasGnssLocationEnabled()) {
adasGnssBypass = false;
@@ -1712,6 +1714,8 @@
if (!GPS_PROVIDER.equals(mName)) {
Log.e(TAG, "adas gnss bypass request received in non-gps provider");
adasGnssBypass = false;
+ } else if (!mUserHelper.isCurrentUserId(identity.getUserId())) {
+ adasGnssBypass = false;
} else if (!mLocationSettings.getUserSettings(
identity.getUserId()).isAdasGnssLocationEnabled()) {
adasGnssBypass = false;
@@ -2193,7 +2197,7 @@
if (!isEnabled(identity.getUserId())) {
return false;
}
- if (!mUserHelper.isCurrentUserId(identity.getUserId())) {
+ if (!mUserHelper.isVisibleUserId(identity.getUserId())) {
return false;
}
}
@@ -2322,6 +2326,10 @@
switch (change) {
case UserListener.CURRENT_USER_CHANGED:
+ // current user changes affect whether system server location requests are
+ // allowed to access location, and visibility changes affect whether any given
+ // user may access location.
+ case UserListener.USER_VISIBILITY_CHANGED:
updateRegistrations(
registration -> registration.getIdentity().getUserId() == userId);
break;
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 374da1c..30fcd06 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -22,10 +22,11 @@
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.credentials.ClearCredentialStateRequest;
import android.credentials.CreateCredentialRequest;
import android.credentials.GetCredentialOption;
import android.credentials.GetCredentialRequest;
-import android.credentials.IClearCredentialSessionCallback;
+import android.credentials.IClearCredentialStateCallback;
import android.credentials.ICreateCredentialCallback;
import android.credentials.ICredentialManager;
import android.credentials.IGetCredentialCallback;
@@ -206,8 +207,8 @@
}
@Override
- public ICancellationSignal clearCredentialSession(
- IClearCredentialSessionCallback callback, String callingPackage) {
+ public ICancellationSignal clearCredentialState(ClearCredentialStateRequest request,
+ IClearCredentialStateCallback callback, String callingPackage) {
// TODO: implement.
Log.i(TAG, "clearCredentialSession");
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
index ac23d4e..014ef3d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
@@ -34,14 +34,16 @@
public static final int DEFAULT_USERID = 0;
private final IntArray mRunningUserIds;
+ private final IntArray mVisibleUserIds;
private final SparseArray<IntArray> mProfiles;
private int mCurrentUserId;
public FakeUserInfoHelper() {
mCurrentUserId = DEFAULT_USERID;
- mRunningUserIds = IntArray.wrap(new int[]{DEFAULT_USERID});
+ mRunningUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
mProfiles = new SparseArray<>();
+ mVisibleUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
}
public void startUser(int userId) {
@@ -65,6 +67,7 @@
mRunningUserIds.remove(idx);
}
+ setUserInvisibleInternal(userId);
dispatchOnUserStopped(userId);
}
@@ -82,16 +85,39 @@
// ensure all profiles are started if they didn't exist before...
for (int userId : currentProfileUserIds) {
startUserInternal(userId, false);
+ setUserVisibleInternal(userId, true);
}
if (oldUserId != mCurrentUserId) {
dispatchOnCurrentUserChanged(oldUserId, mCurrentUserId);
+ setUserVisibleInternal(mCurrentUserId, true);
}
}
- @Override
- public int[] getRunningUserIds() {
- return mRunningUserIds.toArray();
+ private void setUserVisibleInternal(int userId, boolean alwaysDispatch) {
+ int idx = mVisibleUserIds.indexOf(userId);
+ if (idx < 0) {
+ mVisibleUserIds.add(userId);
+ } else if (!alwaysDispatch) {
+ return;
+ }
+ dispatchOnVisibleUserChanged(userId, true);
+ }
+
+ private void setUserInvisibleInternal(int userId) {
+ int idx = mVisibleUserIds.indexOf(userId);
+ if (idx >= 0) {
+ mVisibleUserIds.remove(userId);
+ }
+ dispatchOnVisibleUserChanged(userId, false);
+ }
+
+ public void setUserVisible(int userId, boolean visible) {
+ if (visible) {
+ setUserVisibleInternal(userId, true);
+ } else {
+ setUserInvisibleInternal(userId);
+ }
}
@Override
@@ -100,11 +126,21 @@
}
@Override
+ public int[] getRunningUserIds() {
+ return mRunningUserIds.toArray();
+ }
+
+ @Override
public int getCurrentUserId() {
return mCurrentUserId;
}
@Override
+ public boolean isVisibleUserId(int userId) {
+ return mVisibleUserIds.indexOf(userId) >= 0;
+ }
+
+ @Override
protected int[] getProfileIds(int userId) {
IntArray profiles = mProfiles.get(userId);
if (profiles != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
index 490b2e8..d9aa232 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.location.injector;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -31,6 +32,7 @@
import com.android.server.LocalServices;
import com.android.server.location.injector.UserInfoHelper.UserListener;
+import com.android.server.pm.UserManagerInternal;
import org.junit.After;
import org.junit.Before;
@@ -45,13 +47,14 @@
private static final int USER1_ID = 1;
private static final int USER1_MANAGED_ID = 11;
- private static final int[] USER1_PROFILES = new int[]{USER1_ID, USER1_MANAGED_ID};
+ private static final int[] USER1_PROFILES = new int[] {USER1_ID, USER1_MANAGED_ID};
private static final int USER2_ID = 2;
private static final int USER2_MANAGED_ID = 12;
- private static final int[] USER2_PROFILES = new int[]{USER2_ID, USER2_MANAGED_ID};
+ private static final int[] USER2_PROFILES = new int[] {USER2_ID, USER2_MANAGED_ID};
@Mock private Context mContext;
@Mock private UserManager mUserManager;
+ @Mock private UserManagerInternal mUserManagerInternal;
private SystemUserInfoHelper mHelper;
@@ -63,12 +66,15 @@
doReturn(USER1_PROFILES).when(mUserManager).getEnabledProfileIds(USER1_ID);
doReturn(USER2_PROFILES).when(mUserManager).getEnabledProfileIds(USER2_ID);
+ LocalServices.addService(UserManagerInternal.class, mUserManagerInternal);
+
mHelper = new SystemUserInfoHelper(mContext);
}
@After
public void tearDown() {
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ LocalServices.removeServiceForTest(UserManagerInternal.class);
}
@Test
@@ -77,11 +83,11 @@
mHelper.addListener(listener);
mHelper.dispatchOnCurrentUserChanged(USER1_ID, USER2_ID);
- verify(listener, times(1)).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED);
- verify(listener, times(1)).onUserChanged(USER1_MANAGED_ID,
+ verify(listener).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED);
+ verify(listener).onUserChanged(USER1_MANAGED_ID,
UserListener.CURRENT_USER_CHANGED);
- verify(listener, times(1)).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED);
- verify(listener, times(1)).onUserChanged(USER2_MANAGED_ID,
+ verify(listener).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED);
+ verify(listener).onUserChanged(USER2_MANAGED_ID,
UserListener.CURRENT_USER_CHANGED);
mHelper.dispatchOnCurrentUserChanged(USER2_ID, USER1_ID);
@@ -94,6 +100,25 @@
}
@Test
+ public void testListener_UserVisibilityChanged() {
+ mHelper.onSystemReady();
+ verify(mUserManagerInternal).addUserVisibilityListener(any());
+
+ UserListener listener = mock(UserListener.class);
+ mHelper.addListener(listener);
+
+ mHelper.dispatchOnVisibleUserChanged(USER1_ID, false);
+ mHelper.dispatchOnVisibleUserChanged(USER2_ID, true);
+ verify(listener).onUserChanged(USER1_ID, UserListener.USER_VISIBILITY_CHANGED);
+ verify(listener).onUserChanged(USER2_ID, UserListener.USER_VISIBILITY_CHANGED);
+
+ mHelper.dispatchOnVisibleUserChanged(USER2_ID, false);
+ mHelper.dispatchOnVisibleUserChanged(USER1_ID, true);
+ verify(listener, times(2)).onUserChanged(USER2_ID, UserListener.USER_VISIBILITY_CHANGED);
+ verify(listener, times(2)).onUserChanged(USER1_ID, UserListener.USER_VISIBILITY_CHANGED);
+ }
+
+ @Test
public void testListener_StartUser() {
UserListener listener = mock(UserListener.class);
mHelper.addListener(listener);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index 20e4e80..aa28ad4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -175,7 +175,9 @@
doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
mInjector = new TestInjector(mContext);
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
mInjector.getUserInfoHelper().startUser(OTHER_USER);
+ mInjector.getUserInfoHelper().setUserVisible(OTHER_USER, true);
mPassive = new PassiveLocationProviderManager(mContext, mInjector);
mPassive.startManager(null);
@@ -331,6 +333,20 @@
}
@Test
+ public void testGetLastLocation_InvisibleUser() {
+ Location loc = createLocation(NAME, mRandom);
+ mProvider.setProviderLocation(loc);
+
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+ assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+ PERMISSION_FINE)).isNull();
+
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
+ assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+ PERMISSION_FINE)).isEqualTo(loc);
+ }
+
+ @Test
public void testGetLastLocation_Bypass() {
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
@@ -569,6 +585,25 @@
}
@Test
+ public void testRegisterListener_InvisibleUser() throws Exception {
+ ILocationListener listener = createMockLocationListener();
+ LocationRequest request = new LocationRequest.Builder(0)
+ .setWorkSource(WORK_SOURCE)
+ .build();
+ mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
+
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+ mProvider.setProviderLocation(createLocationResult(NAME, mRandom));
+ verify(listener, never()).onLocationChanged(any(List.class),
+ nullable(IRemoteCallback.class));
+
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
+ LocationResult loc = createLocationResult(NAME, mRandom);
+ mProvider.setProviderLocation(loc);
+ verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
+ }
+
+ @Test
public void testRegisterListener_ExpiringAlarm() throws Exception {
ILocationListener listener = createMockLocationListener();
LocationRequest request = new LocationRequest.Builder(0)
@@ -799,6 +834,17 @@
}
@Test
+ public void testGetCurrentLocation_InvisibleUser() throws Exception {
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+
+ ILocationCallback listener = createMockGetCurrentLocationListener();
+ LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
+ mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
+
+ verify(listener).onLocation(isNull());
+ }
+
+ @Test
public void testFlush() throws Exception {
ILocationListener listener = createMockLocationListener();
mManager.registerLocationRequest(
@@ -1008,6 +1054,21 @@
}
@Test
+ public void testProviderRequest_InvisibleUser() {
+ ILocationListener listener = createMockLocationListener();
+ LocationRequest request = new LocationRequest.Builder(5)
+ .setWorkSource(WORK_SOURCE)
+ .build();
+ mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
+
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
+ assertThat(mProvider.getRequest().isActive()).isFalse();
+
+ mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
+ assertThat(mProvider.getRequest().isActive()).isTrue();
+ }
+
+ @Test
public void testProviderRequest_IgnoreLocationSettings() {
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
diff --git a/tools/lint/common/Android.bp b/tools/lint/common/Android.bp
new file mode 100644
index 0000000..898f88b
--- /dev/null
+++ b/tools/lint/common/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2022 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_host {
+ name: "AndroidCommonLint",
+ srcs: ["src/main/java/**/*.kt"],
+ libs: ["lint_api"],
+ kotlincflags: ["-Xjvm-default=all"],
+}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/Constants.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
diff --git a/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt b/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt
new file mode 100644
index 0000000..720f835
--- /dev/null
+++ b/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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.google.android.lint
+
+import com.android.tools.lint.detector.api.getUMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.UParameter
+
+fun isPermissionMethodCall(callExpression: UCallExpression): Boolean {
+ val method = callExpression.resolve()?.getUMethod() ?: return false
+ return hasPermissionMethodAnnotation(method)
+}
+
+fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations
+ .any {
+ it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD)
+ }
+
+fun hasPermissionNameAnnotation(parameter: UParameter) = parameter.annotations.any {
+ it.hasQualifiedName(ANNOTATION_PERMISSION_NAME)
+}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/model/Method.kt b/tools/lint/common/src/main/java/com/google/android/lint/model/Method.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/model/Method.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/model/Method.kt
diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp
new file mode 100644
index 0000000..5f6c6f7
--- /dev/null
+++ b/tools/lint/fix/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+python_binary_host {
+ name: "lint_fix",
+ main: "lint_fix.py",
+ srcs: ["lint_fix.py"],
+}
diff --git a/tools/lint/Android.bp b/tools/lint/framework/Android.bp
similarity index 87%
rename from tools/lint/Android.bp
rename to tools/lint/framework/Android.bp
index 96618f4..7f27e8a 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/framework/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Android Open Source Project
+// Copyright (C) 2022 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.
@@ -29,6 +29,11 @@
"auto_service_annotations",
"lint_api",
],
+ static_libs: [
+ "AndroidCommonLint",
+ // TODO: remove once b/236558918 is resolved and the below checks actually run globally
+ "AndroidGlobalLintChecker",
+ ],
kotlincflags: ["-Xjvm-default=all"],
}
@@ -51,9 +56,3 @@
unit_test: true,
},
}
-
-python_binary_host {
- name: "lint_fix",
- main: "fix/lint_fix.py",
- srcs: ["fix/lint_fix.py"],
-}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
similarity index 97%
rename from tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
index 1b0f035..e12ec3d 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt
@@ -26,7 +26,6 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.android.tools.lint.detector.api.getUMethod
-import com.google.android.lint.aidl.hasPermissionMethodAnnotation
import com.intellij.psi.PsiType
import org.jetbrains.uast.UAnnotation
import org.jetbrains.uast.UBlockExpression
@@ -193,5 +192,8 @@
else -> false
}
}
+
+ private fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations
+ .any { it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD) }
}
}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/Method.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/Method.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
rename to tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
rename to tools/lint/framework/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
diff --git a/tools/lint/Android.bp b/tools/lint/global/Android.bp
similarity index 84%
copy from tools/lint/Android.bp
copy to tools/lint/global/Android.bp
index 96618f4..3756abe 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/global/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Android Open Source Project
+// Copyright (C) 2022 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.
@@ -22,18 +22,22 @@
}
java_library_host {
- name: "AndroidFrameworkLintChecker",
+ name: "AndroidGlobalLintChecker",
srcs: ["checks/src/main/java/**/*.kt"],
plugins: ["auto_service_plugin"],
libs: [
"auto_service_annotations",
"lint_api",
],
+ static_libs: ["AndroidCommonLint"],
kotlincflags: ["-Xjvm-default=all"],
+ dist: {
+ targets: ["droid"],
+ },
}
java_test_host {
- name: "AndroidFrameworkLintCheckerTest",
+ name: "AndroidGlobalLintCheckerTest",
// TODO(b/239881504): Since this test was written, Android
// Lint was updated, and now includes classes that were
// compiled for java 15. The soong build doesn't support
@@ -42,7 +46,7 @@
enabled: false,
srcs: ["checks/src/test/java/**/*.kt"],
static_libs: [
- "AndroidFrameworkLintChecker",
+ "AndroidGlobalLintChecker",
"junit",
"lint",
"lint_tests",
@@ -51,9 +55,3 @@
unit_test: true,
},
}
-
-python_binary_host {
- name: "lint_fix",
- main: "fix/lint_fix.py",
- srcs: ["fix/lint_fix.py"],
-}
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
new file mode 100644
index 0000000..b377d50
--- /dev/null
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 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.google.android.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.aidl.EnforcePermissionDetector
+import com.google.android.lint.aidl.EnforcePermissionHelperDetector
+import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class AndroidGlobalIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
+ EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
+ EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+ SimpleManualPermissionEnforcementDetector.ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION,
+ )
+
+ override val api: Int
+ get() = CURRENT_API
+
+ override val minApi: Int
+ get() = 8
+
+ override val vendor: Vendor = Vendor(
+ vendorName = "Android",
+ feedbackUrl = "http://b/issues/new?component=315013",
+ contact = "repsonsible-apis@google.com"
+ )
+}
\ No newline at end of file
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
similarity index 97%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
index d120e1d..f1b6348 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt
@@ -19,6 +19,8 @@
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.Location
import com.android.tools.lint.detector.api.getUMethod
+import com.google.android.lint.hasPermissionNameAnnotation
+import com.google.android.lint.isPermissionMethodCall
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.evaluateString
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
similarity index 69%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
index edbdd8d..250ca78 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
@@ -16,14 +16,9 @@
package com.google.android.lint.aidl
-import com.android.tools.lint.detector.api.getUMethod
-import com.google.android.lint.ANNOTATION_PERMISSION_METHOD
-import com.google.android.lint.ANNOTATION_PERMISSION_NAME
import com.google.android.lint.CLASS_STUB
import com.intellij.psi.PsiAnonymousClass
-import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UMethod
-import org.jetbrains.uast.UParameter
/**
* Given a UMethod, determine if this method is
@@ -51,17 +46,3 @@
it.referenceName == CLASS_STUB
} ?: false
}
-
-fun isPermissionMethodCall(callExpression: UCallExpression): Boolean {
- val method = callExpression.resolve()?.getUMethod() ?: return false
- return hasPermissionMethodAnnotation(method)
-}
-
-fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations
- .any {
- it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD)
- }
-
-fun hasPermissionNameAnnotation(parameter: UParameter) = parameter.annotations.any {
- it.hasQualifiedName(ANNOTATION_PERMISSION_NAME)
-}
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
similarity index 100%
rename from tools/lint/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
rename to tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
similarity index 100%
rename from tools/lint/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
rename to tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt