Merge "Disable force-dark"
diff --git a/api/system-current.txt b/api/system-current.txt
index cba137a..8714c0f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1843,7 +1843,9 @@
field public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessChangeEvent> CREATOR;
field public final float batteryLevel;
field public final float brightness;
+ field public final long colorSampleDuration;
field public final int colorTemperature;
+ field @Nullable public final long[] colorValueBuckets;
field public final boolean isDefaultBrightnessConfig;
field public final boolean isUserSetBrightness;
field public final float lastBrightness;
@@ -5520,6 +5522,8 @@
public final class PermissionControllerManager {
method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback);
+ field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1
+ field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2
field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2
field public static final int REASON_MALWARE = 1; // 0x1
}
@@ -5533,7 +5537,7 @@
ctor public PermissionControllerService();
method public final void attachBaseContext(android.content.Context);
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract int onCountPermissionApps(@NonNull java.util.List<java.lang.String>, boolean, boolean);
+ method public abstract int onCountPermissionApps(@NonNull java.util.List<java.lang.String>, int);
method @NonNull public abstract java.util.List<android.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(@NonNull String);
method @NonNull public abstract java.util.List<android.permission.RuntimePermissionUsageInfo> onGetPermissionUsages(boolean, long);
method public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream);
diff --git a/api/test-current.txt b/api/test-current.txt
index 2a7aa17..2a9a149 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -660,7 +660,9 @@
field public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessChangeEvent> CREATOR;
field public final float batteryLevel;
field public final float brightness;
+ field public final long colorSampleDuration;
field public final int colorTemperature;
+ field @Nullable public final long[] colorValueBuckets;
field public final boolean isDefaultBrightnessConfig;
field public final boolean isUserSetBrightness;
field public final float lastBrightness;
@@ -1692,6 +1694,8 @@
public final class PermissionControllerManager {
method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback);
+ field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1
+ field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2
field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2
field public static final int REASON_MALWARE = 1; // 0x1
}
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
index 02eb28c..c6186bb 100644
--- a/core/java/android/hardware/display/BrightnessChangeEvent.java
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -16,11 +16,15 @@
package android.hardware.display;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Objects;
+
/**
* Data about a brightness settings change.
*
@@ -72,12 +76,29 @@
/** Whether brightness curve includes a user brightness point */
public final boolean isUserSetBrightness;
+ /**
+ * Histogram counting how many times a pixel of a given value was displayed onscreen for the
+ * Value component of HSV if the device supports color sampling, if the device does not support
+ * color sampling the value will be null.
+ * The buckets of the histogram are evenly weighted, the number of buckets is device specific.
+ * For example if we had {10, 6, 4, 1} this means that 10 pixels were in the range
+ * [0x00,0x3f], 6 pixels were in the range [0x40,0x7f] etc.
+ */
+ @Nullable
+ public final long[] colorValueBuckets;
+
+ /**
+ * How many milliseconds of data are contained in the colorValueBuckets.
+ */
+ public final long colorSampleDuration;
+
/** @hide */
private BrightnessChangeEvent(float brightness, long timeStamp, String packageName,
int userId, float[] luxValues, long[] luxTimestamps, float batteryLevel,
float powerBrightnessFactor, boolean nightMode, int colorTemperature,
- float lastBrightness, boolean isDefaultBrightnessConfig, boolean isUserSetBrightness) {
+ float lastBrightness, boolean isDefaultBrightnessConfig, boolean isUserSetBrightness,
+ long[] colorValueBuckets, long colorSampleDuration) {
this.brightness = brightness;
this.timeStamp = timeStamp;
this.packageName = packageName;
@@ -91,6 +112,8 @@
this.lastBrightness = lastBrightness;
this.isDefaultBrightnessConfig = isDefaultBrightnessConfig;
this.isUserSetBrightness = isUserSetBrightness;
+ this.colorValueBuckets = colorValueBuckets;
+ this.colorSampleDuration = colorSampleDuration;
}
/** @hide */
@@ -108,6 +131,8 @@
this.lastBrightness = other.lastBrightness;
this.isDefaultBrightnessConfig = other.isDefaultBrightnessConfig;
this.isUserSetBrightness = other.isUserSetBrightness;
+ this.colorValueBuckets = other.colorValueBuckets;
+ this.colorSampleDuration = other.colorSampleDuration;
}
private BrightnessChangeEvent(Parcel source) {
@@ -124,6 +149,8 @@
lastBrightness = source.readFloat();
isDefaultBrightnessConfig = source.readBoolean();
isUserSetBrightness = source.readBoolean();
+ colorValueBuckets = source.createLongArray();
+ colorSampleDuration = source.readLong();
}
public static final Creator<BrightnessChangeEvent> CREATOR =
@@ -156,6 +183,8 @@
dest.writeFloat(lastBrightness);
dest.writeBoolean(isDefaultBrightnessConfig);
dest.writeBoolean(isUserSetBrightness);
+ dest.writeLongArray(colorValueBuckets);
+ dest.writeLong(colorSampleDuration);
}
/** @hide */
@@ -173,6 +202,8 @@
private float mLastBrightness;
private boolean mIsDefaultBrightnessConfig;
private boolean mIsUserSetBrightness;
+ private long[] mColorValueBuckets;
+ private long mColorSampleDuration;
/** {@see BrightnessChangeEvent#brightness} */
public Builder setBrightness(float brightness) {
@@ -252,12 +283,21 @@
return this;
}
+ /** {@see BrightnessChangeEvent#valueBuckets} */
+ public Builder setColorValues(@NonNull long[] colorValueBuckets, long colorSampleDuration) {
+ Objects.requireNonNull(colorValueBuckets);
+ mColorValueBuckets = colorValueBuckets;
+ mColorSampleDuration = colorSampleDuration;
+ return this;
+ }
+
/** Builds a BrightnessChangeEvent */
public BrightnessChangeEvent build() {
return new BrightnessChangeEvent(mBrightness, mTimeStamp,
mPackageName, mUserId, mLuxValues, mLuxTimestamps, mBatteryLevel,
mPowerBrightnessFactor, mNightMode, mColorTemperature, mLastBrightness,
- mIsDefaultBrightnessConfig, mIsUserSetBrightness);
+ mIsDefaultBrightnessConfig, mIsUserSetBrightness, mColorValueBuckets,
+ mColorSampleDuration);
}
}
}
diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl
index 5dd869f..ee6744b 100644
--- a/core/java/android/permission/IPermissionController.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -32,8 +32,8 @@
void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe);
void getAppPermissions(String packageName, in RemoteCallback callback);
void revokeRuntimePermission(String packageName, String permissionName);
- void countPermissionApps(in List<String> permissionNames, boolean countOnlyGranted,
- boolean countSystem, in RemoteCallback callback);
+ void countPermissionApps(in List<String> permissionNames, int flags,
+ in RemoteCallback callback);
void getPermissionUsages(boolean countSystem, long numMillis, in RemoteCallback callback);
void isApplicationQualifiedForRole(String roleName, String packageName,
in RemoteCallback callback);
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index b59d0c7..850d020 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -20,6 +20,7 @@
import static com.android.internal.util.Preconditions.checkArgumentNonnegative;
import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull;
+import static com.android.internal.util.Preconditions.checkFlagsArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkStringNotEmpty;
@@ -113,6 +114,20 @@
*/
public static final int REASON_INSTALLER_POLICY_VIOLATION = 2;
+ /** @hide */
+ @IntDef(prefix = { "COUNT_" }, value = {
+ COUNT_ONLY_WHEN_GRANTED,
+ COUNT_WHEN_SYSTEM,
+ }, flag = true)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CountPermissionAppsFlag {}
+
+ /** Count an app only if the permission is granted to the app. */
+ public static final int COUNT_ONLY_WHEN_GRANTED = 1;
+
+ /** Count and app even if it is a system app. */
+ public static final int COUNT_WHEN_SYSTEM = 2;
+
/**
* Callback for delivering the result of {@link #revokeRuntimePermissions}.
*/
@@ -162,7 +177,7 @@
*/
public interface OnCountPermissionAppsResultCallback {
/**
- * The result for {@link #countPermissionApps(List, boolean, boolean,
+ * The result for {@link #countPermissionApps(List, int,
* OnCountPermissionAppsResultCallback, Handler)}.
*
* @param numApps The number of apps that have one of the permissions
@@ -302,8 +317,8 @@
* Count how many apps have one of a set of permissions.
*
* @param permissionNames The permissions the app might have
- * @param countOnlyGranted Count an app only if the permission is granted to the app
- * @param countSystem Also count system apps
+ * @param flags Modify which apps to count. By default all non-system apps that request a
+ * permission are counted
* @param callback Callback to receive the result
* @param handler Handler on which to invoke the callback
*
@@ -311,13 +326,14 @@
*/
@RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
public void countPermissionApps(@NonNull List<String> permissionNames,
- boolean countOnlyGranted, boolean countSystem,
+ @CountPermissionAppsFlag int flags,
@NonNull OnCountPermissionAppsResultCallback callback, @Nullable Handler handler) {
checkCollectionElementsNotNull(permissionNames, "permissionNames");
+ checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED);
checkNotNull(callback);
sRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(sRemoteService,
- permissionNames, countOnlyGranted, countSystem, callback,
+ permissionNames, flags, callback,
handler == null ? sRemoteService.getHandler() : handler));
}
@@ -731,20 +747,17 @@
AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> {
private final @NonNull List<String> mPermissionNames;
private final @NonNull OnCountPermissionAppsResultCallback mCallback;
- private final boolean mCountOnlyGranted;
- private final boolean mCountSystem;
+ private final @CountPermissionAppsFlag int mFlags;
private final @NonNull RemoteCallback mRemoteCallback;
private PendingCountPermissionAppsRequest(@NonNull RemoteService service,
- @NonNull List<String> permissionNames, boolean countOnlyGranted,
- boolean countSystem, @NonNull OnCountPermissionAppsResultCallback callback,
- @NonNull Handler handler) {
+ @NonNull List<String> permissionNames, @CountPermissionAppsFlag int flags,
+ @NonNull OnCountPermissionAppsResultCallback callback, @NonNull Handler handler) {
super(service);
mPermissionNames = permissionNames;
- mCountOnlyGranted = countOnlyGranted;
- mCountSystem = countSystem;
+ mFlags = flags;
mCallback = callback;
mRemoteCallback = new RemoteCallback(result -> {
@@ -770,7 +783,7 @@
public void run() {
try {
getService().getServiceInterface().countPermissionApps(mPermissionNames,
- mCountOnlyGranted, mCountSystem, mRemoteCallback);
+ mFlags, mRemoteCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error counting permission apps", e);
}
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 9a58b97..70404c3 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -16,9 +16,13 @@
package android.permission;
+import static android.permission.PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED;
+import static android.permission.PermissionControllerManager.COUNT_WHEN_SYSTEM;
+
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkArgumentNonnegative;
import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull;
+import static com.android.internal.util.Preconditions.checkFlagsArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkStringNotEmpty;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
@@ -37,6 +41,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.UserHandle;
+import android.permission.PermissionControllerManager.CountPermissionAppsFlag;
import android.util.ArrayMap;
import android.util.Log;
@@ -121,13 +126,13 @@
* Count how many apps have one of a set of permissions.
*
* @param permissionNames The permissions the app might have
- * @param countOnlyGranted Count an app only if the permission is granted to the app
- * @param countSystem Also count system apps
+ * @param flags Modify which apps to count. By default all non-system apps that request a
+ * permission are counted
*
* @return the number of apps that have one of the permissions
*/
public abstract int onCountPermissionApps(@NonNull List<String> permissionNames,
- boolean countOnlyGranted, boolean countSystem);
+ @CountPermissionAppsFlag int flags);
/**
* Count how many apps have used permissions.
@@ -226,17 +231,18 @@
}
@Override
- public void countPermissionApps(List<String> permissionNames, boolean countOnlyGranted,
- boolean countSystem, RemoteCallback callback) {
+ public void countPermissionApps(List<String> permissionNames, int flags,
+ RemoteCallback callback) {
checkCollectionElementsNotNull(permissionNames, "permissionNames");
+ checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED);
checkNotNull(callback, "callback");
enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
mHandler.sendMessage(
obtainMessage(PermissionControllerService::countPermissionApps,
- PermissionControllerService.this, permissionNames, countOnlyGranted,
- countSystem, callback));
+ PermissionControllerService.this, permissionNames, flags,
+ callback));
}
@Override
@@ -311,8 +317,8 @@
}
private void countPermissionApps(@NonNull List<String> permissionNames,
- boolean countOnlyGranted, boolean countSystem, @NonNull RemoteCallback callback) {
- int numApps = onCountPermissionApps(permissionNames, countOnlyGranted, countSystem);
+ @CountPermissionAppsFlag int flags, @NonNull RemoteCallback callback) {
+ int numApps = onCountPermissionApps(permissionNames, flags);
Bundle result = new Bundle();
result.putInt(PermissionControllerManager.KEY_RESULT, numApps);
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index e76e096..ea2a25d 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -348,7 +348,7 @@
*/
public final void setVoiceState(int state) {
try {
- mSystemService.setVoiceState(state);
+ mSystemService.setVoiceState(mInterface, state);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -359,7 +359,7 @@
*/
public final void setTranscription(@NonNull String transcription) {
try {
- mSystemService.setTranscription(transcription);
+ mSystemService.setTranscription(mInterface, transcription);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -372,7 +372,7 @@
*/
public final void clearTranscription(boolean immediate) {
try {
- mSystemService.clearTranscription(immediate);
+ mSystemService.clearTranscription(mInterface, immediate);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index e9d72a2..bb9bd52 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -6021,6 +6021,9 @@
}
updateSelection(event);
+ if (mTextView.hasSelection() && mEndHandle != null) {
+ mEndHandle.updateMagnifier(event);
+ }
break;
case MotionEvent.ACTION_UP:
@@ -6028,6 +6031,9 @@
break;
}
updateSelection(event);
+ if (mEndHandle != null) {
+ mEndHandle.dismissMagnifier();
+ }
// No longer dragging to select text, let the parent intercept events.
mTextView.getParent().requestDisallowInterceptTouchEvent(false);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index b85488f..8dde44e 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -155,15 +155,15 @@
/**
* Sets the transcribed voice to the given string.
*/
- void setTranscription(String transcription);
+ void setTranscription(IVoiceInteractionService service, String transcription);
/**
* Indicates that the transcription session is finished.
*/
- void clearTranscription(boolean immediate);
+ void clearTranscription(IVoiceInteractionService service, boolean immediate);
/**
* Sets the voice state indication based upon the given value.
*/
- void setVoiceState(int state);
+ void setVoiceState(IVoiceInteractionService service, int state);
}
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index 96d6eee..dde757b 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -90,6 +90,9 @@
public static final int RGBA_F16 = 0x16;
public static final int RGBA_1010102 = 0x2B;
+ /** @hide */
+ public static final int HSV_888 = 0x37;
+
/**
* @deprecated use {@link android.graphics.ImageFormat#JPEG
* ImageFormat.JPEG} instead.
@@ -109,6 +112,7 @@
info.bytesPerPixel = 4;
break;
case RGB_888:
+ case HSV_888:
info.bitsPerPixel = 24;
info.bytesPerPixel = 3;
break;
@@ -227,6 +231,8 @@
return "RGBA_F16";
case RGBA_1010102:
return "RGBA_1010102";
+ case HSV_888:
+ return "HSV_888";
case JPEG:
return "JPEG";
default:
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
index 1cd3509..fa1426e 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
@@ -52,6 +52,10 @@
private val MAX_ITEMS = context.resources.getInteger(R.integer.ongoing_appops_dialog_max_apps)
private val iconFactory = IconDrawableFactory.newInstance(context, true)
private var dismissDialog: (() -> Unit)? = null
+ private val appsAndTypes = dialogBuilder.appsAndTypes
+ .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
+ { it.second.min() },
+ { it.first }))
init {
val a = context.theme.obtainStyledAttributes(
@@ -90,10 +94,10 @@
title.setText(dialogBuilder.getDialogTitle())
- val numItems = dialogBuilder.appsAndTypes.size
+ val numItems = appsAndTypes.size
for (i in 0..(numItems - 1)) {
if (i >= MAX_ITEMS) break
- val item = dialogBuilder.appsAndTypes[i]
+ val item = appsAndTypes[i]
addAppItem(appsList, item.first, item.second, dialogBuilder.types.size > 1)
}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
index 2894621..9c1076a 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
@@ -30,8 +30,7 @@
appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType })
.toList()
.sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
- { it.second.min() }, // Sort by "smallest" AppOpp (Location is largest)
- { it.first })) // Sort alphabetically bt App Name
+ { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest)
types = itemsList.map { it.privacyType }.distinct().sorted()
val singleApp = appsAndTypes.size == 1
app = if (singleApp) appsAndTypes[0].first else null
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
index dbe87d1..f7ca51d 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
@@ -44,17 +44,22 @@
return applicationName.compareTo(other.applicationName)
}
- var icon: Drawable = context.getDrawable(android.R.drawable.sym_def_app_icon)
- var applicationName: String
-
- init {
+ private val applicationInfo: ApplicationInfo? by lazy {
try {
- val app: ApplicationInfo = context.packageManager
- .getApplicationInfo(packageName, 0)
- icon = context.packageManager.getApplicationIcon(app)
- applicationName = context.packageManager.getApplicationLabel(app) as String
- } catch (e: PackageManager.NameNotFoundException) {
- applicationName = packageName
+ context.packageManager.getApplicationInfo(packageName, 0)
+ } catch (_: PackageManager.NameNotFoundException) {
+ null
}
}
+ val icon: Drawable by lazy {
+ applicationInfo?.let {
+ context.packageManager.getApplicationIcon(it)
+ } ?: context.getDrawable(android.R.drawable.sym_def_app_icon)
+ }
+
+ val applicationName: String by lazy {
+ applicationInfo?.let {
+ context.packageManager.getApplicationLabel(it) as String
+ } ?: packageName
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
index f163b88..b6e0d90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
@@ -37,7 +37,7 @@
"Bar", TEST_UID, context))
val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication(
"Bar", TEST_UID, context))
- val foo0 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
+ val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication(
"Foo", TEST_UID, context))
val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
"Baz", TEST_UID, context))
@@ -50,10 +50,11 @@
assertEquals(3, list.size)
val appsList = list.map { it.first }
val typesList = list.map { it.second }
+ // List is sorted by number of types and then by types
assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName })
assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0])
assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1])
- assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[2])
+ assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2])
}
@Test
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 019d726..727cf0e 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -27,12 +27,17 @@
import android.content.IntentFilter;
import android.content.pm.ParceledListSlice;
import android.database.ContentObserver;
+import android.graphics.PixelFormat;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayedContentSample;
+import android.hardware.display.DisplayedContentSamplingAttributes;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Environment;
@@ -48,6 +53,7 @@
import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
+import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -55,6 +61,7 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.RingBuffer;
+import com.android.server.LocalServices;
import libcore.io.IoUtils;
@@ -111,6 +118,8 @@
private static final String ATTR_DEFAULT_CONFIG = "defaultConfig";
private static final String ATTR_POWER_SAVE = "powerSaveFactor";
private static final String ATTR_USER_POINT = "userPoint";
+ private static final String ATTR_COLOR_SAMPLE_DURATION = "colorSampleDuration";
+ private static final String ATTR_COLOR_VALUE_BUCKETS = "colorValueBuckets";
private static final int MSG_BACKGROUND_START = 0;
private static final int MSG_BRIGHTNESS_CHANGED = 1;
@@ -119,6 +128,10 @@
private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+ private static final long COLOR_SAMPLE_DURATION = TimeUnit.SECONDS.toSeconds(10);
+ // Sample chanel 2 of HSV which is the Value component.
+ private static final int COLOR_SAMPLE_COMPONENT_MASK = 0x1 << 2;
+
// Lock held while accessing mEvents, is held while writing events to flash.
private final Object mEventsLock = new Object();
@GuardedBy("mEventsLock")
@@ -136,12 +149,16 @@
private final ContentResolver mContentResolver;
private final Handler mBgHandler;
- // mBroadcastReceiver, mSensorListener, mSettingsObserver and mSensorRegistered
- // should only be used on the mBgHandler thread.
+ // These members should only be accessed on the mBgHandler thread.
private BroadcastReceiver mBroadcastReceiver;
private SensorListener mSensorListener;
private SettingsObserver mSettingsObserver;
+ private DisplayListener mDisplayListener;
private boolean mSensorRegistered;
+ private boolean mColorSamplingEnabled;
+ private int mNoFramesToSample;
+ private float mFrameRate;
+ // End of block of members that should only be accessed on the mBgHandler thread.
private @UserIdInt int mCurrentUserId = UserHandle.USER_NULL;
@@ -208,6 +225,7 @@
mLastBrightness = initialBrightness;
mStarted = true;
}
+ enableColorSampling();
}
/** Stop listening for events */
@@ -226,6 +244,7 @@
synchronized (mDataCollectionLock) {
mStarted = false;
}
+ disableColorSampling();
}
public void onSwitchUser(@UserIdInt int newUserId) {
@@ -367,6 +386,17 @@
builder.setColorTemperature(mInjector.getColorTemperature(mContext,
UserHandle.USER_CURRENT));
+ if (mColorSamplingEnabled) {
+ DisplayedContentSample sample = mInjector.sampleColor(mNoFramesToSample);
+ if (sample != null && sample.getSampleComponent(
+ DisplayedContentSample.ColorComponent.CHANNEL2) != null) {
+ float numMillis = (sample.getNumFrames() / mFrameRate) * 1000.0f;
+ builder.setColorValues(
+ sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL2),
+ Math.round(numMillis));
+ }
+ }
+
BrightnessChangeEvent event = builder.build();
if (DEBUG) {
Slog.d(TAG, "Event " + event.brightness + " " + event.packageName);
@@ -541,6 +571,19 @@
}
out.attribute(null, ATTR_LUX, luxValues.toString());
out.attribute(null, ATTR_LUX_TIMESTAMPS, luxTimestamps.toString());
+ if (toWrite[i].colorValueBuckets != null
+ && toWrite[i].colorValueBuckets.length > 0) {
+ out.attribute(null, ATTR_COLOR_SAMPLE_DURATION,
+ Long.toString(toWrite[i].colorSampleDuration));
+ StringBuilder buckets = new StringBuilder();
+ for (int j = 0; j < toWrite[i].colorValueBuckets.length; ++j) {
+ if (j > 0) {
+ buckets.append(',');
+ }
+ buckets.append(Long.toString(toWrite[i].colorValueBuckets[j]));
+ }
+ out.attribute(null, ATTR_COLOR_VALUE_BUCKETS, buckets.toString());
+ }
out.endTag(null, TAG_EVENT);
}
}
@@ -628,6 +671,20 @@
builder.setUserBrightnessPoint(Boolean.parseBoolean(userPoint));
}
+ String colorSampleDurationString =
+ parser.getAttributeValue(null, ATTR_COLOR_SAMPLE_DURATION);
+ String colorValueBucketsString =
+ parser.getAttributeValue(null, ATTR_COLOR_VALUE_BUCKETS);
+ if (colorSampleDurationString != null && colorValueBucketsString != null) {
+ long colorSampleDuration = Long.parseLong(colorSampleDurationString);
+ String[] buckets = colorValueBucketsString.split(",");
+ long[] bucketValues = new long[buckets.length];
+ for (int i = 0; i < bucketValues.length; ++i) {
+ bucketValues[i] = Long.parseLong(buckets[i]);
+ }
+ builder.setColorValues(bucketValues, colorSampleDuration);
+ }
+
BrightnessChangeEvent event = builder.build();
if (DEBUG) {
Slog.i(TAG, "Read event " + event.brightness
@@ -695,6 +752,73 @@
private void dumpLocal(PrintWriter pw) {
pw.println(" mSensorRegistered=" + mSensorRegistered);
+ pw.println(" mColorSamplingEnabled=" + mColorSamplingEnabled);
+ pw.println(" mNoFramesToSample=" + mNoFramesToSample);
+ pw.println(" mFrameRate=" + mFrameRate);
+ }
+
+ private void enableColorSampling() {
+ if (!mInjector.isBrightnessModeAutomatic(mContentResolver)
+ || !mInjector.isInteractive(mContext)
+ || mColorSamplingEnabled) {
+ return;
+ }
+
+ mFrameRate = mInjector.getFrameRate(mContext);
+ if (mFrameRate <= 0) {
+ Slog.wtf(TAG, "Default display has a zero or negative framerate.");
+ return;
+ }
+ mNoFramesToSample = (int) (mFrameRate * COLOR_SAMPLE_DURATION);
+
+ DisplayedContentSamplingAttributes attributes = mInjector.getSamplingAttributes();
+ if (DEBUG && attributes != null) {
+ Slog.d(TAG, "Color sampling"
+ + " mask=0x" + Integer.toHexString(attributes.getComponentMask())
+ + " dataSpace=0x" + Integer.toHexString(attributes.getDataspace())
+ + " pixelFormat=0x" + Integer.toHexString(attributes.getPixelFormat()));
+ }
+ // Do we support sampling the Value component of HSV
+ if (attributes != null && attributes.getPixelFormat() == PixelFormat.HSV_888
+ && (attributes.getComponentMask() & COLOR_SAMPLE_COMPONENT_MASK) != 0) {
+
+ mColorSamplingEnabled = mInjector.enableColorSampling(/* enable= */true,
+ mNoFramesToSample);
+ if (DEBUG) {
+ Slog.i(TAG, "turning on color sampling for "
+ + mNoFramesToSample + " frames, success=" + mColorSamplingEnabled);
+ }
+ }
+ if (mColorSamplingEnabled && mDisplayListener == null) {
+ mDisplayListener = new DisplayListener();
+ mInjector.registerDisplayListener(mContext, mDisplayListener, mBgHandler);
+ }
+ }
+
+ private void disableColorSampling() {
+ if (!mColorSamplingEnabled) {
+ return;
+ }
+ mInjector.enableColorSampling(/* enable= */ false, /* noFrames= */ 0);
+ mColorSamplingEnabled = false;
+ if (mDisplayListener != null) {
+ mInjector.unRegisterDisplayListener(mContext, mDisplayListener);
+ mDisplayListener = null;
+ }
+ if (DEBUG) {
+ Slog.i(TAG, "turning off color sampling");
+ }
+ }
+
+ private void updateColorSampling() {
+ if (!mColorSamplingEnabled) {
+ return;
+ }
+ float frameRate = mInjector.getFrameRate(mContext);
+ if (frameRate != mFrameRate) {
+ disableColorSampling();
+ enableColorSampling();
+ }
}
public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(int userId) {
@@ -768,6 +892,26 @@
}
}
+ private final class DisplayListener implements DisplayManager.DisplayListener {
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ // Ignore
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ // Ignore
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ updateColorSampling();
+ }
+ }
+ }
+
private final class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
@@ -828,9 +972,11 @@
break;
case MSG_START_SENSOR_LISTENER:
startSensorListener();
+ enableColorSampling();
break;
case MSG_STOP_SENSOR_LISTENER:
stopSensorListener();
+ disableColorSampling();
break;
}
}
@@ -957,5 +1103,44 @@
public boolean isNightModeActive(Context context, int userId) {
return new ColorDisplayController(context, userId).isActivated();
}
+
+ public DisplayedContentSample sampleColor(int noFramesToSample) {
+ final DisplayManagerInternal displayManagerInternal =
+ LocalServices.getService(DisplayManagerInternal.class);
+ return displayManagerInternal.getDisplayedContentSample(
+ Display.DEFAULT_DISPLAY, noFramesToSample, 0);
+ }
+
+ public float getFrameRate(Context context) {
+ final DisplayManager displayManager = context.getSystemService(DisplayManager.class);
+ Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ return display.getRefreshRate();
+ }
+
+ public DisplayedContentSamplingAttributes getSamplingAttributes() {
+ final DisplayManagerInternal displayManagerInternal =
+ LocalServices.getService(DisplayManagerInternal.class);
+ return displayManagerInternal.getDisplayedContentSamplingAttributes(
+ Display.DEFAULT_DISPLAY);
+ }
+
+ public boolean enableColorSampling(boolean enable, int noFrames) {
+ final DisplayManagerInternal displayManagerInternal =
+ LocalServices.getService(DisplayManagerInternal.class);
+ return displayManagerInternal.setDisplayedContentSamplingEnabled(
+ Display.DEFAULT_DISPLAY, enable, COLOR_SAMPLE_COMPONENT_MASK, noFrames);
+ }
+
+ public void registerDisplayListener(Context context,
+ DisplayManager.DisplayListener listener, Handler handler) {
+ final DisplayManager displayManager = context.getSystemService(DisplayManager.class);
+ displayManager.registerDisplayListener(listener, handler);
+ }
+
+ public void unRegisterDisplayListener(Context context,
+ DisplayManager.DisplayListener listener) {
+ final DisplayManager displayManager = context.getSystemService(DisplayManager.class);
+ displayManager.unregisterDisplayListener(listener);
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index ebb61f2..29ba166 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2852,10 +2852,13 @@
// to check super here.
final boolean reallyAnimating = super.isSelfAnimating();
final boolean show = !isHidden() || reallyAnimating;
- if (show && !mLastSurfaceShowing) {
- mPendingTransaction.show(mSurfaceControl);
- } else if (!show && mLastSurfaceShowing) {
- mPendingTransaction.hide(mSurfaceControl);
+
+ if (mSurfaceControl != null) {
+ if (show && !mLastSurfaceShowing) {
+ mPendingTransaction.show(mSurfaceControl);
+ } else if (!show && mLastSurfaceShowing) {
+ mPendingTransaction.hide(mSurfaceControl);
+ }
}
if (mThumbnail != null) {
mThumbnail.setShowing(mPendingTransaction, show);
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 79a654b..e3b1245 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -37,6 +37,9 @@
import android.hardware.SensorEventListener;
import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayedContentSample;
+import android.hardware.display.DisplayedContentSamplingAttributes;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.HandlerThread;
@@ -47,6 +50,7 @@
import android.os.UserManager;
import android.provider.Settings;
import android.util.AtomicFile;
+import android.view.Display;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -116,28 +120,81 @@
assertTrue(mInjector.mIdleScheduled);
mInjector.sendScreenChange(/*screen on */ true);
assertNotNull(mInjector.mSensorListener);
+ assertTrue(mInjector.mColorSamplingEnabled);
mInjector.sendScreenChange(/*screen on */ false);
assertNull(mInjector.mSensorListener);
+ assertFalse(mInjector.mColorSamplingEnabled);
// Turn screen on while brightness mode is manual
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ false);
mInjector.sendScreenChange(/*screen on */ true);
assertNull(mInjector.mSensorListener);
+ assertFalse(mInjector.mColorSamplingEnabled);
// Set brightness mode to automatic while screen is off.
mInjector.sendScreenChange(/*screen on */ false);
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ true);
assertNull(mInjector.mSensorListener);
+ assertFalse(mInjector.mColorSamplingEnabled);
// Turn on screen while brightness mode is automatic.
mInjector.sendScreenChange(/*screen on */ true);
assertNotNull(mInjector.mSensorListener);
+ assertTrue(mInjector.mColorSamplingEnabled);
mTracker.stop();
assertNull(mInjector.mSensorListener);
assertNull(mInjector.mBroadcastReceiver);
assertFalse(mInjector.mIdleScheduled);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ }
+
+ @Test
+ public void testNoColorSampling_WrongPixelFormat() {
+ mInjector.mDefaultSamplingAttributes =
+ new DisplayedContentSamplingAttributes(
+ 0x23,
+ mInjector.mDefaultSamplingAttributes.getDataspace(),
+ mInjector.mDefaultSamplingAttributes.getComponentMask());
+ startTracker(mTracker);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
+ }
+
+ @Test
+ public void testNoColorSampling_MissingComponent() {
+ mInjector.mDefaultSamplingAttributes =
+ new DisplayedContentSamplingAttributes(
+ mInjector.mDefaultSamplingAttributes.getPixelFormat(),
+ mInjector.mDefaultSamplingAttributes.getDataspace(),
+ 0x2);
+ startTracker(mTracker);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
+ }
+
+ @Test
+ public void testNoColorSampling_NoSupport() {
+ mInjector.mDefaultSamplingAttributes = null;
+ startTracker(mTracker);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
+ }
+
+ @Test
+ public void testColorSampling_FrameRateChange() {
+ startTracker(mTracker);
+ assertTrue(mInjector.mColorSamplingEnabled);
+ assertNotNull(mInjector.mDisplayListener);
+ int noFramesSampled = mInjector.mNoColorSamplingFrames;
+ mInjector.mFrameRate = 120.0f;
+ // Wrong display
+ mInjector.mDisplayListener.onDisplayChanged(Display.DEFAULT_DISPLAY + 10);
+ assertEquals(noFramesSampled, mInjector.mNoColorSamplingFrames);
+ // Correct display
+ mInjector.mDisplayListener.onDisplayChanged(Display.DEFAULT_DISPLAY);
+ assertEquals(noFramesSampled * 2, mInjector.mNoColorSamplingFrames);
}
@Test
@@ -149,26 +206,41 @@
assertNotNull(mInjector.mBroadcastReceiver);
assertNotNull(mInjector.mContentObserver);
assertTrue(mInjector.mIdleScheduled);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true);
assertNotNull(mInjector.mSensorListener);
+ assertTrue(mInjector.mColorSamplingEnabled);
+ assertNotNull(mInjector.mDisplayListener);
SensorEventListener listener = mInjector.mSensorListener;
+ DisplayManager.DisplayListener displayListener = mInjector.mDisplayListener;
mInjector.mSensorListener = null;
+ mInjector.mColorSamplingEnabled = false;
+ mInjector.mDisplayListener = null;
// Duplicate notification
mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true);
// Sensor shouldn't have been registered as it was already registered.
assertNull(mInjector.mSensorListener);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
mInjector.mSensorListener = listener;
+ mInjector.mDisplayListener = displayListener;
+ mInjector.mColorSamplingEnabled = true;
mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ false);
assertNull(mInjector.mSensorListener);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
mTracker.stop();
assertNull(mInjector.mSensorListener);
assertNull(mInjector.mBroadcastReceiver);
assertNull(mInjector.mContentObserver);
assertFalse(mInjector.mIdleScheduled);
+ assertFalse(mInjector.mColorSamplingEnabled);
+ assertNull(mInjector.mDisplayListener);
}
@Test
@@ -229,6 +301,8 @@
assertEquals(3333, event.colorTemperature);
assertEquals("a.package", event.packageName);
assertEquals(0, event.userId);
+ assertArrayEquals(new long[] {1, 10, 100, 1000, 300, 30, 10, 1}, event.colorValueBuckets);
+ assertEquals(10000, event.colorSampleDuration);
assertEquals(1, eventsNoPackage.size());
assertNull(eventsNoPackage.get(0).packageName);
@@ -342,7 +416,8 @@
+ "lastNits=\"32\" "
+ "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\"\n"
+ "lux=\"132.2,131.1\" luxTimestamps=\""
- + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
+ + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\""
+ + "colorSampleDuration=\"3456\" colorValueBuckets=\"123,598,23,19\"/>"
// Event that is too old so shouldn't show up.
+ "<event nits=\"142\" timestamp=\""
+ Long.toString(twoMonthsAgo) + "\" packageName=\""
@@ -368,6 +443,7 @@
assertTrue(event.isDefaultBrightnessConfig);
assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA);
assertTrue(event.isUserSetBrightness);
+ assertNull(event.colorValueBuckets);
events = tracker.getEvents(1, true).getList();
assertEquals(1, events.size());
@@ -386,6 +462,8 @@
assertFalse(event.isDefaultBrightnessConfig);
assertEquals(1.0, event.powerBrightnessFactor, FLOAT_DELTA);
assertFalse(event.isUserSetBrightness);
+ assertEquals(3456L, event.colorSampleDuration);
+ assertArrayEquals(new long[] {123L, 598L, 23L, 19L}, event.colorValueBuckets);
// Pretend user 1 is a profile of user 0.
mInjector.mProfiles = new int[]{0, 1};
@@ -481,6 +559,8 @@
assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA);
assertTrue(event.isUserSetBrightness);
assertFalse(event.isDefaultBrightnessConfig);
+ assertArrayEquals(new long[] {1, 10, 100, 1000, 300, 30, 10, 1}, event.colorValueBuckets);
+ assertEquals(10000, event.colorSampleDuration);
}
@Test
@@ -546,6 +626,7 @@
builder.setNightMode(false);
builder.setColorTemperature(345);
builder.setLastBrightness(50f);
+ builder.setColorValues(new long[] {23, 34, 45}, 1000L);
BrightnessChangeEvent event = builder.build();
event.writeToParcel(parcel, 0);
@@ -568,6 +649,8 @@
assertEquals(event.nightMode, event2.nightMode);
assertEquals(event.colorTemperature, event2.colorTemperature);
assertEquals(event.lastBrightness, event2.lastBrightness, FLOAT_DELTA);
+ assertArrayEquals(event.colorValueBuckets, event2.colorValueBuckets);
+ assertEquals(event.colorSampleDuration, event2.colorSampleDuration);
parcel = Parcel.obtain();
builder.setBatteryLevel(Float.NaN);
@@ -714,6 +797,7 @@
private class TestInjector extends BrightnessTracker.Injector {
SensorEventListener mSensorListener;
BroadcastReceiver mBroadcastReceiver;
+ DisplayManager.DisplayListener mDisplayListener;
Map<String, Integer> mSecureIntSettings = new HashMap<>();
long mCurrentTimeMillis = System.currentTimeMillis();
long mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
@@ -723,6 +807,12 @@
int[] mProfiles;
ContentObserver mContentObserver;
boolean mIsBrightnessModeAutomatic = true;
+ boolean mColorSamplingEnabled = false;
+ DisplayedContentSamplingAttributes mDefaultSamplingAttributes =
+ new DisplayedContentSamplingAttributes(0x37, 0, 0x4);
+ float mFrameRate = 60.0f;
+ int mNoColorSamplingFrames;
+
public TestInjector(Handler handler) {
mHandler = handler;
@@ -882,5 +972,43 @@
return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
0) == 1;
}
+
+ @Override
+ public DisplayedContentSample sampleColor(int noFramesToSample) {
+ return new DisplayedContentSample(600L,
+ null,
+ null,
+ new long[] {1, 10, 100, 1000, 300, 30, 10, 1},
+ null);
+ }
+
+ @Override
+ public float getFrameRate(Context context) {
+ return mFrameRate;
+ }
+
+ @Override
+ public DisplayedContentSamplingAttributes getSamplingAttributes() {
+ return mDefaultSamplingAttributes;
+ }
+
+ @Override
+ public boolean enableColorSampling(boolean enable, int noFrames) {
+ mColorSamplingEnabled = enable;
+ mNoColorSamplingFrames = noFrames;
+ return true;
+ }
+
+ @Override
+ public void registerDisplayListener(Context context,
+ DisplayManager.DisplayListener listener, Handler handler) {
+ mDisplayListener = listener;
+ }
+
+ @Override
+ public void unRegisterDisplayListener(Context context,
+ DisplayManager.DisplayListener listener) {
+ mDisplayListener = null;
+ }
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 718f2d3..7cab432 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -613,11 +613,8 @@
@Override
public void showSession(IVoiceInteractionService service, Bundle args, int flags) {
synchronized (this) {
- if (mImpl == null || mImpl.mService == null
- || service.asBinder() != mImpl.mService.asBinder()) {
- throw new SecurityException(
- "Caller is not the current voice interaction service");
- }
+ enforceIsCurrentVoiceInteractionService(service);
+
final long caller = Binder.clearCallingIdentity();
try {
mImpl.showSessionLocked(args, flags, null, null);
@@ -896,11 +893,7 @@
public boolean isEnrolledForKeyphrase(IVoiceInteractionService service, int keyphraseId,
String bcp47Locale) {
synchronized (this) {
- if (mImpl == null || mImpl.mService == null
- || service.asBinder() != mImpl.mService.asBinder()) {
- throw new SecurityException(
- "Caller is not the current voice interaction service");
- }
+ enforceIsCurrentVoiceInteractionService(service);
}
if (bcp47Locale == null) {
@@ -922,11 +915,7 @@
public ModuleProperties getDspModuleProperties(IVoiceInteractionService service) {
// Allow the call if this is the current voice interaction service.
synchronized (this) {
- if (mImpl == null || mImpl.mService == null
- || service == null || service.asBinder() != mImpl.mService.asBinder()) {
- throw new SecurityException(
- "Caller is not the current voice interaction service");
- }
+ enforceIsCurrentVoiceInteractionService(service);
final long caller = Binder.clearCallingIdentity();
try {
@@ -943,11 +932,7 @@
RecognitionConfig recognitionConfig) {
// Allow the call if this is the current voice interaction service.
synchronized (this) {
- if (mImpl == null || mImpl.mService == null
- || service == null || service.asBinder() != mImpl.mService.asBinder()) {
- throw new SecurityException(
- "Caller is not the current voice interaction service");
- }
+ enforceIsCurrentVoiceInteractionService(service);
if (callback == null || recognitionConfig == null || bcp47Locale == null) {
throw new IllegalArgumentException("Illegal argument(s) in startRecognition");
@@ -983,11 +968,7 @@
IRecognitionStatusCallback callback) {
// Allow the call if this is the current voice interaction service.
synchronized (this) {
- if (mImpl == null || mImpl.mService == null
- || service == null || service.asBinder() != mImpl.mService.asBinder()) {
- throw new SecurityException(
- "Caller is not the current voice interaction service");
- }
+ enforceIsCurrentVoiceInteractionService(service);
}
final long caller = Binder.clearCallingIdentity();
@@ -1212,8 +1193,10 @@
}
@Override
- public void setTranscription(String transcription) {
+ public void setTranscription(IVoiceInteractionService service, String transcription) {
synchronized (this) {
+ enforceIsCurrentVoiceInteractionService(service);
+
final int size = mVoiceInteractionSessionListeners.beginBroadcast();
for (int i = 0; i < size; ++i) {
final IVoiceInteractionSessionListener listener =
@@ -1229,8 +1212,10 @@
}
@Override
- public void clearTranscription(boolean immediate) {
+ public void clearTranscription(IVoiceInteractionService service, boolean immediate) {
synchronized (this) {
+ enforceIsCurrentVoiceInteractionService(service);
+
final int size = mVoiceInteractionSessionListeners.beginBroadcast();
for (int i = 0; i < size; ++i) {
final IVoiceInteractionSessionListener listener =
@@ -1246,8 +1231,10 @@
}
@Override
- public void setVoiceState(int state) {
+ public void setVoiceState(IVoiceInteractionService service, int state) {
synchronized (this) {
+ enforceIsCurrentVoiceInteractionService(service);
+
final int size = mVoiceInteractionSessionListeners.beginBroadcast();
for (int i = 0; i < size; ++i) {
final IVoiceInteractionSessionListener listener =
@@ -1269,6 +1256,14 @@
}
}
+ private void enforceIsCurrentVoiceInteractionService(IVoiceInteractionService service) {
+ if (mImpl == null || mImpl.mService == null
+ || service.asBinder() != mImpl.mService.asBinder()) {
+ throw new
+ SecurityException("Caller is not the current voice interaction service");
+ }
+ }
+
private void setImplLocked(VoiceInteractionManagerServiceImpl impl) {
mImpl = impl;
mAtmInternal.notifyActiveVoiceInteractionServiceChanged(
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index ef78ea5..57ae5d3 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -29,11 +29,15 @@
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.Slog;
import com.android.internal.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* Class for managing the default dialer application that will receive incoming calls, and be
@@ -72,19 +76,15 @@
int user) {
long identity = Binder.clearCallingIdentity();
try {
+ RoleManagerCallback.Future cb = new RoleManagerCallback.Future();
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
RoleManager.ROLE_DIALER, packageName, UserHandle.of(user),
- AsyncTask.THREAD_POOL_EXECUTOR, new RoleManagerCallback() {
- @Override
- public void onSuccess() {}
-
- @Override
- public void onFailure() {
- Log.w(TAG, "Failed to set default dialer to %s for user %s",
- packageName, user);
- }
- });
+ AsyncTask.THREAD_POOL_EXECUTOR, cb);
+ cb.get(5, TimeUnit.SECONDS);
return true;
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ Slog.e(TAG, "Failed to set default dialer to " + packageName + " for user " + user, e);
+ return false;
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a1fb090..7c3bde4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -354,27 +354,26 @@
* Returns 3 for Tri standby mode.(Tri SIM functionality)
*/
public int getPhoneCount() {
- int phoneCount = 0;
-
- // check for voice and data support, 0 if not supported
- if (!isVoiceCapable() && !isSmsCapable()) {
- ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- if (cm != null) {
- if (!cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
- return phoneCount;
+ int phoneCount = 1;
+ switch (getMultiSimConfiguration()) {
+ case UNKNOWN:
+ ConnectivityManager cm = mContext == null ? null : (ConnectivityManager) mContext
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ // check for voice and data support, 0 if not supported
+ if (!isVoiceCapable() && !isSmsCapable() && cm != null
+ && !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
+ phoneCount = 0;
+ } else {
+ phoneCount = 1;
}
- }
- }
-
- phoneCount = 1;
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null) {
- phoneCount = telephony.getNumOfActiveSims();
- }
- } catch (RemoteException ex) {
- Rlog.e(TAG, "getNumOfActiveSims RemoteException", ex);
+ break;
+ case DSDS:
+ case DSDA:
+ phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
+ break;
+ case TSTS:
+ phoneCount = PhoneConstants.MAX_PHONE_COUNT_TRI_SIM;
+ break;
}
return phoneCount;
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 762d886..bc43fea 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1843,11 +1843,6 @@
* @hide
*/
void switchMultiSimConfig(int numOfSims);
- /**
- * Get how many modems have been activated on the phone
- * @hide
- */
- int getNumOfActiveSims();
/**
* Get if reboot is required upon altering modems configurations