Merge "Make Resources.Theme.rebase() public API"
diff --git a/api/current.txt b/api/current.txt
index ccfd54a..ec2d93e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24852,6 +24852,7 @@
field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
field public static final int STATUS_PENDING = 3; // 0x3
field public static final int STATUS_USABLE = 0; // 0x0
+ field public static final int STATUS_USABLE_IN_FUTURE = 5; // 0x5
}
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -30758,7 +30759,6 @@
method public double getAltitudeUncertainty();
method public java.util.List<android.net.MacAddress> getColocatedBssids();
method public int getDatum();
- method public boolean getDependentStationIndication();
method public int getExpectedToMove();
method public double getFloorNumber();
method public double getHeightAboveFloorMeters();
@@ -30771,7 +30771,6 @@
method @Nullable public String getMapImageMimeType();
method @Nullable public android.net.Uri getMapImageUri();
method public boolean getRegisteredLocationAgreementIndication();
- method public boolean getRegisteredLocationDseIndication();
method public boolean isLciSubelementValid();
method public boolean isZaxisSubelementValid();
method @Nullable public android.location.Address toCivicLocationAddress();
diff --git a/api/system-current.txt b/api/system-current.txt
index 1b9a64a..1fad776 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1461,6 +1461,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.content.om.OverlayInfo> CREATOR;
field public final String category;
field public final String packageName;
+ field public final String targetOverlayableName;
field public final String targetPackageName;
field public final int userId;
}
@@ -6434,7 +6435,7 @@
public abstract class ContentCaptureService extends android.app.Service {
ctor public ContentCaptureService();
- method public final void disableContentCaptureServices();
+ method public final void disableSelf();
method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
method public void onConnected();
diff --git a/api/test-current.txt b/api/test-current.txt
index 856f131..6532cf8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -352,6 +352,10 @@
method public boolean isUiModeLocked();
}
+ public class WallpaperManager {
+ method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName);
+ }
+
public class WindowConfiguration implements java.lang.Comparable<android.app.WindowConfiguration> android.os.Parcelable {
ctor public WindowConfiguration();
method public int compareTo(android.app.WindowConfiguration);
@@ -584,12 +588,14 @@
}
public final class ContentCaptureOptions implements android.os.Parcelable {
+ ctor public ContentCaptureOptions(int);
ctor public ContentCaptureOptions(int, int, int, int, int, @Nullable android.util.ArraySet<android.content.ComponentName>);
method public int describeContents();
method public static android.content.ContentCaptureOptions forWhitelistingItself();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.ContentCaptureOptions> CREATOR;
field public final int idleFlushingFrequencyMs;
+ field public final boolean lite;
field public final int logHistorySize;
field public final int loggingLevel;
field public final int maxBufferSize;
@@ -608,6 +614,7 @@
public abstract class Context {
method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.view.Display getDisplay();
+ method public abstract int getDisplayId();
method public android.os.UserHandle getUser();
method public int getUserId();
method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
@@ -618,6 +625,7 @@
public class ContextWrapper extends android.content.Context {
method public android.view.Display getDisplay();
+ method public int getDisplayId();
}
public class Intent implements java.lang.Cloneable android.os.Parcelable {
@@ -2440,7 +2448,7 @@
public abstract class ContentCaptureService extends android.app.Service {
ctor public ContentCaptureService();
- method public final void disableContentCaptureServices();
+ method public final void disableSelf();
method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
method public void onConnected();
@@ -2648,8 +2656,10 @@
method public void setCdmaSystemAndNetworkId(int, int);
method public void setCellBandwidths(int[]);
method public void setChannelNumber(int);
+ method public void setDataRoamingType(int);
method public void setRilDataRadioTechnology(int);
method public void setRilVoiceRadioTechnology(int);
+ method public void setVoiceRoamingType(int);
}
public class TelephonyManager {
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 24331af..55b1003 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -196,13 +196,7 @@
std::stringstream stream;
for (const auto& overlay : interesting_apks) {
- std::vector<std::string> verify_args = {"--idmap-path", overlay.idmap_path};
- for (const std::string& policy : overlay.policies) {
- verify_args.emplace_back("--policy");
- verify_args.emplace_back(policy);
- }
-
- if (!Verify(std::vector<std::string>(verify_args))) {
+ if (!Verify(std::vector<std::string>({"--idmap-path", overlay.idmap_path}))) {
std::vector<std::string> create_args = {"--target-apk-path", target_apk_path,
"--overlay-apk-path", overlay.apk_path,
"--idmap-path", overlay.idmap_path};
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a929fe0..325a54b 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -25,6 +25,7 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -1666,6 +1667,7 @@
*
* @hide
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
public boolean setWallpaperComponent(ComponentName name) {
diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java
index 6be0bea..1727d34 100644
--- a/core/java/android/content/ContentCaptureOptions.java
+++ b/core/java/android/content/ContentCaptureOptions.java
@@ -72,9 +72,29 @@
@Nullable
public final ArraySet<ComponentName> whitelistedComponents;
+ /**
+ * Used to enable just a small set of APIs so it can used by activities belonging to the
+ * content capture service APK.
+ */
+ public final boolean lite;
+
+ public ContentCaptureOptions(int loggingLevel) {
+ this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0,
+ /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0,
+ /* logHistorySize= */ 0, /* whitelistedComponents= */ null);
+ }
+
public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs,
int textChangeFlushingFrequencyMs, int logHistorySize,
@Nullable ArraySet<ComponentName> whitelistedComponents) {
+ this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs,
+ textChangeFlushingFrequencyMs, logHistorySize, whitelistedComponents);
+ }
+
+ private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize,
+ int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize,
+ @Nullable ArraySet<ComponentName> whitelistedComponents) {
+ this.lite = lite;
this.loggingLevel = loggingLevel;
this.maxBufferSize = maxBufferSize;
this.idleFlushingFrequencyMs = idleFlushingFrequencyMs;
@@ -115,6 +135,9 @@
@Override
public String toString() {
+ if (lite) {
+ return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]";
+ }
return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize="
+ maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs
+ ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs
@@ -125,6 +148,10 @@
/** @hide */
public void dumpShort(@NonNull PrintWriter pw) {
pw.print("logLvl="); pw.print(loggingLevel);
+ if (lite) {
+ pw.print(", lite");
+ return;
+ }
pw.print(", bufferSize="); pw.print(maxBufferSize);
pw.print(", idle="); pw.print(idleFlushingFrequencyMs);
pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs);
@@ -141,7 +168,10 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeBoolean(lite);
parcel.writeInt(loggingLevel);
+ if (lite) return;
+
parcel.writeInt(maxBufferSize);
parcel.writeInt(idleFlushingFrequencyMs);
parcel.writeInt(textChangeFlushingFrequencyMs);
@@ -154,7 +184,11 @@
@Override
public ContentCaptureOptions createFromParcel(Parcel parcel) {
+ final boolean lite = parcel.readBoolean();
final int loggingLevel = parcel.readInt();
+ if (lite) {
+ return new ContentCaptureOptions(loggingLevel);
+ }
final int maxBufferSize = parcel.readInt();
final int idleFlushingFrequencyMs = parcel.readInt();
final int textChangeFlushingFrequencyMs = parcel.readInt();
@@ -171,6 +205,5 @@
public ContentCaptureOptions[] newArray(int size) {
return new ContentCaptureOptions[size];
}
-
};
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5139064..d7a2e1b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5329,6 +5329,7 @@
* @return display ID associated with this {@link Context}.
* @hide
*/
+ @TestApi
public abstract int getDisplayId();
/**
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index 999d986..aabe59d 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -18,12 +18,14 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
/**
* Immutable overlay information about a package. All PackageInfos that
@@ -138,6 +140,14 @@
public final String targetPackageName;
/**
+ * Name of the target overlayable declaration.
+ *
+ * @hide
+ */
+ @SystemApi
+ public final String targetOverlayableName;
+
+ /**
* Category of the overlay package
*
* @hide
@@ -190,16 +200,19 @@
* @hide
*/
public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
- this(source.packageName, source.targetPackageName, source.category, source.baseCodePath,
- state, source.userId, source.priority, source.isStatic);
+ this(source.packageName, source.targetPackageName, source.targetOverlayableName,
+ source.category, source.baseCodePath, state, source.userId, source.priority,
+ source.isStatic);
}
/** @hide */
public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
- @NonNull String category, @NonNull String baseCodePath, int state, int userId,
+ @Nullable String targetOverlayableName, @Nullable String category,
+ @NonNull String baseCodePath, int state, int userId,
int priority, boolean isStatic) {
this.packageName = packageName;
this.targetPackageName = targetPackageName;
+ this.targetOverlayableName = targetOverlayableName;
this.category = category;
this.baseCodePath = baseCodePath;
this.state = state;
@@ -213,6 +226,7 @@
public OverlayInfo(Parcel source) {
packageName = source.readString();
targetPackageName = source.readString();
+ targetOverlayableName = source.readString();
category = source.readString();
baseCodePath = source.readString();
state = source.readInt();
@@ -256,6 +270,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(packageName);
dest.writeString(targetPackageName);
+ dest.writeString(targetOverlayableName);
dest.writeString(category);
dest.writeString(baseCodePath);
dest.writeInt(state);
@@ -335,6 +350,8 @@
result = prime * result + state;
result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode());
+ result = prime * result + ((targetOverlayableName == null) ? 0
+ : targetOverlayableName.hashCode());
result = prime * result + ((category == null) ? 0 : category.hashCode());
result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode());
return result;
@@ -364,7 +381,10 @@
if (!targetPackageName.equals(other.targetPackageName)) {
return false;
}
- if (!category.equals(other.category)) {
+ if (!Objects.equals(targetOverlayableName, other.targetOverlayableName)) {
+ return false;
+ }
+ if (!Objects.equals(category, other.category)) {
return false;
}
if (!baseCodePath.equals(other.baseCodePath)) {
@@ -375,7 +395,9 @@
@Override
public String toString() {
- return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state="
- + state + " (" + stateToString(state) + "), userId=" + userId + " }";
+ return "OverlayInfo { overlay=" + packageName + ", targetPackage=" + targetPackageName
+ + ((targetOverlayableName == null) ? ""
+ : ", targetOverlyabale=" + targetOverlayableName)
+ + ", state=" + state + " (" + stateToString(state) + "), userId=" + userId + " }";
}
}
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 725d601..d6fb28f 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -354,12 +354,12 @@
public String overlayTarget;
/**
- * What overlayable set of elements package, if any, this package will overlay.
+ * The name of the overlayable set of elements package, if any, this package will overlay.
*
* Overlayable name defined within the target package, or null.
* @hide
*/
- public String overlayTargetName;
+ public String targetOverlayableName;
/**
* The overlay category, if any, of this package
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 743a302..b480939 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -689,7 +689,7 @@
pi.restrictedAccountType = p.mRestrictedAccountType;
pi.requiredAccountType = p.mRequiredAccountType;
pi.overlayTarget = p.mOverlayTarget;
- pi.overlayTargetName = p.mOverlayTargetName;
+ pi.targetOverlayableName = p.mOverlayTargetName;
pi.overlayCategory = p.mOverlayCategory;
pi.overlayPriority = p.mOverlayPriority;
pi.mOverlayIsStatic = p.mOverlayIsStatic;
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 40238d2..915baab 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -66,22 +66,14 @@
*/
public class ZygoteProcess {
- /**
- * @hide for internal use only.
- */
- public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000;
+ private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000;
/**
- * @hide for internal use only.
- *
* Use a relatively short delay, because for app zygote, this is in the critical path of
* service launch.
*/
- public static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50;
+ private static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50;
- /**
- * @hide for internal use only
- */
private static final String LOG_TAG = "ZygoteProcess";
/**
@@ -141,7 +133,7 @@
/**
* State for communicating with the zygote process.
*/
- public static class ZygoteState {
+ private static class ZygoteState implements AutoCloseable {
final LocalSocketAddress mZygoteSocketAddress;
final LocalSocketAddress mUsapSocketAddress;
@@ -178,12 +170,12 @@
* address
* @throws IOException
*/
- public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
- @Nullable LocalSocketAddress usapSocketAddress)
+ static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
+ @Nullable LocalSocketAddress usapSocketAddress)
throws IOException {
- DataInputStream zygoteInputStream = null;
- BufferedWriter zygoteOutputWriter = null;
+ DataInputStream zygoteInputStream;
+ BufferedWriter zygoteOutputWriter;
final LocalSocket zygoteSessionSocket = new LocalSocket();
if (zygoteSocketAddress == null) {
@@ -357,8 +349,6 @@
/**
* Queries the zygote for the list of ABIS it supports.
- *
- * @throws ZygoteStartFailedEx if the query failed.
*/
@GuardedBy("mLock")
private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream)
@@ -411,52 +401,24 @@
* the child or -1 on failure, followed by boolean to
* indicate whether a wrapper process was used.
*/
- String msgStr = Integer.toString(args.size()) + "\n"
- + String.join("\n", args) + "\n";
+ String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
- // Should there be a timeout on this?
- Process.ProcessStartResult result = new Process.ProcessStartResult();
-
- // TODO (chriswailes): Move branch body into separate function.
if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) {
- LocalSocket usapSessionSocket = null;
-
try {
- usapSessionSocket = zygoteState.getUsapSessionSocket();
-
- final BufferedWriter usapWriter =
- new BufferedWriter(
- new OutputStreamWriter(usapSessionSocket.getOutputStream()),
- Zygote.SOCKET_BUFFER_SIZE);
- final DataInputStream usapReader =
- new DataInputStream(usapSessionSocket.getInputStream());
-
- usapWriter.write(msgStr);
- usapWriter.flush();
-
- result.pid = usapReader.readInt();
- // USAPs can't be used to spawn processes that need wrappers.
- result.usingWrapper = false;
-
- if (result.pid < 0) {
- throw new ZygoteStartFailedEx("USAP specialization failed");
- }
-
- return result;
+ return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
// If there was an IOException using the USAP pool we will log the error and
// attempt to start the process through the Zygote.
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
- + ex.getMessage());
- } finally {
- try {
- usapSessionSocket.close();
- } catch (IOException ex) {
- Log.e(LOG_TAG, "Failed to close USAP session socket: " + ex.getMessage());
- }
+ + ex.getMessage());
}
}
+ return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
+ }
+
+ private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
+ ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
@@ -467,20 +429,48 @@
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
+ Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
+
+ if (result.pid < 0) {
+ throw new ZygoteStartFailedEx("fork() failed");
+ }
+
+ return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
+ }
- if (result.pid < 0) {
- throw new ZygoteStartFailedEx("fork() failed");
+ private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
+ ZygoteState zygoteState, String msgStr)
+ throws ZygoteStartFailedEx, IOException {
+ try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
+ final BufferedWriter usapWriter =
+ new BufferedWriter(
+ new OutputStreamWriter(usapSessionSocket.getOutputStream()),
+ Zygote.SOCKET_BUFFER_SIZE);
+ final DataInputStream usapReader =
+ new DataInputStream(usapSessionSocket.getInputStream());
+
+ usapWriter.write(msgStr);
+ usapWriter.flush();
+
+ Process.ProcessStartResult result = new Process.ProcessStartResult();
+ result.pid = usapReader.readInt();
+ // USAPs can't be used to spawn processes that need wrappers.
+ result.usingWrapper = false;
+
+ if (result.pid >= 0) {
+ return result;
+ } else {
+ throw new ZygoteStartFailedEx("USAP specialization failed");
+ }
}
-
- return result;
}
/**
@@ -557,7 +547,7 @@
boolean useUnspecializedAppProcessPool,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
- ArrayList<String> argsForZygote = new ArrayList<String>();
+ ArrayList<String> argsForZygote = new ArrayList<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
@@ -627,17 +617,7 @@
}
if (packagesForUid != null && packagesForUid.length > 0) {
- final StringBuilder sb = new StringBuilder();
- sb.append("--packages-for-uid=");
-
- // TODO (chriswailes): Replace with String.join
- for (int i = 0; i < packagesForUid.length; ++i) {
- if (i != 0) {
- sb.append(',');
- }
- sb.append(packagesForUid[i]);
- }
- argsForZygote.add(sb.toString());
+ argsForZygote.add("--packages-for-uid=" + String.join(",", packagesForUid));
}
if (sandboxId != null) {
@@ -647,9 +627,7 @@
argsForZygote.add(processClass);
if (extraArgs != null) {
- for (String arg : extraArgs) {
- argsForZygote.add(arg);
- }
+ Collections.addAll(argsForZygote, extraArgs);
}
synchronized(mLock) {
@@ -805,10 +783,10 @@
if (state == null || state.isClosed()) {
Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection");
return false;
- }
- if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
+ } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
return true;
}
+
try {
state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1));
state.mZygoteOutputWriter.newLine();
@@ -832,17 +810,15 @@
}
private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) {
- if (state == null || state.isClosed()) {
+ if (state == null || state.isClosed() || mHiddenApiAccessLogSampleRate == -1) {
return;
}
- if (mHiddenApiAccessLogSampleRate == -1) {
- return;
- }
+
try {
state.mZygoteOutputWriter.write(Integer.toString(1));
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate="
- + Integer.toString(mHiddenApiAccessLogSampleRate));
+ + mHiddenApiAccessLogSampleRate);
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.flush();
int status = state.mZygoteInputStream.readInt();
@@ -855,17 +831,15 @@
}
private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) {
- if (state == null || state.isClosed()) {
+ if (state == null || state.isClosed() || mHiddenApiAccessStatslogSampleRate == -1) {
return;
}
- if (mHiddenApiAccessStatslogSampleRate == -1) {
- return;
- }
+
try {
state.mZygoteOutputWriter.write(Integer.toString(1));
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate="
- + Integer.toString(mHiddenApiAccessStatslogSampleRate));
+ + mHiddenApiAccessStatslogSampleRate);
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.flush();
int status = state.mZygoteInputStream.readInt();
@@ -942,8 +916,8 @@
* Only the app zygote supports this function.
* TODO preloadPackageForAbi() can probably be removed and the callers an use this instead.
*/
- public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx,
- IOException {
+ public boolean preloadApp(ApplicationInfo appInfo, String abi)
+ throws ZygoteStartFailedEx, IOException {
synchronized (mLock) {
ZygoteState state = openZygoteSocketIfNeeded(abi);
state.mZygoteOutputWriter.write("2");
@@ -971,10 +945,10 @@
* Instructs the zygote to pre-load the classes and native libraries at the given paths
* for the specified abi. Not all zygotes support this function.
*/
- public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName,
- String cacheKey, String abi) throws ZygoteStartFailedEx,
- IOException {
- synchronized(mLock) {
+ public boolean preloadPackageForAbi(
+ String packagePath, String libsPath, String libFileName, String cacheKey, String abi)
+ throws ZygoteStartFailedEx, IOException {
+ synchronized (mLock) {
ZygoteState state = openZygoteSocketIfNeeded(abi);
state.mZygoteOutputWriter.write("5");
state.mZygoteOutputWriter.newLine();
@@ -1049,8 +1023,7 @@
try {
Thread.sleep(ZYGOTE_CONNECT_RETRY_DELAY_MS);
- } catch (InterruptedException ie) {
- }
+ } catch (InterruptedException ignored) { }
}
Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket "
+ zygoteSocketAddress.getName());
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index df11397..fb07aba 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -298,12 +298,12 @@
/**
* Disables the Content Capture service for the given user.
*/
- public final void disableContentCaptureServices() {
- if (sDebug) Log.d(TAG, "disableContentCaptureServices()");
+ public final void disableSelf() {
+ if (sDebug) Log.d(TAG, "disableSelf()");
final IContentCaptureServiceCallback callback = mCallback;
if (callback == null) {
- Log.w(TAG, "disableContentCaptureServices(): no server callback");
+ Log.w(TAG, "disableSelf(): no server callback");
return;
}
try {
@@ -367,7 +367,6 @@
stateFlags = initialState;
} else {
stateFlags |= ContentCaptureSession.STATE_DISABLED;
-
}
setClientState(clientReceiver, stateFlags, mClientInterface.asBinder());
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 04bb0e3..da6ef4c 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -59,7 +59,7 @@
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true");
DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
- DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "false");
+ DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "true");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0b91d21..0043d32 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -88,10 +88,10 @@
private static native void nativeDestroy(long nativeObject);
private static native void nativeDisconnect(long nativeObject);
- private static native GraphicBuffer nativeScreenshot(IBinder displayToken,
+ private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
boolean captureSecureLayers);
- private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
+ private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
Rect sourceCrop, float frameScale);
private static native long nativeCreateTransaction();
@@ -431,6 +431,46 @@
public static final int METADATA_TASK_ID = 3;
/**
+ * A wrapper around GraphicBuffer that contains extra information about how to
+ * interpret the screenshot GraphicBuffer.
+ * @hide
+ */
+ public static class ScreenshotGraphicBuffer {
+ private final GraphicBuffer mGraphicBuffer;
+ private final ColorSpace mColorSpace;
+
+ public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
+ mGraphicBuffer = graphicBuffer;
+ mColorSpace = colorSpace;
+ }
+
+ /**
+ * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object.
+ * @param width The width in pixels of the buffer
+ * @param height The height in pixels of the buffer
+ * @param format The format of each pixel as specified in {@link PixelFormat}
+ * @param usage Hint indicating how the buffer will be used
+ * @param unwrappedNativeObject The native object of GraphicBuffer
+ * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
+ */
+ private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
+ int usage, long unwrappedNativeObject, int namedColorSpace) {
+ GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
+ usage, unwrappedNativeObject);
+ ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
+ return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
+ }
+
+ public ColorSpace getColorSpace() {
+ return mColorSpace;
+ }
+
+ public GraphicBuffer getGraphicBuffer() {
+ return mGraphicBuffer;
+ }
+ }
+
+ /**
* Builder class for {@link SurfaceControl} objects.
*
* By default the surface will be hidden, and have "unset" bounds, meaning it can
@@ -1823,10 +1863,10 @@
throw new IllegalArgumentException("consumer must not be null");
}
- final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height,
- useIdentityTransform, rotation);
+ final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
+ height, useIdentityTransform, rotation);
try {
- consumer.attachAndQueueBuffer(buffer);
+ consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
} catch (RuntimeException e) {
Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
@@ -1869,17 +1909,16 @@
}
SurfaceControl.rotateCropForSF(sourceCrop, rotation);
- final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height,
- useIdentityTransform, rotation);
+ final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width,
+ height, useIdentityTransform, rotation);
if (buffer == null) {
Log.w(TAG, "Failed to take screenshot");
return null;
}
- // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
- // should continue to fix screenshot.
- return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer),
- ColorSpace.get(ColorSpace.Named.SRGB));
+ return Bitmap.wrapHardwareBuffer(
+ HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()),
+ buffer.getColorSpace());
}
/**
@@ -1905,8 +1944,8 @@
* @return Returns a GraphicBuffer that contains the captured content.
* @hide
*/
- public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width,
- int height, boolean useIdentityTransform, int rotation) {
+ public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop,
+ int width, int height, boolean useIdentityTransform, int rotation) {
if (display == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
@@ -1925,7 +1964,7 @@
*
* @hide
*/
- public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
+ public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
Rect sourceCrop, int width, int height, boolean useIdentityTransform,
int rotation) {
if (display == null) {
@@ -1959,7 +1998,7 @@
* @return Returns a GraphicBuffer that contains the layer capture.
* @hide
*/
- public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
+ public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
float frameScale) {
return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9101c36..4851476 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -300,7 +300,7 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769377)
protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400;
/**
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index afddc38..9e546a8 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -246,6 +246,7 @@
@UiThread
public void onActivityCreated(@NonNull IBinder applicationToken,
@NonNull ComponentName activityComponent, int flags) {
+ if (mOptions.lite) return;
synchronized (mLock) {
mFlags |= flags;
getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags);
@@ -255,18 +256,21 @@
/** @hide */
@UiThread
public void onActivityResumed() {
+ if (mOptions.lite) return;
getMainContentCaptureSession().notifySessionLifecycle(/* started= */ true);
}
/** @hide */
@UiThread
public void onActivityPaused() {
+ if (mOptions.lite) return;
getMainContentCaptureSession().notifySessionLifecycle(/* started= */ false);
}
/** @hide */
@UiThread
public void onActivityDestroyed() {
+ if (mOptions.lite) return;
getMainContentCaptureSession().destroy();
}
@@ -279,6 +283,7 @@
*/
@UiThread
public void flush(@FlushReason int reason) {
+ if (mOptions.lite) return;
getMainContentCaptureSession().flush(reason);
}
@@ -288,7 +293,7 @@
*/
@Nullable
public ComponentName getServiceComponentName() {
- if (!isContentCaptureEnabled()) return null;
+ if (!isContentCaptureEnabled() && !mOptions.lite) return null;
final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
try {
@@ -307,6 +312,7 @@
*
* @hide
*/
+ // TODO: use "lite" options as it's done by activities from the content capture service
@Nullable
public static ComponentName getServiceSettingsComponentName() {
final IBinder binder = ServiceManager
@@ -342,6 +348,8 @@
* </ul>
*/
public boolean isContentCaptureEnabled() {
+ if (mOptions.lite) return false;
+
final MainContentCaptureSession mainSession;
synchronized (mLock) {
mainSession = mMainSession;
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 6d41b28..ed1ca2a 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -135,11 +135,18 @@
public static final int STATE_SERVICE_DIED = 0x400;
/**
+ * Session is disabled because the service package is being udpated.
+ *
+ * @hide
+ */
+ public static final int STATE_SERVICE_UPDATING = 0x800;
+
+ /**
* Session is enabled, after the service died and came back to live.
*
* @hide
*/
- public static final int STATE_SERVICE_RESURRECTED = 0x800;
+ public static final int STATE_SERVICE_RESURRECTED = 0x1000;
private static final int INITIAL_CHILDREN_CAPACITY = 5;
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 666af59..790b8f9 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -230,7 +230,8 @@
/**
* Callback from {@code system_server} after call to
- * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IBinder)}
+ * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int,
+ * IResultReceiver)}.
*
* @param resultCode session state
* @param binder handle to {@code IContentCaptureDirectManager}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index cb44f79..0f2e702e 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -86,7 +86,8 @@
new File("/data/misc/textclassifier/lang_id.model");
// Actions
- private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = "actions_suggestions.model";
+ private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX =
+ "actions_suggestions\\.(.*)\\.model";
private static final File UPDATED_ACTIONS_MODEL =
new File("/data/misc/textclassifier/actions_suggestions.model");
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 702b507..54fff9b 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -237,7 +237,7 @@
if (DEBUG) {
Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
}
- if (isDestroyed()) {
+ if (mChooserListAdapter == null || isDestroyed()) {
break;
}
unbindRemainingServices();
@@ -822,6 +822,7 @@
mRefinementResultReceiver = null;
}
unbindRemainingServices();
+ mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 5c144d3..0a83fcc 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -481,7 +481,11 @@
@Override
public String toString() {
- return getClass().getSimpleName() + "[" + mComponentName + "]";
+ return getClass().getSimpleName() + "[" + mComponentName
+ + " " + System.identityHashCode(this)
+ + (mService != null ? " (bound)" : " (unbound)")
+ + (mDestroyed ? " (destroyed)" : "")
+ + "]";
}
/**
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 4a6c72b..94f96ba 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -126,6 +126,41 @@
jfieldID white;
} gDisplayPrimariesClassInfo;
+static struct {
+ jclass clazz;
+ jmethodID builder;
+} gScreenshotGraphicBufferClassInfo;
+
+class JNamedColorSpace {
+public:
+ // ColorSpace.Named.SRGB.ordinal() = 0;
+ static constexpr jint SRGB = 0;
+
+ // ColorSpace.Named.DISPLAY_P3.ordinal() = 6;
+ static constexpr jint DISPLAY_P3 = 6;
+};
+
+constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
+ switch (dataspace) {
+ case ui::Dataspace::DISPLAY_P3:
+ return JNamedColorSpace::DISPLAY_P3;
+ default:
+ return JNamedColorSpace::SRGB;
+ }
+}
+
+constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
+ switch (colorMode) {
+ case ui::ColorMode::DISPLAY_P3:
+ case ui::ColorMode::BT2100_PQ:
+ case ui::ColorMode::BT2100_HLG:
+ case ui::ColorMode::DISPLAY_BT2020:
+ return ui::Dataspace::DISPLAY_P3;
+ default:
+ return ui::Dataspace::V0_SRGB;
+ }
+}
+
// ----------------------------------------------------------------------------
static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -210,9 +245,12 @@
if (displayToken == NULL) {
return NULL;
}
+ const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
+ const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
+
Rect sourceCrop = rectFromObj(env, sourceCropObj);
sp<GraphicBuffer> buffer;
- status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB,
+ status_t res = ScreenshotClient::capture(displayToken, dataspace,
ui::PixelFormat::RGBA_8888,
sourceCrop, width, height,
useIdentityTransform, rotation, captureSecureLayers, &buffer);
@@ -220,13 +258,15 @@
return NULL;
}
- return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
- gGraphicBufferClassInfo.builder,
+ const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+ return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
+ gScreenshotGraphicBufferClassInfo.builder,
buffer->getWidth(),
buffer->getHeight(),
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
- (jlong)buffer.get());
+ (jlong)buffer.get(),
+ namedColorSpace);
}
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
@@ -243,20 +283,23 @@
}
sp<GraphicBuffer> buffer;
- status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB,
+ const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+ status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
ui::PixelFormat::RGBA_8888, sourceCrop,
frameScale, &buffer);
if (res != NO_ERROR) {
return NULL;
}
- return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
- gGraphicBufferClassInfo.builder,
+ const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+ return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
+ gScreenshotGraphicBufferClassInfo.builder,
buffer->getWidth(),
buffer->getHeight(),
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
- (jlong)buffer.get());
+ (jlong)buffer.get(),
+ namedColorSpace);
}
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1306,9 +1349,13 @@
(void*)nativeSetOverrideScalingMode },
{"nativeGetHandle", "(J)Landroid/os/IBinder;",
(void*)nativeGetHandle },
- {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;",
+ {"nativeScreenshot",
+ "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
+ "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
(void*)nativeScreenshot },
- {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
+ {"nativeCaptureLayers",
+ "(Landroid/os/IBinder;Landroid/graphics/Rect;F)"
+ "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
(void*)nativeCaptureLayers },
{"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
(void*)nativeSetInputWindowInfo },
@@ -1386,6 +1433,14 @@
gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
"createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
+ jclass screenshotGraphicsBufferClazz = FindClassOrDie(env,
+ "android/view/SurfaceControl$ScreenshotGraphicBuffer");
+ gScreenshotGraphicBufferClassInfo.clazz =
+ MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
+ gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
+ screenshotGraphicsBufferClazz,
+ "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
+
jclass displayedContentSampleClazz = FindClassOrDie(env,
"android/hardware/display/DisplayedContentSample");
gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 25caafb..b4be3f5 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2316,4 +2316,7 @@
// OPEN: Settings > Face > Remove face
// OS: Q
DIALOG_FACE_REMOVE = 1693;
+
+ // Settings > Display > Theme
+ DARK_UI_SETTINGS = 1698;
}
diff --git a/core/res/res/drawable-car/car_dialog_button_background.xml b/core/res/res/drawable-car/car_dialog_button_background.xml
index dc742d5..67506cb 100644
--- a/core/res/res/drawable-car/car_dialog_button_background.xml
+++ b/core/res/res/drawable-car/car_dialog_button_background.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@*android:color/car_card_ripple_background">
+ android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">
<color android:color="@*android:color/car_white_1000" />
</item>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 24fd3a8..79bf738 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -802,7 +802,7 @@
<string name="permgrouprequest_visual">Allow
<b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your photos and videos?</string>
<!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]-->
- <string name="permgrouprequestdetail_visual">Locations and other people in your photos and videos can be identified by the app</string>
+ <string name="permgrouprequestdetail_visual">This includes any locations tagged in your photos and videos</string>
<!-- Title for the capability of an accessibility service to retrieve window content. -->
<string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
@@ -1584,7 +1584,7 @@
<!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] -->
<string name="face_error_hw_not_available">Face hardware not available.</string>
<!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] -->
- <string name="face_error_timeout">Face time out reached. Try again.</string>
+ <string name="face_error_timeout">Face timeout reached. Try again.</string>
<!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=50] -->
<string name="face_error_no_space">Face can\u2019t be stored.</string>
<!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
@@ -1596,11 +1596,11 @@
<!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] -->
<string name="face_error_lockout_permanent">Too many attempts. Facial authentication disabled.</string>
<!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] -->
- <string name="face_error_unable_to_process">Try again.</string>
+ <string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string>
<!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] -->
- <string name="face_error_not_enrolled">No face enrolled.</string>
+ <string name="face_error_not_enrolled">You haven\u2019t set up face authentication.</string>
<!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] -->
- <string name="face_error_hw_not_present">This device does not have a face authentication sensor.</string>
+ <string name="face_error_hw_not_present">Face authentication is not supported on this device.</string>
<!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] -->
<string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string>
@@ -3283,18 +3283,36 @@
<string name="dump_heap_notification"><xliff:g id="proc">%1$s</xliff:g> exceeded memory
limit</string>
+ <!-- Notification text to tell the user that a heap dump that they initiated for a process is ready [CHAR LIMIT=NONE] -->
+ <string name="dump_heap_ready_notification">
+ <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> heap dump ready</string>
+
<!-- Notification details to tell the user that a process has exceeded its memory limit. -->
<string name="dump_heap_notification_detail">Heap dump collected. Tap to share.</string>
<!-- Title of dialog prompting the user to share a heap dump. -->
<string name="dump_heap_title">Share heap dump?</string>
- <!-- Text of dialog prompting the user to share a heap dump. -->
- <string name="dump_heap_text">The process <xliff:g id="proc">%1$s</xliff:g> has exceeded
- its process memory limit of <xliff:g id="size">%2$s</xliff:g>. A heap dump is available
+ <!-- Text of dialog prompting the user to share a heap dump for an application [CHAR LIMIT=NONE] -->
+ <string name="dump_heap_text">The
+ <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> process has exceeded
+ its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available
for you to share with its developer. Be careful: this heap dump can contain any
of your personal information that the application has access to.</string>
+ <!-- Text of dialog prompting the user to share a heap dump for a system process [CHAR LIMIT=NONE] -->
+ <string name="dump_heap_system_text">The
+ <xliff:g id="proc" example="Android System">%1$s</xliff:g> process has exceeded
+ its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available
+ for you to share. Be careful: this heap dump can contain any sensitive personal information
+ that the process has access to.</string>
+
+ <!-- Text of dialog prompting the user to share a heap dump that they initiated [CHAR LIMIT=NONE] -->
+ <string name="dump_heap_ready_text">A heap dump of
+ <xliff:g id="proc" example="com.android.example">%1$s</xliff:g>\u2019s process is available
+ for you to share. Be careful: this heap dump may contain any sensitive personal information
+ that the process has access to.</string>
+
<!-- Displayed in the title of the chooser for things to do with text that
is to be sent to another application. For example, I can send
text through SMS or IM. A dialog with those choices would be shown,
@@ -5302,6 +5320,21 @@
<string name="battery_saver_sticky_disabled_notification_title">Battery Saver won\u2019t reactivate until battery low again</string>
<!-- Summary of notification letting users know why battery saver didn't turn back on automatically after the device was unplugged [CHAR_LIMIT=NONE] -->
<string name="battery_saver_sticky_disabled_notification_summary">Battery has been charged to a sufficient level. Battery Saver won\u2019t reactivate until the battery is low again.</string>
+ <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] -->
+ <string name="battery_saver_charged_notification_title" product="default">Phone <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string>
+ <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] -->
+ <string name="battery_saver_charged_notification_title" product="tablet">Tablet <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string>
+ <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] -->
+ <string name="battery_saver_charged_notification_title" product="device">Device <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string>
+ <!-- Summary of notification letting users know that battery saver is now off [CHAR_LIMIT=NONE] -->
+ <string name="battery_saver_off_notification_summary">Battery Saver is off. Features no longer restricted.</string>
+ <!-- Alternative summary of notification letting users know that battery saver has been turned off.
+ If it's easy to translate the difference between "Battery Saver turned off. Features no longer restricted."
+ and "Battery Saver is off. Features no longer restricted." into the target language,
+ then translate "Battery Saver turned off. Features no longer restricted."
+ If the translation doesn't make a difference or the difference is hard to capture in the target language,
+ then translate "Battery Saver is off. Features no longer restricted." instead. [CHAR_LIMIT=NONE] -->
+ <string name="battery_saver_off_alternative_notification_summary">Battery Saver turned off. Features no longer restricted.</string>
<!-- Description of media type: folder or directory that contains additional files. [CHAR LIMIT=32] -->
<string name="mime_type_folder">Folder</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8797b0e..012f736 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2115,8 +2115,11 @@
<java-symbol type="string" name="device_storage_monitor_notification_channel" />
<java-symbol type="string" name="dlg_ok" />
<java-symbol type="string" name="dump_heap_notification" />
+ <java-symbol type="string" name="dump_heap_ready_notification" />
<java-symbol type="string" name="dump_heap_notification_detail" />
<java-symbol type="string" name="dump_heap_text" />
+ <java-symbol type="string" name="dump_heap_ready_text" />
+ <java-symbol type="string" name="dump_heap_system_text" />
<java-symbol type="string" name="dump_heap_title" />
<java-symbol type="string" name="factorytest_failed" />
<java-symbol type="string" name="factorytest_no_action" />
@@ -3650,6 +3653,9 @@
<java-symbol type="string" name="battery_saver_notification_channel_name" />
<java-symbol type="string" name="battery_saver_sticky_disabled_notification_title" />
<java-symbol type="string" name="battery_saver_sticky_disabled_notification_summary" />
+ <java-symbol type="string" name="battery_saver_charged_notification_title" />
+ <java-symbol type="string" name="battery_saver_off_notification_summary" />
+ <java-symbol type="string" name="battery_saver_off_alternative_notification_summary" />
<java-symbol type="string" name="dynamic_mode_notification_channel_name" />
<java-symbol type="string" name="dynamic_mode_notification_title" />
<java-symbol type="string" name="dynamic_mode_notification_summary" />
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
index 72d1ab1..e1ccd75 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
@@ -64,7 +64,9 @@
null,
null,
null,
- null);
+ null,
+ 0,
+ 0);
List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create(
InstrumentationRegistry.getContext(),
@@ -98,7 +100,9 @@
null,
null,
null,
- null);
+ null,
+ 0,
+ 0);
List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create(
InstrumentationRegistry.getContext(),
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
index ccf8607..2e97e63 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
@@ -82,7 +82,9 @@
null,
null,
null,
- createRemoteActionTemplates());
+ createRemoteActionTemplates(),
+ 0,
+ 0);
List<LabeledIntent> intents =
mTemplateClassificationIntentFactory.create(
@@ -121,7 +123,9 @@
null,
null,
null,
- createRemoteActionTemplates());
+ createRemoteActionTemplates(),
+ 0,
+ 0);
List<LabeledIntent> intents =
mTemplateClassificationIntentFactory.create(
@@ -156,7 +160,9 @@
null,
null,
null,
- null);
+ null,
+ 0,
+ 0);
mTemplateClassificationIntentFactory.create(
InstrumentationRegistry.getContext(),
@@ -189,7 +195,9 @@
null,
null,
null,
- new RemoteActionTemplate[0]);
+ new RemoteActionTemplate[0],
+ 0,
+ 0);
mTemplateClassificationIntentFactory.create(
InstrumentationRegistry.getContext(),
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 185fa07..8c2375e 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -599,7 +599,7 @@
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+ verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
// First invocation is from onCreate
assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
@@ -629,7 +629,7 @@
ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+ verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
// First invocation is from onCreate
assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index aa1a217..afb5071 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -308,6 +308,8 @@
<permission name="android.permission.STATUS_BAR_SERVICE"/>
<permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
<permission name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"/>
+ <permission name="android.permission.SET_WALLPAPER" />
+ <permission name="android.permission.SET_WALLPAPER_COMPONENT" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 9db7533..b6d8fa1 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -42,7 +42,7 @@
* String text = "Hello, Android.";
* MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
* .appendStyleRun(paint, 7, false) // Use paint for "Hello, "
- * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Hello, "
+ * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Android."
* .build();
* </code>
* </pre>
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 005f2d4..a08aec3 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -552,6 +552,13 @@
*/
public static final int STATUS_INTERNAL_ERROR = 4;
+ /**
+ * The key is not yet usable to decrypt media because the start
+ * time is in the future. The key will become usable when
+ * its start time is reached.
+ */
+ public static final int STATUS_USABLE_IN_FUTURE = 5;
+
/** @hide */
@IntDef({
STATUS_USABLE,
@@ -559,6 +566,7 @@
STATUS_OUTPUT_NOT_ALLOWED,
STATUS_PENDING,
STATUS_INTERNAL_ERROR,
+ STATUS_USABLE_IN_FUTURE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KeyStatusCode {}
diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS
new file mode 100644
index 0000000..7e7335d
--- /dev/null
+++ b/media/java/android/media/projection/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 441f88c..d6e61eb 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -182,6 +182,10 @@
<!-- Permission needed to run keyguard manager tests in CTS -->
<uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
+ <!-- Permission needed to test wallpaper component -->
+ <uses-permission android:name="android.permission.SET_WALLPAPER" />
+ <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" />
+
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 3d2f570..0a0530c0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -60,6 +60,7 @@
boolean areCaptionsEnabled();
void setCaptionsEnabled(boolean isEnabled);
+ boolean isCaptionStreamOptedOut();
void getCaptionsComponentState(boolean fromTooltip);
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 5714556..2f2f84a 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -444,15 +444,15 @@
<!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] -->
<string-array name="type_clock_minutes">
<item>O\u2019Clock</item>
- <item>O\u2019One</item>
- <item>O\u2019Two</item>
- <item>O\u2019Three</item>
- <item>O\u2019Four</item>
- <item>O\u2019Five</item>
- <item>O\u2019Six</item>
- <item>O\u2019Seven</item>
- <item>O\u2019Eight</item>
- <item>O\u2019Nine</item>
+ <item>Oh One</item>
+ <item>Oh Two</item>
+ <item>Oh Three</item>
+ <item>Oh Four</item>
+ <item>Oh Five</item>
+ <item>Oh Six</item>
+ <item>Oh Seven</item>
+ <item>Oh Eight</item>
+ <item>Oh Nine</item>
<item>Ten</item>
<item>Eleven</item>
<item>Twelve</item>
diff --git a/packages/SystemUI/res/color/caption_tint_color_selector.xml b/packages/SystemUI/res/color/caption_tint_color_selector.xml
new file mode 100644
index 0000000..30843ec
--- /dev/null
+++ b/packages/SystemUI/res/color/caption_tint_color_selector.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto">
+ <item sysui:optedOut="true"
+ android:color="?android:attr/colorButtonNormal"/>
+
+ <item android:color="?android:attr/colorAccent"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 1d0a242..d1c80c4 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -15,6 +15,7 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:id="@+id/volume_dialog_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -117,16 +118,17 @@
android:clipToPadding="false"
android:translationZ="@dimen/volume_dialog_elevation"
android:background="@drawable/rounded_bg_full">
- <com.android.keyguard.AlphaOptimizedImageButton
+ <com.android.systemui.volume.CaptionsToggleImageButton
android:id="@+id/odi_captions_icon"
android:src="@drawable/ic_volume_odi_captions_disabled"
style="@style/VolumeButtons"
android:background="@drawable/rounded_ripple"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:tint="@color/accent_tint_color_selector"
+ android:tint="@color/caption_tint_color_selector"
android:layout_gravity="center"
- android:soundEffectsEnabled="false" />
+ android:soundEffectsEnabled="false"
+ sysui:optedOut="false"/>
</FrameLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 27d2bcd..e0bcf24 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -146,5 +146,9 @@
<attr name="showAirplaneMode" format="boolean" />
</declare-styleable>
+ <declare-styleable name="CaptionsToggleImageButton">
+ <attr name="optedOut" format="boolean" />
+ </declare-styleable>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 6ae2b45..fd92e9e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -1,5 +1,7 @@
package com.android.keyguard;
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -24,8 +26,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
import com.android.keyguard.clock.ClockManager;
-import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.ClockPlugin;
@@ -37,37 +39,65 @@
import java.util.Arrays;
import java.util.TimeZone;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
public class KeyguardClockSwitch extends RelativeLayout {
+ /**
+ * Controller used to track StatusBar state to know when to show the big_clock_container.
+ */
+ private final StatusBarStateController mStatusBarStateController;
+
+ /**
+ * Color extractor used to apply colors from wallpaper to custom clock faces.
+ */
+ private final SysuiColorExtractor mSysuiColorExtractor;
+
+ /**
+ * Manager used to know when to show a custom clock face.
+ */
+ private final ClockManager mClockManager;
+
+ /**
+ * Layout transition that scales the default clock face.
+ */
private final Transition mTransition;
+
/**
* Optional/alternative clock injected via plugin.
*/
private ClockPlugin mClockPlugin;
+
/**
* Default clock.
*/
private TextClock mClockView;
+
/**
* Frame for default and custom clock.
*/
private FrameLayout mSmallClockFrame;
+
/**
* Container for big custom clock.
*/
private ViewGroup mBigClockContainer;
+
/**
* Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
* show it below the alternate clock.
*/
private View mKeyguardStatusArea;
+
/**
* Maintain state so that a newly connected plugin can be initialized.
*/
private float mDarkAmount;
+
/**
* If the Keyguard Slice has a header (big center-aligned text.)
*/
@@ -96,22 +126,20 @@
*
* The color palette changes when the wallpaper is changed.
*/
- private SysuiColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> {
+ private final OnColorsChangedListener mColorsListener = (extractor, which) -> {
if ((which & WallpaperManager.FLAG_LOCK) != 0) {
- if (extractor instanceof SysuiColorExtractor) {
- updateColors((SysuiColorExtractor) extractor);
- } else {
- updateColors(Dependency.get(SysuiColorExtractor.class));
- }
+ updateColors();
}
};
- public KeyguardClockSwitch(Context context) {
- this(context, null);
- }
-
- public KeyguardClockSwitch(Context context, AttributeSet attrs) {
+ @Inject
+ public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+ StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor,
+ ClockManager clockManager) {
super(context, attrs);
+ mStatusBarStateController = statusBarStateController;
+ mSysuiColorExtractor = colorExtractor;
+ mClockManager = clockManager;
mTransition = new ClockBoundsTransition();
}
@@ -133,22 +161,18 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener);
- StatusBarStateController stateController = Dependency.get(StatusBarStateController.class);
- stateController.addCallback(mStateListener);
- mStateListener.onStateChanged(stateController.getState());
- SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class);
- colorExtractor.addOnColorsChangedListener(mColorsListener);
- updateColors(colorExtractor);
+ mClockManager.addOnClockChangedListener(mClockChangedListener);
+ mStatusBarStateController.addCallback(mStateListener);
+ mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener);
+ updateColors();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener);
- Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
- Dependency.get(SysuiColorExtractor.class)
- .removeOnColorsChangedListener(mColorsListener);
+ mClockManager.removeOnClockChangedListener(mClockChangedListener);
+ mStatusBarStateController.removeCallback(mStateListener);
+ mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener);
setClockPlugin(null);
}
@@ -290,9 +314,9 @@
}
}
- private void updateColors(SysuiColorExtractor colorExtractor) {
- ColorExtractor.GradientColors colors = colorExtractor.getColors(WallpaperManager.FLAG_LOCK,
- true);
+ private void updateColors() {
+ ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK, true);
mSupportsDarkText = colors.supportsDarkText();
mColorPalette = colors.getColorPalette();
if (mClockPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 9dd9717..ae8bc52 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -28,9 +28,12 @@
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
+import com.android.systemui.util.InjectionInflationController;
+
// TODO(multi-display): Support multiple external displays
public class KeyguardDisplayManager {
protected static final String TAG = "KeyguardDisplayManager";
@@ -38,6 +41,7 @@
private final MediaRouter mMediaRouter;
private final DisplayManager mDisplayService;
+ private final InjectionInflationController mInjectableInflater;
private final Context mContext;
private boolean mShowing;
@@ -75,8 +79,10 @@
}
};
- public KeyguardDisplayManager(Context context) {
+ public KeyguardDisplayManager(Context context,
+ InjectionInflationController injectableInflater) {
mContext = context;
+ mInjectableInflater = injectableInflater;
mMediaRouter = mContext.getSystemService(MediaRouter.class);
mDisplayService = mContext.getSystemService(DisplayManager.class);
mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */);
@@ -110,7 +116,7 @@
final int displayId = display.getDisplayId();
Presentation presentation = mPresentations.get(displayId);
if (presentation == null) {
- presentation = new KeyguardPresentation(mContext, display);
+ presentation = new KeyguardPresentation(mContext, display, mInjectableInflater);
presentation.setOnDismissListener(dialog -> {
if (null != mPresentations.get(displayId)) {
mPresentations.remove(displayId);
@@ -201,6 +207,7 @@
private final static class KeyguardPresentation extends Presentation {
private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
+ private final InjectionInflationController mInjectableInflater;
private View mClock;
private int mUsableWidth;
private int mUsableHeight;
@@ -217,8 +224,10 @@
}
};
- KeyguardPresentation(Context context, Display display) {
+ KeyguardPresentation(Context context, Display display,
+ InjectionInflationController injectionInflater) {
super(context, display, R.style.keyguard_presentation_theme);
+ mInjectableInflater = injectionInflater;
getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
setCancelable(false);
}
@@ -239,7 +248,9 @@
mMarginLeft = (100 - VIDEO_SAFE_REGION) * p.x / 200;
mMarginTop = (100 - VIDEO_SAFE_REGION) * p.y / 200;
- setContentView(R.layout.keyguard_presentation);
+ LayoutInflater inflater = mInjectableInflater.injectable(
+ LayoutInflater.from(getContext()));
+ setContentView(inflater.inflate(R.layout.keyguard_presentation, null));
mClock = findViewById(R.id.clock);
// Avoid screen burn in
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 870ac87..32c1242 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -141,6 +141,8 @@
@Override
public void onTimeTick() {
mAnalogClock.onTimeChanged();
+ mDigitalClock.refresh();
+ mLockClock.refresh();
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
index 7401819..34b2fd8 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
@@ -136,6 +136,8 @@
@Override
public void onTimeTick() {
mAnalogClock.onTimeChanged();
+ mDigitalClock.refresh();
+ mLockClock.refresh();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 676e594..d70d0d8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -90,6 +90,7 @@
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -710,7 +711,10 @@
mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
SYSTEMUI_PERMISSION, null /* scheduler */);
- mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
+ InjectionInflationController injectionInflationController =
+ new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent());
+ mKeyguardDisplayManager = new KeyguardDisplayManager(mContext,
+ injectionInflationController);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/media/OWNERS b/packages/SystemUI/src/com/android/systemui/media/OWNERS
new file mode 100644
index 0000000..69ea57b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/OWNERS
@@ -0,0 +1 @@
+per-file MediaProjectionPermissionActivity.java = michaelwr@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index ef82b34..e9a9606 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -50,8 +50,6 @@
import android.graphics.Region;
import android.graphics.Region.Op;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.AttributeSet;
@@ -150,10 +148,6 @@
private final NavigationBarTransitions mBarTransitions;
private final OverviewProxyService mOverviewProxyService;
- // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
- final static boolean WORKAROUND_INVALID_LAYOUT = true;
- final static int MSG_CHECK_INVALID_LAYOUT = 8686;
-
// performs manual animation in sync with layout transitions
private final NavTransitionListener mTransitionListener = new NavTransitionListener();
@@ -260,29 +254,6 @@
}
};
- private class H extends Handler {
- public void handleMessage(Message m) {
- switch (m.what) {
- case MSG_CHECK_INVALID_LAYOUT:
- final String how = "" + m.obj;
- final int w = getWidth();
- final int h = getHeight();
- final int vw = getCurrentView().getWidth();
- final int vh = getCurrentView().getHeight();
-
- if (h != vh || w != vw) {
- Log.w(TAG, String.format(
- "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
- how, w, h, vw, vh));
- if (WORKAROUND_INVALID_LAYOUT) {
- requestLayout();
- }
- }
- break;
- }
- }
- }
-
private final AccessibilityDelegate mQuickStepAccessibilityDelegate
= new AccessibilityDelegate() {
private AccessibilityAction mToggleOverviewAction;
@@ -450,7 +421,7 @@
mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */
};
- mPrototypeController = new NavigationPrototypeController(mHandler, mContext);
+ mPrototypeController = new NavigationPrototypeController(mContext);
mPrototypeController.register();
mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController());
@@ -591,8 +562,6 @@
getHomeButton().abortCurrentGesture();
}
- private H mHandler = new H();
-
public View getCurrentView() {
return mCurrentView;
}
@@ -1193,23 +1162,23 @@
}
@Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int w = MeasureSpec.getSize(widthMeasureSpec);
+ int h = MeasureSpec.getSize(heightMeasureSpec);
if (DEBUG) Log.d(TAG, String.format(
- "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
+ "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight()));
final boolean newVertical = w > 0 && h > w;
if (newVertical != mIsVertical) {
mIsVertical = newVertical;
if (DEBUG) {
- Log.d(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w,
+ Log.d(TAG, String.format("onMeasure: h=%d, w=%d, vert=%s", h, w,
mIsVertical ? "y" : "n"));
}
reorient();
notifyVerticalChangedListener(newVertical);
}
-
- postCheckForInvalidLayout("sizeChanged");
- super.onSizeChanged(w, h, oldw, oldh);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void notifyVerticalChangedListener(boolean newVertical) {
@@ -1264,28 +1233,6 @@
return uiCarModeChanged;
}
- /*
- @Override
- protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
- if (DEBUG) Log.d(TAG, String.format(
- "onLayout: %s (%d,%d,%d,%d)",
- changed?"changed":"notchanged", left, top, right, bottom));
- super.onLayout(changed, left, top, right, bottom);
- }
-
- // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
- // fails, any touch on the display will fix the layout.
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- postCheckForInvalidLayout("touch");
- }
- return super.onInterceptTouchEvent(ev);
- }
- */
-
-
private String getResourceName(int resId) {
if (resId != 0) {
final android.content.res.Resources res = getContext().getResources();
@@ -1299,10 +1246,6 @@
}
}
- private void postCheckForInvalidLayout(final String how) {
- mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
- }
-
private static String visibilityToString(int vis) {
switch (vis) {
case View.INVISIBLE:
@@ -1471,7 +1414,7 @@
void onVerticalChanged(boolean isVertical);
}
- private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
+ private final Consumer<Boolean> mDockedListener = exists -> post(() -> {
mDockedStackExists = exists;
updateRecentsIcon();
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index 979de07..9ea8b64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -67,8 +67,8 @@
private final Context mContext;
- public NavigationPrototypeController(Handler handler, Context context) {
- super(handler);
+ public NavigationPrototypeController(Context context) {
+ super(new Handler());
mContext = context;
updateSwipeLTRBackSetting();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 253bdfb..b902e43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -92,6 +92,7 @@
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -141,6 +142,7 @@
private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties()
.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ private final InjectionInflationController mInjectionInflationController;
private final PowerManager mPowerManager;
private final AccessibilityManager mAccessibilityManager;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
@@ -336,10 +338,12 @@
@Inject
public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+ InjectionInflationController injectionInflationController,
NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler pulseExpansionHandler) {
super(context, attrs);
setWillNotDraw(!DEBUG);
+ mInjectionInflationController = injectionInflationController;
mFalsingManager = FalsingManager.getInstance(context);
mPowerManager = context.getSystemService(PowerManager.class);
mWakeUpCoordinator = coordinator;
@@ -475,10 +479,11 @@
// Re-inflate the status view group.
int index = indexOfChild(mKeyguardStatusView);
removeView(mKeyguardStatusView);
- mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate(
- R.layout.keyguard_status_view,
- this,
- false);
+ mKeyguardStatusView = (KeyguardStatusView) mInjectionInflationController
+ .injectable(LayoutInflater.from(mContext)).inflate(
+ R.layout.keyguard_status_view,
+ this,
+ false);
addView(mKeyguardStatusView, index);
// Re-associate the clock container with the keyguard clock switch.
@@ -490,10 +495,11 @@
index = indexOfChild(mKeyguardBottomArea);
removeView(mKeyguardBottomArea);
KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea;
- mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
- R.layout.keyguard_bottom_area,
- this,
- false);
+ mKeyguardBottomArea = (KeyguardBottomAreaView) mInjectionInflationController
+ .injectable(LayoutInflater.from(mContext)).inflate(
+ R.layout.keyguard_bottom_area,
+ this,
+ false);
mKeyguardBottomArea.initFrom(oldBottomArea);
addView(mKeyguardBottomArea, index);
initBottomArea();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index a8ae5f6..9609057 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -114,17 +114,19 @@
if (mSingleTapEnabled) {
mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
"SINGLE_TAP");
+ return true;
}
- return mSingleTapEnabled;
+ return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
- if (mDoubleTapEnabled) {
+ if (mDoubleTapEnabled || mSingleTapEnabled) {
mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
"DOUBLE_TAP");
+ return true;
}
- return mDoubleTapEnabled;
+ return false;
}
};
private final TunerService.Tunable mTunable = (key, newValue) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
index 3c8ed6e..b53ff0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -16,9 +16,11 @@
package com.android.systemui.statusbar.policy;
+import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.Context;
+import com.android.internal.util.Preconditions;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.settings.CurrentUserTracker;
@@ -69,7 +71,8 @@
}
@Override
- public void addCallback(Callback callback) {
+ public void addCallback(@NonNull Callback callback) {
+ Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449");
mCallbacks.add(callback);
if (mCallbacks.size() != 0 && !mListening) {
mListening = true;
@@ -81,7 +84,8 @@
}
@Override
- public void removeCallback(Callback callback) {
+ public void removeCallback(@NonNull Callback callback) {
+ Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449");
if (mCallbacks.remove(callback) && mCallbacks.size() == 0 && mListening) {
mListening = false;
mKeyguardUpdateMonitor.removeCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index e6b6672..7705e4e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -23,6 +23,7 @@
import android.view.LayoutInflater;
import android.view.View;
+import com.android.keyguard.KeyguardClockSwitch;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.qs.QSCarrierGroup;
import com.android.systemui.qs.QSFooterImpl;
@@ -130,6 +131,11 @@
* Creates the QSCarrierGroup
*/
QSCarrierGroup createQSCarrierGroup();
+
+ /**
+ * Creates the KeyguardClockSwitch.
+ */
+ KeyguardClockSwitch createKeyguardClockSwitch();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
new file mode 100644
index 0000000..8ec66e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.keyguard.AlphaOptimizedImageButton;
+import com.android.systemui.R;
+
+/** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */
+public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
+
+ private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut };
+
+ private boolean mComponentEnabled = false;
+ private boolean mOptedOut = false;
+
+ public CaptionsToggleImageButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public int[] onCreateDrawableState(int extraSpace) {
+ int[] state = super.onCreateDrawableState(extraSpace + 1);
+ if (mOptedOut) {
+ mergeDrawableStates(state, OPTED_OUT_STATE);
+ }
+ return state;
+ }
+
+ Runnable setComponentEnabled(boolean isComponentEnabled) {
+ this.mComponentEnabled = isComponentEnabled;
+
+ return this.setImageResourceAsync(this.mComponentEnabled
+ ? R.drawable.ic_volume_odi_captions
+ : R.drawable.ic_volume_odi_captions_disabled);
+ }
+
+ boolean getComponentEnabled() {
+ return this.mComponentEnabled;
+ }
+
+ /** Sets whether or not the current stream has opted out of captions */
+ void setOptedOut(boolean isOptedOut) {
+ this.mOptedOut = isOptedOut;
+ refreshDrawableState();
+ }
+
+ boolean getOptedOut() {
+ return this.mOptedOut;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 2fa8889..a3db533 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -282,6 +282,13 @@
Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0);
}
+ @Override
+ public boolean isCaptionStreamOptedOut() {
+ int currentValue = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ODI_CAPTIONS_OPTED_OUT, 0);
+ return currentValue == 1;
+ }
+
public void getCaptionsComponentState(boolean fromTooltip) {
if (mDestroyed) return;
mWorker.obtainMessage(W.GET_CAPTIONS_COMPONENT_STATE, fromTooltip).sendToTarget();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index cdda216..bd7824d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -133,7 +133,7 @@
private ViewGroup mRinger;
private ImageButton mRingerIcon;
private ViewGroup mODICaptionsView;
- private ImageButton mODICaptionsIcon;
+ private CaptionsToggleImageButton mODICaptionsIcon;
private View mSettingsView;
private ImageButton mSettingsIcon;
private FrameLayout mZenIcon;
@@ -587,11 +587,15 @@
}
private void updateCaptionsIcon() {
- mHandler.post(
- mODICaptionsIcon.setImageResourceAsync(
- mController.areCaptionsEnabled()
- ? R.drawable.ic_volume_odi_captions
- : R.drawable.ic_volume_odi_captions_disabled));
+ boolean componentEnabled = mController.areCaptionsEnabled();
+ if (mODICaptionsIcon.getComponentEnabled() != componentEnabled) {
+ mHandler.post(mODICaptionsIcon.setComponentEnabled(componentEnabled));
+ }
+
+ boolean isOptedOut = mController.isCaptionStreamOptedOut();
+ if (mODICaptionsIcon.getOptedOut() != isOptedOut) {
+ mHandler.post(() -> mODICaptionsIcon.setOptedOut(isOptedOut));
+ }
}
private void onCaptionIconClicked() {
@@ -952,7 +956,7 @@
}
private void updateVolumeRowH(VolumeRow row) {
- if (D.BUG) Log.d(TAG, "updateVolumeRowH s=" + row.stream);
+ if (D.BUG) Log.i(TAG, "updateVolumeRowH s=" + row.stream);
if (mState == null) return;
final StreamState ss = mState.states.get(row.stream);
if (ss == null) return;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 29505a2..632b0c0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -39,10 +39,12 @@
import android.widget.TextClock;
import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +72,10 @@
@Before
public void setUp() {
- LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater layoutInflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
mKeyguardClockSwitch =
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index 3582ab01..31ea39c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -24,8 +24,10 @@
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.Assert;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +50,10 @@
@Before
public void setUp() {
Assert.sMainLooper = TestableLooper.get(this).getLooper();
- LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater layoutInflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
mKeyguardStatusView =
(KeyguardStatusView) layoutInflater.inflate(R.layout.keyguard_status_view, null);
org.mockito.MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
index eec836f..dfe2913 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
@@ -23,7 +23,9 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +37,10 @@
@Test
public void testInflation_doesntCrash() {
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
- LayoutInflater inflater = LayoutInflater.from(getContext());
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater inflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
inflater.inflate(R.layout.keyguard_presentation, null);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 6889c57..232c6a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -27,6 +27,7 @@
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.AmbientPulseManager;
@@ -38,6 +39,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -104,7 +106,10 @@
private class TestableNotificationPanelView extends NotificationPanelView {
TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler expansionHandler) {
- super(NotificationPanelViewTest.this.mContext, null, coordinator, expansionHandler);
+ super(NotificationPanelViewTest.this.mContext, null,
+ new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent()),
+ coordinator, expansionHandler);
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 32c595a..95abd05 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7147,6 +7147,8 @@
// OS: Q
BIOMETRIC_AUTH = 1697;
+ // Settings > Display > Theme
+ DARK_UI_SETTINGS = 1698;
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 3d41d71..87a265c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -533,7 +533,7 @@
new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)),
- new String[] { value2 }, null, algorithmName, null, null, null);
+ new String[] { value2 }, new String[] { null }, algorithmName, null, null, null);
}
// Called by Shell command.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 89c4043..ff284dc 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -40,6 +40,7 @@
import android.metrics.LogMaker;
import android.os.AsyncTask;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -1212,6 +1213,18 @@
@GuardedBy("mLock")
boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) {
+ if (Build.IS_USER && mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)) {
+ final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId);
+ final ComponentName component = ComponentName.unflattenFromString(serviceName);
+ final String servicePackage = component == null ? null : component.getPackageName();
+ final String packageName = componentName.getPackageName();
+ if (!packageName.equals(servicePackage)) {
+ Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill while "
+ + "using temporary service " + servicePackage);
+ return false;
+ }
+ }
+
return mAugmentedWhitelistHelper.isWhitelisted(componentName);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ac8f61b..c62794d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2659,17 +2659,16 @@
mAugmentedAutofillDestroyer = triggerAugmentedAutofillLocked();
if (mAugmentedAutofillDestroyer == null) {
if (sVerbose) {
- Slog.v(TAG, "canceling session " + id + " when server returned null and there is no"
- + " AugmentedAutofill for user. AutofillableIds: " + autofillableIds);
+ Slog.v(TAG, "canceling session " + id + " when service returned null and it cannot "
+ + "be augmented. AutofillableIds: " + autofillableIds);
}
// Nothing to be done, but need to notify client.
notifyUnavailableToClient(AutofillManager.STATE_FINISHED, autofillableIds);
removeSelf();
} else {
if (sVerbose) {
- Slog.v(TAG, "keeping session " + id + " when server returned null but "
- + "there is an AugmentedAutofill for user. AutofillableIds: "
- + autofillableIds);
+ Slog.v(TAG, "keeping session " + id + " when service returned null but "
+ + "it can be augmented. AutofillableIds: " + autofillableIds);
}
mAugmentedAutofillableIds = autofillableIds;
}
@@ -2687,7 +2686,10 @@
// Check if Smart Suggestions is supported...
final @SmartSuggestionMode int supportedModes = mService
.getSupportedSmartSuggestionModesLocked();
- if (supportedModes == 0) return null;
+ if (supportedModes == 0) {
+ if (sVerbose) Slog.v(TAG, "triggerAugmentedAutofillLocked(): no supported modes");
+ return null;
+ }
// ...then if the service is set for the user
@@ -2712,14 +2714,6 @@
return null;
}
- if (sVerbose) {
- Slog.v(TAG, "calling Augmented Autofill Service ("
- + remoteService.getComponentName().toShortString() + ") on view "
- + mCurrentViewId + " using suggestion mode "
- + getSmartSuggestionModeToString(mode)
- + " when server returned null for session " + this.id);
- }
-
final boolean isWhitelisted = mService
.isWhitelistedForAugmentedAutofillLocked(mComponentName);
@@ -2733,12 +2727,20 @@
if (!isWhitelisted) {
if (sVerbose) {
- Slog.v(TAG, mComponentName.toShortString() + " is not whitelisted for "
- + "augmented autofill");
+ Slog.v(TAG, "triggerAugmentedAutofillLocked(): "
+ + ComponentName.flattenToShortString(mComponentName) + " not whitelisted ");
}
return null;
}
+ if (sVerbose) {
+ Slog.v(TAG, "calling Augmented Autofill Service ("
+ + ComponentName.flattenToShortString(remoteService.getComponentName())
+ + ") on view " + mCurrentViewId + " using suggestion mode "
+ + getSmartSuggestionModeToString(mode)
+ + " when server returned null for session " + this.id);
+ }
+
final ViewState viewState = mViewStates.get(mCurrentViewId);
viewState.setState(ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL);
final AutofillValue currentValue = viewState.getCurrentValue();
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 3619a9d..b2760e0 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -172,6 +172,22 @@
}
@Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatingLocked(int userId) {
+ final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatingLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatedLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
protected void enforceCallingPermissionForManagement() {
getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag);
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index 955f260..d909736 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -40,6 +40,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;
@@ -74,7 +75,7 @@
AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService>
implements ContentCaptureServiceCallbacks {
- private static final String TAG = ContentCaptureManagerService.class.getSimpleName();
+ private static final String TAG = ContentCapturePerUserService.class.getSimpleName();
@GuardedBy("mLock")
private final ArrayMap<String, ContentCaptureServerSession> mSessions =
@@ -87,7 +88,8 @@
* master's cache (for example, because a temporary service was set).
*/
@GuardedBy("mLock")
- private RemoteContentCaptureService mRemoteService;
+ @Nullable
+ RemoteContentCaptureService mRemoteService;
private final ContentCaptureServiceRemoteCallback mRemoteServiceCallback =
new ContentCaptureServiceRemoteCallback();
@@ -135,6 +137,10 @@
}
if (!disabled) {
+ if (mMaster.debug) {
+ Slog.d(TAG, "updateRemoteService(): creating new remote service for "
+ + serviceComponentName);
+ }
mRemoteService = new RemoteContentCaptureService(mMaster.getContext(),
ContentCaptureService.SERVICE_INTERFACE, serviceComponentName,
mRemoteServiceCallback, mUserId, this, mMaster.isBindInstantServiceAllowed(),
@@ -182,20 +188,40 @@
}
mZombie = false;
- final int numSessions = mSessions.size();
- if (mMaster.debug) {
- Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
- + numSessions + " sessions");
- }
-
- for (int i = 0; i < numSessions; i++) {
- final ContentCaptureServerSession session = mSessions.valueAt(i);
- session.resurrectLocked();
- }
+ resurrectSessionsLocked();
}
}
}
+ private void resurrectSessionsLocked() {
+ final int numSessions = mSessions.size();
+ if (mMaster.debug) {
+ Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
+ + numSessions + " sessions");
+ }
+
+ for (int i = 0; i < numSessions; i++) {
+ final ContentCaptureServerSession session = mSessions.valueAt(i);
+ session.resurrectLocked();
+ }
+ }
+
+ void onPackageUpdatingLocked() {
+ final int numSessions = mSessions.size();
+ if (mMaster.debug) {
+ Slog.d(TAG, "Pausing " + numSessions + " sessions while package is updating");
+ }
+ for (int i = 0; i < numSessions; i++) {
+ final ContentCaptureServerSession session = mSessions.valueAt(i);
+ session.pauseLocked();
+ }
+ }
+
+ void onPackageUpdatedLocked() {
+ updateRemoteServiceLocked(!isEnabledLocked());
+ resurrectSessionsLocked();
+ }
+
// TODO(b/119613670): log metrics
@GuardedBy("mLock")
public void startSessionLocked(@NonNull IBinder activityToken,
@@ -274,9 +300,12 @@
return;
}
+ // Make sure service is bound, just in case the initial connection failed somehow
+ mRemoteService.ensureBoundLocked();
+
final ContentCaptureServerSession newSession = new ContentCaptureServerSession(
- activityToken, this, mRemoteService, componentName, clientReceiver, taskId,
- displayId, sessionId, uid, flags);
+ activityToken, this, componentName, clientReceiver, taskId, displayId, sessionId,
+ uid, flags);
if (mMaster.verbose) {
Slog.v(TAG, "startSession(): new session for "
+ ComponentName.flattenToShortString(componentName) + " and id " + sessionId);
@@ -290,21 +319,6 @@
return mWhitelistHelper.isWhitelisted(componentName);
}
- /**
- * @throws IllegalArgumentException if packages or components are empty.
- */
- private void setWhitelist(@Nullable List<String> packages,
- @Nullable List<ComponentName> components) {
- // TODO(b/122595322): add CTS test for when it's null
- synchronized (mLock) {
- if (mMaster.verbose) {
- Slog.v(TAG, "whitelisting packages: " + packages + " and activities: "
- + components);
- }
- mWhitelistHelper.setWhitelist(packages, components);
- }
- }
-
// TODO(b/119613670): log metrics
@GuardedBy("mLock")
public void finishSessionLocked(@NonNull String sessionId) {
@@ -442,8 +456,13 @@
}
@GuardedBy("mLock")
+ @Nullable
ContentCaptureOptions getOptionsForPackageLocked(@NonNull String packageName) {
if (!mWhitelistHelper.isWhitelisted(packageName)) {
+ if (packageName.equals(getServicePackageName())) {
+ if (mMaster.verbose) Slog.v(mTag, "getOptionsForPackage() lite for " + packageName);
+ return new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel);
+ }
if (mMaster.verbose) {
Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted");
}
@@ -452,6 +471,14 @@
final ArraySet<ComponentName> whitelistedComponents = mWhitelistHelper
.getWhitelistedComponents(packageName);
+ if (Build.IS_USER && isTemporaryServiceSetLocked()) {
+ final String servicePackageName = getServicePackageName();
+ if (!packageName.equals(servicePackageName)) {
+ Slog.w(mTag, "Ignoring package " + packageName
+ + " while using temporary service " + servicePackageName);
+ return null;
+ }
+ }
ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel,
mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs,
mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize,
@@ -530,12 +557,16 @@
@Override
public void setContentCaptureWhitelist(List<String> packages,
List<ComponentName> activities) {
+ // TODO(b/122595322): add CTS test for when it's null
if (mMaster.verbose) {
- Slog.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities="
- + activities + ")");
+ Slog.v(TAG, "setContentCaptureWhitelist(" + (packages == null
+ ? "null_packages" : packages.size() + " packages")
+ + ", " + (activities == null
+ ? "null_activities" : activities.size() + " activities") + ")");
}
- setWhitelist(packages, activities);
-
+ synchronized (mLock) {
+ mWhitelistHelper.setWhitelist(packages, activities);
+ }
// TODO(b/119613670): log metrics
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
index da19836..9b2c05f 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
@@ -15,6 +15,12 @@
*/
package com.android.server.contentcapture;
+import static android.service.contentcapture.ContentCaptureService.setClientState;
+import static android.view.contentcapture.ContentCaptureSession.STATE_ACTIVE;
+import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
+import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_RESURRECTED;
+import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_UPDATING;
+
import android.annotation.NonNull;
import android.content.ComponentName;
import android.os.IBinder;
@@ -23,7 +29,6 @@
import android.util.LocalLog;
import android.util.Slog;
import android.view.contentcapture.ContentCaptureContext;
-import android.view.contentcapture.ContentCaptureSession;
import android.view.contentcapture.ContentCaptureSessionId;
import com.android.internal.annotations.GuardedBy;
@@ -38,7 +43,6 @@
final IBinder mActivityToken;
private final ContentCapturePerUserService mService;
- private final RemoteContentCaptureService mRemoteService;
// NOTE: this is the "internal" context (like package and taskId), not the explicit content
// set by apps - those are only send to the ContentCaptureService.
@@ -61,15 +65,13 @@
private final int mUid;
ContentCaptureServerSession(@NonNull IBinder activityToken,
- @NonNull ContentCapturePerUserService service,
- @NonNull RemoteContentCaptureService remoteService,
- @NonNull ComponentName appComponentName, @NonNull IResultReceiver sessionStateReceiver,
+ @NonNull ContentCapturePerUserService service, @NonNull ComponentName appComponentName,
+ @NonNull IResultReceiver sessionStateReceiver,
int taskId, int displayId, @NonNull String sessionId, int uid, int flags) {
mActivityToken = activityToken;
mService = service;
mId = Preconditions.checkNotNull(sessionId);
mUid = uid;
- mRemoteService = remoteService;
mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null,
appComponentName, taskId, displayId, flags);
mSessionStateReceiver = sessionStateReceiver;
@@ -87,8 +89,12 @@
*/
@GuardedBy("mLock")
public void notifySessionStartedLocked(@NonNull IResultReceiver clientReceiver) {
- mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
- ContentCaptureSession.STATE_ACTIVE);
+ if (mService.mRemoteService == null) {
+ Slog.w(TAG, "notifySessionStartedLocked(): no remote service");
+ return;
+ }
+ mService.mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
+ STATE_ACTIVE);
}
/**
@@ -101,7 +107,11 @@
logHistory.log("snapshot: id=" + mId);
}
- mRemoteService.onActivitySnapshotRequest(mId, snapshotData);
+ if (mService.mRemoteService == null) {
+ Slog.w(TAG, "sendActivitySnapshotLocked(): no remote service");
+ return;
+ }
+ mService.mRemoteService.onActivitySnapshotRequest(mId, snapshotData);
}
/**
@@ -134,7 +144,11 @@
}
// TODO(b/111276913): must call client to set session as FINISHED_BY_SERVER
if (notifyRemoteService) {
- mRemoteService.onSessionFinished(mId);
+ if (mService.mRemoteService == null) {
+ Slog.w(TAG, "destroyLocked(): no remote service");
+ return;
+ }
+ mService.mRemoteService.onSessionFinished(mId);
}
}
@@ -143,10 +157,27 @@
*/
@GuardedBy("mLock")
public void resurrectLocked() {
- mRemoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
+ final RemoteContentCaptureService remoteService = mService.mRemoteService;
+ if (remoteService == null) {
+ Slog.w(TAG, "destroyLocked(: no remote service");
+ return;
+ }
+ if (mService.isVerbose()) {
+ Slog.v(TAG, "resurrecting " + mActivityToken + " on " + remoteService);
+ }
+ remoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
ContentCaptureContext.FLAG_RECONNECTED), mId, mUid, mSessionStateReceiver,
- ContentCaptureSession.STATE_ACTIVE
- | ContentCaptureSession.STATE_SERVICE_RESURRECTED);
+ STATE_ACTIVE | STATE_SERVICE_RESURRECTED);
+ }
+
+ /**
+ * Called to pause the session while the service is being updated.
+ */
+ @GuardedBy("mLock")
+ public void pauseLocked() {
+ if (mService.isVerbose()) Slog.v(TAG, "pausing " + mActivityToken);
+ setClientState(mSessionStateReceiver, STATE_DISABLED | STATE_SERVICE_UPDATING,
+ /* binder= */ null);
}
@GuardedBy("mLock")
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 2ce5059..df9ccbc 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -54,7 +54,7 @@
mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
// Bind right away, which will trigger a onConnected() on service's
- scheduleBind();
+ ensureBoundLocked();
}
@Override // from AbstractRemoteService
@@ -89,6 +89,10 @@
}
}
+ public void ensureBoundLocked() {
+ scheduleBind();
+ }
+
/**
* Called by {@link ContentCaptureServerSession} to generate a call to the
* {@link RemoteContentCaptureService} to indicate the session was created.
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index b89223b..f0244c3 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -3597,10 +3597,18 @@
pw.println(" " + provider + ": " + location);
}
- mGeofenceManager.dump(pw);
-
- pw.append(" ");
- mBlacklist.dump(pw);
+ if (mGeofenceManager != null) {
+ mGeofenceManager.dump(pw);
+ } else {
+ pw.println(" Geofences: null");
+ }
+
+ if (mBlacklist != null) {
+ pw.append(" ");
+ mBlacklist.dump(pw);
+ } else {
+ pw.println(" mBlacklist=null");
+ }
if (mLocationControllerExtraPackage != null) {
pw.println(" Location controller extra package: " + mLocationControllerExtraPackage
@@ -3614,8 +3622,12 @@
}
}
- pw.append(" fudger: ");
- mLocationFudger.dump(fd, pw, args);
+ if (mLocationFudger != null) {
+ pw.append(" fudger: ");
+ mLocationFudger.dump(fd, pw, args);
+ } else {
+ pw.println(" fudger: null");
+ }
if (args.length > 0 && "short".equals(args[0])) {
return;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 10b67c1..2e5dd3b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1257,6 +1257,7 @@
}
scheduleWriteLocked();
}
+ uidState.evalForegroundOps(mOpModeWatchers);
}
String[] uidPackageNames = getPackagesForUid(uid);
@@ -2414,8 +2415,6 @@
private void commitUidPendingStateLocked(UidState uidState) {
final boolean lastForeground = uidState.state <= UID_STATE_MAX_LAST_NON_RESTRICTED;
final boolean nowForeground = uidState.pendingState <= UID_STATE_MAX_LAST_NON_RESTRICTED;
- uidState.state = uidState.pendingState;
- uidState.pendingStateCommitTime = 0;
if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
if (!uidState.foregroundOps.valueAt(fgi)) {
@@ -2424,11 +2423,10 @@
final int code = uidState.foregroundOps.keyAt(fgi);
// For location ops we consider fg state only if the fg service
// is of location type, for all other ops any fg service will do.
- final long resolvedLastRestrictedUidState = resolveFirstUnrestrictedUidState(code);
- final boolean resolvedLastFg = uidState.state <= resolvedLastRestrictedUidState;
- final boolean resolvedNowBg = uidState.pendingState
- <= resolvedLastRestrictedUidState;
- if (resolvedLastFg == resolvedNowBg) {
+ final long firstUnrestrictedUidState = resolveFirstUnrestrictedUidState(code);
+ final boolean resolvedLastFg = uidState.state <= firstUnrestrictedUidState;
+ final boolean resolvedNowFg = uidState.pendingState <= firstUnrestrictedUidState;
+ if (resolvedLastFg == resolvedNowFg) {
continue;
}
final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
@@ -2460,6 +2458,8 @@
}
}
}
+ uidState.state = uidState.pendingState;
+ uidState.pendingStateCommitTime = 0;
}
private Ops getOpsRawLocked(int uid, String packageName, boolean edit,
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 3e48445..c60dd6c 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -1251,8 +1251,6 @@
if (getCurrentClient() instanceof InternalRemovalClient
|| getCurrentClient() instanceof InternalEnumerateClient) {
Slog.w(getTag(), "User switched while performing cleanup");
- removeClient(getCurrentClient());
- clearEnumerateState();
}
updateActiveGroup(userId, null);
doTemplateCleanupForUser(userId);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 32f34b8..3010324 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -37,7 +37,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.ColorSpace;
-import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.SensorManager;
@@ -1275,11 +1274,12 @@
if (token == null) {
return false;
}
- final GraphicBuffer gb = SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
- token, new Rect(), 0 /* width */, 0 /* height */, false /* useIdentityTransform */,
- 0 /* rotation */);
+ final SurfaceControl.ScreenshotGraphicBuffer gb =
+ SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
+ token, new Rect(), 0 /* width */, 0 /* height */,
+ false /* useIdentityTransform */, 0 /* rotation */);
try {
- outSurface.attachAndQueueBuffer(gb);
+ outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
} catch (RuntimeException e) {
Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 430203d..ed894ee 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -131,14 +131,10 @@
private final boolean mRefreshServiceOnPackageUpdate;
/**
- * Name of the service's package that was active but then was removed because its package
- * update.
- *
- * <p>It's a temporary state set / used by the {@link PackageMonitor} implementation, but
- * defined here so it can be dumped.
+ * Name of the service packages whose APK are being updated, keyed by user id.
*/
@GuardedBy("mLock")
- private String mLastActivePackageName;
+ private SparseArray<String> mUpdatingPackageNames;
/**
* Default constructor.
@@ -565,6 +561,20 @@
}
/**
+ * Called before the package that provides the service for the given user is being updated.
+ */
+ protected void onServicePackageUpdatingLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")");
+ }
+
+ /**
+ * Called after the package that provides the service for the given user is being updated.
+ */
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
+ }
+
+ /**
* Called after the service is removed from the cache.
*/
@SuppressWarnings("unused")
@@ -602,8 +612,10 @@
final int size = mServicesCache.size();
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
pw.print(" Verbose: "); pw.println(realVerbose);
- pw.print(" Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
- pw.print(" Last active service on update: "); pw.println(mLastActivePackageName);
+ pw.print("Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
+ if (mUpdatingPackageNames != null) {
+ pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
+ }
if (mServiceNameResolver != null) {
pw.print(prefix); pw.print("Name resolver: ");
mServiceNameResolver.dumpShort(pw); pw.println();
@@ -644,39 +656,49 @@
final PackageMonitor monitor = new PackageMonitor() {
@Override
- public void onPackageUpdateStarted(String packageName, int uid) {
+ public void onPackageUpdateStarted(@NonNull String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName);
+ final String activePackageName = getActiveServicePackageNameLocked();
+ if (!packageName.equals(activePackageName)) return;
+
+ final int userId = getChangingUserId();
synchronized (mLock) {
- final String activePackageName = getActiveServicePackageNameLocked();
- if (packageName.equals(activePackageName)) {
- final int userId = getChangingUserId();
- if (mRefreshServiceOnPackageUpdate) {
- if (debug) {
- Slog.d(mTag, "Removing service for user " + userId
- + " because package " + activePackageName
- + " is being updated");
- }
- mLastActivePackageName = activePackageName;
- removeCachedServiceLocked(userId);
- } else {
- if (debug) {
- Slog.d(mTag, "Holding service for user " + userId
- + " while package " + activePackageName
- + " is being updated");
- }
+ if (mUpdatingPackageNames == null) {
+ mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size());
+ }
+ mUpdatingPackageNames.put(userId, packageName);
+ onServicePackageUpdatingLocked(userId);
+ if (mRefreshServiceOnPackageUpdate) {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId + " because package "
+ + activePackageName + " is being updated");
+ }
+ removeCachedServiceLocked(userId);
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being updated");
}
}
}
}
@Override
- public void onPackageUpdateFinished(String packageName, int uid) {
+ public void onPackageUpdateFinished(@NonNull String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName);
+ final int userId = getChangingUserId();
synchronized (mLock) {
- String activePackageName = getActiveServicePackageNameLocked();
- if (activePackageName == null) {
- activePackageName = mLastActivePackageName;
- mLastActivePackageName = null;
- }
- if (!packageName.equals(activePackageName)) {
+ final String activePackageName = mUpdatingPackageNames == null ? null
+ : mUpdatingPackageNames.get(userId);
+ if (packageName.equals(activePackageName)) {
+ if (mUpdatingPackageNames != null) {
+ mUpdatingPackageNames.remove(userId);
+ if (mUpdatingPackageNames.size() == 0) {
+ mUpdatingPackageNames = null;
+ }
+ }
+ onServicePackageUpdatedLocked(userId);
+ } else {
handlePackageUpdateLocked(packageName);
}
}
diff --git a/services/core/java/com/android/server/media/projection/OWNERS b/services/core/java/com/android/server/media/projection/OWNERS
new file mode 100644
index 0000000..7e7335d
--- /dev/null
+++ b/services/core/java/com/android/server/media/projection/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index b0d2704..15ed063 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -83,6 +83,9 @@
if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) {
return true;
}
+ if (!Objects.equals(theTruth.targetOverlayableName, oldSettings.targetOverlayableName)) {
+ return true;
+ }
if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) {
return true;
}
@@ -149,6 +152,7 @@
mSettings.init(overlayPackage.packageName, newUserId,
overlayPackage.overlayTarget,
+ overlayPackage.targetOverlayableName,
overlayPackage.applicationInfo.getBaseCodePath(),
overlayPackage.isStaticOverlayPackage(),
overlayPackage.overlayPriority,
@@ -331,6 +335,7 @@
}
mSettings.init(packageName, userId, overlayPackage.overlayTarget,
+ overlayPackage.targetOverlayableName,
overlayPackage.applicationInfo.getBaseCodePath(),
overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
overlayPackage.overlayCategory);
@@ -395,7 +400,7 @@
if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) {
mListener.onOverlaysChanged(pkg.overlayTarget, userId);
}
- mSettings.init(packageName, userId, pkg.overlayTarget,
+ mSettings.init(packageName, userId, pkg.overlayTarget, pkg.targetOverlayableName,
pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
pkg.overlayPriority, pkg.overlayCategory);
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index 2b4ec03..667dfa1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -65,12 +65,13 @@
private final ArrayList<SettingsItem> mItems = new ArrayList<>();
void init(@NonNull final String packageName, final int userId,
- @NonNull final String targetPackageName, @NonNull final String baseCodePath,
- boolean isStatic, int priority, String overlayCategory) {
+ @NonNull final String targetPackageName, @Nullable final String targetOverlayableName,
+ @NonNull final String baseCodePath, boolean isStatic, int priority,
+ @Nullable String overlayCategory) {
remove(packageName, userId);
final SettingsItem item =
- new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
- isStatic, priority, overlayCategory);
+ new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
+ baseCodePath, isStatic, priority, overlayCategory);
if (isStatic) {
// All static overlays are always enabled.
item.setEnabled(true);
@@ -302,16 +303,17 @@
pw.println(item.mPackageName + ":" + item.getUserId() + " {");
pw.increaseIndent();
- pw.println("mPackageName.......: " + item.mPackageName);
- pw.println("mUserId............: " + item.getUserId());
- pw.println("mTargetPackageName.: " + item.getTargetPackageName());
- pw.println("mBaseCodePath......: " + item.getBaseCodePath());
- pw.println("mState.............: " + OverlayInfo.stateToString(item.getState()));
- pw.println("mState.............: " + OverlayInfo.stateToString(item.getState()));
- pw.println("mIsEnabled.........: " + item.isEnabled());
- pw.println("mIsStatic..........: " + item.isStatic());
- pw.println("mPriority..........: " + item.mPriority);
- pw.println("mCategory..........: " + item.mCategory);
+ pw.println("mPackageName...........: " + item.mPackageName);
+ pw.println("mUserId................: " + item.getUserId());
+ pw.println("mTargetPackageName.....: " + item.getTargetPackageName());
+ pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName());
+ pw.println("mBaseCodePath..........: " + item.getBaseCodePath());
+ pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
+ pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
+ pw.println("mIsEnabled.............: " + item.isEnabled());
+ pw.println("mIsStatic..............: " + item.isStatic());
+ pw.println("mPriority..............: " + item.mPriority);
+ pw.println("mCategory..............: " + item.mCategory);
pw.decreaseIndent();
pw.println("}");
@@ -335,6 +337,7 @@
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_STATE = "state";
private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName";
+ private static final String ATTR_TARGET_OVERLAYABLE_NAME = "targetOverlayableName";
private static final String ATTR_IS_STATIC = "isStatic";
private static final String ATTR_PRIORITY = "priority";
private static final String ATTR_CATEGORY = "category";
@@ -387,6 +390,8 @@
final int userId = XmlUtils.readIntAttribute(parser, ATTR_USER_ID);
final String targetPackageName = XmlUtils.readStringAttribute(parser,
ATTR_TARGET_PACKAGE_NAME);
+ final String targetOverlayableName = XmlUtils.readStringAttribute(parser,
+ ATTR_TARGET_OVERLAYABLE_NAME);
final String baseCodePath = XmlUtils.readStringAttribute(parser, ATTR_BASE_CODE_PATH);
final int state = XmlUtils.readIntAttribute(parser, ATTR_STATE);
final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED);
@@ -394,8 +399,8 @@
final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY);
final String category = XmlUtils.readStringAttribute(parser, ATTR_CATEGORY);
- return new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
- state, isEnabled, isStatic, priority, category);
+ return new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
+ baseCodePath, state, isEnabled, isStatic, priority, category);
}
public static void persist(@NonNull final ArrayList<SettingsItem> table,
@@ -422,6 +427,8 @@
XmlUtils.writeStringAttribute(xml, ATTR_PACKAGE_NAME, item.mPackageName);
XmlUtils.writeIntAttribute(xml, ATTR_USER_ID, item.mUserId);
XmlUtils.writeStringAttribute(xml, ATTR_TARGET_PACKAGE_NAME, item.mTargetPackageName);
+ XmlUtils.writeStringAttribute(xml, ATTR_TARGET_OVERLAYABLE_NAME,
+ item.mTargetOverlayableName);
XmlUtils.writeStringAttribute(xml, ATTR_BASE_CODE_PATH, item.mBaseCodePath);
XmlUtils.writeIntAttribute(xml, ATTR_STATE, item.mState);
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.mIsEnabled);
@@ -436,6 +443,7 @@
private final int mUserId;
private final String mPackageName;
private final String mTargetPackageName;
+ private final String mTargetOverlayableName;
private String mBaseCodePath;
private @OverlayInfo.State int mState;
private boolean mIsEnabled;
@@ -445,12 +453,14 @@
private String mCategory;
SettingsItem(@NonNull final String packageName, final int userId,
- @NonNull final String targetPackageName, @NonNull final String baseCodePath,
+ @NonNull final String targetPackageName,
+ @Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
final @OverlayInfo.State int state, final boolean isEnabled, final boolean isStatic,
- final int priority, String category) {
+ final int priority, @Nullable String category) {
mPackageName = packageName;
mUserId = userId;
mTargetPackageName = targetPackageName;
+ mTargetOverlayableName = targetOverlayableName;
mBaseCodePath = baseCodePath;
mState = state;
mIsEnabled = isEnabled || isStatic;
@@ -461,16 +471,21 @@
}
SettingsItem(@NonNull final String packageName, final int userId,
- @NonNull final String targetPackageName, @NonNull final String baseCodePath,
- final boolean isStatic, final int priority, String category) {
- this(packageName, userId, targetPackageName, baseCodePath, OverlayInfo.STATE_UNKNOWN,
- false, isStatic, priority, category);
+ @NonNull final String targetPackageName,
+ @Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
+ final boolean isStatic, final int priority, @Nullable String category) {
+ this(packageName, userId, targetPackageName, targetOverlayableName, baseCodePath,
+ OverlayInfo.STATE_UNKNOWN, false, isStatic, priority, category);
}
private String getTargetPackageName() {
return mTargetPackageName;
}
+ private String getTargetOverlayableName() {
+ return mTargetOverlayableName;
+ }
+
private int getUserId() {
return mUserId;
}
@@ -520,7 +535,7 @@
private boolean setCategory(String category) {
if (!Objects.equals(mCategory, category)) {
- mCategory = category.intern();
+ mCategory = (category == null) ? null : category.intern();
invalidateCache();
return true;
}
@@ -529,8 +544,8 @@
private OverlayInfo getOverlayInfo() {
if (mCache == null) {
- mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
- mState, mUserId, mPriority, mIsStatic);
+ mCache = new OverlayInfo(mPackageName, mTargetPackageName, mTargetOverlayableName,
+ mCategory, mBaseCodePath, mState, mUserId, mPriority, mIsStatic);
}
return mCache;
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index e36ac23..40f2a2b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1552,13 +1552,13 @@
oldPermAreModernStorageModel = false;
}
- boolean shouldBeRestricted;
+ boolean shouldBeHidden;
boolean shouldBeFixed;
boolean shouldBeGranted = false;
boolean shouldBeRevoked = false;
int userFlags = -1;
if (useLegacyStoragePermissionModel) {
- shouldBeRestricted = isModernStoragePermission;
+ shouldBeHidden = isModernStoragePermission;
shouldBeFixed = isQApp || isModernStoragePermission;
if (shouldBeFixed) {
@@ -1576,7 +1576,7 @@
shouldBeRevoked = !shouldBeGranted;
}
} else {
- shouldBeRestricted = isLegacyStoragePermission;
+ shouldBeHidden = isLegacyStoragePermission;
shouldBeFixed = isLegacyStoragePermission;
if (shouldBeFixed) {
@@ -1636,7 +1636,12 @@
changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), userId,
FLAG_PERMISSION_HIDDEN,
- shouldBeRestricted ? FLAG_PERMISSION_HIDDEN : 0);
+ shouldBeHidden ? FLAG_PERMISSION_HIDDEN : 0);
+
+ if (shouldBeHidden) {
+ changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm),
+ userId, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
+ }
}
if (changed) {
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index b7be768..fe0b9a6 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -45,6 +45,7 @@
import com.android.server.power.BatterySaverStateMachineProto;
import java.io.PrintWriter;
+import java.text.NumberFormat;
/**
* Decides when to enable / disable battery saver.
@@ -791,7 +792,7 @@
manager.notify(DYNAMIC_MODE_NOTIFICATION_ID,
buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID,
- R.string.dynamic_mode_notification_title,
+ mContext.getResources().getString(R.string.dynamic_mode_notification_title),
R.string.dynamic_mode_notification_summary,
Intent.ACTION_POWER_USAGE_SUMMARY));
}
@@ -801,10 +802,13 @@
ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID,
R.string.battery_saver_notification_channel_name);
+ final String percentage = NumberFormat.getPercentInstance()
+ .format((double) mBatteryLevel / 100.0);
manager.notify(STICKY_AUTO_DISABLED_NOTIFICATION_ID,
buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID,
- R.string.battery_saver_sticky_disabled_notification_title,
- R.string.battery_saver_sticky_disabled_notification_summary,
+ mContext.getResources().getString(
+ R.string.battery_saver_charged_notification_title, percentage),
+ R.string.battery_saver_off_notification_summary,
Settings.ACTION_BATTERY_SAVER_SETTINGS));
}
@@ -816,7 +820,7 @@
manager.createNotificationChannel(channel);
}
- private Notification buildNotification(@NonNull String channelId, @StringRes int titleId,
+ private Notification buildNotification(@NonNull String channelId, @NonNull String title,
@StringRes int summaryId, @NonNull String intentAction) {
Resources res = mContext.getResources();
Intent intent = new Intent(intentAction);
@@ -827,11 +831,12 @@
return new Notification.Builder(mContext, channelId)
.setSmallIcon(R.drawable.ic_battery)
- .setContentTitle(res.getString(titleId))
+ .setContentTitle(title)
.setContentText(summary)
.setContentIntent(batterySaverIntent)
.setStyle(new Notification.BigTextStyle().bigText(summary))
.setOnlyAlertOnce(true)
+ .setAutoCancel(true)
.build();
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index d69ae3d..24b0213 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -845,6 +845,11 @@
return mService.mAmInternal.getCurrentProfileIds();
}
+ @VisibleForTesting
+ boolean isUserRunning(int userId, int flags) {
+ return mService.mAmInternal.isUserRunning(userId, flags);
+ }
+
/**
* @return the list of recent tasks for presentation.
*/
@@ -861,7 +866,7 @@
boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) {
final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;
- if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
+ if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) {
Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
return new ArrayList<>();
}
@@ -881,7 +886,7 @@
if (isVisibleRecentTask(tr)) {
numVisibleTasks++;
- if (isInVisibleRange(tr, numVisibleTasks)) {
+ if (isInVisibleRange(tr, numVisibleTasks, withExcluded)) {
// Fall through
} else {
// Not in visible range
@@ -908,51 +913,43 @@
continue;
}
- // Return the entry if desired by the caller. We always return
- // the first entry, because callers always expect this to be the
- // foreground app. We may filter others if the caller has
- // not supplied RECENT_WITH_EXCLUDED and there is some reason
- // we should exclude the entry.
-
- if (i == 0
- || withExcluded
- || (tr.intent == null)
- || ((tr.intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- == 0)) {
- if (!getTasksAllowed) {
- // If the caller doesn't have the GET_TASKS permission, then only
- // allow them to see a small subset of tasks -- their own and home.
- if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
- continue;
- }
- }
- if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
- // Don't include auto remove tasks that are finished or finishing.
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, auto-remove without activity: " + tr);
+ if (!getTasksAllowed) {
+ // If the caller doesn't have the GET_TASKS permission, then only
+ // allow them to see a small subset of tasks -- their own and home.
+ if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
+ if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
continue;
}
- if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, unavail real act: " + tr);
- continue;
- }
-
- if (!tr.mUserSetupComplete) {
- // Don't include task launched while user is not done setting-up.
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, user setup not complete: " + tr);
- continue;
- }
-
- final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
- if (!getDetailedTasks) {
- rti.baseIntent.replaceExtras((Bundle)null);
- }
-
- res.add(rti);
}
+
+ if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
+ // Don't include auto remove tasks that are finished or finishing.
+ if (DEBUG_RECENTS) {
+ Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + tr);
+ }
+ continue;
+ }
+ if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
+ if (DEBUG_RECENTS) {
+ Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + tr);
+ }
+ continue;
+ }
+
+ if (!tr.mUserSetupComplete) {
+ // Don't include task launched while user is not done setting-up.
+ if (DEBUG_RECENTS) {
+ Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr);
+ }
+ continue;
+ }
+
+ final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
+ if (!getDetailedTasks) {
+ rti.baseIntent.replaceExtras((Bundle) null);
+ }
+
+ res.add(rti);
}
return res;
}
@@ -994,7 +991,7 @@
final TaskRecord tr = mTasks.get(i);
if (isVisibleRecentTask(tr)) {
numVisibleTasks++;
- if (isInVisibleRange(tr, numVisibleTasks)) {
+ if (isInVisibleRange(tr, numVisibleTasks, false /* skipExcludedCheck */)) {
res.put(tr.taskId, true);
}
}
@@ -1215,7 +1212,8 @@
continue;
} else {
numVisibleTasks++;
- if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) {
+ if (isInVisibleRange(task, numVisibleTasks, false /* skipExcludedCheck */)
+ || !isTrimmable(task)) {
// Keep visible tasks in range
i++;
continue;
@@ -1329,14 +1327,17 @@
/**
* @return whether the given visible task is within the policy range.
*/
- private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) {
- // Keep the last most task even if it is excluded from recents
- final boolean isExcludeFromRecents =
- (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
- if (isExcludeFromRecents) {
- if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
- return numVisibleTasks == 1;
+ private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks,
+ boolean skipExcludedCheck) {
+ if (!skipExcludedCheck) {
+ // Keep the most recent task even if it is excluded from recents
+ final boolean isExcludeFromRecents =
+ (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+ if (isExcludeFromRecents) {
+ if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
+ return numVisibleTasks == 1;
+ }
}
if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) {
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index e0d85e8..4379b7c 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -41,7 +41,7 @@
return new TaskScreenshotAnimatable(task, getBufferFromTask(task));
}
- private static GraphicBuffer getBufferFromTask(Task task) {
+ private static SurfaceControl.ScreenshotGraphicBuffer getBufferFromTask(Task task) {
if (task == null) {
return null;
}
@@ -51,7 +51,10 @@
task.getSurfaceControl().getHandle(), tmpRect, 1f);
}
- private TaskScreenshotAnimatable(Task task, GraphicBuffer buffer) {
+ private TaskScreenshotAnimatable(Task task,
+ SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer) {
+ GraphicBuffer buffer = screenshotBuffer == null
+ ? null : screenshotBuffer.getGraphicBuffer();
mTask = task;
mWidth = (buffer != null) ? buffer.getWidth() : 1;
mHeight = (buffer != null) ? buffer.getHeight() : 1;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index beb3d82..6fe8b43 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -279,8 +279,11 @@
Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task);
return null;
}
- final GraphicBuffer buffer = SurfaceControl.captureLayers(
- task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+ final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
+ SurfaceControl.captureLayers(
+ task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+ final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
+ : null;
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
if (DEBUG_SCREENSHOT) {
Slog.w(TAG_WM, "Failed to take screenshot for " + task);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index dddc6b7..166a33d 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -34,8 +34,6 @@
import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
import android.graphics.Bitmap;
-import android.graphics.ColorSpace;
-import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Bundle;
@@ -738,17 +736,16 @@
final Rect bounds = wallpaperWindowState.getBounds();
bounds.offsetTo(0, 0);
- GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
+ SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);
if (wallpaperBuffer == null) {
Slog.w(TAG_WM, "Failed to screenshot wallpaper");
return null;
}
- // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
- // should continue to fix screenshot.
- return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer),
- ColorSpace.get(ColorSpace.Named.SRGB));
+ return Bitmap.wrapHardwareBuffer(
+ HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()),
+ wallpaperBuffer.getColorSpace());
}
private WindowState getTopVisibleWallpaper() {
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 65a7eec..7df7ef3 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -998,8 +998,9 @@
template<class T>
size_t getMeasurementCount(const T& data);
- jobject translateGnssClock(
- JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
+ template<class T>
+ void translateGnssClock(JavaObject& object, const T& data);
+
void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
};
@@ -1025,12 +1026,12 @@
void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
JNIEnv* env = getJniEnv();
- jobject clock;
- jobjectArray measurementArray;
+ JavaObject gnssClockJavaObject(env, "android/location/GnssClock");
+ translateGnssClock(gnssClockJavaObject, data);
+ jobject clock = gnssClockJavaObject.get();
- clock = translateGnssClock(env, &data.clock);
size_t count = getMeasurementCount(data);
- measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
+ jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
setMeasurementData(env, clock, measurementArray);
env->DeleteLocalRef(clock);
@@ -1124,43 +1125,59 @@
SET(ConstellationType, static_cast<int32_t>(measurement_V2_0->constellation));
}
-jobject GnssMeasurementCallback::translateGnssClock(
- JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
- JavaObject object(env, "android/location/GnssClock");
+template<class T>
+void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) {
+ translateGnssClock(object, data.clock);
+}
- uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
+template<>
+void GnssMeasurementCallback::translateGnssClock(
+ JavaObject& object, const IGnssMeasurementCallback_V1_0::GnssClock& clock) {
+ uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags);
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
- SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
+ SET(LeapSecond, static_cast<int32_t>(clock.leapSecond));
}
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
- SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
+ SET(TimeUncertaintyNanos, clock.timeUncertaintyNs);
}
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
- SET(FullBiasNanos, clock->fullBiasNs);
+ SET(FullBiasNanos, clock.fullBiasNs);
}
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
- SET(BiasNanos, clock->biasNs);
+ SET(BiasNanos, clock.biasNs);
}
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
- SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
+ SET(BiasUncertaintyNanos, clock.biasUncertaintyNs);
}
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
- SET(DriftNanosPerSecond, clock->driftNsps);
+ SET(DriftNanosPerSecond, clock.driftNsps);
}
if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
- SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
+ SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps);
}
- SET(TimeNanos, clock->timeNs);
- SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
+ SET(TimeNanos, clock.timeNs);
+ SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount);
+}
- return object.get();
+template<>
+void GnssMeasurementCallback::translateGnssClock(
+ JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) {
+ auto elapsedRealtime = data.elapsedRealtime;
+ uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
+ if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+ SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
+ }
+ if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+ SET(ElapsedRealtimeUncertaintyNanos, static_cast<uint64_t>(elapsedRealtime.timeUncertaintyNs));
+ }
+ translateGnssClock(object, data.clock);
}
template<class T>
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 23bae88..de4fb98 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -37,6 +37,7 @@
import android.platform.test.annotations.Presubmit;
import android.util.SparseIntArray;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
@@ -118,6 +119,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnIntentStarted() throws Exception {
Intent intent = new Intent("action 1");
@@ -128,6 +130,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnIntentFailed() throws Exception {
testOnIntentStarted();
@@ -143,6 +146,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunched() throws Exception {
testOnIntentStarted();
@@ -154,6 +158,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchFinished() throws Exception {
testOnActivityLaunched();
@@ -168,6 +173,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchCancelled() throws Exception {
testOnActivityLaunched();
@@ -181,6 +187,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchedTrampoline() throws Exception {
testOnIntentStarted();
@@ -197,6 +204,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchFinishedTrampoline() throws Exception {
testOnActivityLaunchedTrampoline();
@@ -211,6 +219,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchCancelledTrampoline() throws Exception {
testOnActivityLaunchedTrampoline();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 68e7470..08e6ce4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -29,7 +30,9 @@
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -512,6 +515,52 @@
}
@Test
+ public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() {
+ // Create some set of tasks, some of which are visible and some are not
+ TaskRecord homeTask = setTaskActivityType(
+ createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
+ ACTIVITY_TYPE_HOME);
+ homeTask.mUserSetupComplete = true;
+ mRecentTasks.add(homeTask);
+ TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ excludedTask1.mUserSetupComplete = true;
+ mRecentTasks.add(excludedTask1);
+
+ // Expect that the first visible excluded-from-recents task is visible
+ assertGetRecentTasksOrder(0 /* flags */, excludedTask1);
+ }
+
+ @Test
+ public void testVisibleTasks_excludedFromRecents_withExcluded() {
+ // Create some set of tasks, some of which are visible and some are not
+ TaskRecord t1 = createTaskBuilder("com.android.pkg1", ".Task1").build();
+ t1.mUserSetupComplete = true;
+ mRecentTasks.add(t1);
+ TaskRecord homeTask = setTaskActivityType(
+ createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
+ ACTIVITY_TYPE_HOME);
+ homeTask.mUserSetupComplete = true;
+ mRecentTasks.add(homeTask);
+ TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ excludedTask1.mUserSetupComplete = true;
+ mRecentTasks.add(excludedTask1);
+ TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ excludedTask2.mUserSetupComplete = true;
+ mRecentTasks.add(excludedTask2);
+ TaskRecord t2 = createTaskBuilder("com.android.pkg2", ".Task1").build();
+ t2.mUserSetupComplete = true;
+ mRecentTasks.add(t2);
+
+ assertGetRecentTasksOrder(RECENT_WITH_EXCLUDED, t2, excludedTask2, excludedTask1, t1);
+ }
+
+ @Test
public void testVisibleTasks_minNum() {
mRecentTasks.setOnlyTestVisibleRange();
mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */);
@@ -830,7 +879,7 @@
}
/**
- * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
+ * Ensures that the raw recent tasks list is in the provided order. Note that the expected tasks
* should be ordered from least to most recent.
*/
private void assertRecentTasksOrder(TaskRecord... expectedTasks) {
@@ -841,6 +890,22 @@
}
}
+ /**
+ * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
+ * should be ordered from least to most recent.
+ */
+ private void assertGetRecentTasksOrder(int getRecentTaskFlags, TaskRecord... expectedTasks) {
+ doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt());
+ doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt());
+ List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, getRecentTaskFlags,
+ true /* getTasksAllowed */, false /* getDetailedTasks */,
+ TEST_USER_0_ID, 0).getList();
+ assertTrue(expectedTasks.length == infos.size());
+ for (int i = 0; i < infos.size(); i++) {
+ assertTrue(expectedTasks[i].taskId == infos.get(i).taskId);
+ }
+ }
+
private void assertNotRestoreTask(Runnable action) {
// Verify stack count doesn't change because task with fullscreen mode and standard type
// would have its own stack.
@@ -1018,7 +1083,7 @@
@Override
protected RecentTasks createRecentTasks() {
- return new TestRecentTasks(this, mTaskPersister);
+ return spy(new TestRecentTasks(this, mTaskPersister));
}
@Override
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 75e6186..0a9b904 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1862,12 +1862,32 @@
"use_wfc_home_network_mode_in_roaming_network_bool";
/**
+ * Flag specifying whether the carrier is allowed to use metered network to download a
+ * certificate of Carrier-WiFi.
+ * {@code false} - default value.
+ *
+ * @hide
+ */
+ public static final String KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL =
+ "allow_metered_network_for_cert_download_bool";
+
+ /**
* Carrier specified WiFi networks.
* @hide
*/
public static final String KEY_CARRIER_WIFI_STRING_ARRAY = "carrier_wifi_string_array";
/**
+ * Base64 Encoding method the carrier will use for encoding encrypted IMSI and SSID.
+ * The value set as below:
+ * 2045 - RFC2045 (default value)
+ * 4648 - RFC4648
+ *
+ * @hide
+ */
+ public static final String KEY_IMSI_ENCODING_METHOD_INT = "imsi_encoding_method_int";
+
+ /**
* Time delay (in ms) after which we show the notification to switch the preferred
* network.
* @hide
@@ -2682,6 +2702,14 @@
"cdma_enhanced_roaming_indicator_for_home_network_int_array";
/**
+ * Determines whether wifi calling location privacy policy is shown.
+ *
+ * @hide
+ */
+ public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL =
+ "show_wfc_location_privacy_policy_bool";
+
+ /**
* Indicates use 3GPP application to replace 3GPP2 application even if it's a CDMA/CDMA-LTE
* phone, becasue some carriers's CSIM application is present but not supported.
* @hide
@@ -2998,7 +3026,9 @@
sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
+ sDefaults.putBoolean(KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL, false);
sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null);
+ sDefaults.putInt(KEY_IMSI_ENCODING_METHOD_INT, 2045);
sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1);
sDefaults.putInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1);
sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true);
@@ -3089,6 +3119,7 @@
});
sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]);
sDefaults.putBoolean(KEY_USE_USIM_BOOL, false);
+ sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, true);
sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN,
false);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 49398ed..a794ba1 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1132,7 +1132,7 @@
}
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @TestApi
public void setVoiceRoamingType(@RoamingType int type) {
NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1153,7 +1153,7 @@
}
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @TestApi
public void setDataRoamingType(@RoamingType int type) {
NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index 6765316..a87e2f5 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -3,6 +3,7 @@
public class MockContext extends android.content.Context {
method public android.view.Display getDisplay();
+ method public int getDisplayId();
}
@Deprecated public class MockPackageManager extends android.content.pm.PackageManager {
diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
index 37d5f0a..e1d82f8 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
@@ -1169,6 +1169,8 @@
* (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
* <p>
* Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
+ *
+ * @hide
*/
public boolean getRegisteredLocationDseIndication() {
if (!mIsLciValid) {
@@ -1185,6 +1187,8 @@
* (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
* <p>
* Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
+ *
+ * @hide
*/
public boolean getDependentStationIndication() {
if (!mIsLciValid) {