Merge "Reduce flakiness of TaskStackChangedListenerTest"
diff --git a/cmds/idmap2/tests/ResultTests.cpp b/cmds/idmap2/tests/ResultTests.cpp
index cbced0a..f2f8854 100644
--- a/cmds/idmap2/tests/ResultTests.cpp
+++ b/cmds/idmap2/tests/ResultTests.cpp
@@ -260,7 +260,8 @@
struct NoCopyContainer {
uint32_t value; // NOLINT(misc-non-private-member-variables-in-classes)
- DISALLOW_COPY_AND_ASSIGN(NoCopyContainer);
+ NoCopyContainer(const NoCopyContainer&) = delete;
+ NoCopyContainer& operator=(const NoCopyContainer&) = delete;
};
Result<std::unique_ptr<NoCopyContainer>> CreateNoCopyContainer(bool succeed) {
diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java
index 7f43640..fa135b1 100644
--- a/core/java/android/app/prediction/AppPredictor.java
+++ b/core/java/android/app/prediction/AppPredictor.java
@@ -83,6 +83,8 @@
private final AppPredictionSessionId mSessionId;
private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>();
+ private final IBinder mToken = new Binder();
+
/**
* Creates a new Prediction client.
* <p>
@@ -98,7 +100,7 @@
mSessionId = new AppPredictionSessionId(
context.getPackageName() + ":" + UUID.randomUUID().toString(), context.getUserId());
try {
- mPredictionManager.createPredictionSession(predictionContext, mSessionId);
+ mPredictionManager.createPredictionSession(predictionContext, mSessionId, mToken);
} catch (RemoteException e) {
Log.e(TAG, "Failed to create predictor", e);
e.rethrowAsRuntimeException();
diff --git a/core/java/android/app/prediction/IPredictionManager.aidl b/core/java/android/app/prediction/IPredictionManager.aidl
index 587e3fd..863fc6f9 100644
--- a/core/java/android/app/prediction/IPredictionManager.aidl
+++ b/core/java/android/app/prediction/IPredictionManager.aidl
@@ -29,7 +29,7 @@
interface IPredictionManager {
void createPredictionSession(in AppPredictionContext context,
- in AppPredictionSessionId sessionId);
+ in AppPredictionSessionId sessionId, in IBinder token);
void notifyAppTargetEvent(in AppPredictionSessionId sessionId, in AppTargetEvent event);
diff --git a/core/java/android/app/timezonedetector/ITimeZoneConfigurationListener.aidl b/core/java/android/app/timezonedetector/ITimeZoneConfigurationListener.aidl
index af77fe0..6d0fe72 100644
--- a/core/java/android/app/timezonedetector/ITimeZoneConfigurationListener.aidl
+++ b/core/java/android/app/timezonedetector/ITimeZoneConfigurationListener.aidl
@@ -20,5 +20,5 @@
/** {@hide} */
oneway interface ITimeZoneConfigurationListener {
- void onChange(in TimeZoneConfiguration configuration);
+ void onChange();
}
\ No newline at end of file
diff --git a/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl b/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
index 6e93af6..4f7e1f6 100644
--- a/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
+++ b/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
@@ -32,17 +32,15 @@
* this Binder interface directly. See {@link android.app.timezonedetector.TimeZoneDetectorService}
* for more complete documentation.
*
- *
* {@hide}
*/
interface ITimeZoneDetectorService {
TimeZoneCapabilities getCapabilities();
-
- TimeZoneConfiguration getConfiguration();
- boolean updateConfiguration(in TimeZoneConfiguration configuration);
void addConfigurationListener(ITimeZoneConfigurationListener listener);
void removeConfigurationListener(ITimeZoneConfigurationListener listener);
+ boolean updateConfiguration(in TimeZoneConfiguration configuration);
+
boolean suggestManualTimeZone(in ManualTimeZoneSuggestion timeZoneSuggestion);
void suggestTelephonyTimeZone(in TelephonyTimeZoneSuggestion timeZoneSuggestion);
}
diff --git a/core/java/android/app/timezonedetector/TimeZoneCapabilities.java b/core/java/android/app/timezonedetector/TimeZoneCapabilities.java
index cc0af3f..09fffe9 100644
--- a/core/java/android/app/timezonedetector/TimeZoneCapabilities.java
+++ b/core/java/android/app/timezonedetector/TimeZoneCapabilities.java
@@ -16,9 +16,12 @@
package android.app.timezonedetector;
+import static android.app.timezonedetector.TimeZoneConfiguration.SETTING_AUTO_DETECTION_ENABLED;
+import static android.app.timezonedetector.TimeZoneConfiguration.SETTING_GEO_DETECTION_ENABLED;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.UserIdInt;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,9 +41,9 @@
*
* <p>Actions have associated methods, see the documentation for each action for details.
*
- * <p>For configuration capabilities, the associated current configuration value can be retrieved
- * using {@link TimeZoneDetector#getConfiguration()} and may be changed using
- * {@link TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)}.
+ * <p>For configuration settings capabilities, the associated settings value can be found via
+ * {@link #getConfiguration()} and may be changed using {@link
+ * TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} (if the user's capabilities allow).
*
* <p>Note: Capabilities are independent of app permissions required to call the associated APIs.
*
@@ -60,7 +63,8 @@
public static final int CAPABILITY_NOT_SUPPORTED = 10;
/**
- * Indicates that a capability is supported on this device, but not allowed for the user.
+ * Indicates that a capability is supported on this device, but not allowed for the user, e.g.
+ * if the capability relates to the ability to modify settings the user is not able to.
* This could be because of the user's type (e.g. maybe it applies to the primary user only) or
* device policy. Depending on the capability, this could mean the associated UI
* should be hidden, or displayed but disabled.
@@ -68,9 +72,11 @@
public static final int CAPABILITY_NOT_ALLOWED = 20;
/**
- * Indicates that a capability is possessed but not applicable, e.g. if it is configuration,
- * the current configuration or device state renders it irrelevant. The associated UI may be
- * hidden, disabled, or left visible (but ineffective) depending on requirements.
+ * Indicates that a capability is possessed but not currently applicable, e.g. if the
+ * capability relates to the ability to modify settings, the user has the ability to modify
+ * it, but it is currently rendered irrelevant by other settings or other device state (flags,
+ * resource config, etc.). The associated UI may be hidden, disabled, or left visible (but
+ * ineffective) depending on requirements.
*/
public static final int CAPABILITY_NOT_APPLICABLE = 30;
@@ -89,13 +95,13 @@
};
- private final @UserIdInt int mUserId;
+ @NonNull private final TimeZoneConfiguration mConfiguration;
private final @CapabilityState int mConfigureAutoDetectionEnabled;
private final @CapabilityState int mConfigureGeoDetectionEnabled;
private final @CapabilityState int mSuggestManualTimeZone;
private TimeZoneCapabilities(@NonNull Builder builder) {
- this.mUserId = builder.mUserId;
+ this.mConfiguration = Objects.requireNonNull(builder.mConfiguration);
this.mConfigureAutoDetectionEnabled = builder.mConfigureAutoDetectionEnabled;
this.mConfigureGeoDetectionEnabled = builder.mConfigureGeoDetectionEnabled;
this.mSuggestManualTimeZone = builder.mSuggestManualTimeZone;
@@ -103,7 +109,8 @@
@NonNull
private static TimeZoneCapabilities createFromParcel(Parcel in) {
- return new TimeZoneCapabilities.Builder(in.readInt())
+ return new TimeZoneCapabilities.Builder()
+ .setConfiguration(in.readParcelable(null))
.setConfigureAutoDetectionEnabled(in.readInt())
.setConfigureGeoDetectionEnabled(in.readInt())
.setSuggestManualTimeZone(in.readInt())
@@ -112,21 +119,24 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mUserId);
+ dest.writeParcelable(mConfiguration, flags);
dest.writeInt(mConfigureAutoDetectionEnabled);
dest.writeInt(mConfigureGeoDetectionEnabled);
dest.writeInt(mSuggestManualTimeZone);
}
- /** Returns the user ID the capabilities are for. */
- public @UserIdInt int getUserId() {
- return mUserId;
+ /**
+ * Returns the user's time zone behavior configuration.
+ */
+ public @NonNull TimeZoneConfiguration getConfiguration() {
+ return mConfiguration;
}
/**
- * Returns the user's capability state for controlling whether automatic time zone detection is
- * enabled via {@link TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and {@link
- * TimeZoneConfiguration#isAutoDetectionEnabled()}.
+ * Returns the capability state associated with the user's ability to modify the automatic time
+ * zone detection setting. The setting can be updated via {@link
+ * TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and accessed via {@link
+ * #getConfiguration()}.
*/
@CapabilityState
public int getConfigureAutoDetectionEnabled() {
@@ -134,9 +144,10 @@
}
/**
- * Returns the user's capability state for controlling whether geolocation can be used to detect
- * time zone via {@link TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and {@link
- * TimeZoneConfiguration#isGeoDetectionEnabled()}.
+ * Returns the capability state associated with the user's ability to modify the geolocation
+ * detection setting. The setting can be updated via {@link
+ * TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and accessed via {@link
+ * #getConfiguration()}.
*/
@CapabilityState
public int getConfigureGeoDetectionEnabled() {
@@ -144,8 +155,8 @@
}
/**
- * Returns the user's capability state for manually setting the time zone on a device via
- * {@link TimeZoneDetector#suggestManualTimeZone(ManualTimeZoneSuggestion)}.
+ * Returns the capability state associated with the user's ability to manually set the time zone
+ * on a device via {@link TimeZoneDetector#suggestManualTimeZone(ManualTimeZoneSuggestion)}.
*
* <p>The suggestion will be ignored in all cases unless the value is {@link
* #CAPABILITY_POSSESSED}. See also {@link TimeZoneConfiguration#isAutoDetectionEnabled()}.
@@ -155,6 +166,38 @@
return mSuggestManualTimeZone;
}
+ /**
+ * Constructs a new {@link TimeZoneConfiguration} from an {@code oldConfiguration} and a set of
+ * {@code requestedChanges}, if the current capabilities allow. The new configuration is
+ * returned and the capabilities are left unchanged. If the capabilities do not permit one or
+ * more of the changes then {@code null} is returned.
+ */
+ @Nullable
+ public TimeZoneConfiguration applyUpdate(TimeZoneConfiguration requestedChanges) {
+ if (requestedChanges.getUserId() != mConfiguration.getUserId()) {
+ throw new IllegalArgumentException("User does not match:"
+ + " this=" + mConfiguration + ", other=" + requestedChanges);
+ }
+
+ TimeZoneConfiguration.Builder newConfigBuilder =
+ new TimeZoneConfiguration.Builder(mConfiguration);
+ if (requestedChanges.hasSetting(SETTING_AUTO_DETECTION_ENABLED)) {
+ if (getConfigureAutoDetectionEnabled() < CAPABILITY_NOT_APPLICABLE) {
+ return null;
+ }
+ newConfigBuilder.setAutoDetectionEnabled(requestedChanges.isAutoDetectionEnabled());
+ }
+
+ if (requestedChanges.hasSetting(SETTING_GEO_DETECTION_ENABLED)) {
+ if (getConfigureGeoDetectionEnabled() < CAPABILITY_NOT_APPLICABLE) {
+ return null;
+ }
+ newConfigBuilder.setGeoDetectionEnabled(requestedChanges.isGeoDetectionEnabled());
+ }
+
+ return newConfigBuilder.build();
+ }
+
@Override
public int describeContents() {
return 0;
@@ -169,7 +212,7 @@
return false;
}
TimeZoneCapabilities that = (TimeZoneCapabilities) o;
- return mUserId == that.mUserId
+ return Objects.equals(mConfiguration, that.mConfiguration)
&& mConfigureAutoDetectionEnabled == that.mConfigureAutoDetectionEnabled
&& mConfigureGeoDetectionEnabled == that.mConfigureGeoDetectionEnabled
&& mSuggestManualTimeZone == that.mSuggestManualTimeZone;
@@ -177,7 +220,7 @@
@Override
public int hashCode() {
- return Objects.hash(mUserId,
+ return Objects.hash(mConfiguration,
mConfigureAutoDetectionEnabled,
mConfigureGeoDetectionEnabled,
mSuggestManualTimeZone);
@@ -186,7 +229,7 @@
@Override
public String toString() {
return "TimeZoneDetectorCapabilities{"
- + "mUserId=" + mUserId
+ + "mConfiguration=" + mConfiguration
+ ", mConfigureAutomaticDetectionEnabled=" + mConfigureAutoDetectionEnabled
+ ", mConfigureGeoDetectionEnabled=" + mConfigureGeoDetectionEnabled
+ ", mSuggestManualTimeZone=" + mSuggestManualTimeZone
@@ -196,16 +239,18 @@
/** @hide */
public static class Builder {
- private final @UserIdInt int mUserId;
+ private TimeZoneConfiguration mConfiguration;
private @CapabilityState int mConfigureAutoDetectionEnabled;
private @CapabilityState int mConfigureGeoDetectionEnabled;
private @CapabilityState int mSuggestManualTimeZone;
- /**
- * Creates a new Builder with no properties set.
- */
- public Builder(@UserIdInt int userId) {
- mUserId = userId;
+ /** Sets the user-visible configuration settings. */
+ public Builder setConfiguration(@NonNull TimeZoneConfiguration configuration) {
+ if (!configuration.isComplete()) {
+ throw new IllegalArgumentException(configuration + " is not complete");
+ }
+ this.mConfiguration = configuration;
+ return this;
}
/** Sets the state for the automatic time zone detection enabled config. */
diff --git a/core/java/android/app/timezonedetector/TimeZoneConfiguration.java b/core/java/android/app/timezonedetector/TimeZoneConfiguration.java
index 6f84ee2..95db0a2 100644
--- a/core/java/android/app/timezonedetector/TimeZoneConfiguration.java
+++ b/core/java/android/app/timezonedetector/TimeZoneConfiguration.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.StringDef;
+import android.annotation.UserIdInt;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,21 +28,20 @@
import java.util.Objects;
/**
- * Configuration that controls the behavior of the time zone detector associated with a specific
- * user.
+ * User visible settings that control the behavior of the time zone detector / manual time zone
+ * entry.
*
- * <p>Configuration consists of a set of known properties. When reading configuration via
- * {@link TimeZoneDetector#getConfiguration()} values for all known properties will be provided. In
- * some cases, such as when the configuration relies on optional hardware, the values may be
- * meaningless / defaulted to safe values.
+ * <p>When reading the configuration, values for all settings will be provided. In some cases, such
+ * as when the device behavior relies on optional hardware / OEM configuration, or the value of
+ * several settings, the device behavior may not be directly affected by the setting value.
*
- * <p>Configuration properties can be left absent when updating configuration via {@link
- * TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and those values will not be
- * changed. Not all configuration properties can be modified by all users. See {@link
- * TimeZoneDetector#getCapabilities()} and {@link TimeZoneCapabilities}.
+ * <p>Settings can be left absent when updating configuration via {@link
+ * TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and those settings will not be
+ * changed. Not all configuration settings can be modified by all users: see {@link
+ * TimeZoneDetector#getCapabilities()} and {@link TimeZoneCapabilities} for details.
*
- * <p>See {@link #isComplete()} to tell if all known properties are present, and {@link
- * #hasProperty(String)} with {@code PROPERTY_} constants for testing individual properties.
+ * <p>See {@link #hasSetting(String)} with {@code PROPERTY_} constants for testing for the presence
+ * of individual settings.
*
* @hide
*/
@@ -59,80 +59,82 @@
};
/** All configuration properties */
- @StringDef(PROPERTY_AUTO_DETECTION_ENABLED)
+ @StringDef({ SETTING_AUTO_DETECTION_ENABLED, SETTING_GEO_DETECTION_ENABLED })
@Retention(RetentionPolicy.SOURCE)
- @interface Property {}
+ @interface Setting {}
/** See {@link TimeZoneConfiguration#isAutoDetectionEnabled()} for details. */
- @Property
- public static final String PROPERTY_AUTO_DETECTION_ENABLED = "autoDetectionEnabled";
+ @Setting
+ public static final String SETTING_AUTO_DETECTION_ENABLED = "autoDetectionEnabled";
/** See {@link TimeZoneConfiguration#isGeoDetectionEnabled()} for details. */
- @Property
- public static final String PROPERTY_GEO_DETECTION_ENABLED = "geoDetectionEnabled";
+ @Setting
+ public static final String SETTING_GEO_DETECTION_ENABLED = "geoDetectionEnabled";
- private final Bundle mBundle;
+ private final @UserIdInt int mUserId;
+ @NonNull private final Bundle mBundle;
private TimeZoneConfiguration(Builder builder) {
- this.mBundle = builder.mBundle;
+ this.mUserId = builder.mUserId;
+ this.mBundle = Objects.requireNonNull(builder.mBundle);
}
private static TimeZoneConfiguration createFromParcel(Parcel in) {
- return new TimeZoneConfiguration.Builder()
+ return new TimeZoneConfiguration.Builder(in.readInt())
.setPropertyBundleInternal(in.readBundle())
.build();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mUserId);
dest.writeBundle(mBundle);
}
- /** Returns {@code true} if all known properties are set. */
- public boolean isComplete() {
- return hasProperty(PROPERTY_AUTO_DETECTION_ENABLED)
- && hasProperty(PROPERTY_GEO_DETECTION_ENABLED);
+ /** Returns the ID of the user this configuration is associated with. */
+ public @UserIdInt int getUserId() {
+ return mUserId;
}
- /** Returns true if the specified property is set. */
- public boolean hasProperty(@Property String property) {
- return mBundle.containsKey(property);
+ /** Returns {@code true} if all known settings are present. */
+ public boolean isComplete() {
+ return hasSetting(SETTING_AUTO_DETECTION_ENABLED)
+ && hasSetting(SETTING_GEO_DETECTION_ENABLED);
+ }
+
+ /** Returns true if the specified setting is set. */
+ public boolean hasSetting(@Setting String setting) {
+ return mBundle.containsKey(setting);
}
/**
- * Returns the value of the {@link #PROPERTY_AUTO_DETECTION_ENABLED} property. This
+ * Returns the value of the {@link #SETTING_AUTO_DETECTION_ENABLED} setting. This
* controls whether a device will attempt to determine the time zone automatically using
- * contextual information.
+ * contextual information if the device supports auto detection.
*
- * @throws IllegalStateException if the field has not been set
+ * <p>This setting is global and can be updated by some users.
+ *
+ * @throws IllegalStateException if the setting has not been set
*/
public boolean isAutoDetectionEnabled() {
- if (!mBundle.containsKey(PROPERTY_AUTO_DETECTION_ENABLED)) {
- throw new IllegalStateException(PROPERTY_AUTO_DETECTION_ENABLED + " is not set");
- }
- return mBundle.getBoolean(PROPERTY_AUTO_DETECTION_ENABLED);
+ enforceSettingPresent(SETTING_AUTO_DETECTION_ENABLED);
+ return mBundle.getBoolean(SETTING_AUTO_DETECTION_ENABLED);
}
/**
- * Returns the value of the {@link #PROPERTY_GEO_DETECTION_ENABLED} property. This
- * controls whether a device can use location to determine time zone. Only used when
- * {@link #isAutoDetectionEnabled()} is true.
+ * Returns the value of the {@link #SETTING_GEO_DETECTION_ENABLED} setting. This
+ * controls whether a device can use geolocation to determine time zone. Only used when
+ * {@link #isAutoDetectionEnabled()} is {@code true} and when the user has allowed their
+ * location to be used.
*
- * @throws IllegalStateException if the field has not been set
+ * <p>This setting is user-scoped and can be updated by some users.
+ * See {@link TimeZoneCapabilities#getConfigureGeoDetectionEnabled()}.
+ *
+ * @throws IllegalStateException if the setting has not been set
*/
public boolean isGeoDetectionEnabled() {
- if (!mBundle.containsKey(PROPERTY_GEO_DETECTION_ENABLED)) {
- throw new IllegalStateException(PROPERTY_GEO_DETECTION_ENABLED + " is not set");
- }
- return mBundle.getBoolean(PROPERTY_GEO_DETECTION_ENABLED);
- }
-
- /**
- * Convenience method to merge this with another. The argument configuration properties have
- * precedence.
- */
- public TimeZoneConfiguration with(TimeZoneConfiguration other) {
- return new Builder(this).mergeProperties(other).build();
+ enforceSettingPresent(SETTING_GEO_DETECTION_ENABLED);
+ return mBundle.getBoolean(SETTING_GEO_DETECTION_ENABLED);
}
@Override
@@ -149,43 +151,61 @@
return false;
}
TimeZoneConfiguration that = (TimeZoneConfiguration) o;
- return mBundle.kindofEquals(that.mBundle);
+ return mUserId == that.mUserId
+ && mBundle.kindofEquals(that.mBundle);
}
@Override
public int hashCode() {
- return Objects.hash(mBundle);
+ return Objects.hash(mUserId, mBundle);
}
@Override
public String toString() {
return "TimeZoneDetectorConfiguration{"
+ + "mUserId=" + mUserId
+ "mBundle=" + mBundle
+ '}';
}
+ private void enforceSettingPresent(@Setting String setting) {
+ if (!mBundle.containsKey(setting)) {
+ throw new IllegalStateException(setting + " is not set");
+ }
+ }
+
/** @hide */
public static class Builder {
- private Bundle mBundle = new Bundle();
+ private final @UserIdInt int mUserId;
+ private final Bundle mBundle = new Bundle();
/**
- * Creates a new Builder with no properties set.
+ * Creates a new Builder for a userId with no settings held.
*/
- public Builder() {}
+ public Builder(@UserIdInt int userId) {
+ mUserId = userId;
+ }
/**
- * Creates a new Builder by copying properties from an existing instance.
+ * Creates a new Builder by copying the user ID and settings from an existing instance.
*/
public Builder(TimeZoneConfiguration toCopy) {
+ this.mUserId = toCopy.mUserId;
mergeProperties(toCopy);
}
/**
- * Merges {@code other} properties into this instances, replacing existing values in this
- * where the properties appear in both.
+ * Merges {@code other} settings into this instances, replacing existing values in this
+ * where the settings appear in both.
*/
public Builder mergeProperties(TimeZoneConfiguration other) {
+ if (mUserId != other.mUserId) {
+ throw new IllegalArgumentException(
+ "Cannot merge configurations for different user IDs."
+ + " this.mUserId=" + this.mUserId
+ + ", other.mUserId=" + other.mUserId);
+ }
this.mBundle.putAll(other.mBundle);
return this;
}
@@ -195,15 +215,19 @@
return this;
}
- /** Sets the desired state of the automatic time zone detection property. */
+ /**
+ * Sets the state of the {@link #SETTING_AUTO_DETECTION_ENABLED} setting.
+ */
public Builder setAutoDetectionEnabled(boolean enabled) {
- this.mBundle.putBoolean(PROPERTY_AUTO_DETECTION_ENABLED, enabled);
+ this.mBundle.putBoolean(SETTING_AUTO_DETECTION_ENABLED, enabled);
return this;
}
- /** Sets the desired state of the geolocation time zone detection enabled property. */
+ /**
+ * Sets the state of the {@link #SETTING_GEO_DETECTION_ENABLED} setting.
+ */
public Builder setGeoDetectionEnabled(boolean enabled) {
- this.mBundle.putBoolean(PROPERTY_GEO_DETECTION_ENABLED, enabled);
+ this.mBundle.putBoolean(SETTING_GEO_DETECTION_ENABLED, enabled);
return this;
}
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java
index 7885613..2b1cbf2 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetector.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java
@@ -37,37 +37,29 @@
TimeZoneCapabilities getCapabilities();
/**
- * Returns the current user's complete time zone configuration. See {@link
- * TimeZoneConfiguration}.
- */
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @NonNull
- TimeZoneConfiguration getConfiguration();
-
- /**
* Modifies the time zone detection configuration.
*
- * <p>Configuration properties vary in scope: some may be device-wide, others may be specific to
- * the current user.
+ * <p>Configuration settings vary in scope: some may be global (affect all users), others may be
+ * specific to the current user.
*
- * <p>The ability to modify configuration properties can be subject to restrictions. For
+ * <p>The ability to modify configuration settings can be subject to restrictions. For
* example, they may be determined by device hardware, general policy (i.e. only the primary
- * user can set them), or by a managed device policy. See {@link #getCapabilities()} to obtain
+ * user can set them), or by a managed device policy. Use {@link #getCapabilities()} to obtain
* information at runtime about the user's capabilities.
*
- * <p>Attempts to set configuration with capabilities that are {@link
+ * <p>Attempts to modify configuration settings with capabilities that are {@link
* TimeZoneCapabilities#CAPABILITY_NOT_SUPPORTED} or {@link
* TimeZoneCapabilities#CAPABILITY_NOT_ALLOWED} will have no effect and a {@code false}
- * will be returned. Setting configuration with capabilities that are {@link
+ * will be returned. Modifying configuration settings with capabilities that are {@link
* TimeZoneCapabilities#CAPABILITY_NOT_APPLICABLE} or {@link
* TimeZoneCapabilities#CAPABILITY_POSSESSED} will succeed. See {@link
* TimeZoneCapabilities} for further details.
*
- * <p>If the configuration is not "complete", then only the specified properties will be
- * updated (where the user's capabilities allow) and other settings will be left unchanged. See
- * {@link TimeZoneConfiguration#isComplete()}.
+ * <p>If the supplied configuration only has some values set, then only the specified settings
+ * will be updated (where the user's capabilities allow) and other settings will be left
+ * unchanged.
*
- * @return {@code true} if all the configuration properties specified have been set to the
+ * @return {@code true} if all the configuration settings specified have been set to the
* new values, {@code false} if none have
*/
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -76,14 +68,20 @@
/**
* An interface that can be used to listen for changes to the time zone detector configuration.
*/
+ @FunctionalInterface
interface TimeZoneConfigurationListener {
- /** Called when the configuration changes. There are no guarantees about the thread used. */
- void onChange(@NonNull TimeZoneConfiguration configuration);
+ /**
+ * Called when something about the time zone configuration on the device has changed.
+ * This could be because the current user has changed, one of the device's relevant settings
+ * has changed, or something that could affect a user's capabilities has changed.
+ * There are no guarantees about the thread used.
+ */
+ void onChange();
}
/**
- * Registers a listener that will be informed when the configuration changes. The complete
- * configuration is passed to the listener, not just the properties that have changed.
+ * Registers a listener that will be informed when something about the time zone configuration
+ * changes.
*/
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
void addConfigurationListener(@NonNull TimeZoneConfigurationListener listener);
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
index 0770aff..4c69732 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
@@ -57,19 +57,6 @@
}
@Override
- @NonNull
- public TimeZoneConfiguration getConfiguration() {
- if (DEBUG) {
- Log.d(TAG, "getConfiguration called");
- }
- try {
- return mITimeZoneDetectorService.getConfiguration();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- @Override
public boolean updateConfiguration(@NonNull TimeZoneConfiguration configuration) {
if (DEBUG) {
Log.d(TAG, "updateConfiguration called: " + configuration);
@@ -94,8 +81,8 @@
ITimeZoneConfigurationListener iListener =
new ITimeZoneConfigurationListener.Stub() {
@Override
- public void onChange(@NonNull TimeZoneConfiguration configuration) {
- notifyConfigurationListeners(configuration);
+ public void onChange() {
+ notifyConfigurationListeners();
}
};
mConfigurationReceiver = iListener;
@@ -116,14 +103,14 @@
}
}
- private void notifyConfigurationListeners(@NonNull TimeZoneConfiguration configuration) {
+ private void notifyConfigurationListeners() {
final ArraySet<TimeZoneConfigurationListener> configurationListeners;
synchronized (this) {
configurationListeners = new ArraySet<>(mConfigurationListeners);
}
int size = configurationListeners.size();
for (int i = 0; i < size; i++) {
- configurationListeners.valueAt(i).onChange(configuration);
+ configurationListeners.valueAt(i).onChange();
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c302def..03cf0cf 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6404,6 +6404,17 @@
public static final int LOCATION_MODE_ON = LOCATION_MODE_HIGH_ACCURACY;
/**
+ * The current location time zone detection enabled state for the user.
+ *
+ * See {@link
+ * android.app.timezonedetector.TimeZoneDetector#getCapabilities} for access. See {@link
+ * android.app.timezonedetector.TimeZoneDetector#updateConfiguration} to update.
+ * @hide
+ */
+ public static final String LOCATION_TIME_ZONE_DETECTION_ENABLED =
+ "location_time_zone_detection_enabled";
+
+ /**
* The accuracy in meters used for coarsening location for clients with only the coarse
* location permission.
*
diff --git a/core/java/com/android/internal/protolog/ProtoLogGroup.java b/core/java/com/android/internal/protolog/ProtoLogGroup.java
index 73d148c..0834b2d 100644
--- a/core/java/com/android/internal/protolog/ProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/ProtoLogGroup.java
@@ -36,7 +36,18 @@
Consts.TAG_WM),
WM_DEBUG_ADD_REMOVE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM),
- WM_DEBUG_FOCUS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
+ WM_DEBUG_CONFIGURATION(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_SWITCH(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_CONTAINERS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_FOCUS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_IMMERSIVE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_LOCKTASK(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
WM_DEBUG_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM),
WM_SHOW_TRANSACTIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 23af70a..cbcbe7f 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -613,7 +613,7 @@
}
// Do not change sched policy cgroup after boot complete.
- rc = androidSetThreadPriority(pid, pri, !boot_completed);
+ rc = androidSetThreadPriorityAndPolicy(pid, pri, !boot_completed);
if (rc != 0) {
if (rc == INVALID_OPERATION) {
signalExceptionForPriorityError(env, errno, pid);
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 4aa5df2..6212bcb 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2743,4 +2743,9 @@
// CATEGORY: SETTINGS
// OS: S
DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = 1849;
+
+ // OPEN: Settings > Network & internet > Adaptive connectivity
+ // CATEGORY: SETTINGS
+ // OS: R QPR
+ ADAPTIVE_CONNECTIVITY_CATEGORY = 1850;
}
diff --git a/core/tests/coretests/src/android/app/timezonedetector/TimeZoneCapabilitiesTest.java b/core/tests/coretests/src/android/app/timezonedetector/TimeZoneCapabilitiesTest.java
index 72391f4..db127c6 100644
--- a/core/tests/coretests/src/android/app/timezonedetector/TimeZoneCapabilitiesTest.java
+++ b/core/tests/coretests/src/android/app/timezonedetector/TimeZoneCapabilitiesTest.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
import org.junit.Test;
@@ -31,11 +32,22 @@
@Test
public void testEquals() {
- TimeZoneCapabilities.Builder builder1 = new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
+ TimeZoneConfiguration configuration1 = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ TimeZoneConfiguration configuration2 = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(false)
+ .setGeoDetectionEnabled(false)
+ .build();
+
+ TimeZoneCapabilities.Builder builder1 = new TimeZoneCapabilities.Builder()
+ .setConfiguration(configuration1)
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
- TimeZoneCapabilities.Builder builder2 = new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
+ TimeZoneCapabilities.Builder builder2 = new TimeZoneCapabilities.Builder()
+ .setConfiguration(configuration1)
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
@@ -45,6 +57,20 @@
assertEquals(one, two);
}
+ builder2.setConfiguration(configuration2);
+ {
+ TimeZoneCapabilities one = builder1.build();
+ TimeZoneCapabilities two = builder2.build();
+ assertNotEquals(one, two);
+ }
+
+ builder1.setConfiguration(configuration2);
+ {
+ TimeZoneCapabilities one = builder1.build();
+ TimeZoneCapabilities two = builder2.build();
+ assertEquals(one, two);
+ }
+
builder2.setConfigureAutoDetectionEnabled(CAPABILITY_NOT_ALLOWED);
{
TimeZoneCapabilities one = builder1.build();
@@ -90,7 +116,12 @@
@Test
public void testParcelable() {
- TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
+ TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder()
+ .setConfiguration(configuration)
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
@@ -105,4 +136,51 @@
builder.setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED);
assertRoundTripParcelable(builder.build());
}
+
+ @Test
+ public void testApplyUpdate_permitted() {
+ TimeZoneConfiguration oldConfiguration =
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder()
+ .setConfiguration(oldConfiguration)
+ .setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
+ .setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
+ .setSuggestManualTimeZone(CAPABILITY_POSSESSED)
+ .build();
+ assertEquals(oldConfiguration, capabilities.getConfiguration());
+
+ TimeZoneConfiguration configChange = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(false)
+ .build();
+
+ TimeZoneConfiguration expected = new TimeZoneConfiguration.Builder(oldConfiguration)
+ .setAutoDetectionEnabled(false)
+ .build();
+ assertEquals(expected, capabilities.applyUpdate(configChange));
+ }
+
+ @Test
+ public void testApplyUpdate_notPermitted() {
+ TimeZoneConfiguration oldConfiguration =
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder()
+ .setConfiguration(oldConfiguration)
+ .setConfigureAutoDetectionEnabled(CAPABILITY_NOT_ALLOWED)
+ .setConfigureGeoDetectionEnabled(CAPABILITY_NOT_ALLOWED)
+ .setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED)
+ .build();
+ assertEquals(oldConfiguration, capabilities.getConfiguration());
+
+ TimeZoneConfiguration configChange = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(false)
+ .build();
+
+ assertNull(capabilities.applyUpdate(configChange));
+ }
}
diff --git a/core/tests/coretests/src/android/app/timezonedetector/TimeZoneConfigurationTest.java b/core/tests/coretests/src/android/app/timezonedetector/TimeZoneConfigurationTest.java
index 00dc73e..faf908d 100644
--- a/core/tests/coretests/src/android/app/timezonedetector/TimeZoneConfigurationTest.java
+++ b/core/tests/coretests/src/android/app/timezonedetector/TimeZoneConfigurationTest.java
@@ -27,11 +27,14 @@
public class TimeZoneConfigurationTest {
+ private static final int ARBITRARY_USER_ID = 9876;
+
@Test
public void testBuilder_copyConstructor() {
- TimeZoneConfiguration.Builder builder1 = new TimeZoneConfiguration.Builder()
- .setAutoDetectionEnabled(true)
- .setGeoDetectionEnabled(true);
+ TimeZoneConfiguration.Builder builder1 =
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .setGeoDetectionEnabled(true);
TimeZoneConfiguration configuration1 = builder1.build();
TimeZoneConfiguration configuration2 =
@@ -41,28 +44,28 @@
}
@Test
- public void testIsComplete() {
- TimeZoneConfiguration.Builder builder =
- new TimeZoneConfiguration.Builder();
- assertFalse(builder.build().isComplete());
+ public void testIntrospectionMethods() {
+ TimeZoneConfiguration empty = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID).build();
+ assertFalse(empty.isComplete());
+ assertFalse(empty.hasSetting(TimeZoneConfiguration.SETTING_AUTO_DETECTION_ENABLED));
- builder.setAutoDetectionEnabled(true);
- assertFalse(builder.build().isComplete());
-
- builder.setGeoDetectionEnabled(true);
- assertTrue(builder.build().isComplete());
+ TimeZoneConfiguration completeConfig = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ assertTrue(completeConfig.isComplete());
+ assertTrue(completeConfig.hasSetting(TimeZoneConfiguration.SETTING_AUTO_DETECTION_ENABLED));
}
@Test
public void testBuilder_mergeProperties() {
- TimeZoneConfiguration configuration1 =
- new TimeZoneConfiguration.Builder()
- .setAutoDetectionEnabled(true)
- .build();
+ TimeZoneConfiguration configuration1 = new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionEnabled(true)
+ .build();
{
TimeZoneConfiguration mergedEmptyAnd1 =
- new TimeZoneConfiguration.Builder()
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
.mergeProperties(configuration1)
.build();
assertEquals(configuration1, mergedEmptyAnd1);
@@ -70,7 +73,7 @@
{
TimeZoneConfiguration configuration2 =
- new TimeZoneConfiguration.Builder()
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
.setAutoDetectionEnabled(false)
.build();
@@ -87,14 +90,22 @@
@Test
public void testEquals() {
TimeZoneConfiguration.Builder builder1 =
- new TimeZoneConfiguration.Builder();
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID);
{
TimeZoneConfiguration one = builder1.build();
assertEquals(one, one);
}
+ {
+ TimeZoneConfiguration.Builder differentUserBuilder =
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID + 1);
+ TimeZoneConfiguration one = builder1.build();
+ TimeZoneConfiguration two = differentUserBuilder.build();
+ assertNotEquals(one, two);
+ }
+
TimeZoneConfiguration.Builder builder2 =
- new TimeZoneConfiguration.Builder();
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID);
{
TimeZoneConfiguration one = builder1.build();
TimeZoneConfiguration two = builder2.build();
@@ -148,7 +159,7 @@
@Test
public void testParcelable() {
TimeZoneConfiguration.Builder builder =
- new TimeZoneConfiguration.Builder();
+ new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID);
assertRoundTripParcelable(builder.build());
builder.setAutoDetectionEnabled(true);
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 73296987..03f7be7 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -13,6 +13,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-2121056984": {
+ "message": "%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"-2109936758": {
"message": "removeAppToken make exiting: %s",
"level": "VERBOSE",
@@ -43,6 +49,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-2029985709": {
+ "message": "setFocusedTask: taskId=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-2024464438": {
"message": "app-onAnimationFinished(): mOuter=%s",
"level": "DEBUG",
@@ -139,6 +151,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayRotation.java"
},
+ "-1868048288": {
+ "message": "Updating to new configuration after starting activity.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityStarter.java"
+ },
"-1862269827": {
"message": "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s",
"level": "VERBOSE",
@@ -163,6 +181,18 @@
"group": "WM_DEBUG_RESIZE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "-1810446914": {
+ "message": "Trying to update display configuration for system\/invalid process.",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
+ "-1791031393": {
+ "message": "Ensuring correct configuration: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-1782453012": {
"message": "Checking theme of starting window: 0x%x",
"level": "VERBOSE",
@@ -211,6 +241,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-1699018375": {
+ "message": "Adding activity %s to task %s callers: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/Task.java"
+ },
"-1698815688": {
"message": "Resetting app token %s of replacing window marks.",
"level": "DEBUG",
@@ -229,12 +265,30 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-1638958146": {
+ "message": "Removing activity %s from task=%s adding to task=%s Callers=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
+ },
"-1632122349": {
"message": "Changing surface while display frozen: %s",
"level": "VERBOSE",
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-1630752478": {
+ "message": "removeLockedTask: removed %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
+ "-1598452494": {
+ "message": "activityDestroyedLocked: r=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_CONTAINERS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-1596995693": {
"message": "startAnimation",
"level": "DEBUG",
@@ -307,6 +361,18 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
+ "-1495062622": {
+ "message": "Can't report activity moved to display - client not running, activityRecord=%s, displayId=%d",
+ "level": "WARN",
+ "group": "WM_DEBUG_SWITCH",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
+ "-1492881555": {
+ "message": "Starting activity when config will change = %b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityStarter.java"
+ },
"-1471946192": {
"message": "Marking app token %s with replacing child windows.",
"level": "DEBUG",
@@ -379,6 +445,12 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "-1305755880": {
+ "message": "Initial config: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-1292329638": {
"message": "Added starting %s: startingWindow=%s startingView=%s",
"level": "VERBOSE",
@@ -445,6 +517,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
+ "-1155279885": {
+ "message": "Frontmost changed immersion: %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IMMERSIVE",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-1144293044": {
"message": "SURFACE SET FREEZE LAYER: %s",
"level": "INFO",
@@ -475,6 +553,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayRotation.java"
},
+ "-1115019498": {
+ "message": "Configuration & display unchanged in %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-1113134997": {
"message": "Attempted to add application window with unknown token %s. Aborting.",
"level": "WARN",
@@ -559,12 +643,24 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "-929676529": {
+ "message": "Configuration changes for %s, allChanges=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-928291778": {
"message": "applyAnimation: anim=%s nextAppTransition=%d transit=%s Callers=%s",
"level": "VERBOSE",
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
+ "-927199900": {
+ "message": "Updating global configuration to: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-916108501": {
"message": "Adding %s to %s",
"level": "VERBOSE",
@@ -619,12 +715,24 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-846078709": {
+ "message": "Configuration doesn't matter in finishing %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-809771899": {
"message": "findFocusedWindow: Reached focused app=%s",
"level": "VERBOSE",
"group": "WM_DEBUG_FOCUS_LIGHT",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-804217032": {
+ "message": "Skipping config check (will change): %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-793346159": {
"message": "New transit into wallpaper: %s",
"level": "VERBOSE",
@@ -673,6 +781,18 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-743431900": {
+ "message": "Configuration no differences in %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
+ "-716565534": {
+ "message": "moveActivityStackToFront: unfocusable activity=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-714291355": {
"message": "Losing delayed focus: %s",
"level": "INFO",
@@ -739,6 +859,12 @@
"group": "WM_DEBUG_FOCUS_LIGHT",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-593535526": {
+ "message": "Binding proc %s with config %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/am\/ActivityManagerService.java"
+ },
"-583031528": {
"message": "%s",
"level": "INFO",
@@ -757,6 +883,12 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-548282316": {
+ "message": "setLockTaskMode: Locking to %s Callers=%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"-547111355": {
"message": "hideIme Control target: %s ",
"level": "DEBUG",
@@ -781,6 +913,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-503656156": {
+ "message": "Update process config of %s to new config %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-496681057": {
"message": "Attempted to get remove mode of a display that does not exist: %d",
"level": "WARN",
@@ -799,6 +937,12 @@
"group": "WM_SHOW_SURFACE_ALLOC",
"at": "com\/android\/server\/wm\/WindowStateAnimator.java"
},
+ "-449118559": {
+ "message": "Trying to update display configuration for invalid process, pid=%d",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-445944810": {
"message": "finish(%b): mCanceled=%b",
"level": "DEBUG",
@@ -835,6 +979,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
},
+ "-401282500": {
+ "message": "destroyIfPossible: r=%s destroy returned removed=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_CONTAINERS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-395922585": {
"message": "InsetsSource setWin %s",
"level": "DEBUG",
@@ -907,18 +1057,42 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "-317194205": {
+ "message": "clearLockedTasks: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"-303497363": {
"message": "reparent: moving activity=%s to task=%d at %d",
"level": "INFO",
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-272719931": {
+ "message": "startLockTaskModeLocked: %s",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
+ "-260960989": {
+ "message": "Removing and adding activity %s to stack at top callers=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/Task.java"
+ },
"-251259736": {
"message": "No longer freezing: %s",
"level": "VERBOSE",
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-235225312": {
+ "message": "Skipping config check for initializing activity: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-198463978": {
"message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b",
"level": "VERBOSE",
@@ -943,6 +1117,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimationController.java"
},
+ "-168799453": {
+ "message": "Allowing features %d:0x%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"-167822951": {
"message": "Attempted to add starting window to token with already existing starting window",
"level": "WARN",
@@ -979,6 +1159,12 @@
"group": "WM_DEBUG_FOCUS_LIGHT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-90559682": {
+ "message": "Config is skipping already pausing %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-87705714": {
"message": "findFocusedWindow: focusedApp=null using new focus @ %s",
"level": "VERBOSE",
@@ -1303,6 +1489,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "355940361": {
+ "message": "Config is destroying non-running %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"371641947": {
"message": "Window Manager Crash %s",
"level": "WTF",
@@ -1315,6 +1507,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "374506950": {
+ "message": "Reporting activity moved to display, activityRecord=%s, displayId=%d, config=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_SWITCH",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"374972436": {
"message": "performEnableScreen: Waiting for anim complete",
"level": "INFO",
@@ -1411,6 +1609,12 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "556758086": {
+ "message": "Applying new update lock state '%s' for %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IMMERSIVE",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"557227556": {
"message": "onAnimationFinished(): Notify animation finished:",
"level": "DEBUG",
@@ -1531,12 +1735,6 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "676824470": {
- "message": "Test completed successfully: %b %d %o %x %e %g %f %% %s.",
- "level": "ERROR",
- "group": "TEST_GROUP",
- "at": "com\/android\/server\/wm\/ProtoLogGroup.java"
- },
"685047360": {
"message": "Resizing window %s",
"level": "VERBOSE",
@@ -1561,6 +1759,18 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "715749922": {
+ "message": "Allowlisting %d:%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
+ "736692676": {
+ "message": "Config is relaunching %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"745391677": {
"message": " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x \/ %s",
"level": "INFO",
@@ -1615,6 +1825,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
+ "869266572": {
+ "message": "Removing activity %s from stack, reason= %s callers=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"873914452": {
"message": "goodToGo()",
"level": "DEBUG",
@@ -1645,12 +1861,30 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowStateAnimator.java"
},
+ "950074526": {
+ "message": "setLockTaskMode: Can't lock due to auth",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"954470154": {
"message": "FORCED DISPLAY SCALING DISABLED",
"level": "INFO",
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "956374481": {
+ "message": "removeLockedTask: task=%s last task, reverting locktask mode. Callers=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
+ "969323241": {
+ "message": "Sending new config to %s, config: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"972354148": {
"message": "\tcontainer=%s",
"level": "DEBUG",
@@ -1663,12 +1897,24 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1040675582": {
+ "message": "Can't report activity configuration update - client not running, activityRecord=%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"1046922686": {
"message": "requestScrollCapture: caught exception dispatching callback: %s",
"level": "WARN",
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1049367566": {
+ "message": "Sending to proc %s new config %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/WindowProcessController.java"
+ },
"1051545910": {
"message": "Exit animation finished in %s: remove=%b",
"level": "VERBOSE",
@@ -1681,6 +1927,12 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
},
+ "1088929964": {
+ "message": "onLockTaskPackagesUpdated: starting new locktask task=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"1089714158": {
"message": " FREEZE %s: DESTROY",
"level": "INFO",
@@ -1789,6 +2041,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1337596507": {
+ "message": "Sending to proc %s new compat %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/CompatModePackages.java"
+ },
"1346895820": {
"message": "ScreenRotation still animating: type: %d\nmDisplayAnimator: %s\nmEnterBlackFrameAnimator: %s\nmRotateScreenAnimator: %s\nmScreenshotRotationAnimator: %s",
"level": "VERBOSE",
@@ -1801,6 +2059,12 @@
"group": "WM_DEBUG_FOCUS",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "1360551978": {
+ "message": "Trying to update display configuration for non-existing displayId=%d",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"1364498663": {
"message": "notifyAppResumed: wasStopped=%b %s",
"level": "VERBOSE",
@@ -1819,6 +2083,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/TaskDisplayArea.java"
},
+ "1401295262": {
+ "message": "Mode default, asking user",
+ "level": "WARN",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"1401700824": {
"message": "Window drawn win=%s",
"level": "DEBUG",
@@ -1927,6 +2197,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1522489371": {
+ "message": "moveActivityStackToFront: activity=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"1525976603": {
"message": "cancelAnimation(): reason=%s",
"level": "DEBUG",
@@ -1951,6 +2227,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1576607724": {
+ "message": "Report configuration: %s %s %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"1577579529": {
"message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b",
"level": "ERROR",
@@ -1981,6 +2263,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1635062046": {
+ "message": "Skipping config check invisible: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"1635462459": {
"message": "onMovedByResize: Moving %s",
"level": "DEBUG",
@@ -2023,6 +2311,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "1679569477": {
+ "message": "Configuration doesn't matter not running %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"1720229827": {
"message": "Creating animation bounds layer",
"level": "INFO",
@@ -2077,12 +2371,30 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1789603530": {
+ "message": "Removing activity %s hasSavedState=%b stateNotNeeded=%s finishing=%b state=%s callers=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"1822843721": {
"message": "Aborted starting %s: startingData=%s",
"level": "VERBOSE",
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "1824105730": {
+ "message": "setLockTaskAuth: task=%s mLockTaskAuth=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/Task.java"
+ },
+ "1829094918": {
+ "message": "onLockTaskPackagesUpdated: removing %s mLockTaskAuth()=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_LOCKTASK",
+ "at": "com\/android\/server\/wm\/LockTaskController.java"
+ },
"1831008694": {
"message": "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s surfaceInsets=%s",
"level": "DEBUG",
@@ -2161,6 +2473,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/AppTransitionController.java"
},
+ "1975793405": {
+ "message": "setFocusedStack: stackId=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+ },
"1984470582": {
"message": "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d",
"level": "DEBUG",
@@ -2173,6 +2491,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowAnimator.java"
},
+ "1995093920": {
+ "message": "Checking to restart %s: changed=0x%s, handles=0x%s, mLastReportedConfiguration=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"2016061474": {
"message": "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d Callers=%s",
"level": "VERBOSE",
@@ -2191,6 +2515,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "2022322588": {
+ "message": "Adding activity %s to stack to task %s callers: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/Task.java"
+ },
"2022422429": {
"message": "createAnimationAdapter(): container=%s",
"level": "DEBUG",
@@ -2269,6 +2599,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayRotation.java"
},
+ "2134999275": {
+ "message": "moveActivityStackToFront: already on top, activity=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"2137411379": {
"message": "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b Callers=%s",
"level": "VERBOSE",
@@ -2277,9 +2613,6 @@
}
},
"groups": {
- "TEST_GROUP": {
- "tag": "WindowManagetProtoLogTest"
- },
"WM_DEBUG_ADD_REMOVE": {
"tag": "WindowManager"
},
@@ -2292,6 +2625,12 @@
"WM_DEBUG_BOOT": {
"tag": "WindowManager"
},
+ "WM_DEBUG_CONFIGURATION": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_CONTAINERS": {
+ "tag": "WindowManager"
+ },
"WM_DEBUG_DRAW": {
"tag": "WindowManager"
},
@@ -2304,9 +2643,15 @@
"WM_DEBUG_IME": {
"tag": "WindowManager"
},
+ "WM_DEBUG_IMMERSIVE": {
+ "tag": "WindowManager"
+ },
"WM_DEBUG_KEEP_SCREEN_ON": {
"tag": "WindowManager"
},
+ "WM_DEBUG_LOCKTASK": {
+ "tag": "WindowManager"
+ },
"WM_DEBUG_ORIENTATION": {
"tag": "WindowManager"
},
@@ -2325,6 +2670,9 @@
"WM_DEBUG_STARTING_WINDOW": {
"tag": "WindowManager"
},
+ "WM_DEBUG_SWITCH": {
+ "tag": "WindowManager"
+ },
"WM_DEBUG_WINDOW_MOVEMENT": {
"tag": "WindowManager"
},
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
index 552cadf..b17ad0f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
@@ -16,7 +16,9 @@
package com.android.systemui;
+import com.android.systemui.dagger.GlobalModule;
import com.android.systemui.dagger.GlobalRootComponent;
+import com.android.systemui.dagger.WMModule;
import javax.inject.Singleton;
@@ -26,7 +28,9 @@
@Singleton
@Component(
modules = {
- CarSysUIComponentModule.class
+ GlobalModule.class,
+ CarSysUIComponentModule.class,
+ WMModule.class
})
public interface CarGlobalRootComponent extends GlobalRootComponent {
/**
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
index 24d9d09..9039671 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
@@ -20,7 +20,6 @@
import com.android.systemui.dagger.DependencyProvider;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.SystemServicesModule;
import com.android.systemui.dagger.SystemUIModule;
import com.android.systemui.pip.phone.dagger.PipModule;
@@ -35,7 +34,6 @@
DependencyProvider.class,
DependencyBinder.class,
PipModule.class,
- SystemServicesModule.class,
SystemUIModule.class,
CarSystemUIModule.class,
CarSystemUIBinder.class})
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
index 3b22fdb..38e1a48 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
@@ -299,10 +299,10 @@
// The glass pane is used to view touch events before passed to the notification list.
// This allows us to initialize gesture listeners and detect when to close the notifications
glassPane.setOnTouchListener((v, event) -> {
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ if (isClosingAction(event)) {
mNotificationListAtEndAtTimeOfTouch = false;
}
- if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ if (isOpeningAction(event)) {
mFirstTouchDownOnGlassPane = event.getRawX();
mNotificationListAtEndAtTimeOfTouch = mNotificationListAtEnd;
// Reset the tracker when there is a touch down on the glass pane.
@@ -355,8 +355,7 @@
if (rect != null) {
clippedHeight = rect.bottom;
}
- if (!handled && event.getActionMasked() == MotionEvent.ACTION_UP
- && mIsSwipingVerticallyToClose) {
+ if (!handled && isClosingAction(event) && mIsSwipingVerticallyToClose) {
if (getSettleClosePercentage() < getPercentageFromEndingEdge() && isTracking) {
animatePanel(DEFAULT_FLING_VELOCITY, false);
} else if (clippedHeight != getLayout().getHeight() && isTracking) {
@@ -369,7 +368,7 @@
// Updating the mNotificationListAtEndAtTimeOfTouch state has to be done after
// the event has been passed to the closeGestureDetector above, such that the
// closeGestureDetector sees the up event before the state has changed.
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ if (isClosingAction(event)) {
mNotificationListAtEndAtTimeOfTouch = false;
}
return handled || isTracking;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
index 45808a8..bde31f1 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
@@ -191,6 +191,38 @@
}
}
+ /** Checks if a {@link MotionEvent} is an action to open the panel.
+ * @param e {@link MotionEvent} to check.
+ * @return true only if opening action.
+ */
+ protected boolean isOpeningAction(MotionEvent e) {
+ if (mAnimateDirection == POSITIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+ }
+
+ if (mAnimateDirection == NEGATIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_UP;
+ }
+
+ return false;
+ }
+
+ /** Checks if a {@link MotionEvent} is an action to close the panel.
+ * @param e {@link MotionEvent} to check.
+ * @return true only if closing action.
+ */
+ protected boolean isClosingAction(MotionEvent e) {
+ if (mAnimateDirection == POSITIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_UP;
+ }
+
+ if (mAnimateDirection == NEGATIVE_DIRECTION) {
+ return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+ }
+
+ return false;
+ }
+
/* ***************************************************************************************** *
* Panel Animation
* ***************************************************************************************** */
@@ -243,8 +275,7 @@
* Depending on certain conditions, determines whether to fully expand or collapse the panel.
*/
protected void maybeCompleteAnimation(MotionEvent event) {
- if (event.getActionMasked() == MotionEvent.ACTION_UP
- && isPanelVisible()) {
+ if (isClosingAction(event) && isPanelVisible()) {
if (mSettleClosePercentage < mPercentageFromEndingEdge) {
animatePanel(DEFAULT_FLING_VELOCITY, false);
} else {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index ecf1c2c9..5ad8cad 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -22,6 +22,7 @@
import android.widget.TextClock;
import com.android.internal.colorextraction.ColorExtractor;
+import com.android.keyguard.dagger.KeyguardStatusViewScope;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.ClockPlugin;
@@ -36,6 +37,7 @@
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
+@KeyguardStatusViewScope
public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch";
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index f17f1ca..fe5fcc6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -34,10 +34,11 @@
public class KeyguardClockSwitchController {
private static final boolean CUSTOM_CLOCKS_ENABLED = true;
+ private final KeyguardClockSwitch mView;
private final StatusBarStateController mStatusBarStateController;
private final SysuiColorExtractor mColorExtractor;
private final ClockManager mClockManager;
- private KeyguardClockSwitch mView;
+ private final KeyguardSliceViewController mKeyguardSliceViewController;
private final StatusBarStateController.StateListener mStateListener =
new StatusBarStateController.StateListener() {
@@ -52,9 +53,13 @@
*
* The color palette changes when the wallpaper is changed.
*/
- private final ColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> {
- if ((which & WallpaperManager.FLAG_LOCK) != 0) {
- mView.updateColors(getGradientColors());
+ private final ColorExtractor.OnColorsChangedListener mColorsListener =
+ new ColorExtractor.OnColorsChangedListener() {
+ @Override
+ public void onColorsChanged(ColorExtractor extractor, int which) {
+ if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+ mView.updateColors(getGradientColors());
+ }
}
};
@@ -84,22 +89,27 @@
};
@Inject
- public KeyguardClockSwitchController(StatusBarStateController statusBarStateController,
- SysuiColorExtractor colorExtractor, ClockManager clockManager) {
+ public KeyguardClockSwitchController(KeyguardClockSwitch keyguardClockSwitch,
+ StatusBarStateController statusBarStateController,
+ SysuiColorExtractor colorExtractor, ClockManager clockManager,
+ KeyguardSliceViewController keyguardSliceViewController) {
+ mView = keyguardClockSwitch;
mStatusBarStateController = statusBarStateController;
mColorExtractor = colorExtractor;
mClockManager = clockManager;
+ mKeyguardSliceViewController = keyguardSliceViewController;
}
/**
* Attach the controller to the view it relates to.
*/
- public void attach(KeyguardClockSwitch view) {
- mView = view;
+ public void init() {
if (mView.isAttachedToWindow()) {
mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
}
mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+
+ mKeyguardSliceViewController.init();
}
/**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 6f19613..be21d20 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -34,12 +34,15 @@
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.util.InjectionInflationController;
+import javax.inject.Inject;
+
public class KeyguardDisplayManager {
protected static final String TAG = "KeyguardDisplayManager";
private static boolean DEBUG = KeyguardConstants.DEBUG;
@@ -47,6 +50,7 @@
private final MediaRouter mMediaRouter;
private final DisplayManager mDisplayService;
private final InjectionInflationController mInjectableInflater;
+ private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
private final Context mContext;
private boolean mShowing;
@@ -86,10 +90,13 @@
}
};
+ @Inject
public KeyguardDisplayManager(Context context,
- InjectionInflationController injectableInflater) {
+ InjectionInflationController injectableInflater,
+ KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory) {
mContext = context;
mInjectableInflater = injectableInflater;
+ mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mMediaRouter = mContext.getSystemService(MediaRouter.class);
mDisplayService = mContext.getSystemService(DisplayManager.class);
mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */);
@@ -124,6 +131,7 @@
Presentation presentation = mPresentations.get(displayId);
if (presentation == null) {
final Presentation newPresentation = new KeyguardPresentation(mContext, display,
+ mKeyguardStatusViewComponentFactory,
mInjectableInflater.injectable(LayoutInflater.from(mContext)));
newPresentation.setOnDismissListener(dialog -> {
if (newPresentation.equals(mPresentations.get(displayId))) {
@@ -241,7 +249,9 @@
static final 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 KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
private final LayoutInflater mInjectableLayoutInflater;
+ private KeyguardClockSwitchController mKeyguardClockSwitchController;
private View mClock;
private int mUsableWidth;
private int mUsableHeight;
@@ -259,8 +269,10 @@
};
KeyguardPresentation(Context context, Display display,
+ KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
LayoutInflater injectionLayoutInflater) {
super(context, display, R.style.Theme_SystemUI_KeyguardPresentation);
+ mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mInjectableLayoutInflater = injectionLayoutInflater;
getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
setCancelable(false);
@@ -302,6 +314,12 @@
// Avoid screen burn in
mClock.post(mMoveTextRunnable);
+
+ mKeyguardClockSwitchController = mKeyguardStatusViewComponentFactory
+ .build(findViewById(R.id.clock))
+ .getKeyguardClockSwitchController();
+
+ mKeyguardClockSwitchController.init();
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index f639c88..a479bca 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -16,12 +16,6 @@
package com.android.keyguard;
-import static android.app.slice.Slice.HINT_LIST_ITEM;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.INVALID_DISPLAY;
-
-import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
-
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
@@ -35,28 +29,19 @@
import android.graphics.text.LineBreaker;
import android.net.Uri;
import android.os.Trace;
-import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.TypedValue;
-import android.view.Display;
import android.view.View;
import android.view.animation.Animation;
import android.widget.LinearLayout;
import android.widget.TextView;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.Observer;
-import androidx.slice.Slice;
import androidx.slice.SliceItem;
-import androidx.slice.SliceViewManager;
import androidx.slice.core.SliceQuery;
-import androidx.slice.widget.ListContent;
import androidx.slice.widget.RowContent;
import androidx.slice.widget.SliceContent;
-import androidx.slice.widget.SliceLiveData;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
@@ -64,70 +49,49 @@
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.keyguard.KeyguardSliceProvider;
-import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Named;
+import java.util.Map;
/**
* View visible under the clock on the lock screen and AoD.
*/
-public class KeyguardSliceView extends LinearLayout implements View.OnClickListener,
- Observer<Slice>, TunerService.Tunable, ConfigurationController.ConfigurationListener {
+public class KeyguardSliceView extends LinearLayout {
private static final String TAG = "KeyguardSliceView";
public static final int DEFAULT_ANIM_DURATION = 550;
- private final HashMap<View, PendingIntent> mClickActions;
- private final ActivityStarter mActivityStarter;
- private final ConfigurationController mConfigurationController;
private final LayoutTransition mLayoutTransition;
- private final TunerService mTunerService;
- private Uri mKeyguardSliceUri;
@VisibleForTesting
TextView mTitle;
private Row mRow;
private int mTextColor;
private float mDarkAmount = 0;
- private LiveData<Slice> mLiveData;
- private int mDisplayId = INVALID_DISPLAY;
private int mIconSize;
private int mIconSizeWithHeader;
/**
* Runnable called whenever the view contents change.
*/
private Runnable mContentChangeListener;
- private Slice mSlice;
private boolean mHasHeader;
private final int mRowWithHeaderPadding;
private final int mRowPadding;
private float mRowTextSize;
private float mRowWithHeaderTextSize;
+ private View.OnClickListener mOnClickListener;
- @Inject
- public KeyguardSliceView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
- ActivityStarter activityStarter, ConfigurationController configurationController,
- TunerService tunerService, @Main Resources resources) {
+ public KeyguardSliceView(Context context, AttributeSet attrs) {
super(context, attrs);
- mTunerService = tunerService;
- mClickActions = new HashMap<>();
+ Resources resources = context.getResources();
mRowPadding = resources.getDimensionPixelSize(R.dimen.subtitle_clock_padding);
mRowWithHeaderPadding = resources.getDimensionPixelSize(R.dimen.header_subtitle_padding);
- mActivityStarter = activityStarter;
- mConfigurationController = configurationController;
mLayoutTransition = new LayoutTransition();
mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION / 2);
@@ -153,39 +117,10 @@
R.dimen.widget_label_font_size);
mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize(
R.dimen.header_row_font_size);
- mTitle.setOnClickListener(this);
mTitle.setBreakStrategy(LineBreaker.BREAK_STRATEGY_BALANCED);
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- Display display = getDisplay();
- if (display != null) {
- mDisplayId = display.getDisplayId();
- }
- mTunerService.addTunable(this, Settings.Secure.KEYGUARD_SLICE_URI);
- // Make sure we always have the most current slice
- if (mDisplayId == DEFAULT_DISPLAY) {
- mLiveData.observeForever(this);
- }
- mConfigurationController.addCallback(this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
- // TODO(b/117344873) Remove below work around after this issue be fixed.
- if (mDisplayId == DEFAULT_DISPLAY) {
- mLiveData.removeObserver(this);
- }
- mTunerService.removeTunable(this);
- mConfigurationController.removeCallback(this);
- }
-
- @Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
setLayoutTransition(isVisible ? mLayoutTransition : null);
@@ -198,44 +133,31 @@
return mHasHeader;
}
- private void showSlice() {
- Trace.beginSection("KeyguardSliceView#showSlice");
- if (mSlice == null) {
- mTitle.setVisibility(GONE);
- mRow.setVisibility(GONE);
- mHasHeader = false;
- if (mContentChangeListener != null) {
- mContentChangeListener.run();
- }
- Trace.endSection();
- return;
+ void hideSlice() {
+ mTitle.setVisibility(GONE);
+ mRow.setVisibility(GONE);
+ mHasHeader = false;
+ if (mContentChangeListener != null) {
+ mContentChangeListener.run();
}
- mClickActions.clear();
+ }
- ListContent lc = new ListContent(getContext(), mSlice);
- SliceContent headerContent = lc.getHeader();
- mHasHeader = headerContent != null && !headerContent.getSliceItem().hasHint(HINT_LIST_ITEM);
- List<SliceContent> subItems = new ArrayList<>();
- for (int i = 0; i < lc.getRowItems().size(); i++) {
- SliceContent subItem = lc.getRowItems().get(i);
- String itemUri = subItem.getSliceItem().getSlice().getUri().toString();
- // Filter out the action row
- if (!KeyguardSliceProvider.KEYGUARD_ACTION_URI.equals(itemUri)) {
- subItems.add(subItem);
- }
- }
+ Map<View, PendingIntent> showSlice(RowContent header, List<SliceContent> subItems) {
+ Trace.beginSection("KeyguardSliceView#showSlice");
+ mHasHeader = header != null;
+ Map<View, PendingIntent> clickActions = new HashMap<>();
+
if (!mHasHeader) {
mTitle.setVisibility(GONE);
} else {
mTitle.setVisibility(VISIBLE);
- RowContent header = lc.getHeader();
SliceItem mainTitle = header.getTitleItem();
CharSequence title = mainTitle != null ? mainTitle.getText() : null;
mTitle.setText(title);
if (header.getPrimaryAction() != null
&& header.getPrimaryAction().getAction() != null) {
- mClickActions.put(mTitle, header.getPrimaryAction().getAction());
+ clickActions.put(mTitle, header.getPrimaryAction().getAction());
}
}
@@ -265,7 +187,7 @@
if (rc.getPrimaryAction() != null) {
pendingIntent = rc.getPrimaryAction().getAction();
}
- mClickActions.put(button, pendingIntent);
+ clickActions.put(button, pendingIntent);
final SliceItem titleItem = rc.getTitleItem();
button.setText(titleItem == null ? null : titleItem.getText());
@@ -286,14 +208,14 @@
}
}
button.setCompoundDrawables(iconDrawable, null, null, null);
- button.setOnClickListener(this);
+ button.setOnClickListener(mOnClickListener);
button.setClickable(pendingIntent != null);
}
// Removing old views
for (int i = 0; i < mRow.getChildCount(); i++) {
View child = mRow.getChildAt(i);
- if (!mClickActions.containsKey(child)) {
+ if (!clickActions.containsKey(child)) {
mRow.removeView(child);
i--;
}
@@ -303,6 +225,8 @@
mContentChangeListener.run();
}
Trace.endSection();
+
+ return clickActions;
}
public void setDarkAmount(float darkAmount) {
@@ -323,14 +247,6 @@
}
}
- @Override
- public void onClick(View v) {
- final PendingIntent action = mClickActions.get(v);
- if (action != null) {
- mActivityStarter.startPendingIntentDismissingKeyguard(action);
- }
- }
-
/**
* Runnable that gets invoked every time the title or the row visibility changes.
* @param contentChangeListener The listener.
@@ -339,43 +255,6 @@
mContentChangeListener = contentChangeListener;
}
- /**
- * LiveData observer lifecycle.
- * @param slice the new slice content.
- */
- @Override
- public void onChanged(Slice slice) {
- mSlice = slice;
- showSlice();
- }
-
- @Override
- public void onTuningChanged(String key, String newValue) {
- setupUri(newValue);
- }
-
- /**
- * Sets the slice provider Uri.
- */
- public void setupUri(String uriString) {
- if (uriString == null) {
- uriString = KeyguardSliceProvider.KEYGUARD_SLICE_URI;
- }
-
- boolean wasObserving = false;
- if (mLiveData != null && mLiveData.hasActiveObservers()) {
- wasObserving = true;
- mLiveData.removeObserver(this);
- }
-
- mKeyguardSliceUri = Uri.parse(uriString);
- mLiveData = SliceLiveData.fromUri(mContext, mKeyguardSliceUri);
-
- if (wasObserving) {
- mLiveData.observeForever(this);
- }
- }
-
@VisibleForTesting
int getTextColor() {
return ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
@@ -387,8 +266,7 @@
updateTextColors();
}
- @Override
- public void onDensityOrFontScaleChanged() {
+ void onDensityOrFontScaleChanged() {
mIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.widget_icon_size);
mIconSizeWithHeader = (int) mContext.getResources().getDimension(R.dimen.header_icon_size);
mRowTextSize = mContext.getResources().getDimensionPixelSize(
@@ -397,37 +275,21 @@
R.dimen.header_row_font_size);
}
- public void refresh() {
- Slice slice;
- Trace.beginSection("KeyguardSliceView#refresh");
- // We can optimize performance and avoid binder calls when we know that we're bound
- // to a Slice on the same process.
- if (KeyguardSliceProvider.KEYGUARD_SLICE_URI.equals(mKeyguardSliceUri.toString())) {
- KeyguardSliceProvider instance = KeyguardSliceProvider.getAttachedInstance();
- if (instance != null) {
- slice = instance.onBindSlice(mKeyguardSliceUri);
- } else {
- Log.w(TAG, "Keyguard slice not bound yet?");
- slice = null;
- }
- } else {
- slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
- }
- onChanged(slice);
- Trace.endSection();
- }
-
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardSliceView:");
- pw.println(" mClickActions: " + mClickActions);
pw.println(" mTitle: " + (mTitle == null ? "null" : mTitle.getVisibility() == VISIBLE));
pw.println(" mRow: " + (mRow == null ? "null" : mRow.getVisibility() == VISIBLE));
pw.println(" mTextColor: " + Integer.toHexString(mTextColor));
pw.println(" mDarkAmount: " + mDarkAmount);
- pw.println(" mSlice: " + mSlice);
pw.println(" mHasHeader: " + mHasHeader);
}
+ @Override
+ public void setOnClickListener(View.OnClickListener onClickListener) {
+ mOnClickListener = onClickListener;
+ mTitle.setOnClickListener(onClickListener);
+ }
+
public static class Row extends LinearLayout {
/**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
new file mode 100644
index 0000000..35a2392
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2020 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.keyguard;
+
+import static android.app.slice.Slice.HINT_LIST_ITEM;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.PendingIntent;
+import android.net.Uri;
+import android.os.Trace;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Display;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.Observer;
+import androidx.slice.Slice;
+import androidx.slice.SliceViewManager;
+import androidx.slice.widget.ListContent;
+import androidx.slice.widget.RowContent;
+import androidx.slice.widget.SliceContent;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.keyguard.dagger.KeyguardStatusViewScope;
+import com.android.systemui.Dumpable;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.tuner.TunerService;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+
+/** Controller for a {@link KeyguardSliceView}. */
+@KeyguardStatusViewScope
+public class KeyguardSliceViewController implements Dumpable {
+ private static final String TAG = "KeyguardSliceViewCtrl";
+
+ private final KeyguardSliceView mView;
+ private final KeyguardStatusView mKeyguardStatusView;
+ private final ActivityStarter mActivityStarter;
+ private final ConfigurationController mConfigurationController;
+ private final TunerService mTunerService;
+ private final DumpManager mDumpManager;
+ private int mDisplayId;
+ private LiveData<Slice> mLiveData;
+ private Uri mKeyguardSliceUri;
+ private Slice mSlice;
+ private Map<View, PendingIntent> mClickActions;
+
+ private final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
+ new View.OnAttachStateChangeListener() {
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+
+ Display display = mView.getDisplay();
+ if (display != null) {
+ mDisplayId = display.getDisplayId();
+ }
+ mTunerService.addTunable(mTunable, Settings.Secure.KEYGUARD_SLICE_URI);
+ // Make sure we always have the most current slice
+ if (mDisplayId == DEFAULT_DISPLAY && mLiveData != null) {
+ mLiveData.observeForever(mObserver);
+ }
+ mConfigurationController.addCallback(mConfigurationListener);
+ mDumpManager.registerDumpable(TAG, KeyguardSliceViewController.this);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+
+ // TODO(b/117344873) Remove below work around after this issue be fixed.
+ if (mDisplayId == DEFAULT_DISPLAY) {
+ mLiveData.removeObserver(mObserver);
+ }
+ mTunerService.removeTunable(mTunable);
+ mConfigurationController.removeCallback(mConfigurationListener);
+ mDumpManager.unregisterDumpable(TAG);
+ }
+ };
+
+ TunerService.Tunable mTunable = (key, newValue) -> setupUri(newValue);
+
+ ConfigurationController.ConfigurationListener mConfigurationListener =
+ new ConfigurationController.ConfigurationListener() {
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ mView.onDensityOrFontScaleChanged();
+ }
+ };
+
+ Observer<Slice> mObserver = new Observer<Slice>() {
+ @Override
+ public void onChanged(Slice slice) {
+ mSlice = slice;
+ showSlice(slice);
+ }
+ };
+
+ private View.OnClickListener mOnClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final PendingIntent action = mClickActions.get(v);
+ if (action != null && mActivityStarter != null) {
+ mActivityStarter.startPendingIntentDismissingKeyguard(action);
+ }
+ }
+ };
+
+ @Inject
+ public KeyguardSliceViewController(KeyguardSliceView keyguardSliceView,
+ KeyguardStatusView keyguardStatusView, ActivityStarter activityStarter,
+ ConfigurationController configurationController, TunerService tunerService,
+ DumpManager dumpManager) {
+ mView = keyguardSliceView;
+ mKeyguardStatusView = keyguardStatusView;
+ mActivityStarter = activityStarter;
+ mConfigurationController = configurationController;
+ mTunerService = tunerService;
+ mDumpManager = dumpManager;
+ }
+
+ /** Initialize the controller. */
+ public void init() {
+ if (mView.isAttachedToWindow()) {
+ mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
+ }
+ mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+ mView.setOnClickListener(mOnClickListener);
+ // TODO: remove the line below.
+ mKeyguardStatusView.setKeyguardSliceViewController(this);
+ }
+
+ /**
+ * Sets the slice provider Uri.
+ */
+ public void setupUri(String uriString) {
+ if (uriString == null) {
+ uriString = KeyguardSliceProvider.KEYGUARD_SLICE_URI;
+ }
+
+ boolean wasObserving = false;
+ if (mLiveData != null && mLiveData.hasActiveObservers()) {
+ wasObserving = true;
+ mLiveData.removeObserver(mObserver);
+ }
+
+ mKeyguardSliceUri = Uri.parse(uriString);
+ mLiveData = SliceLiveData.fromUri(mView.getContext(), mKeyguardSliceUri);
+
+ if (wasObserving) {
+ mLiveData.observeForever(mObserver);
+ }
+ }
+
+ /**
+ * Update contents of the view.
+ */
+ public void refresh() {
+ Slice slice;
+ Trace.beginSection("KeyguardSliceViewController#refresh");
+ // We can optimize performance and avoid binder calls when we know that we're bound
+ // to a Slice on the same process.
+ if (KeyguardSliceProvider.KEYGUARD_SLICE_URI.equals(mKeyguardSliceUri.toString())) {
+ KeyguardSliceProvider instance = KeyguardSliceProvider.getAttachedInstance();
+ if (instance != null) {
+ slice = instance.onBindSlice(mKeyguardSliceUri);
+ } else {
+ Log.w(TAG, "Keyguard slice not bound yet?");
+ slice = null;
+ }
+ } else {
+ // TODO: Make SliceViewManager injectable
+ slice = SliceViewManager.getInstance(mView.getContext()).bindSlice(mKeyguardSliceUri);
+ }
+ mObserver.onChanged(slice);
+ Trace.endSection();
+ }
+
+ void showSlice(Slice slice) {
+ Trace.beginSection("KeyguardSliceViewController#showSlice");
+ if (slice == null) {
+ mView.hideSlice();
+ Trace.endSection();
+ return;
+ }
+
+ ListContent lc = new ListContent(slice);
+ RowContent headerContent = lc.getHeader();
+ boolean hasHeader =
+ headerContent != null && !headerContent.getSliceItem().hasHint(HINT_LIST_ITEM);
+
+ List<SliceContent> subItems = lc.getRowItems().stream().filter(sliceContent -> {
+ String itemUri = sliceContent.getSliceItem().getSlice().getUri().toString();
+ // Filter out the action row
+ return !KeyguardSliceProvider.KEYGUARD_ACTION_URI.equals(itemUri);
+ }).collect(Collectors.toList());
+
+
+ mClickActions = mView.showSlice(hasHeader ? headerContent : null, subItems);
+
+ Trace.endSection();
+ }
+
+
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println(" mSlice: " + mSlice);
+ pw.println(" mClickActions: " + mClickActions);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 4c6aafb..6e11174 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -32,7 +32,6 @@
import android.util.TypedValue;
import android.view.View;
import android.widget.GridLayout;
-import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
@@ -56,7 +55,6 @@
private final LockPatternUtils mLockPatternUtils;
private final IActivityManager mIActivityManager;
- private LinearLayout mStatusViewContainer;
private TextView mLogoutView;
private KeyguardClockSwitch mClockView;
private TextView mOwnerInfo;
@@ -64,6 +62,7 @@
private View mNotificationIcons;
private Runnable mPendingMarqueeStart;
private Handler mHandler;
+ private KeyguardSliceViewController mKeyguardSliceViewController;
private boolean mPulsing;
private float mDarkAmount = 0;
@@ -179,7 +178,6 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mStatusViewContainer = findViewById(R.id.status_view_container);
mLogoutView = findViewById(R.id.logout);
mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
if (mLogoutView != null) {
@@ -250,7 +248,7 @@
public void dozeTimeTick() {
refreshTime();
- mKeyguardSlice.refresh();
+ mKeyguardSliceViewController.refresh();
}
private void refreshTime() {
@@ -456,4 +454,9 @@
Log.e(TAG, "Failed to logout user", re);
}
}
+
+ // TODO: remove this method when a controller is available.
+ void setKeyguardSliceViewController(KeyguardSliceViewController keyguardSliceViewController) {
+ mKeyguardSliceViewController = keyguardSliceViewController;
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
new file mode 100644
index 0000000..21ccff7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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.keyguard.dagger;
+
+import com.android.keyguard.KeyguardClockSwitchController;
+import com.android.keyguard.KeyguardStatusView;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+
+/**
+ * Subcomponent for helping work with KeyguardStatusView and its children.
+ */
+@Subcomponent(modules = {KeyguardStatusViewModule.class})
+@KeyguardStatusViewScope
+public interface KeyguardStatusViewComponent {
+ /** Simple factory for {@link KeyguardStatusViewComponent}. */
+ @Subcomponent.Factory
+ interface Factory {
+ KeyguardStatusViewComponent build(@BindsInstance KeyguardStatusView presentation);
+ }
+
+ /** Builds a {@link com.android.keyguard.KeyguardClockSwitchController}. */
+ KeyguardClockSwitchController getKeyguardClockSwitchController();
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java
new file mode 100644
index 0000000..1d51e59
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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.keyguard.dagger;
+
+import com.android.keyguard.KeyguardClockSwitch;
+import com.android.keyguard.KeyguardSliceView;
+import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.R;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** Dagger module for {@link KeyguardStatusViewComponent}. */
+@Module
+public abstract class KeyguardStatusViewModule {
+ @Provides
+ static KeyguardClockSwitch getKeyguardClockSwitch(KeyguardStatusView keyguardPresentation) {
+ return keyguardPresentation.findViewById(R.id.keyguard_clock_container);
+ }
+
+ @Provides
+ static KeyguardSliceView getKeyguardSliceView(KeyguardClockSwitch keyguardClockSwitch) {
+ return keyguardClockSwitch.findViewById(R.id.keyguard_status_area);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java
new file mode 100644
index 0000000..880822a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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.keyguard.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the StatusBarComponent.
+ */
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface KeyguardStatusViewScope {}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 8a67e96..0dd9488 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -18,6 +18,8 @@
import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.app.INotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
@@ -26,6 +28,7 @@
import android.os.HandlerThread;
import android.os.Looper;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.util.DisplayMetrics;
import android.view.Choreographer;
import android.view.IWindowManager;
@@ -39,6 +42,7 @@
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.Prefs;
import com.android.systemui.accessibility.ModeSwitchesController;
import com.android.systemui.accessibility.SystemActions;
@@ -88,7 +92,7 @@
* Provides dependencies for the root component of sysui injection.
*
* Only SystemUI owned classes and instances should go in here. Other, framework-owned classes
- * should go in {@link SystemServicesModule}.
+ * should go in {@link FrameworkServicesModule}.
*
* See SystemUI/docs/dagger.md
*/
@@ -163,6 +167,15 @@
}
+ @SuppressLint("MissingPermission")
+ @SysUISingleton
+ @Provides
+ @Nullable
+ static LocalBluetoothManager provideLocalBluetoothController(Context context,
+ @Background Handler bgHandler) {
+ return LocalBluetoothManager.create(context, bgHandler, UserHandle.ALL);
+ }
+
/** */
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
rename to packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index ceb9aee..66063a8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -17,7 +17,6 @@
package com.android.systemui.dagger;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.AlarmManager;
@@ -49,10 +48,8 @@
import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.BatteryStats;
-import android.os.Handler;
import android.os.PowerManager;
import android.os.ServiceManager;
-import android.os.UserHandle;
import android.os.UserManager;
import android.os.Vibrator;
import android.service.dreams.DreamService;
@@ -68,12 +65,12 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.LatencyTracker;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.PackageManagerWrapper;
+import javax.inject.Singleton;
+
import dagger.Module;
import dagger.Provides;
@@ -81,51 +78,51 @@
* Provides Non-SystemUI, Framework-Owned instances to the dependency graph.
*/
@Module
-public class SystemServicesModule {
+public class FrameworkServicesModule {
@Provides
- @SysUISingleton
+ @Singleton
static AccessibilityManager provideAccessibilityManager(Context context) {
return context.getSystemService(AccessibilityManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static ActivityManager provideActivityManager(Context context) {
return context.getSystemService(ActivityManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static AlarmManager provideAlarmManager(Context context) {
return context.getSystemService(AlarmManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static AudioManager provideAudioManager(Context context) {
return context.getSystemService(AudioManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static ColorDisplayManager provideColorDisplayManager(Context context) {
return context.getSystemService(ColorDisplayManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static ConnectivityManager provideConnectivityManagager(Context context) {
return context.getSystemService(ConnectivityManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static ContentResolver provideContentResolver(Context context) {
return context.getContentResolver();
}
@Provides
- @SysUISingleton
+ @Singleton
static DevicePolicyManager provideDevicePolicyManager(Context context) {
return context.getSystemService(DevicePolicyManager.class);
}
@@ -137,39 +134,39 @@
}
@Provides
- @SysUISingleton
+ @Singleton
static DisplayManager provideDisplayManager(Context context) {
return context.getSystemService(DisplayManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static IActivityManager provideIActivityManager() {
return ActivityManager.getService();
}
- @SysUISingleton
@Provides
+ @Singleton
static IActivityTaskManager provideIActivityTaskManager() {
return ActivityTaskManager.getService();
}
@Provides
- @SysUISingleton
+ @Singleton
static IBatteryStats provideIBatteryStats() {
return IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
}
@Provides
- @SysUISingleton
+ @Singleton
static IDreamManager provideIDreamManager() {
return IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
}
@Provides
- @SysUISingleton
+ @Singleton
@Nullable
static FaceManager provideFaceManager(Context context) {
return context.getSystemService(FaceManager.class);
@@ -177,13 +174,13 @@
}
@Provides
- @SysUISingleton
+ @Singleton
static IPackageManager provideIPackageManager() {
return IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
}
- @SysUISingleton
@Provides
+ @Singleton
static IStatusBarService provideIStatusBarService() {
return IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -196,39 +193,30 @@
ServiceManager.getService(Context.WALLPAPER_SERVICE));
}
- @SysUISingleton
@Provides
+ @Singleton
static IWindowManager provideIWindowManager() {
return WindowManagerGlobal.getWindowManagerService();
}
- @SysUISingleton
@Provides
+ @Singleton
static KeyguardManager provideKeyguardManager(Context context) {
return context.getSystemService(KeyguardManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static LatencyTracker provideLatencyTracker(Context context) {
return LatencyTracker.getInstance(context);
}
- @SysUISingleton
@Provides
+ @Singleton
static LauncherApps provideLauncherApps(Context context) {
return context.getSystemService(LauncherApps.class);
}
- @SuppressLint("MissingPermission")
- @SysUISingleton
- @Provides
- @Nullable
- static LocalBluetoothManager provideLocalBluetoothController(Context context,
- @Background Handler bgHandler) {
- return LocalBluetoothManager.create(context, bgHandler, UserHandle.ALL);
- }
-
@Provides
static MediaRouter2Manager provideMediaRouter2Manager(Context context) {
return MediaRouter2Manager.getInstance(context);
@@ -240,32 +228,32 @@
}
@Provides
- @SysUISingleton
+ @Singleton
static NetworkScoreManager provideNetworkScoreManager(Context context) {
return context.getSystemService(NetworkScoreManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static NotificationManager provideNotificationManager(Context context) {
return context.getSystemService(NotificationManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static PackageManager providePackageManager(Context context) {
return context.getPackageManager();
}
- @SysUISingleton
@Provides
+ @Singleton
static PackageManagerWrapper providePackageManagerWrapper() {
return PackageManagerWrapper.getInstance();
}
/** */
- @SysUISingleton
@Provides
+ @Singleton
static PowerManager providePowerManager(Context context) {
return context.getSystemService(PowerManager.class);
}
@@ -277,57 +265,63 @@
}
@Provides
- @SysUISingleton
+ @Singleton
+ static RoleManager provideRoleManager(Context context) {
+ return context.getSystemService(RoleManager.class);
+ }
+
+ @Provides
+ @Singleton
static SensorManager providesSensorManager(Context context) {
return context.getSystemService(SensorManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static SensorPrivacyManager provideSensorPrivacyManager(Context context) {
return context.getSystemService(SensorPrivacyManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static ShortcutManager provideShortcutManager(Context context) {
return context.getSystemService(ShortcutManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
@Nullable
static TelecomManager provideTelecomManager(Context context) {
return context.getSystemService(TelecomManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static TelephonyManager provideTelephonyManager(Context context) {
return context.getSystemService(TelephonyManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static TrustManager provideTrustManager(Context context) {
return context.getSystemService(TrustManager.class);
}
@Provides
- @SysUISingleton
+ @Singleton
@Nullable
static Vibrator provideVibrator(Context context) {
return context.getSystemService(Vibrator.class);
}
@Provides
- @SysUISingleton
+ @Singleton
static ViewConfiguration provideViewConfiguration(Context context) {
return ViewConfiguration.get(context);
}
@Provides
- @SysUISingleton
+ @Singleton
static UserManager provideUserManager(Context context) {
return context.getSystemService(UserManager.class);
}
@@ -338,21 +332,15 @@
}
@Provides
- @SysUISingleton
+ @Singleton
@Nullable
static WifiManager provideWifiManager(Context context) {
return context.getSystemService(WifiManager.class);
}
- @SysUISingleton
@Provides
+ @Singleton
static WindowManager provideWindowManager(Context context) {
return context.getSystemService(WindowManager.class);
}
-
- @Provides
- @SysUISingleton
- static RoleManager provideRoleManager(Context context) {
- return context.getSystemService(RoleManager.class);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 553655b..fd4a409 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -16,63 +16,23 @@
package com.android.systemui.dagger;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.hardware.display.AmbientDisplayConfiguration;
-import android.util.DisplayMetrics;
-import android.view.Choreographer;
-
-import com.android.systemui.Prefs;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import javax.inject.Singleton;
-
import dagger.Module;
-import dagger.Provides;
/**
- * Supplies globally scoped instances.
+ * Supplies globally scoped instances that should be available in all versions of SystemUI
*
* Providers in this module will be accessible to both WMComponent and SysUIComponent scoped
* classes. They are in here because they are either needed globally or are inherently universal
* to the application.
*
* Note that just because a class might be used by both WM and SysUI does not necessarily mean that
- * it should got into this module. If WM and SysUI might need the class for different purposes
+ * it should go into this module. If WM and SysUI might need the class for different purposes
* or different semantics, it may make sense to ask them to supply their own. Something like
* threading and concurrency provide a good example. Both components need
* Threads/Handlers/Executors, but they need separate instances of them in many cases.
*
* Please use discretion when adding things to the global scope.
*/
-@Module
+@Module(includes = {FrameworkServicesModule.class})
public class GlobalModule {
- /** */
- @Provides
- @Main
- public SharedPreferences provideSharePreferences(Context context) {
- return Prefs.get(context);
- }
-
- /** */
- @Provides
- public AmbientDisplayConfiguration provideAmbientDisplayConfiguration(Context context) {
- return new AmbientDisplayConfiguration(context);
- }
-
- /** */
- @Provides
- @Singleton
- public Choreographer providesChoreographer() {
- return Choreographer.getInstance();
- }
-
- /** */
- @Provides
- @Singleton
- public DisplayMetrics provideDisplayMetrics(Context context) {
- DisplayMetrics displayMetrics = new DisplayMetrics();
- context.getDisplay().getMetrics(displayMetrics);
- return displayMetrics;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
index 3d7c8ad4..36fd337 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
@@ -28,6 +28,7 @@
*/
@Singleton
@Component(modules = {
+ GlobalModule.class,
SysUISubcomponentModule.class,
WMModule.class})
public interface GlobalRootComponent {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index b606201..e4e3d7a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -37,7 +37,6 @@
DependencyProvider.class,
DependencyBinder.class,
PipModule.class,
- SystemServicesModule.class,
SystemUIBinder.class,
SystemUIModule.class,
SystemUIDefaultModule.class})
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index e38dce0..8364b48 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -262,11 +262,11 @@
onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState());
} else if (isLongPress) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
- null /* onPulseSupressedListener */);
+ null /* onPulseSuppressedListener */);
} else if (isWakeLockScreen) {
if (wakeEvent) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
- null /* onPulseSupressedListener */);
+ null /* onPulseSuppressedListener */);
}
} else {
proximityCheckThenCall((result) -> {
@@ -536,7 +536,7 @@
if (PULSE_ACTION.equals(intent.getAction())) {
if (DozeMachine.DEBUG) Log.d(TAG, "Received pulse intent");
requestPulse(DozeLog.PULSE_REASON_INTENT, false, /* performedProxCheck */
- null /* onPulseSupressedListener */);
+ null /* onPulseSuppressedListener */);
}
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
mMachine.requestState(DozeMachine.State.FINISH);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6214a64..3340791 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -89,15 +89,14 @@
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.dagger.KeyguardModule;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.DeviceConfigProxy;
-import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -228,7 +227,6 @@
/** TrustManager for letting it know when we change visibility */
private final TrustManager mTrustManager;
- private final InjectionInflationController mInjectionInflationController;
/**
* Used to keep the device awake while to ensure the keyguard finishes opening before
@@ -345,7 +343,7 @@
/**
* For managing external displays
*/
- private KeyguardDisplayManager mKeyguardDisplayManager;
+ private final KeyguardDisplayManager mKeyguardDisplayManager;
private final ArrayList<IKeyguardStateCallback> mKeyguardStateCallbacks = new ArrayList<>();
@@ -724,7 +722,7 @@
TrustManager trustManager,
DeviceConfigProxy deviceConfig,
NavigationModeController navigationModeController,
- InjectionInflationController injectionInflationController) {
+ KeyguardDisplayManager keyguardDisplayManager) {
super(context);
mFalsingManager = falsingManager;
mLockPatternUtils = lockPatternUtils;
@@ -735,7 +733,7 @@
mUpdateMonitor = keyguardUpdateMonitor;
mPM = powerManager;
mTrustManager = trustManager;
- mInjectionInflationController = injectionInflationController;
+ mKeyguardDisplayManager = keyguardDisplayManager;
dumpManager.registerDumpable(getClass().getName(), this);
mDeviceConfig = deviceConfig;
mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
@@ -775,9 +773,6 @@
mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
SYSTEMUI_PERMISSION, null /* scheduler */);
- mKeyguardDisplayManager = new KeyguardDisplayManager(mContext,
- mInjectionInflationController);
-
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index c9164f0..9d8e73a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -26,8 +26,10 @@
import android.os.PowerManager;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardViewController;
+import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -43,7 +45,6 @@
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.DeviceConfigProxy;
-import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.settings.GlobalSettings;
import com.android.systemui.util.settings.SystemSettings;
@@ -58,7 +59,7 @@
/**
* Dagger Module providing {@link StatusBar}.
*/
-@Module
+@Module(subcomponents = {KeyguardStatusViewComponent.class})
public class KeyguardModule {
/**
* Provides our instance of KeyguardViewMediator which is considered optional.
@@ -79,7 +80,7 @@
@UiBackground Executor uiBgExecutor,
DeviceConfigProxy deviceConfig,
NavigationModeController navigationModeController,
- InjectionInflationController injectionInflationController) {
+ KeyguardDisplayManager keyguardDisplayManager) {
return new KeyguardViewMediator(
context,
falsingManager,
@@ -94,7 +95,8 @@
trustManager,
deviceConfig,
navigationModeController,
- injectionInflationController);
+ keyguardDisplayManager
+ );
}
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index 214088c..7037403 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -36,8 +36,8 @@
* Activity to show the PIP menu to control PIP.
*/
public class PipMenuActivity extends Activity implements PipManager.Listener {
- private static final boolean DEBUG = false;
private static final String TAG = "PipMenuActivity";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
static final String EXTRA_CUSTOM_ACTIONS = "custom_actions";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index d83758a..fc7e548 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -68,6 +68,7 @@
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.systemui.DejankUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -129,7 +130,6 @@
import java.util.function.Function;
import javax.inject.Inject;
-import javax.inject.Provider;
@StatusBarComponent.StatusBarScope
public class NotificationPanelViewController extends PanelViewController {
@@ -260,7 +260,7 @@
private final ConversationNotificationManager mConversationNotificationManager;
private final MediaHierarchyManager mMediaHierarchyManager;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
- private final Provider<KeyguardClockSwitchController> mKeyguardClockSwitchControllerProvider;
+ private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
// Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
// If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
private final int mMaxKeyguardNotifications;
@@ -511,9 +511,9 @@
MediaHierarchyManager mediaHierarchyManager,
BiometricUnlockController biometricUnlockController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
- Provider<KeyguardClockSwitchController> keyguardClockSwitchControllerProvider,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
- NotificationIconAreaController notificationIconAreaController) {
+ NotificationIconAreaController notificationIconAreaController,
+ KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager);
@@ -525,9 +525,9 @@
mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder;
mMediaHierarchyManager = mediaHierarchyManager;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
- mKeyguardClockSwitchControllerProvider = keyguardClockSwitchControllerProvider;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mNotificationIconAreaController = notificationIconAreaController;
+ mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mView.setWillNotDraw(!DEBUG);
mInjectionInflationController = injectionInflationController;
mFalsingManager = falsingManager;
@@ -602,8 +602,10 @@
mKeyguardStatusView = mView.findViewById(R.id.keyguard_status_view);
KeyguardClockSwitchController keyguardClockSwitchController =
- mKeyguardClockSwitchControllerProvider.get();
- keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container));
+ mKeyguardStatusViewComponentFactory
+ .build(mKeyguardStatusView)
+ .getKeyguardClockSwitchController();
+ keyguardClockSwitchController.init();
mBigClockContainer = mView.findViewById(R.id.big_clock_container);
keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
@@ -733,8 +735,10 @@
// Re-associate the clock container with the keyguard clock switch.
mBigClockContainer.removeAllViews();
KeyguardClockSwitchController keyguardClockSwitchController =
- mKeyguardClockSwitchControllerProvider.get();
- keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container));
+ mKeyguardStatusViewComponentFactory
+ .build(mKeyguardStatusView)
+ .getKeyguardClockSwitchController();
+ keyguardClockSwitchController.init();
keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
// Update keyguard bottom area
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
index 37aac11..df741a0 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
@@ -16,7 +16,9 @@
package com.android.systemui.tv;
+import com.android.systemui.dagger.GlobalModule;
import com.android.systemui.dagger.GlobalRootComponent;
+import com.android.systemui.dagger.WMModule;
import javax.inject.Singleton;
@@ -26,7 +28,11 @@
* Root component for Dagger injection.
*/
@Singleton
-@Component(modules = {TvSysUIComponentModule.class})
+@Component(modules = {
+ GlobalModule.class,
+ TvSysUIComponentModule.class,
+ WMModule.class
+})
public interface TvGlobalRootComponent extends GlobalRootComponent {
/**
* Component Builder interface. This allows to bind Context instance in the component
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java
index 302301d..3577bc0 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java
@@ -21,7 +21,6 @@
import com.android.systemui.dagger.DependencyProvider;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.SystemServicesModule;
import com.android.systemui.dagger.SystemUIBinder;
import com.android.systemui.dagger.SystemUIModule;
@@ -35,7 +34,6 @@
DefaultComponentBinder.class,
DependencyProvider.class,
DependencyBinder.class,
- SystemServicesModule.class,
SystemUIBinder.class,
SystemUIModule.class,
TvSystemUIModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index d278905..eb8f065 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -24,7 +24,6 @@
import android.view.View;
import com.android.keyguard.KeyguardMessageArea;
-import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.qs.QSFooterImpl;
import com.android.systemui.qs.QSPanel;
@@ -109,11 +108,6 @@
NotificationStackScrollLayout createNotificationStackScrollLayout();
/**
- * Creates the KeyguardSliceView.
- */
- KeyguardSliceView createKeyguardSliceView();
-
- /**
* Creates the KeyguardMessageArea.
*/
KeyguardMessageArea createKeyguardMessageArea();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 657e4fb..3aa6ec0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -62,6 +62,8 @@
private ClockPlugin mClockPlugin;
@Mock
ColorExtractor.GradientColors mGradientColors;
+ @Mock
+ KeyguardSliceViewController mKeyguardSliceViewController;
private KeyguardClockSwitchController mController;
@@ -69,28 +71,30 @@
public void setup() {
MockitoAnnotations.initMocks(this);
- mController = new KeyguardClockSwitchController(
- mStatusBarStateController, mColorExtractor, mClockManager);
-
when(mView.isAttachedToWindow()).thenReturn(true);
+
+ mController = new KeyguardClockSwitchController(
+ mView, mStatusBarStateController, mColorExtractor, mClockManager,
+ mKeyguardSliceViewController);
+
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
}
@Test
- public void testAttach_viewAlreadyAttached() {
- mController.attach(mView);
+ public void testInit_viewAlreadyAttached() {
+ mController.init();
verifyAttachment(times(1));
}
@Test
- public void testAttach_viewNotYetAttached() {
+ public void testInit_viewNotYetAttached() {
ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
when(mView.isAttachedToWindow()).thenReturn(false);
- mController.attach(mView);
+ mController.init();
verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
verifyAttachment(never());
@@ -100,12 +104,17 @@
verifyAttachment(times(1));
}
+ @Test
+ public void testInitSubControllers() {
+ mController.init();
+ verify(mKeyguardSliceViewController).init();
+ }
@Test
- public void testAttach_viewDetached() {
+ public void testInit_viewDetached() {
ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
- mController.attach(mView);
+ mController.init();
verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
verifyAttachment(times(1));
@@ -122,7 +131,7 @@
public void testBigClockPassesStatusBarState() {
ViewGroup testView = new FrameLayout(mContext);
- mController.attach(mView);
+ mController.init();
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
mController.setBigClockContainer(testView);
verify(mView).setBigClockContainer(testView, StatusBarState.SHADE);
@@ -143,7 +152,7 @@
ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class);
- mController.attach(mView);
+ mController.init();
verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture());
listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
index 446b122..559284a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -28,6 +29,7 @@
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardDisplayManager.KeyguardPresentation;
+import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
@@ -51,6 +53,12 @@
KeyguardSliceView mMockKeyguardSliceView;
@Mock
KeyguardStatusView mMockKeyguardStatusView;
+ @Mock
+ private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
+ @Mock
+ private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
+ @Mock
+ private KeyguardClockSwitchController mKeyguardClockSwitchController;
LayoutInflater mLayoutInflater;
@@ -62,6 +70,11 @@
when(mMockKeyguardSliceView.getContext()).thenReturn(mContext);
when(mMockKeyguardStatusView.getContext()).thenReturn(mContext);
when(mMockKeyguardStatusView.findViewById(R.id.clock)).thenReturn(mMockKeyguardStatusView);
+ when(mKeyguardStatusViewComponentFactory.build(any(KeyguardStatusView.class)))
+ .thenReturn(mKeyguardStatusViewComponent);
+ when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
+ .thenReturn(mKeyguardClockSwitchController);
+
allowTestableLooperAsMainThread();
InjectionInflationController inflationController = new InjectionInflationController(
@@ -99,7 +112,8 @@
@Test
public void testInflation_doesntCrash() {
KeyguardPresentation keyguardPresentation = new KeyguardPresentation(mContext,
- mContext.getDisplayNoVerify(), mLayoutInflater);
+ mContext.getDisplayNoVerify(), mKeyguardStatusViewComponentFactory,
+ mLayoutInflater);
keyguardPresentation.onCreate(null /*savedInstanceState */);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
new file mode 100644
index 0000000..b7bcaa3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 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.keyguard;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.tuner.TunerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
+public class KeyguardSliceViewControllerTest extends SysuiTestCase {
+ @Mock
+ private KeyguardSliceView mView;;
+ @Mock
+ private KeyguardStatusView mKeyguardStatusView;
+ @Mock
+ private TunerService mTunerService;
+ @Mock
+ private ConfigurationController mConfigurationController;
+ @Mock
+ private ActivityStarter mActivityStarter;
+ private DumpManager mDumpManager = new DumpManager();
+
+ private KeyguardSliceViewController mController;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mView.isAttachedToWindow()).thenReturn(true);
+ when(mView.getContext()).thenReturn(mContext);
+ mController = new KeyguardSliceViewController(
+ mView, mKeyguardStatusView, mActivityStarter, mConfigurationController,
+ mTunerService, mDumpManager);
+ mController.setupUri(KeyguardSliceProvider.KEYGUARD_SLICE_URI);
+ }
+
+ @Test
+ public void refresh_replacesSliceContentAndNotifiesListener() {
+ mController.refresh();
+ verify(mView).hideSlice();
+ }
+
+ @Test
+ public void onAttachedToWindow_registersListeners() {
+ mController.init();
+ verify(mTunerService).addTunable(any(TunerService.Tunable.class), anyString());
+ verify(mConfigurationController).addCallback(
+ any(ConfigurationController.ConfigurationListener.class));
+ }
+
+ @Test
+ public void onDetachedFromWindow_unregistersListeners() {
+ ArgumentCaptor<View.OnAttachStateChangeListener> attachListenerArgumentCaptor =
+ ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+
+ mController.init();
+ verify(mView).addOnAttachStateChangeListener(attachListenerArgumentCaptor.capture());
+
+ attachListenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
+
+ verify(mTunerService).removeTunable(any(TunerService.Tunable.class));
+ verify(mConfigurationController).removeCallback(
+ any(ConfigurationController.ConfigurationListener.class));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 06552b9..1ab08c2 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -15,37 +15,27 @@
*/
package com.android.keyguard;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Color;
import android.net.Uri;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
-import android.util.AttributeSet;
import android.view.LayoutInflater;
-import android.view.View;
+import androidx.slice.Slice;
import androidx.slice.SliceProvider;
import androidx.slice.SliceSpecs;
import androidx.slice.builders.ListBuilder;
+import androidx.slice.widget.RowContent;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.KeyguardSliceProvider;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.tuner.TunerService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Collections;
@@ -53,46 +43,18 @@
import java.util.concurrent.atomic.AtomicBoolean;
@SmallTest
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidTestingRunner.class)
public class KeyguardSliceViewTest extends SysuiTestCase {
private KeyguardSliceView mKeyguardSliceView;
private Uri mSliceUri;
- @Mock
- private TunerService mTunerService;
- @Mock
- private ConfigurationController mConfigurationController;
- @Mock
- private ActivityStarter mActivityStarter;
- @Mock
- private Resources mResources;
-
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- allowTestableLooperAsMainThread();
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
- layoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
-
- @Override
- public View onCreateView(View parent, String name, Context context,
- AttributeSet attrs) {
- return onCreateView(name, context, attrs);
- }
-
- @Override
- public View onCreateView(String name, Context context, AttributeSet attrs) {
- if ("com.android.keyguard.KeyguardSliceView".equals(name)) {
- return new KeyguardSliceView(getContext(), attrs, mActivityStarter,
- mConfigurationController, mTunerService, mResources);
- }
- return null;
- }
- });
mKeyguardSliceView = (KeyguardSliceView) layoutInflater
.inflate(R.layout.keyguard_status_area, null);
- mKeyguardSliceView.setupUri(KeyguardSliceProvider.KEYGUARD_SLICE_URI);
mSliceUri = Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI);
SliceProvider.setSpecs(new HashSet<>(Collections.singletonList(SliceSpecs.LIST)));
}
@@ -100,9 +62,13 @@
@Test
public void showSlice_notifiesListener() {
ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
+ builder.setHeader(new ListBuilder.HeaderBuilder().setTitle("header title!"));
+ Slice slice = builder.build();
+ RowContent rowContent = new RowContent(slice.getItemArray()[0], 0);
+
AtomicBoolean notified = new AtomicBoolean();
mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
- mKeyguardSliceView.onChanged(builder.build());
+ mKeyguardSliceView.showSlice(rowContent, Collections.EMPTY_LIST);
Assert.assertTrue("Listener should be notified about slice changes.",
notified.get());
}
@@ -111,7 +77,7 @@
public void showSlice_emptySliceNotifiesListener() {
AtomicBoolean notified = new AtomicBoolean();
mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
- mKeyguardSliceView.onChanged(null);
+ mKeyguardSliceView.showSlice(null, Collections.EMPTY_LIST);
Assert.assertTrue("Listener should be notified about slice changes.",
notified.get());
}
@@ -119,24 +85,17 @@
@Test
public void hasHeader_readsSliceData() {
ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
- mKeyguardSliceView.onChanged(builder.build());
+ mKeyguardSliceView.showSlice(null, Collections.EMPTY_LIST);
Assert.assertFalse("View should not have a header", mKeyguardSliceView.hasHeader());
builder.setHeader(new ListBuilder.HeaderBuilder().setTitle("header title!"));
- mKeyguardSliceView.onChanged(builder.build());
+ Slice slice = builder.build();
+ RowContent rowContent = new RowContent(slice.getItemArray()[0], 0);
+ mKeyguardSliceView.showSlice(rowContent, Collections.EMPTY_LIST);
Assert.assertTrue("View should have a header", mKeyguardSliceView.hasHeader());
}
@Test
- public void refresh_replacesSliceContentAndNotifiesListener() {
- AtomicBoolean notified = new AtomicBoolean();
- mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
- mKeyguardSliceView.refresh();
- Assert.assertTrue("Listener should be notified about slice changes.",
- notified.get());
- }
-
- @Test
public void getTextColor_whiteTextWhenAOD() {
// Set text color to red since the default is white and test would always pass
mKeyguardSliceView.setTextColor(Color.RED);
@@ -147,18 +106,4 @@
Assert.assertEquals("Should be using AOD text color", Color.WHITE,
mKeyguardSliceView.getTextColor());
}
-
- @Test
- public void onAttachedToWindow_registersListeners() {
- mKeyguardSliceView.onAttachedToWindow();
- verify(mTunerService).addTunable(eq(mKeyguardSliceView), anyString());
- verify(mConfigurationController).addCallback(eq(mKeyguardSliceView));
- }
-
- @Test
- public void onDetachedFromWindow_unregistersListeners() {
- mKeyguardSliceView.onDetachedFromWindow();
- verify(mTunerService).removeTunable(eq(mKeyguardSliceView));
- verify(mConfigurationController).removeCallback(eq(mKeyguardSliceView));
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index 0bf1376..0431704 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -40,7 +40,8 @@
public class KeyguardStatusViewTest extends SysuiTestCase {
@Mock
- KeyguardSliceView mKeyguardSlice;
+ KeyguardSliceViewController mKeyguardSliceViewController;
+
@Mock
KeyguardClockSwitch mClockView;
@InjectMocks
@@ -64,7 +65,7 @@
@Test
public void dozeTimeTick_updatesSlice() {
mKeyguardStatusView.dozeTimeTick();
- verify(mKeyguardSlice).refresh();
+ verify(mKeyguardSliceViewController).refresh();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index c874b1f..f6d6f562 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -37,6 +37,7 @@
import androidx.test.filters.SmallTest;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -46,7 +47,6 @@
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
-import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -72,7 +72,7 @@
private @Mock PowerManager mPowerManager;
private @Mock TrustManager mTrustManager;
private @Mock NavigationModeController mNavigationModeController;
- private @Mock InjectionInflationController mInjectionInflationController;
+ private @Mock KeyguardDisplayManager mKeyguardDisplayManager;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -91,7 +91,7 @@
() -> mStatusBarKeyguardViewManager,
mDismissCallbackRegistry, mUpdateMonitor, mDumpManager, mUiBgExecutor,
mPowerManager, mTrustManager, mDeviceConfig, mNavigationModeController,
- mInjectionInflationController);
+ mKeyguardDisplayManager);
mViewMediator.start();
}
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 04e870d..a9484af 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
@@ -54,6 +54,7 @@
import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
@@ -187,10 +188,16 @@
@Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock
+ private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
+ @Mock
+ private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
+ @Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock
private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
+ private FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder;
+
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
@@ -241,6 +248,10 @@
mock(NotificationRoundnessManager.class),
mStatusBarStateController,
new FalsingManagerFake());
+ when(mKeyguardStatusViewComponentFactory.build(any()))
+ .thenReturn(mKeyguardStatusViewComponent);
+ when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
+ .thenReturn(mKeyguardClockSwitchController);
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mResources,
mInjectionInflationController,
@@ -254,9 +265,9 @@
flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
mConversationNotificationManager, mMediaHiearchyManager,
mBiometricUnlockController, mStatusBarKeyguardViewManager,
- () -> mKeyguardClockSwitchController,
mNotificationStackScrollLayoutController,
- mNotificationAreaController);
+ mNotificationAreaController,
+ mKeyguardStatusViewComponentFactory);
mNotificationPanelViewController.initDependencies(
mStatusBar,
mGroupManager,
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index b587dd3..d127172 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -594,15 +594,23 @@
if (pointerIndex < 0) {
return;
}
- final float deltaX =
- mReceivedPointerTracker.getReceivedPointerDownX(pointerId)
- - rawEvent.getX(pointerIndex);
- final float deltaY =
- mReceivedPointerTracker.getReceivedPointerDownY(pointerId)
- - rawEvent.getY(pointerIndex);
- final double moveDelta = Math.hypot(deltaX, deltaY);
- if (moveDelta < mTouchSlop) {
- return;
+ // Require both fingers to have moved a certain amount before starting a drag.
+ for (int index = 0; index < event.getPointerCount(); ++index) {
+ int id = event.getPointerId(index);
+ if (!mReceivedPointerTracker.isReceivedPointerDown(id)) {
+ // Something is wrong with the event stream.
+ Slog.e(LOG_TAG, "Invalid pointer id: " + id);
+ }
+ final float deltaX =
+ mReceivedPointerTracker.getReceivedPointerDownX(id)
+ - rawEvent.getX(index);
+ final float deltaY =
+ mReceivedPointerTracker.getReceivedPointerDownY(id)
+ - rawEvent.getY(index);
+ final double moveDelta = Math.hypot(deltaX, deltaY);
+ if (moveDelta < mTouchSlop) {
+ return;
+ }
}
}
// More than one pointer so the user is not touch exploring
@@ -612,12 +620,20 @@
if (isDraggingGesture(event)) {
// Two pointers moving in the same direction within
// a given distance perform a drag.
- mState.startDragging();
computeDraggingPointerIdIfNeeded(event);
pointerIdBits = 1 << mDraggingPointerId;
event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
- mDispatcher.sendMotionEvent(
- event, ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ MotionEvent downEvent = computeDownEventForDrag(event);
+ if (downEvent != null) {
+ mDispatcher.sendMotionEvent(
+ downEvent, ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ mDispatcher.sendMotionEvent(
+ event, ACTION_MOVE, rawEvent, pointerIdBits, policyFlags);
+ } else {
+ mDispatcher.sendMotionEvent(
+ event, ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ }
+ mState.startDragging();
} else {
// Two pointers moving arbitrary are delegated to the view hierarchy.
mState.startDelegating();
@@ -1004,6 +1020,49 @@
return distance;
}
+ /**
+ * Creates a down event using the down coordinates of the dragging pointer and other information
+ * from the supplied event. The supplied event's down time is adjusted to reflect the time when
+ * the dragging pointer initially went down.
+ */
+ private MotionEvent computeDownEventForDrag(MotionEvent event) {
+ // Creating a down event only makes sense if we haven't started touch exploring yet.
+ if (mState.isTouchExploring()
+ || mDraggingPointerId == INVALID_POINTER_ID
+ || event == null) {
+ return null;
+ }
+ final float x = mReceivedPointerTracker.getReceivedPointerDownX(mDraggingPointerId);
+ final float y = mReceivedPointerTracker.getReceivedPointerDownY(mDraggingPointerId);
+ final long time = mReceivedPointerTracker.getReceivedPointerDownTime(mDraggingPointerId);
+ MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[1];
+ coords[0] = new MotionEvent.PointerCoords();
+ coords[0].x = x;
+ coords[0].y = y;
+ MotionEvent.PointerProperties[] properties = new MotionEvent.PointerProperties[1];
+ properties[0] = new MotionEvent.PointerProperties();
+ properties[0].id = mDraggingPointerId;
+ properties[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ MotionEvent downEvent =
+ MotionEvent.obtain(
+ time,
+ time,
+ ACTION_DOWN,
+ 1,
+ properties,
+ coords,
+ event.getMetaState(),
+ event.getButtonState(),
+ event.getXPrecision(),
+ event.getYPrecision(),
+ event.getDeviceId(),
+ event.getEdgeFlags(),
+ event.getSource(),
+ event.getFlags());
+ event.setDownTime(time);
+ return downEvent;
+ }
+
public TouchState getState() {
return mState;
}
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
index 1c4db12..59ba82e 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
@@ -34,6 +34,7 @@
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
+import android.os.IBinder;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.util.Slog;
@@ -108,9 +109,9 @@
@Override
public void createPredictionSession(@NonNull AppPredictionContext context,
- @NonNull AppPredictionSessionId sessionId) {
- runForUserLocked("createPredictionSession", sessionId,
- (service) -> service.onCreatePredictionSessionLocked(context, sessionId));
+ @NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
+ runForUserLocked("createPredictionSession", sessionId, (service) ->
+ service.onCreatePredictionSessionLocked(context, sessionId, token));
}
@Override
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 7ee607c..735f420 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -30,6 +30,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.ServiceInfo;
+import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.provider.DeviceConfig;
@@ -44,8 +45,6 @@
import com.android.server.infra.AbstractPerUserSystemService;
import com.android.server.people.PeopleServiceInternal;
-import java.util.function.Consumer;
-
/**
* Per-user instance of {@link AppPredictionManagerService}.
*/
@@ -112,17 +111,24 @@
*/
@GuardedBy("mLock")
public void onCreatePredictionSessionLocked(@NonNull AppPredictionContext context,
- @NonNull AppPredictionSessionId sessionId) {
- if (!mSessionInfos.containsKey(sessionId)) {
- mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context,
- DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
- PREDICT_USING_PEOPLE_SERVICE_PREFIX + context.getUiSurface(), false),
- this::removeAppPredictionSessionInfo));
- }
- final boolean serviceExists = resolveService(sessionId, s ->
- s.onCreatePredictionSession(context, sessionId), true);
- if (!serviceExists) {
- mSessionInfos.remove(sessionId);
+ @NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
+ final boolean usesPeopleService = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
+ PREDICT_USING_PEOPLE_SERVICE_PREFIX + context.getUiSurface(), false);
+ final boolean serviceExists = resolveService(sessionId, false,
+ usesPeopleService, s -> s.onCreatePredictionSession(context, sessionId));
+ if (serviceExists && !mSessionInfos.containsKey(sessionId)) {
+ final AppPredictionSessionInfo sessionInfo = new AppPredictionSessionInfo(
+ sessionId, context, usesPeopleService, token, () -> {
+ synchronized (mLock) {
+ onDestroyPredictionSessionLocked(sessionId);
+ }
+ });
+ if (sessionInfo.linkToDeath()) {
+ mSessionInfos.put(sessionId, sessionInfo);
+ } else {
+ // destroy the session if calling process is already dead
+ onDestroyPredictionSessionLocked(sessionId);
+ }
}
}
@@ -132,7 +138,10 @@
@GuardedBy("mLock")
public void notifyAppTargetEventLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull AppTargetEvent event) {
- resolveService(sessionId, s -> s.notifyAppTargetEvent(sessionId, event), false);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, false, sessionInfo.mUsesPeopleService,
+ s -> s.notifyAppTargetEvent(sessionId, event));
}
/**
@@ -141,8 +150,10 @@
@GuardedBy("mLock")
public void notifyLaunchLocationShownLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull String launchLocation, @NonNull ParceledListSlice targetIds) {
- resolveService(sessionId, s ->
- s.notifyLaunchLocationShown(sessionId, launchLocation, targetIds), false);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, false, sessionInfo.mUsesPeopleService,
+ s -> s.notifyLaunchLocationShown(sessionId, launchLocation, targetIds));
}
/**
@@ -151,7 +162,10 @@
@GuardedBy("mLock")
public void sortAppTargetsLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull ParceledListSlice targets, @NonNull IPredictionCallback callback) {
- resolveService(sessionId, s -> s.sortAppTargets(sessionId, targets, callback), true);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, true, sessionInfo.mUsesPeopleService,
+ s -> s.sortAppTargets(sessionId, targets, callback));
}
/**
@@ -160,10 +174,12 @@
@GuardedBy("mLock")
public void registerPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull IPredictionCallback callback) {
- final boolean serviceExists = resolveService(sessionId, s ->
- s.registerPredictionUpdates(sessionId, callback), false);
final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (serviceExists && sessionInfo != null) {
+ if (sessionInfo == null) return;
+ final boolean serviceExists = resolveService(sessionId, false,
+ sessionInfo.mUsesPeopleService,
+ s -> s.registerPredictionUpdates(sessionId, callback));
+ if (serviceExists) {
sessionInfo.addCallbackLocked(callback);
}
}
@@ -174,10 +190,12 @@
@GuardedBy("mLock")
public void unregisterPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId,
@NonNull IPredictionCallback callback) {
- final boolean serviceExists = resolveService(sessionId, s ->
- s.unregisterPredictionUpdates(sessionId, callback), false);
final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (serviceExists && sessionInfo != null) {
+ if (sessionInfo == null) return;
+ final boolean serviceExists = resolveService(sessionId, false,
+ sessionInfo.mUsesPeopleService,
+ s -> s.unregisterPredictionUpdates(sessionId, callback));
+ if (serviceExists) {
sessionInfo.removeCallbackLocked(callback);
}
}
@@ -187,7 +205,10 @@
*/
@GuardedBy("mLock")
public void requestPredictionUpdateLocked(@NonNull AppPredictionSessionId sessionId) {
- resolveService(sessionId, s -> s.requestPredictionUpdate(sessionId), true);
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, true, sessionInfo.mUsesPeopleService,
+ s -> s.requestPredictionUpdate(sessionId));
}
/**
@@ -195,12 +216,14 @@
*/
@GuardedBy("mLock")
public void onDestroyPredictionSessionLocked(@NonNull AppPredictionSessionId sessionId) {
- final boolean serviceExists = resolveService(sessionId, s ->
- s.onDestroyPredictionSession(sessionId), false);
- final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (serviceExists && sessionInfo != null) {
- sessionInfo.destroy();
+ if (isDebug()) {
+ Slog.d(TAG, "onDestroyPredictionSessionLocked(): sessionId=" + sessionId);
}
+ final AppPredictionSessionInfo sessionInfo = mSessionInfos.remove(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, false, sessionInfo.mUsesPeopleService,
+ s -> s.onDestroyPredictionSession(sessionId));
+ sessionInfo.destroy();
}
@Override
@@ -291,27 +314,18 @@
}
for (AppPredictionSessionInfo sessionInfo : mSessionInfos.values()) {
- sessionInfo.resurrectSessionLocked(this);
- }
- }
-
- private void removeAppPredictionSessionInfo(AppPredictionSessionId sessionId) {
- if (isDebug()) {
- Slog.d(TAG, "removeAppPredictionSessionInfo(): sessionId=" + sessionId);
- }
- synchronized (mLock) {
- mSessionInfos.remove(sessionId);
+ sessionInfo.resurrectSessionLocked(this, sessionInfo.mToken);
}
}
@GuardedBy("mLock")
@Nullable
- protected boolean resolveService(@NonNull final AppPredictionSessionId sessionId,
- @NonNull final AbstractRemoteService.AsyncRequest<IPredictionService> cb,
- boolean sendImmediately) {
- final AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
- if (sessionInfo == null) return false;
- if (sessionInfo.mUsesPeopleService) {
+ protected boolean resolveService(
+ @NonNull final AppPredictionSessionId sessionId,
+ boolean sendImmediately,
+ boolean usesPeopleService,
+ @NonNull final AbstractRemoteService.AsyncRequest<IPredictionService> cb) {
+ if (usesPeopleService) {
final IPredictionService service =
LocalServices.getService(PeopleServiceInternal.class);
if (service != null) {
@@ -368,7 +382,9 @@
private final AppPredictionContext mPredictionContext;
private final boolean mUsesPeopleService;
@NonNull
- private final Consumer<AppPredictionSessionId> mRemoveSessionInfoAction;
+ final IBinder mToken;
+ @NonNull
+ final IBinder.DeathRecipient mDeathRecipient;
private final RemoteCallbackList<IPredictionCallback> mCallbacks =
new RemoteCallbackList<IPredictionCallback>() {
@@ -388,14 +404,16 @@
@NonNull final AppPredictionSessionId id,
@NonNull final AppPredictionContext predictionContext,
final boolean usesPeopleService,
- @NonNull final Consumer<AppPredictionSessionId> removeSessionInfoAction) {
+ @NonNull final IBinder token,
+ @NonNull final IBinder.DeathRecipient deathRecipient) {
if (DEBUG) {
Slog.d(TAG, "Creating AppPredictionSessionInfo for session Id=" + id);
}
mSessionId = id;
mPredictionContext = predictionContext;
mUsesPeopleService = usesPeopleService;
- mRemoveSessionInfoAction = removeSessionInfoAction;
+ mToken = token;
+ mDeathRecipient = deathRecipient;
}
void addCallbackLocked(IPredictionCallback callback) {
@@ -414,23 +432,38 @@
mCallbacks.unregister(callback);
}
+ boolean linkToDeath() {
+ try {
+ mToken.linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Caller is dead before session can be started, sessionId: "
+ + mSessionId);
+ }
+ return false;
+ }
+ return true;
+ }
+
void destroy() {
if (DEBUG) {
Slog.d(TAG, "Removing all callbacks for session Id=" + mSessionId
+ " and " + mCallbacks.getRegisteredCallbackCount() + " callbacks.");
}
+ if (mToken != null) {
+ mToken.unlinkToDeath(mDeathRecipient, 0);
+ }
mCallbacks.kill();
- mRemoveSessionInfoAction.accept(mSessionId);
}
- void resurrectSessionLocked(AppPredictionPerUserService service) {
+ void resurrectSessionLocked(AppPredictionPerUserService service, IBinder token) {
int callbackCount = mCallbacks.getRegisteredCallbackCount();
if (DEBUG) {
Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked()
+ ") for session Id=" + mSessionId + " and "
+ callbackCount + " callbacks.");
}
- service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId);
+ service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId, token);
mCallbacks.broadcast(
callback -> service.registerPredictionUpdatesLocked(mSessionId, callback));
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 96d973e..687af10 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -85,6 +85,7 @@
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
public class VibratorService extends IVibratorService.Stub
implements InputManager.InputDeviceListener {
@@ -114,6 +115,9 @@
private static final VibrationAttributes DEFAULT_ATTRIBUTES =
new VibrationAttributes.Builder().build();
+ // Used to generate globally unique vibration ids.
+ private final AtomicInteger mNextVibrationId = new AtomicInteger(1); // 0 = no callback
+
// A mapping from the intensity adjustment to the scaling to apply, where the intensity
// adjustment is defined as the delta between the default intensity level and the user selected
// intensity level. It's important that we apply the scaling on the delta between the two so
@@ -171,34 +175,34 @@
private int mRingIntensity;
private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>();
- static native long vibratorInit();
+ static native long vibratorInit(OnCompleteListener listener);
static native long vibratorGetFinalizer();
- static native boolean vibratorExists(long controllerPtr);
+ static native boolean vibratorExists(long nativeServicePtr);
- static native void vibratorOn(long controllerPtr, long milliseconds, Vibration vibration);
+ static native void vibratorOn(long nativeServicePtr, long milliseconds, long vibrationId);
- static native void vibratorOff(long controllerPtr);
+ static native void vibratorOff(long nativeServicePtr);
- static native void vibratorSetAmplitude(long controllerPtr, int amplitude);
+ static native void vibratorSetAmplitude(long nativeServicePtr, int amplitude);
- static native int[] vibratorGetSupportedEffects(long controllerPtr);
+ static native int[] vibratorGetSupportedEffects(long nativeServicePtr);
- static native int[] vibratorGetSupportedPrimitives(long controllerPtr);
+ static native int[] vibratorGetSupportedPrimitives(long nativeServicePtr);
static native long vibratorPerformEffect(
- long controllerPtr, long effect, long strength, Vibration vibration);
+ long nativeServicePtr, long effect, long strength, long vibrationId);
- static native void vibratorPerformComposedEffect(long controllerPtr,
- VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration);
+ static native void vibratorPerformComposedEffect(long nativeServicePtr,
+ VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId);
- static native void vibratorSetExternalControl(long controllerPtr, boolean enabled);
+ static native void vibratorSetExternalControl(long nativeServicePtr, boolean enabled);
- static native long vibratorGetCapabilities(long controllerPtr);
- static native void vibratorAlwaysOnEnable(long controllerPtr, long id, long effect,
+ static native long vibratorGetCapabilities(long nativeServicePtr);
+ static native void vibratorAlwaysOnEnable(long nativeServicePtr, long id, long effect,
long strength);
- static native void vibratorAlwaysOnDisable(long controllerPtr, long id);
+ static native void vibratorAlwaysOnDisable(long nativeServicePtr, long id);
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
@@ -220,12 +224,19 @@
}
};
+ /** Listener for vibration completion callbacks from native. */
+ public interface OnCompleteListener {
+
+ /** Callback triggered when vibration is complete, identified by {@link Vibration#id}. */
+ void onComplete(long vibrationId);
+ }
+
/**
* Holder for a vibration to be played. This class can be shared with native methods for
* hardware callback support.
*/
- @VisibleForTesting
- public final class Vibration implements IBinder.DeathRecipient {
+ private final class Vibration implements IBinder.DeathRecipient {
+
public final IBinder token;
// Start time in CLOCK_BOOTTIME base.
public final long startTime;
@@ -234,6 +245,7 @@
// not to be affected by discontinuities created by RTC adjustments.
public final long startTimeDebug;
public final VibrationAttributes attrs;
+ public final long id;
public final int uid;
public final String opPkg;
public final String reason;
@@ -248,6 +260,7 @@
VibrationAttributes attrs, int uid, String opPkg, String reason) {
this.token = token;
this.effect = effect;
+ this.id = mNextVibrationId.getAndIncrement();
this.startTime = SystemClock.elapsedRealtime();
this.startTimeDebug = System.currentTimeMillis();
this.attrs = attrs;
@@ -268,19 +281,6 @@
}
}
- /** Callback for when vibration is complete, to be called by native. */
- @VisibleForTesting
- public void onComplete() {
- synchronized (mLock) {
- if (this == mCurrentVibration) {
- if (DEBUG) {
- Slog.d(TAG, "Vibration finished by callback, cleaning up");
- }
- doCancelVibrateLocked();
- }
- }
- }
-
public boolean hasTimeoutLongerThan(long millis) {
final long duration = effect.getDuration();
return duration >= 0 && duration > millis;
@@ -385,14 +385,14 @@
mNativeWrapper = injector.getNativeWrapper();
mH = injector.createHandler(Looper.myLooper());
- long controllerPtr = mNativeWrapper.vibratorInit();
+ long nativeServicePtr = mNativeWrapper.vibratorInit(this::onVibrationComplete);
long finalizerPtr = mNativeWrapper.vibratorGetFinalizer();
if (finalizerPtr != 0) {
NativeAllocationRegistry registry =
NativeAllocationRegistry.createMalloced(
VibratorService.class.getClassLoader(), finalizerPtr);
- registry.registerNativeAllocation(this, controllerPtr);
+ registry.registerNativeAllocation(this, nativeServicePtr);
}
// Reset the hardware to a default state, in case this is a runtime
@@ -549,6 +549,19 @@
}
}
+ /** Callback for when vibration is complete, to be called by native. */
+ @VisibleForTesting
+ public void onVibrationComplete(long vibrationId) {
+ synchronized (mLock) {
+ if (mCurrentVibration != null && mCurrentVibration.id == vibrationId) {
+ if (DEBUG) {
+ Slog.d(TAG, "Vibration finished by callback, cleaning up");
+ }
+ doCancelVibrateLocked();
+ }
+ }
+ }
+
@Override // Binder call
public boolean hasVibrator() {
return doVibratorExists();
@@ -1266,18 +1279,18 @@
return mNativeWrapper.vibratorExists();
}
- /** Vibrates with native callback trigger for {@link Vibration#onComplete()}. */
+ /** Vibrates with native callback trigger for {@link #onVibrationComplete(long)}. */
private void doVibratorOn(long millis, int amplitude, Vibration vib) {
- doVibratorOn(millis, amplitude, vib.uid, vib.attrs, vib);
+ doVibratorOn(millis, amplitude, vib.uid, vib.attrs, vib.id);
}
/** Vibrates without native callback. */
private void doVibratorOn(long millis, int amplitude, int uid, VibrationAttributes attrs) {
- doVibratorOn(millis, amplitude, uid, attrs, /* vib= */ null);
+ doVibratorOn(millis, amplitude, uid, attrs, /* vibrationId= */ 0);
}
private void doVibratorOn(long millis, int amplitude, int uid, VibrationAttributes attrs,
- @Nullable Vibration vib) {
+ long vibrationId) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
try {
synchronized (mInputDeviceVibrators) {
@@ -1299,7 +1312,7 @@
// Note: ordering is important here! Many haptic drivers will reset their
// amplitude when enabled, so we always have to enable first, then set the
// amplitude.
- mNativeWrapper.vibratorOn(millis, vib);
+ mNativeWrapper.vibratorOn(millis, vibrationId);
doVibratorSetAmplitude(amplitude);
}
}
@@ -1348,7 +1361,7 @@
// Input devices don't support prebaked effect, so skip trying it with them.
if (!usingInputDeviceVibrators) {
long duration = mNativeWrapper.vibratorPerformEffect(
- prebaked.getId(), prebaked.getEffectStrength(), vib);
+ prebaked.getId(), prebaked.getEffectStrength(), vib.id);
if (duration > 0) {
noteVibratorOnLocked(vib.uid, duration);
return;
@@ -1395,7 +1408,7 @@
PrimitiveEffect[] primitiveEffects =
composed.getPrimitiveEffects().toArray(new PrimitiveEffect[0]);
- mNativeWrapper.vibratorPerformComposedEffect(primitiveEffects, vib);
+ mNativeWrapper.vibratorPerformComposedEffect(primitiveEffects, vib.id);
// Composed effects don't actually give us an estimated duration, so we just guess here.
noteVibratorOnLocked(vib.uid, 10 * primitiveEffects.length);
@@ -1726,20 +1739,20 @@
@VisibleForTesting
public static class NativeWrapper {
- private long mNativeControllerPtr = 0;
+ private long mNativeServicePtr = 0;
/** Checks if vibrator exists on device. */
public boolean vibratorExists() {
- return VibratorService.vibratorExists(mNativeControllerPtr);
+ return VibratorService.vibratorExists(mNativeServicePtr);
}
/**
* Returns native pointer to newly created controller and initializes connection to vibrator
* HAL service.
*/
- public long vibratorInit() {
- mNativeControllerPtr = VibratorService.vibratorInit();
- return mNativeControllerPtr;
+ public long vibratorInit(OnCompleteListener listener) {
+ mNativeServicePtr = VibratorService.vibratorInit(listener);
+ return mNativeServicePtr;
}
/** Returns pointer to native finalizer function to be called by GC. */
@@ -1748,60 +1761,61 @@
}
/** Turns vibrator on for given time. */
- public void vibratorOn(long milliseconds, @Nullable Vibration vibration) {
- VibratorService.vibratorOn(mNativeControllerPtr, milliseconds, vibration);
+ public void vibratorOn(long milliseconds, long vibrationId) {
+ VibratorService.vibratorOn(mNativeServicePtr, milliseconds, vibrationId);
}
/** Turns vibrator off. */
public void vibratorOff() {
- VibratorService.vibratorOff(mNativeControllerPtr);
+ VibratorService.vibratorOff(mNativeServicePtr);
}
/** Sets the amplitude for the vibrator to run. */
public void vibratorSetAmplitude(int amplitude) {
- VibratorService.vibratorSetAmplitude(mNativeControllerPtr, amplitude);
+ VibratorService.vibratorSetAmplitude(mNativeServicePtr, amplitude);
}
/** Returns all predefined effects supported by the device vibrator. */
public int[] vibratorGetSupportedEffects() {
- return VibratorService.vibratorGetSupportedEffects(mNativeControllerPtr);
+ return VibratorService.vibratorGetSupportedEffects(mNativeServicePtr);
}
/** Returns all compose primitives supported by the device vibrator. */
public int[] vibratorGetSupportedPrimitives() {
- return VibratorService.vibratorGetSupportedPrimitives(mNativeControllerPtr);
+ return VibratorService.vibratorGetSupportedPrimitives(mNativeServicePtr);
}
/** Turns vibrator on to perform one of the supported effects. */
- public long vibratorPerformEffect(long effect, long strength, Vibration vibration) {
+ public long vibratorPerformEffect(long effect, long strength, long vibrationId) {
return VibratorService.vibratorPerformEffect(
- mNativeControllerPtr, effect, strength, vibration);
+ mNativeServicePtr, effect, strength, vibrationId);
}
/** Turns vibrator on to perform one of the supported composed effects. */
public void vibratorPerformComposedEffect(
- VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration) {
- VibratorService.vibratorPerformComposedEffect(mNativeControllerPtr, effect, vibration);
+ VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) {
+ VibratorService.vibratorPerformComposedEffect(mNativeServicePtr, effect,
+ vibrationId);
}
/** Enabled the device vibrator to be controlled by another service. */
public void vibratorSetExternalControl(boolean enabled) {
- VibratorService.vibratorSetExternalControl(mNativeControllerPtr, enabled);
+ VibratorService.vibratorSetExternalControl(mNativeServicePtr, enabled);
}
/** Returns all capabilities of the device vibrator. */
public long vibratorGetCapabilities() {
- return VibratorService.vibratorGetCapabilities(mNativeControllerPtr);
+ return VibratorService.vibratorGetCapabilities(mNativeServicePtr);
}
/** Enable always-on vibration with given id and effect. */
public void vibratorAlwaysOnEnable(long id, long effect, long strength) {
- VibratorService.vibratorAlwaysOnEnable(mNativeControllerPtr, id, effect, strength);
+ VibratorService.vibratorAlwaysOnEnable(mNativeServicePtr, id, effect, strength);
}
/** Disable always-on vibration for given id. */
public void vibratorAlwaysOnDisable(long id) {
- VibratorService.vibratorAlwaysOnDisable(mNativeControllerPtr, id);
+ VibratorService.vibratorAlwaysOnDisable(mNativeServicePtr, id);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6e1e3d0..2d803437 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -83,6 +83,7 @@
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
@@ -117,7 +118,6 @@
import static com.android.server.am.MemoryStatUtil.hasMemcg;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
@@ -319,6 +319,7 @@
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
import com.android.internal.os.Zygote;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
@@ -4946,9 +4947,8 @@
notifyPackageUse(instr.mClass.getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
}
- if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
- + processName + " with config "
- + app.getWindowProcessController().getConfiguration());
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Binding proc %s with config %s",
+ processName, app.getWindowProcessController().getConfiguration());
ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackage(appInfo);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index 3f949ba..653323d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -25,7 +25,7 @@
* A helper class to build {@link HdmiCecMessage} from various cec commands.
*/
public class HdmiCecMessageBuilder {
- private static final int OSD_NAME_MAX_LENGTH = 13;
+ private static final int OSD_NAME_MAX_LENGTH = 14;
private HdmiCecMessageBuilder() {}
diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java
index 05aa315..06105bf 100644
--- a/services/core/java/com/android/server/location/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/LocationProviderManager.java
@@ -314,6 +314,14 @@
}
@Override
+ public final <Listener> void onOperationFailure(ListenerOperation<Listener> operation,
+ Exception e) {
+ synchronized (mLock) {
+ super.onOperationFailure(operation, e);
+ }
+ }
+
+ @Override
public final LocationRequest getRequest() {
return mProviderLocationRequest;
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index dfdf115..0c4eaec3 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -88,7 +88,6 @@
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -189,7 +188,6 @@
* Validates the signature used to sign the container of the new apex package
*
* @param newApexPkg The new apex package that is being installed
- * @throws PackageManagerException
*/
private void validateApexSignature(PackageInfo newApexPkg)
throws PackageManagerException {
@@ -725,12 +723,9 @@
return ret;
}
- @NonNull
private PackageInstallerSession createAndWriteApkSession(
- @NonNull PackageInstallerSession originalSession, boolean preReboot)
- throws PackageManagerException {
- final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
- : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
+ PackageInstallerSession originalSession) throws PackageManagerException {
+ final int errorCode = SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
if (originalSession.stageDir == null) {
Slog.wtf(TAG, "Attempting to install a staged APK session with no staging dir");
throw new PackageManagerException(errorCode,
@@ -746,12 +741,7 @@
PackageInstaller.SessionParams params = originalSession.params.copy();
params.isStaged = false;
params.installFlags |= PackageManager.INSTALL_STAGED;
- if (preReboot) {
- params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
- params.installFlags |= PackageManager.INSTALL_DRY_RUN;
- } else {
- params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
- }
+ params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
try {
int apkSessionId = mPi.createSession(
params, originalSession.getInstallerPackageName(),
@@ -783,12 +773,10 @@
* apks in the given session. Only parent session is returned for multi-package session.
*/
@Nullable
- private PackageInstallerSession extractApksInSession(PackageInstallerSession session,
- boolean preReboot) throws PackageManagerException {
- final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
- : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
+ private PackageInstallerSession extractApksInSession(PackageInstallerSession session)
+ throws PackageManagerException {
if (!session.isMultiPackage() && !isApexSession(session)) {
- return createAndWriteApkSession(session, preReboot);
+ return createAndWriteApkSession(session);
} else if (session.isMultiPackage()) {
// For multi-package staged sessions containing APKs, we identify which child sessions
// contain an APK, and with those then create a new multi-package group of sessions,
@@ -810,10 +798,6 @@
}
final PackageInstaller.SessionParams params = session.params.copy();
params.isStaged = false;
- if (preReboot) {
- params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
- params.installFlags |= PackageManager.INSTALL_DRY_RUN;
- }
final int apkParentSessionId = mPi.createSession(
params, session.getInstallerPackageName(), session.getInstallerAttributionTag(),
session.userId);
@@ -823,18 +807,18 @@
} catch (IOException e) {
Slog.e(TAG, "Unable to prepare multi-package session for staged session "
+ session.sessionId);
- throw new PackageManagerException(errorCode,
+ throw new PackageManagerException(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
"Unable to prepare multi-package session for staged session");
}
for (int i = 0, size = childSessions.size(); i < size; i++) {
final PackageInstallerSession apkChildSession = createAndWriteApkSession(
- childSessions.get(i), preReboot);
+ childSessions.get(i));
try {
apkParentSession.addChildSessionId(apkChildSession.sessionId);
} catch (IllegalStateException e) {
Slog.e(TAG, "Failed to add a child session for installing the APK files", e);
- throw new PackageManagerException(errorCode,
+ throw new PackageManagerException(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
"Failed to add a child session " + apkChildSession.sessionId);
}
}
@@ -877,11 +861,9 @@
}
}
- private void installApksInSession(@NonNull PackageInstallerSession session)
+ private void installApksInSession(PackageInstallerSession session)
throws PackageManagerException {
-
- final PackageInstallerSession apksToInstall = extractApksInSession(
- session, /* preReboot */ false);
+ final PackageInstallerSession apksToInstall = extractApksInSession(session);
if (apksToInstall == null) {
return;
}
@@ -1047,7 +1029,7 @@
/**
* <p>Abort committed staged session
*
- * <p>This method must be called while holding {@link PackageInstallerSession.mLock}.
+ * <p>This method must be called while holding {@link PackageInstallerSession#mLock}.
*
* <p>The method returns {@code false} to indicate it is not safe to clean up the session from
* system yet. When it is safe, the method returns {@code true}.
@@ -1218,7 +1200,7 @@
}
}
- void markStagedSessionsAsSuccessful() {
+ private void markStagedSessionsAsSuccessful() {
synchronized (mSuccessfulStagedSessionIds) {
for (int i = 0; i < mSuccessfulStagedSessionIds.size(); i++) {
mApexManager.markStagedSessionSuccessful(mSuccessfulStagedSessionIds.get(i));
@@ -1242,30 +1224,10 @@
mFailureReasonFile.delete();
}
- private static class LocalIntentReceiverAsync {
- final Consumer<Intent> mConsumer;
-
- LocalIntentReceiverAsync(Consumer<Intent> consumer) {
- mConsumer = consumer;
- }
-
- private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
- @Override
- public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
- IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
- mConsumer.accept(intent);
- }
- };
-
- public IntentSender getIntentSender() {
- return new IntentSender((IIntentSender) mLocalSender);
- }
- }
-
private static class LocalIntentReceiverSync {
private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
- private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
+ private final IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
@Override
public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission,
@@ -1300,14 +1262,14 @@
}
// TODO(b/136257624): Temporary API to let PMS communicate with StagingManager. When all
- // verification logic is extraced out of StagingManager into PMS, we can remove
+ // verification logic is extracted out of StagingManager into PMS, we can remove
// this.
void notifyVerificationComplete(int sessionId) {
mPreRebootVerificationHandler.onPreRebootVerificationComplete(sessionId);
}
// TODO(b/136257624): Temporary API to let PMS communicate with StagingManager. When all
- // verification logic is extraced out of StagingManager into PMS, we can remove
+ // verification logic is extracted out of StagingManager into PMS, we can remove
// this.
void notifyPreRebootVerification_Apk_Complete(int sessionId) {
mPreRebootVerificationHandler.notifyPreRebootVerification_Apk_Complete(sessionId);
@@ -1526,35 +1488,6 @@
session.verifyStagedSession();
}
- private void verifyApksInSession(PackageInstallerSession session)
- throws PackageManagerException {
-
- final PackageInstallerSession apksToVerify = extractApksInSession(
- session, /* preReboot */ true);
- if (apksToVerify == null) {
- return;
- }
-
- final LocalIntentReceiverAsync receiver = new LocalIntentReceiverAsync(
- (Intent result) -> {
- final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
- PackageInstaller.STATUS_FAILURE);
- if (status != PackageInstaller.STATUS_SUCCESS) {
- final String errorMessage = result.getStringExtra(
- PackageInstaller.EXTRA_STATUS_MESSAGE);
- Slog.e(TAG, "Failure to verify APK staged session "
- + session.sessionId + " [" + errorMessage + "]");
- onPreRebootVerificationFailure(session,
- SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMessage);
- return;
- }
- mPreRebootVerificationHandler.notifyPreRebootVerification_Apk_Complete(
- session.sessionId);
- });
-
- apksToVerify.commit(receiver.getIntentSender(), false);
- }
-
/**
* Pre-reboot verification state for wrapping up:
* <p><ul>
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index c1aebd3..d137fd0 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -84,7 +84,6 @@
import android.security.GateKeeper;
import android.service.gatekeeper.IGateKeeperService;
import android.stats.devicepolicy.DevicePolicyEnums;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -142,6 +141,7 @@
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Service for {@link UserManager}.
@@ -159,10 +159,6 @@
private static final String LOG_TAG = "UserManagerService";
static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
-
- // TODO(b/164159026): remove once owner_name issue on automotive is fixed
- // Can be used to track getUsers() / userWithNameLU() behavior
- public static final boolean DBG_CACHED_USERINFOS = false; // DO NOT SUBMIT WITH TRUE
// Can be used for manual testing of id recycling
private static final boolean RELEASE_DELETED_USER_ID = false; // DO NOT SUBMIT WITH TRUE
@@ -276,25 +272,6 @@
private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
/**
- * Reference to the {@link UserHandle#SYSTEM} user's UserInfo; it's {@code name} was either
- * manually set, or it's {@code null}.
- *
- * <p>The reference is set just once, but it's {@code name} is updated when it's manually set.
- */
- @GuardedBy("mUsersLock")
- private UserInfo mSystemUserInfo;
-
- /**
- * Reference to the {@link UserHandle#SYSTEM} user's UserInfo, with its {@code name} set to
- * the localized value of {@code owner_name}.
- *
- * <p>The reference is set just once, but it's {@code name} is updated everytime the reference
- * is used and the locale changed.
- */
- @GuardedBy("mUsersLock")
- private UserInfo mSystemUserInfoWithName;
-
- /**
* Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps.
*/
@VisibleForTesting
@@ -467,6 +444,11 @@
}
};
+ // TODO(b/161915546): remove once userWithName() is fixed / removed
+ // Use to debug / dump when user 0 is allocated at userWithName()
+ public static final boolean DBG_ALLOCATION = false; // DO NOT SUBMIT WITH TRUE
+ public final AtomicInteger mUser0Allocations;
+
/**
* Start an {@link IntentSender} when user is unlocked after disabling quiet mode.
*
@@ -656,6 +638,7 @@
LocalServices.addService(UserManagerInternal.class, mLocalService);
mLockPatternUtils = new LockPatternUtils(mContext);
mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING);
+ mUser0Allocations = DBG_ALLOCATION ? new AtomicInteger() : null;
}
void systemReady() {
@@ -801,7 +784,7 @@
|| (excludePreCreated && ui.preCreated)) {
continue;
}
- users.add(userWithNameLU(ui));
+ users.add(userWithName(ui));
}
return users;
}
@@ -870,7 +853,7 @@
userInfo.name = null;
userInfo.iconPath = null;
} else {
- userInfo = userWithNameLU(userInfo);
+ userInfo = userWithName(userInfo);
}
users.add(userInfo);
}
@@ -1327,57 +1310,26 @@
public UserInfo getUserInfo(@UserIdInt int userId) {
checkManageOrCreateUsersPermission("query user");
synchronized (mUsersLock) {
- return userWithNameLU(getUserInfoLU(userId));
+ return userWithName(getUserInfoLU(userId));
}
}
/**
* Returns a UserInfo object with the name filled in, for Owner, or the original
* if the name is already set.
- *
- * <p>Note:</p> the Owner name is localized, so the current value must be checked every time
- * this method is called.
*/
- private UserInfo userWithNameLU(UserInfo orig) {
- // Only the system user uses the owner_name string.
- if (orig == null || orig.id != UserHandle.USER_SYSTEM) return orig;
-
- if (mSystemUserInfo == null) {
- mSystemUserInfo = orig;
- if (DBG_CACHED_USERINFOS) {
- Slog.d(LOG_TAG, "Set mSystemUserInfo:" + mSystemUserInfo.toFullString());
+ private UserInfo userWithName(UserInfo orig) {
+ if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
+ if (DBG_ALLOCATION) {
+ final int number = mUser0Allocations.incrementAndGet();
+ Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
}
+ UserInfo withName = new UserInfo(orig);
+ withName.name = getOwnerName();
+ return withName;
+ } else {
+ return orig;
}
-
- if (mSystemUserInfo.name != null) {
- if (DBG_CACHED_USERINFOS) {
- Slog.v(LOG_TAG, "Returning mSystemUserInfo: " + mSystemUserInfo.toFullString());
- }
- return mSystemUserInfo;
- }
-
- final String ownerName = getOwnerName();
-
- if (mSystemUserInfoWithName == null) {
- mSystemUserInfoWithName = new UserInfo(orig);
- mSystemUserInfoWithName.name = ownerName;
- if (DBG_CACHED_USERINFOS) {
- Slog.d(LOG_TAG, "Set mSystemUserInfoWithName: "
- + mSystemUserInfoWithName.toFullString());
- }
- } else if (!TextUtils.equals(ownerName, mSystemUserInfoWithName.name)) {
- if (DBG_CACHED_USERINFOS) {
- Slog.d(LOG_TAG, "Updating mSystemUserInfoWithName.name from "
- + mSystemUserInfoWithName.name + " to " + ownerName);
- }
- mSystemUserInfoWithName.name = ownerName;
- }
-
- if (DBG_CACHED_USERINFOS) {
- Slog.v(LOG_TAG, "Returning mSystemUserInfoWithName:"
- + mSystemUserInfoWithName.toFullString());
- }
- return mSystemUserInfoWithName;
}
/** Returns whether the given user type is one of the FULL user types. */
@@ -1530,7 +1482,7 @@
}
final int userId = UserHandle.getUserId(Binder.getCallingUid());
synchronized (mUsersLock) {
- UserInfo userInfo = userWithNameLU(getUserInfoLU(userId));
+ UserInfo userInfo = userWithName(getUserInfoLU(userId));
return userInfo == null ? "" : userInfo.name;
}
}
@@ -1645,13 +1597,6 @@
Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId);
return null;
}
-
- if (DBG_CACHED_USERINFOS && userId == UserHandle.USER_SYSTEM && userData != null
- && userData.info != mSystemUserInfo) {
- Slog.wtf(LOG_TAG, "getUserInfoLU(): system user on userData (" + userData.info
- + ") is not the same as mSystemUserInfo (" + mSystemUserInfo + ")");
- }
-
return userData != null ? userData.info : null;
}
@@ -4910,15 +4855,8 @@
pw.println(" Is headless-system mode: " + UserManager.isHeadlessSystemUserMode());
pw.println(" User version: " + mUserVersion);
pw.println(" Owner name: " + getOwnerName());
- if (mSystemUserInfo == null) {
- pw.println(" (mSystemUserInfo not set)");
- } else {
- pw.println(" System user: " + mSystemUserInfo.toFullString());
- }
- if (mSystemUserInfoWithName == null) {
- pw.println(" (mSystemUserInfoWithName not set)");
- } else {
- pw.println(" System user (with name): " + mSystemUserInfoWithName.toFullString());
+ if (DBG_ALLOCATION) {
+ pw.println(" System user allocations: " + mUser0Allocations.get());
}
// Dump UserTypes
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 548cd70..137c587 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2219,11 +2219,6 @@
}
@Override
- public int getMaxWallpaperLayer() {
- return getWindowLayerFromTypeLw(TYPE_NOTIFICATION_SHADE);
- }
-
- @Override
public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
return attrs.type == TYPE_NOTIFICATION_SHADE;
}
@@ -5324,15 +5319,6 @@
}
@Override
- public boolean isTopLevelWindow(int windowType) {
- if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW
- && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
- return (windowType == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG);
- }
- return true;
- }
-
- @Override
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 651eafd..b96d65c 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -67,7 +67,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.WindowConfiguration;
import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -90,7 +89,6 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.server.wm.DisplayRotation;
-import com.android.server.wm.WindowFrames;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -181,92 +179,11 @@
*/
public interface WindowState {
/**
- * Return the uid of the app that owns this window.
- */
- int getOwningUid();
-
- /**
* Return the package name of the app that owns this window.
*/
String getOwningPackage();
/**
- * Perform standard frame computation. The result can be obtained with
- * getFrame() if so desired. Must be called with the window manager
- * lock held.
- *
- */
- public void computeFrameLw();
-
- /**
- * Retrieve the current frame of the window that has been assigned by
- * the window manager. Must be called with the window manager lock held.
- *
- * @return Rect The rectangle holding the window frame.
- */
- public Rect getFrameLw();
-
- /**
- * Retrieve the frame of the display that this window was last
- * laid out in. Must be called with the
- * window manager lock held.
- *
- * @return Rect The rectangle holding the display frame.
- */
- public Rect getDisplayFrameLw();
-
- /**
- * Retrieve the frame of the content area that this window was last
- * laid out in. This is the area in which the content of the window
- * should be placed. It will be smaller than the display frame to
- * account for screen decorations such as a status bar or soft
- * keyboard. Must be called with the
- * window manager lock held.
- *
- * @return Rect The rectangle holding the content frame.
- */
- public Rect getContentFrameLw();
-
- /**
- * Retrieve the frame of the visible area that this window was last
- * laid out in. This is the area of the screen in which the window
- * will actually be fully visible. It will be smaller than the
- * content frame to account for transient UI elements blocking it
- * such as an input method's candidates UI. Must be called with the
- * window manager lock held.
- *
- * @return Rect The rectangle holding the visible frame.
- */
- public Rect getVisibleFrameLw();
-
- /**
- * Returns true if this window is waiting to receive its given
- * internal insets from the client app, and so should not impact the
- * layout of other windows.
- */
- public boolean getGivenInsetsPendingLw();
-
- /**
- * Retrieve the insets given by this window's client for the content
- * area of windows behind it. Must be called with the
- * window manager lock held.
- *
- * @return Rect The left, top, right, and bottom insets, relative
- * to the window's frame, of the actual contents.
- */
- public Rect getGivenContentInsetsLw();
-
- /**
- * Retrieve the insets given by this window's client for the visible
- * area of windows behind it. Must be called with the
- * window manager lock held.
- *
- * @return Rect The left, top, right, and bottom insets, relative
- * to the window's frame, of the actual visible area.
- */
- public Rect getGivenVisibleInsetsLw();
-
- /**
* Retrieve the current LayoutParams of the window.
*
* @return WindowManager.LayoutParams The window's internal LayoutParams
@@ -275,17 +192,6 @@
public WindowManager.LayoutParams getAttrs();
/**
- * Retrieve the current system UI visibility flags associated with
- * this window.
- */
- public int getSystemUiVisibility();
-
- /**
- * Get the layer at which this window's surface will be Z-ordered.
- */
- public int getSurfaceLayer();
-
- /**
* Retrieve the type of the top-level window.
*
* @return the base type of the parent window if attached or its own type otherwise
@@ -301,22 +207,6 @@
public IApplicationToken getAppToken();
/**
- * Return true if this window is participating in voice interaction.
- */
- public boolean isVoiceInteraction();
-
- /**
- * Return true if, at any point, the application token associated with
- * this window has actually displayed any windows. This is most useful
- * with the "starting up" window to determine if any windows were
- * displayed when it is closed.
- *
- * @return Returns true if one or more windows have been displayed,
- * else false.
- */
- public boolean hasAppShownWindows();
-
- /**
* Is this window visible? It is not visible if there is no
* surface, or we are in the process of running an exit animation
* that will remove the surface.
@@ -324,42 +214,12 @@
boolean isVisibleLw();
/**
- * Is this window currently visible to the user on-screen? It is
- * displayed either if it is visible or it is currently running an
- * animation before no longer being visible. Must be called with the
- * window manager lock held.
- */
- boolean isDisplayedLw();
-
- /**
* Return true if this window (or a window it is attached to, but not
* considering its app token) is currently animating.
*/
boolean isAnimatingLw();
/**
- * Is this window considered to be gone for purposes of layout?
- */
- boolean isGoneForLayoutLw();
-
- /**
- * Returns true if the window has a surface that it has drawn a
- * complete UI in to. Note that this is different from {@link #hasDrawnLw()}
- * in that it also returns true if the window is READY_TO_SHOW, but was not yet
- * promoted to HAS_DRAWN.
- */
- boolean isDrawnLw();
-
- /**
- * Returns true if this window has been shown on screen at some time in
- * the past. Must be called with the window manager lock held.
- *
- * @deprecated Use {@link #isDrawnLw} or any of the other drawn/visibility methods.
- */
- @Deprecated
- public boolean hasDrawnLw();
-
- /**
* Can be called by the policy to force a window to be hidden,
* regardless of whether the client or window manager would like
* it shown. Must be called with the window manager lock held.
@@ -377,51 +237,12 @@
public boolean showLw(boolean doAnimation);
/**
- * Check whether the process hosting this window is currently alive.
- */
- public boolean isAlive();
-
- /**
- * Check if window is on {@link Display#DEFAULT_DISPLAY}.
- * @return true if window is on default display.
- */
- public boolean isDefaultDisplay();
-
- /**
* Check whether the window is currently dimming.
*/
public boolean isDimming();
- /**
- * Returns true if the window is letterboxed for the display cutout.
- */
- default boolean isLetterboxedForDisplayCutoutLw() {
- return false;
- }
-
- /** @return the current windowing mode of this window. */
- int getWindowingMode();
-
- /**
- * Returns the {@link WindowConfiguration.ActivityType} associated with the configuration
- * of this window.
- */
- default int getActivityType() {
- return WindowConfiguration.WINDOWING_MODE_UNDEFINED;
- }
-
- /**
- * Returns true if the window is current in multi-windowing mode. i.e. it shares the
- * screen with other application windows.
- */
- boolean inMultiWindowMode();
-
- public int getRotationAnimationHint();
-
public boolean isInputMethodWindow();
- public boolean isInputMethodTarget();
-
public int getDisplayId();
/**
@@ -432,42 +253,8 @@
return false;
}
- /**
- * Returns true if the window owner has the permission to acquire a sleep token when it's
- * visible. That is, they have the permission {@link Manifest.permission#DEVICE_POWER}.
- */
- boolean canAcquireSleepToken();
-
- /** @return true if this window desires key events. */
- boolean canReceiveKeys();
-
/** @return true if the window can show over keyguard. */
boolean canShowWhenLocked();
-
- /**
- * Writes {@link com.android.server.wm.IdentifierProto} to stream.
- */
- void writeIdentifierToProto(ProtoOutputStream proto, long fieldId);
-
- /**
- * @return The {@link WindowFrames} associated with this {@link WindowState}
- */
- WindowFrames getWindowFrames();
- }
-
- /**
- * Representation of a input consumer that the policy has added to the
- * window manager to consume input events going to windows below it.
- */
- public interface InputConsumer {
- /**
- * Remove the input consumer from the window manager.
- */
- void dismiss();
- /**
- * Dispose the input consumer and input receiver from UI thread.
- */
- void dispose();
}
/**
@@ -538,11 +325,6 @@
void unregisterPointerEventListener(PointerEventListener listener, int displayId);
/**
- * @return The currently active input method window.
- */
- WindowState getInputMethodWindowLw();
-
- /**
* Notifies window manager that {@link #isKeyguardTrustedLw} has changed.
*/
void notifyKeyguardTrustedChanged();
@@ -615,17 +397,6 @@
}
/**
- * Provides the rotation of a device.
- *
- * @see com.android.server.policy.WindowOrientationListener
- */
- public interface RotationSource {
- int getProposedRotation();
-
- void setCurrentRotation(int rotation);
- }
-
- /**
* Interface to get public information of a display content.
*/
public interface DisplayContentInfo {
@@ -889,12 +660,6 @@
}
/**
- * Get the highest layer (actually one more than) that the wallpaper is
- * allowed to be in.
- */
- public int getMaxWallpaperLayer();
-
- /**
* Return whether the given window can become the Keyguard window. Typically returns true for
* the StatusBar.
*/
@@ -1384,17 +1149,6 @@
void dumpDebug(ProtoOutputStream proto, long fieldId);
/**
- * Returns whether a given window type is considered a top level one.
- * A top level window does not have a container, i.e. attached window,
- * or if it has a container it is laid out as a top-level window, not
- * as a child of its container.
- *
- * @param windowType The window type.
- * @return True if the window is a top level one.
- */
- public boolean isTopLevelWindow(int windowType);
-
- /**
* Notifies the keyguard to start fading out.
*
* @param startTime the start time of the animation in uptime milliseconds
diff --git a/services/core/java/com/android/server/timezonedetector/CallerIdentityInjector.java b/services/core/java/com/android/server/timezonedetector/CallerIdentityInjector.java
new file mode 100644
index 0000000..1500cfa
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/CallerIdentityInjector.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import android.annotation.UserIdInt;
+import android.os.Binder;
+import android.os.UserHandle;
+
+/**
+ * An interface to wrap various difficult-to-intercept calls that services make to access / manage
+ * caller identity, e.g. {@link Binder#clearCallingIdentity()}.
+ */
+public interface CallerIdentityInjector {
+
+ /** A singleton for the real implementation of {@link CallerIdentityInjector}. */
+ CallerIdentityInjector REAL = new Real();
+
+ /** A {@link UserHandle#getCallingUserId()} call. */
+ @UserIdInt int getCallingUserId();
+
+ /** A {@link Binder#clearCallingIdentity()} call. */
+ long clearCallingIdentity();
+
+ /** A {@link Binder#restoreCallingIdentity(long)} ()} call. */
+ void restoreCallingIdentity(long token);
+
+ /** The real implementation of {@link CallerIdentityInjector}. */
+ class Real implements CallerIdentityInjector {
+
+ protected Real() {
+ }
+
+ @Override
+ public int getCallingUserId() {
+ return UserHandle.getCallingUserId();
+ }
+
+ @Override
+ public long clearCallingIdentity() {
+ return Binder.clearCallingIdentity();
+ }
+
+ @Override
+ public void restoreCallingIdentity(long token) {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationChangeListener.java b/services/core/java/com/android/server/timezonedetector/ConfigurationChangeListener.java
new file mode 100644
index 0000000..4c7b1f3
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/ConfigurationChangeListener.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+/**
+ * A listener used to receive notification that time zone configuration has changed.
+ */
+@FunctionalInterface
+public interface ConfigurationChangeListener {
+ /** Called when the current user or a configuration value has changed. */
+ void onChange();
+}
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
new file mode 100644
index 0000000..aee3d8d
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.app.timezonedetector.TimeZoneCapabilities;
+import android.app.timezonedetector.TimeZoneConfiguration;
+
+import java.util.Objects;
+
+/**
+ * Holds all configuration values that affect time zone behavior and some associated logic, e.g.
+ * {@link #getAutoDetectionEnabledBehavior()}, {@link #getGeoDetectionEnabledBehavior()} and {@link
+ * #createCapabilities()}.
+ */
+public final class ConfigurationInternal {
+
+ private final @UserIdInt int mUserId;
+ private final boolean mUserConfigAllowed;
+ private final boolean mAutoDetectionSupported;
+ private final boolean mAutoDetectionEnabled;
+ private final boolean mLocationEnabled;
+ private final boolean mGeoDetectionEnabled;
+
+ private ConfigurationInternal(Builder builder) {
+ mUserId = builder.mUserId;
+ mUserConfigAllowed = builder.mUserConfigAllowed;
+ mAutoDetectionSupported = builder.mAutoDetectionSupported;
+ mAutoDetectionEnabled = builder.mAutoDetectionEnabled;
+ mLocationEnabled = builder.mLocationEnabled;
+ mGeoDetectionEnabled = builder.mGeoDetectionEnabled;
+ }
+
+ /** Returns the ID of the user this configuration is associated with. */
+ public @UserIdInt int getUserId() {
+ return mUserId;
+ }
+
+ /** Returns true if the user allowed to modify time zone configuration. */
+ public boolean isUserConfigAllowed() {
+ return mUserConfigAllowed;
+ }
+
+ /** Returns true if the device supports some form of auto time zone detection. */
+ public boolean isAutoDetectionSupported() {
+ return mAutoDetectionSupported;
+ }
+
+ /** Returns the value of the auto time zone detection enabled setting. */
+ public boolean getAutoDetectionEnabledSetting() {
+ return mAutoDetectionEnabled;
+ }
+
+ /**
+ * Returns true if auto time zone detection behavior is actually enabled, which can be distinct
+ * from the raw setting value. */
+ public boolean getAutoDetectionEnabledBehavior() {
+ return mAutoDetectionSupported && mAutoDetectionEnabled;
+ }
+
+ /** Returns true if user's location can be used generally. */
+ public boolean isLocationEnabled() {
+ return mLocationEnabled;
+ }
+
+ /** Returns the value of the geolocation time zone detection enabled setting. */
+ public boolean getGeoDetectionEnabledSetting() {
+ return mGeoDetectionEnabled;
+ }
+
+ /**
+ * Returns true if geolocation time zone detection behavior is actually enabled, which can be
+ * distinct from the raw setting value.
+ */
+ public boolean getGeoDetectionEnabledBehavior() {
+ if (getAutoDetectionEnabledBehavior()) {
+ return mLocationEnabled && mGeoDetectionEnabled;
+ }
+ return false;
+ }
+
+ /** Creates a {@link TimeZoneCapabilities} object using the configuration values. */
+ public TimeZoneCapabilities createCapabilities() {
+ TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder()
+ .setConfiguration(asConfiguration());
+
+ boolean allowConfigDateTime = isUserConfigAllowed();
+
+ // Automatic time zone detection is only supported on devices if there is a telephony
+ // network available or geolocation time zone detection is possible.
+ boolean deviceHasTimeZoneDetection = isAutoDetectionSupported();
+
+ final int configureAutoDetectionEnabledCapability;
+ if (!deviceHasTimeZoneDetection) {
+ configureAutoDetectionEnabledCapability = CAPABILITY_NOT_SUPPORTED;
+ } else if (!allowConfigDateTime) {
+ configureAutoDetectionEnabledCapability = CAPABILITY_NOT_ALLOWED;
+ } else {
+ configureAutoDetectionEnabledCapability = CAPABILITY_POSSESSED;
+ }
+ builder.setConfigureAutoDetectionEnabled(configureAutoDetectionEnabledCapability);
+
+ final int configureGeolocationDetectionEnabledCapability;
+ if (!deviceHasTimeZoneDetection) {
+ configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_SUPPORTED;
+ } else if (!allowConfigDateTime) {
+ configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_ALLOWED;
+ } else if (!isLocationEnabled()) {
+ configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_APPLICABLE;
+ } else {
+ configureGeolocationDetectionEnabledCapability = CAPABILITY_POSSESSED;
+ }
+ builder.setConfigureGeoDetectionEnabled(configureGeolocationDetectionEnabledCapability);
+
+ // The ability to make manual time zone suggestions can also be restricted by policy. With
+ // the current logic above, this could lead to a situation where a device hardware does not
+ // support auto detection, the device has been forced into "auto" mode by an admin and the
+ // user is unable to disable auto detection.
+ final int suggestManualTimeZoneCapability;
+ if (!allowConfigDateTime) {
+ suggestManualTimeZoneCapability = CAPABILITY_NOT_ALLOWED;
+ } else if (getAutoDetectionEnabledBehavior()) {
+ suggestManualTimeZoneCapability = CAPABILITY_NOT_APPLICABLE;
+ } else {
+ suggestManualTimeZoneCapability = CAPABILITY_POSSESSED;
+ }
+ builder.setSuggestManualTimeZone(suggestManualTimeZoneCapability);
+
+ return builder.build();
+ }
+
+ /** Returns a {@link TimeZoneConfiguration} from the configuration values. */
+ public TimeZoneConfiguration asConfiguration() {
+ return new TimeZoneConfiguration.Builder(mUserId)
+ .setAutoDetectionEnabled(getAutoDetectionEnabledSetting())
+ .setGeoDetectionEnabled(getGeoDetectionEnabledSetting())
+ .build();
+ }
+
+ /**
+ * Merges the configuration values from this with any properties set in {@code
+ * newConfiguration}. The new configuration has precedence. Used to apply user updates to
+ * internal configuration.
+ */
+ public ConfigurationInternal merge(TimeZoneConfiguration newConfiguration) {
+ Builder builder = new Builder(this);
+ if (newConfiguration.hasSetting(TimeZoneConfiguration.SETTING_AUTO_DETECTION_ENABLED)) {
+ builder.setAutoDetectionEnabled(newConfiguration.isAutoDetectionEnabled());
+ }
+ if (newConfiguration.hasSetting(TimeZoneConfiguration.SETTING_GEO_DETECTION_ENABLED)) {
+ builder.setGeoDetectionEnabled(newConfiguration.isGeoDetectionEnabled());
+ }
+ return builder.build();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ConfigurationInternal that = (ConfigurationInternal) o;
+ return mUserId == that.mUserId
+ && mUserConfigAllowed == that.mUserConfigAllowed
+ && mAutoDetectionSupported == that.mAutoDetectionSupported
+ && mAutoDetectionEnabled == that.mAutoDetectionEnabled
+ && mLocationEnabled == that.mLocationEnabled
+ && mGeoDetectionEnabled == that.mGeoDetectionEnabled;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUserId, mUserConfigAllowed, mAutoDetectionSupported,
+ mAutoDetectionEnabled, mLocationEnabled, mGeoDetectionEnabled);
+ }
+
+ @Override
+ public String toString() {
+ return "TimeZoneDetectorConfiguration{"
+ + "mUserId=" + mUserId
+ + "mUserConfigAllowed=" + mUserConfigAllowed
+ + "mAutoDetectionSupported=" + mAutoDetectionSupported
+ + "mAutoDetectionEnabled=" + mAutoDetectionEnabled
+ + "mLocationEnabled=" + mLocationEnabled
+ + "mGeoDetectionEnabled=" + mGeoDetectionEnabled
+ + '}';
+ }
+
+ /**
+ * A Builder for {@link ConfigurationInternal}.
+ */
+ public static class Builder {
+
+ private final @UserIdInt int mUserId;
+ private boolean mUserConfigAllowed;
+ private boolean mAutoDetectionSupported;
+ private boolean mAutoDetectionEnabled;
+ private boolean mLocationEnabled;
+ private boolean mGeoDetectionEnabled;
+
+ /**
+ * Creates a new Builder with only the userId set.
+ */
+ public Builder(@UserIdInt int userId) {
+ mUserId = userId;
+ }
+
+ /**
+ * Creates a new Builder by copying values from an existing instance.
+ */
+ public Builder(ConfigurationInternal toCopy) {
+ this.mUserId = toCopy.mUserId;
+ this.mUserConfigAllowed = toCopy.mUserConfigAllowed;
+ this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported;
+ this.mAutoDetectionEnabled = toCopy.mAutoDetectionEnabled;
+ this.mLocationEnabled = toCopy.mLocationEnabled;
+ this.mGeoDetectionEnabled = toCopy.mGeoDetectionEnabled;
+ }
+
+ /**
+ * Sets whether the user is allowed to configure time zone settings on this device.
+ */
+ public Builder setUserConfigAllowed(boolean configAllowed) {
+ mUserConfigAllowed = configAllowed;
+ return this;
+ }
+
+ /**
+ * Sets whether automatic time zone detection is supported on this device.
+ */
+ public Builder setAutoDetectionSupported(boolean supported) {
+ mAutoDetectionSupported = supported;
+ return this;
+ }
+
+ /**
+ * Sets the value of the automatic time zone detection enabled setting for this device.
+ */
+ public Builder setAutoDetectionEnabled(boolean enabled) {
+ mAutoDetectionEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Sets the value of the location mode setting for this user.
+ */
+ public Builder setLocationEnabled(boolean enabled) {
+ mLocationEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Sets the value of the geolocation time zone detection setting for this user.
+ */
+ public Builder setGeoDetectionEnabled(boolean enabled) {
+ mGeoDetectionEnabled = enabled;
+ return this;
+ }
+
+ /** Returns a new {@link ConfigurationInternal}. */
+ @NonNull
+ public ConfigurationInternal build() {
+ return new ConfigurationInternal(this);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
index 0ca36e0..d640323 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
@@ -16,24 +16,30 @@
package com.android.server.timezonedetector;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
+import static android.content.Intent.ACTION_USER_SWITCHED;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
-import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.location.LocationManager;
import android.net.ConnectivityManager;
+import android.os.Handler;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
import java.util.Objects;
@@ -42,103 +48,87 @@
*/
public final class TimeZoneDetectorCallbackImpl implements TimeZoneDetectorStrategyImpl.Callback {
+ private static final String LOG_TAG = "TimeZoneDetectorCallbackImpl";
private static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
- private final Context mContext;
- private final ContentResolver mCr;
- private final UserManager mUserManager;
+ @NonNull private final Context mContext;
+ @NonNull private final Handler mHandler;
+ @NonNull private final ContentResolver mCr;
+ @NonNull private final UserManager mUserManager;
+ @NonNull private final boolean mGeoDetectionFeatureEnabled;
+ @NonNull private final LocationManager mLocationManager;
+ // @NonNull after setConfigChangeListener() is called.
+ private ConfigurationChangeListener mConfigChangeListener;
- TimeZoneDetectorCallbackImpl(Context context) {
- mContext = context;
+ TimeZoneDetectorCallbackImpl(@NonNull Context context, @NonNull Handler handler,
+ boolean geoDetectionFeatureEnabled) {
+ mContext = Objects.requireNonNull(context);
+ mHandler = Objects.requireNonNull(handler);
mCr = context.getContentResolver();
mUserManager = context.getSystemService(UserManager.class);
+ mLocationManager = context.getSystemService(LocationManager.class);
+ mGeoDetectionFeatureEnabled = geoDetectionFeatureEnabled;
+
+ // Wire up the change listener. All invocations are performed on the mHandler thread.
+
+ // Listen for the user changing / the user's location mode changing.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_USER_SWITCHED);
+ filter.addAction(LocationManager.MODE_CHANGED_ACTION);
+ mContext.registerReceiverForAllUsers(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ handleConfigChangeOnHandlerThread();
+ }
+ }, filter, null, mHandler);
+
+ // Add async callbacks for global settings being changed.
+ ContentResolver contentResolver = mContext.getContentResolver();
+ contentResolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
+ new ContentObserver(mHandler) {
+ public void onChange(boolean selfChange) {
+ handleConfigChangeOnHandlerThread();
+ }
+ });
+
+ // Add async callbacks for user scoped location settings being changed.
+ contentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED),
+ true,
+ new ContentObserver(mHandler) {
+ public void onChange(boolean selfChange) {
+ handleConfigChangeOnHandlerThread();
+ }
+ }, UserHandle.USER_ALL);
+ }
+
+ private void handleConfigChangeOnHandlerThread() {
+ if (mConfigChangeListener == null) {
+ Slog.wtf(LOG_TAG, "mConfigChangeListener is unexpectedly null");
+ }
+ mConfigChangeListener.onChange();
}
@Override
- public TimeZoneCapabilities getCapabilities(@UserIdInt int userId) {
- UserHandle userHandle = UserHandle.of(userId);
- boolean disallowConfigDateTime =
- mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME, userHandle);
-
- TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder(userId);
-
- // Automatic time zone detection is only supported (currently) on devices if there is a
- // telephony network available.
- if (!deviceHasTelephonyNetwork()) {
- builder.setConfigureAutoDetectionEnabled(CAPABILITY_NOT_SUPPORTED);
- } else if (disallowConfigDateTime) {
- builder.setConfigureAutoDetectionEnabled(CAPABILITY_NOT_ALLOWED);
- } else {
- builder.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED);
- }
-
- // TODO(b/149014708) Replace this with real logic when the settings storage is fully
- // implemented.
- builder.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_SUPPORTED);
-
- // The ability to make manual time zone suggestions can also be restricted by policy. With
- // the current logic above, this could lead to a situation where a device hardware does not
- // support auto detection, the device has been forced into "auto" mode by an admin and the
- // user is unable to disable auto detection.
- if (disallowConfigDateTime) {
- builder.setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED);
- } else if (isAutoDetectionEnabled()) {
- builder.setSuggestManualTimeZone(CAPABILITY_NOT_APPLICABLE);
- } else {
- builder.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
- }
- return builder.build();
+ public void setConfigChangeListener(@NonNull ConfigurationChangeListener listener) {
+ mConfigChangeListener = Objects.requireNonNull(listener);
}
@Override
- public TimeZoneConfiguration getConfiguration(@UserIdInt int userId) {
- return new TimeZoneConfiguration.Builder()
+ public ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
+ return new ConfigurationInternal.Builder(userId)
+ .setUserConfigAllowed(isUserConfigAllowed(userId))
+ .setAutoDetectionSupported(isAutoDetectionSupported())
.setAutoDetectionEnabled(isAutoDetectionEnabled())
- .setGeoDetectionEnabled(isGeoDetectionEnabled())
+ .setLocationEnabled(isLocationEnabled(userId))
+ .setGeoDetectionEnabled(isGeoDetectionEnabled(userId))
.build();
}
@Override
- public void setConfiguration(
- @UserIdInt int userId, @NonNull TimeZoneConfiguration configuration) {
- Objects.requireNonNull(configuration);
- if (!configuration.isComplete()) {
- throw new IllegalArgumentException("configuration=" + configuration + " not complete");
- }
-
- // Avoid writing auto detection config for devices that do not support auto time zone
- // detection: if we wrote it down then we'd set the default explicitly. That might influence
- // what happens on later releases that do support auto detection on the same hardware.
- if (isAutoDetectionSupported()) {
- final int autoEnabledValue = configuration.isAutoDetectionEnabled() ? 1 : 0;
- Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE, autoEnabledValue);
-
- final boolean geoTzDetectionEnabledValue = configuration.isGeoDetectionEnabled();
- // TODO(b/149014708) Write this down to user-scoped settings once implemented.
- }
- }
-
- @Override
- public boolean isAutoDetectionEnabled() {
- // To ensure that TimeZoneConfiguration is "complete" for simplicity, devices that do not
- // support auto detection have safe, hard coded configuration values that make it look like
- // auto detection is turned off. It is therefore important that false is returned from this
- // method for devices that do not support auto time zone detection. Such devices will not
- // have a UI to turn the auto detection on/off. Returning true could prevent the user
- // entering information manually. On devices that do support auto time detection the default
- // is to turn auto detection on.
- if (isAutoDetectionSupported()) {
- return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME_ZONE, 1 /* default */) > 0;
- }
- return false;
- }
-
- @Override
- public boolean isGeoDetectionEnabled() {
- // TODO(b/149014708) Read this from user-scoped settings once implemented. The user's
- // location toggle will act as an override for this setting, i.e. so that the setting will
- // return false if the location toggle is disabled.
- return false;
+ public @UserIdInt int getCurrentUserId() {
+ return LocalServices.getService(ActivityManagerInternal.class).getCurrentUserId();
}
@Override
@@ -165,8 +155,55 @@
alarmManager.setTimeZone(zoneId);
}
+ @Override
+ public void storeConfiguration(TimeZoneConfiguration configuration) {
+ Objects.requireNonNull(configuration);
+
+ // Avoid writing the auto detection enabled setting for devices that do not support auto
+ // time zone detection: if we wrote it down then we'd set the value explicitly, which would
+ // prevent detecting "default" later. That might influence what happens on later releases
+ // that support new types of auto detection on the same hardware.
+ if (isAutoDetectionSupported()) {
+ final boolean autoDetectionEnabled = configuration.isAutoDetectionEnabled();
+ setAutoDetectionEnabled(autoDetectionEnabled);
+
+ final int userId = configuration.getUserId();
+ final boolean geoTzDetectionEnabled = configuration.isGeoDetectionEnabled();
+ setGeoDetectionEnabled(userId, geoTzDetectionEnabled);
+ }
+ }
+
+ private boolean isUserConfigAllowed(@UserIdInt int userId) {
+ UserHandle userHandle = UserHandle.of(userId);
+ return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME, userHandle);
+ }
+
private boolean isAutoDetectionSupported() {
- return deviceHasTelephonyNetwork();
+ return deviceHasTelephonyNetwork() || mGeoDetectionFeatureEnabled;
+ }
+
+ private boolean isAutoDetectionEnabled() {
+ return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME_ZONE, 1 /* default */) > 0;
+ }
+
+ private void setAutoDetectionEnabled(boolean enabled) {
+ Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE, enabled ? 1 : 0);
+ }
+
+ private boolean isLocationEnabled(@UserIdInt int userId) {
+ return mLocationManager.isLocationEnabledForUser(UserHandle.of(userId));
+ }
+
+ private boolean isGeoDetectionEnabled(@UserIdInt int userId) {
+ final boolean locationEnabled = isLocationEnabled(userId);
+ return Settings.Secure.getIntForUser(mCr,
+ Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
+ locationEnabled ? 1 : 0 /* defaultValue */, userId) != 0;
+ }
+
+ private void setGeoDetectionEnabled(@UserIdInt int userId, boolean enabled) {
+ Settings.Secure.putIntForUser(mCr, Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
+ enabled ? 1 : 0, userId);
}
private boolean deviceHasTelephonyNetwork() {
@@ -174,4 +211,4 @@
return mContext.getSystemService(ConnectivityManager.class)
.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
}
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java
index fb7a73d..2d50390 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java
@@ -27,6 +27,12 @@
*/
public interface TimeZoneDetectorInternal extends Dumpable.Container {
+ /** Adds a listener that will be invoked when time zone detection configuration is changed. */
+ void addConfigurationListener(ConfigurationChangeListener listener);
+
+ /** Returns the {@link ConfigurationInternal} for the current user. */
+ ConfigurationInternal getCurrentUserConfigurationInternal();
+
/**
* Suggests the current time zone, determined using geolocation, to the detector. The
* detector may ignore the signal based on system settings, whether better information is
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
index 15412a0..f0ce827 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
@@ -20,8 +20,8 @@
import android.content.Context;
import android.os.Handler;
-import com.android.internal.annotations.VisibleForTesting;
-
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
/**
@@ -34,18 +34,26 @@
@NonNull private final Context mContext;
@NonNull private final Handler mHandler;
@NonNull private final TimeZoneDetectorStrategy mTimeZoneDetectorStrategy;
+ @NonNull private final List<ConfigurationChangeListener> mConfigurationListeners =
+ new ArrayList<>();
- static TimeZoneDetectorInternalImpl create(@NonNull Context context, @NonNull Handler handler,
- @NonNull TimeZoneDetectorStrategy timeZoneDetectorStrategy) {
- return new TimeZoneDetectorInternalImpl(context, handler, timeZoneDetectorStrategy);
- }
-
- @VisibleForTesting
public TimeZoneDetectorInternalImpl(@NonNull Context context, @NonNull Handler handler,
@NonNull TimeZoneDetectorStrategy timeZoneDetectorStrategy) {
mContext = Objects.requireNonNull(context);
mHandler = Objects.requireNonNull(handler);
mTimeZoneDetectorStrategy = Objects.requireNonNull(timeZoneDetectorStrategy);
+
+ // Wire up a change listener so that any downstream listeners can be notified when
+ // the configuration changes for any reason.
+ mTimeZoneDetectorStrategy.addConfigChangeListener(this::handleConfigurationChanged);
+ }
+
+ private void handleConfigurationChanged() {
+ synchronized (mConfigurationListeners) {
+ for (ConfigurationChangeListener listener : mConfigurationListeners) {
+ listener.onChange();
+ }
+ }
}
@Override
@@ -54,6 +62,19 @@
}
@Override
+ public void addConfigurationListener(ConfigurationChangeListener listener) {
+ synchronized (mConfigurationListeners) {
+ mConfigurationListeners.add(Objects.requireNonNull(listener));
+ }
+ }
+
+ @Override
+ @NonNull
+ public ConfigurationInternal getCurrentUserConfigurationInternal() {
+ return mTimeZoneDetectorStrategy.getCurrentUserConfigurationInternal();
+ }
+
+ @Override
public void suggestGeolocationTimeZone(
@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
Objects.requireNonNull(timeZoneSuggestion);
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index d81f949..7501d9f 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -24,32 +24,24 @@
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
-import android.content.ContentResolver;
import android.content.Context;
-import android.database.ContentObserver;
-import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.IndentingPrintWriter;
import android.util.Slog;
-import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
import com.android.server.SystemService;
-import com.android.server.timezonedetector.TimeZoneDetectorStrategy.StrategyListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.Objects;
/**
@@ -65,6 +57,9 @@
private static final String TAG = "TimeZoneDetectorService";
+ /** A compile time switch for enabling / disabling geolocation-based time zone detection. */
+ private static final boolean GEOLOCATION_TIME_ZONE_DETECTION_ENABLED = false;
+
/**
* Handles the service lifecycle for {@link TimeZoneDetectorService} and
* {@link TimeZoneDetectorInternalImpl}.
@@ -80,18 +75,20 @@
// Obtain / create the shared dependencies.
Context context = getContext();
Handler handler = FgThread.getHandler();
+
TimeZoneDetectorStrategy timeZoneDetectorStrategy =
- TimeZoneDetectorStrategyImpl.create(context);
+ TimeZoneDetectorStrategyImpl.create(
+ context, handler, GEOLOCATION_TIME_ZONE_DETECTION_ENABLED);
// Create and publish the local service for use by internal callers.
TimeZoneDetectorInternal internal =
- TimeZoneDetectorInternalImpl.create(context, handler, timeZoneDetectorStrategy);
+ new TimeZoneDetectorInternalImpl(context, handler, timeZoneDetectorStrategy);
publishLocalService(TimeZoneDetectorInternal.class, internal);
// Publish the binder service so it can be accessed from other (appropriately
// permissioned) processes.
- TimeZoneDetectorService service =
- TimeZoneDetectorService.create(context, handler, timeZoneDetectorStrategy);
+ TimeZoneDetectorService service = TimeZoneDetectorService.create(
+ context, handler, timeZoneDetectorStrategy);
publishBinderService(Context.TIME_ZONE_DETECTOR_SERVICE, service);
}
}
@@ -103,52 +100,38 @@
private final Handler mHandler;
@NonNull
+ private final CallerIdentityInjector mCallerIdentityInjector;
+
+ @NonNull
private final TimeZoneDetectorStrategy mTimeZoneDetectorStrategy;
- /**
- * This sparse array acts as a map from userId to listeners running as that userId. User scoped
- * as time zone detection configuration is partially user-specific, so different users can
- * get different configuration.
- */
@GuardedBy("mConfigurationListeners")
@NonNull
- private final SparseArray<ArrayList<ITimeZoneConfigurationListener>> mConfigurationListeners =
- new SparseArray<>();
+ private final ArrayList<ITimeZoneConfigurationListener> mConfigurationListeners =
+ new ArrayList<>();
private static TimeZoneDetectorService create(
@NonNull Context context, @NonNull Handler handler,
@NonNull TimeZoneDetectorStrategy timeZoneDetectorStrategy) {
- TimeZoneDetectorService service =
- new TimeZoneDetectorService(context, handler, timeZoneDetectorStrategy);
-
- ContentResolver contentResolver = context.getContentResolver();
- contentResolver.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
- new ContentObserver(handler) {
- public void onChange(boolean selfChange) {
- service.handleAutoTimeZoneConfigChanged();
- }
- });
- // TODO(b/149014708) Listen for changes to geolocation time zone detection enabled config.
- // This should also include listening to the current user and the current user's location
- // toggle since the config is user-scoped and the location toggle overrides the geolocation
- // time zone enabled setting.
+ CallerIdentityInjector callerIdentityInjector = CallerIdentityInjector.REAL;
+ TimeZoneDetectorService service = new TimeZoneDetectorService(
+ context, handler, callerIdentityInjector, timeZoneDetectorStrategy);
return service;
}
@VisibleForTesting
public TimeZoneDetectorService(@NonNull Context context, @NonNull Handler handler,
+ @NonNull CallerIdentityInjector callerIdentityInjector,
@NonNull TimeZoneDetectorStrategy timeZoneDetectorStrategy) {
mContext = Objects.requireNonNull(context);
mHandler = Objects.requireNonNull(handler);
+ mCallerIdentityInjector = Objects.requireNonNull(callerIdentityInjector);
mTimeZoneDetectorStrategy = Objects.requireNonNull(timeZoneDetectorStrategy);
- mTimeZoneDetectorStrategy.setStrategyListener(new StrategyListener() {
- @Override
- public void onConfigurationChanged() {
- handleConfigurationChanged();
- }
- });
+
+ // Wire up a change listener so that ITimeZoneConfigurationListeners can be notified when
+ // the configuration changes for any reason.
+ mTimeZoneDetectorStrategy.addConfigChangeListener(this::handleConfigurationChanged);
}
@Override
@@ -156,26 +139,12 @@
public TimeZoneCapabilities getCapabilities() {
enforceManageTimeZoneDetectorConfigurationPermission();
- int userId = UserHandle.getCallingUserId();
- long token = Binder.clearCallingIdentity();
+ int userId = mCallerIdentityInjector.getCallingUserId();
+ long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mTimeZoneDetectorStrategy.getCapabilities(userId);
+ return mTimeZoneDetectorStrategy.getConfigurationInternal(userId).createCapabilities();
} finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- @NonNull
- public TimeZoneConfiguration getConfiguration() {
- enforceManageTimeZoneDetectorConfigurationPermission();
-
- int userId = UserHandle.getCallingUserId();
- long token = Binder.clearCallingIdentity();
- try {
- return mTimeZoneDetectorStrategy.getConfiguration(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
+ mCallerIdentityInjector.restoreCallingIdentity(token);
}
}
@@ -184,12 +153,16 @@
enforceManageTimeZoneDetectorConfigurationPermission();
Objects.requireNonNull(configuration);
- int userId = UserHandle.getCallingUserId();
- long token = Binder.clearCallingIdentity();
+ int callingUserId = mCallerIdentityInjector.getCallingUserId();
+ if (callingUserId != configuration.getUserId()) {
+ return false;
+ }
+
+ long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mTimeZoneDetectorStrategy.updateConfiguration(userId, configuration);
+ return mTimeZoneDetectorStrategy.updateConfiguration(configuration);
} finally {
- Binder.restoreCallingIdentity(token);
+ mCallerIdentityInjector.restoreCallingIdentity(token);
}
}
@@ -197,25 +170,17 @@
public void addConfigurationListener(@NonNull ITimeZoneConfigurationListener listener) {
enforceManageTimeZoneDetectorConfigurationPermission();
Objects.requireNonNull(listener);
- int userId = UserHandle.getCallingUserId();
synchronized (mConfigurationListeners) {
- ArrayList<ITimeZoneConfigurationListener> listeners =
- mConfigurationListeners.get(userId);
- if (listeners != null && listeners.contains(listener)) {
+ if (mConfigurationListeners.contains(listener)) {
return;
}
try {
- if (listeners == null) {
- listeners = new ArrayList<>(1);
- mConfigurationListeners.put(userId, listeners);
- }
-
// Ensure the reference to the listener will be removed if the client process dies.
listener.asBinder().linkToDeath(this, 0 /* flags */);
// Only add the listener if we can linkToDeath().
- listeners.add(listener);
+ mConfigurationListeners.add(listener);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to linkToDeath() for listener=" + listener, e);
}
@@ -226,19 +191,16 @@
public void removeConfigurationListener(@NonNull ITimeZoneConfigurationListener listener) {
enforceManageTimeZoneDetectorConfigurationPermission();
Objects.requireNonNull(listener);
- int userId = UserHandle.getCallingUserId();
synchronized (mConfigurationListeners) {
boolean removedListener = false;
- ArrayList<ITimeZoneConfigurationListener> userListeners =
- mConfigurationListeners.get(userId);
- if (userListeners.remove(listener)) {
+ if (mConfigurationListeners.remove(listener)) {
// Stop listening for the client process to die.
listener.asBinder().unlinkToDeath(this, 0 /* flags */);
removedListener = true;
}
if (!removedListener) {
- Slog.w(TAG, "Client asked to remove listenener=" + listener
+ Slog.w(TAG, "Client asked to remove listener=" + listener
+ ", but no listeners were removed."
+ " mConfigurationListeners=" + mConfigurationListeners);
}
@@ -259,19 +221,14 @@
public void binderDied(IBinder who) {
synchronized (mConfigurationListeners) {
boolean removedListener = false;
- final int userCount = mConfigurationListeners.size();
- for (int i = 0; i < userCount; i++) {
- ArrayList<ITimeZoneConfigurationListener> userListeners =
- mConfigurationListeners.valueAt(i);
- Iterator<ITimeZoneConfigurationListener> userListenerIterator =
- userListeners.iterator();
- while (userListenerIterator.hasNext()) {
- ITimeZoneConfigurationListener userListener = userListenerIterator.next();
- if (userListener.asBinder().equals(who)) {
- userListenerIterator.remove();
- removedListener = true;
- break;
- }
+ final int listenerCount = mConfigurationListeners.size();
+ for (int listenerIndex = listenerCount - 1; listenerIndex >= 0; listenerIndex--) {
+ ITimeZoneConfigurationListener listener =
+ mConfigurationListeners.get(listenerIndex);
+ if (listener.asBinder().equals(who)) {
+ mConfigurationListeners.remove(listenerIndex);
+ removedListener = true;
+ break;
}
}
if (!removedListener) {
@@ -283,42 +240,25 @@
}
void handleConfigurationChanged() {
- // Note: we could trigger an async time zone detection operation here via a call to
- // handleAutoTimeZoneConfigChanged(), but that is triggered in response to the underlying
- // setting value changing so it is currently unnecessary. If we get to a point where all
- // configuration changes are guaranteed to happen in response to an updateConfiguration()
- // call, then we can remove that path and call it here instead.
-
// Configuration has changed, but each user may have a different view of the configuration.
// It's possible that this will cause unnecessary notifications but that shouldn't be a
// problem.
synchronized (mConfigurationListeners) {
- final int userCount = mConfigurationListeners.size();
- for (int userIndex = 0; userIndex < userCount; userIndex++) {
- int userId = mConfigurationListeners.keyAt(userIndex);
- TimeZoneConfiguration configuration =
- mTimeZoneDetectorStrategy.getConfiguration(userId);
-
- ArrayList<ITimeZoneConfigurationListener> listeners =
- mConfigurationListeners.valueAt(userIndex);
- final int listenerCount = listeners.size();
- for (int listenerIndex = 0; listenerIndex < listenerCount; listenerIndex++) {
- ITimeZoneConfigurationListener listener = listeners.get(listenerIndex);
- try {
- listener.onChange(configuration);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to notify listener=" + listener
- + " for userId=" + userId
- + " of updated configuration=" + configuration, e);
- }
+ final int listenerCount = mConfigurationListeners.size();
+ for (int listenerIndex = 0; listenerIndex < listenerCount; listenerIndex++) {
+ ITimeZoneConfigurationListener listener =
+ mConfigurationListeners.get(listenerIndex);
+ try {
+ listener.onChange();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to notify listener=" + listener, e);
}
}
}
}
/** Provided for command-line access. This is not exposed as a binder API. */
- void suggestGeolocationTimeZone(
- @NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
+ void suggestGeolocationTimeZone(@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
enforceSuggestGeolocationTimeZonePermission();
Objects.requireNonNull(timeZoneSuggestion);
@@ -331,12 +271,12 @@
enforceSuggestManualTimeZonePermission();
Objects.requireNonNull(timeZoneSuggestion);
- int userId = UserHandle.getCallingUserId();
- long token = Binder.clearCallingIdentity();
+ int userId = mCallerIdentityInjector.getCallingUserId();
+ long token = mCallerIdentityInjector.clearCallingIdentity();
try {
return mTimeZoneDetectorStrategy.suggestManualTimeZone(userId, timeZoneSuggestion);
} finally {
- Binder.restoreCallingIdentity(token);
+ mCallerIdentityInjector.restoreCallingIdentity(token);
}
}
@@ -358,12 +298,6 @@
ipw.flush();
}
- /** Internal method for handling the auto time zone configuration being changed. */
- @VisibleForTesting
- public void handleAutoTimeZoneConfigChanged() {
- mHandler.post(mTimeZoneDetectorStrategy::handleAutoTimeZoneConfigChanged);
- }
-
private void enforceManageTimeZoneDetectorConfigurationPermission() {
// TODO Switch to a dedicated MANAGE_TIME_AND_ZONE_CONFIGURATION permission.
mContext.enforceCallingPermission(
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index c5b7e39..f944c56 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -19,51 +19,84 @@
import android.annotation.UserIdInt;
import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
-import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
import android.util.IndentingPrintWriter;
/**
- * The interface for the class that implements the time detection algorithm used by the
- * {@link TimeZoneDetectorService}.
+ * The interface for the class that is responsible for setting the time zone on a device, used by
+ * {@link TimeZoneDetectorService} and {@link TimeZoneDetectorInternal}.
*
- * <p>The strategy uses suggestions to decide whether to modify the device's time zone setting
- * and what to set it to.
+ * <p>The strategy receives suggestions, which it may use to modify the device's time zone setting.
+ * Suggestions are acted on or ignored as needed, depending on previously received suggestions and
+ * the current user's configuration (see {@link ConfigurationInternal}).
*
- * <p>Most calls will be handled by a single thread, but that is not true for all calls. For example
- * {@link #dump(IndentingPrintWriter, String[])}) may be called on a different thread concurrently
- * with other operations so implementations must still handle thread safety.
+ * <p>Devices can have zero, one or two automatic time zone detection algorithm available at any
+ * point in time.
+ *
+ * <p>The two automatic detection algorithms supported are "telephony" and "geolocation". Algorithm
+ * availability and use depends on several factors:
+ * <ul>
+ * <li>Telephony is only available on devices with a telephony stack.
+ * <li>Geolocation is also optional and configured at image creation time. When enabled on a
+ * device, its availability depends on the current user's settings, so switching between users can
+ * change the automatic algorithm used by the device.</li>
+ * </ul>
+ *
+ * <p>If there are no automatic time zone detections algorithms available then the user can usually
+ * change the device time zone manually. Under most circumstances the current user can turn
+ * automatic time zone detection on or off, or choose the algorithm via settings.
+ *
+ * <p>Telephony detection is independent of the current user. The device keeps track of the most
+ * recent telephony suggestion from each slotIndex. When telephony detection is in use, the highest
+ * scoring suggestion is used to set the device time zone based on a scoring algorithm. If several
+ * slotIndexes provide the same score then the slotIndex with the lowest numeric value "wins". If
+ * the situation changes and it is no longer possible to be confident about the time zone,
+ * slotIndexes must have an empty suggestion submitted in order to "withdraw" their previous
+ * suggestion otherwise it will remain in use.
+ *
+ * <p>Geolocation detection is dependent on the current user and their settings. The device retains
+ * at most one geolocation suggestion. Generally, use of a device's location is dependent on the
+ * user's "location toggle", but even when that is enabled the user may choose to enable / disable
+ * the use of geolocation for device time zone detection. If the current user changes to one that
+ * does not have geolocation detection enabled, or the user turns off geolocation detection, then
+ * the strategy discards the latest geolocation suggestion. Devices that lose a location fix must
+ * have an empty suggestion submitted in order to "withdraw" their previous suggestion otherwise it
+ * will remain in use.
+ *
+ * <p>Threading:
+ *
+ * <p>Suggestion calls with a void return type may be handed off to a separate thread and handled
+ * asynchronously. Synchronous calls like {@link #getCurrentUserConfigurationInternal()}, and debug
+ * calls like {@link #dump(IndentingPrintWriter, String[])}, may be called on a different thread
+ * concurrently with other operations.
*
* @hide
*/
public interface TimeZoneDetectorStrategy extends Dumpable, Dumpable.Container {
- /** A listener for strategy events. */
- interface StrategyListener {
- /**
- * Invoked when configuration has been changed.
- */
- void onConfigurationChanged();
- }
+ /**
+ * Sets a listener that will be triggered whenever time zone detection configuration is
+ * changed.
+ */
+ void addConfigChangeListener(@NonNull ConfigurationChangeListener listener);
- /** Sets the listener that enables the strategy to communicate with the surrounding service. */
- void setStrategyListener(@NonNull StrategyListener listener);
-
- /** Returns the user's time zone capabilities. */
+ /** Returns the user's time zone configuration. */
@NonNull
- TimeZoneCapabilities getCapabilities(@UserIdInt int userId);
+ ConfigurationInternal getConfigurationInternal(@UserIdInt int userId);
/**
- * Returns the configuration that controls time zone detector behavior.
+ * Returns the configuration that controls time zone detector behavior for the current user.
*/
@NonNull
- TimeZoneConfiguration getConfiguration(@UserIdInt int userId);
+ ConfigurationInternal getCurrentUserConfigurationInternal();
/**
- * Updates the configuration settings that control time zone detector behavior.
+ * Updates the configuration properties that control a device's time zone behavior.
+ *
+ * <p>This method returns {@code true} if the configuration was changed,
+ * {@code false} otherwise.
*/
- boolean updateConfiguration(
- @UserIdInt int userId, @NonNull TimeZoneConfiguration configuration);
+ boolean updateConfiguration(@NonNull TimeZoneConfiguration configuration);
/**
* Suggests zero, one or more time zones for the device, or withdraws a previous suggestion if
@@ -85,9 +118,4 @@
* suggestion.
*/
void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion suggestion);
-
- /**
- * Called when there has been a change to the automatic time zone detection configuration.
- */
- void handleAutoTimeZoneConfigChanged();
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index d1369a2..8a42b18 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -20,10 +20,7 @@
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
-import static android.app.timezonedetector.TimeZoneConfiguration.PROPERTY_AUTO_DETECTION_ENABLED;
-import static android.app.timezonedetector.TimeZoneConfiguration.PROPERTY_GEO_DETECTION_ENABLED;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -33,6 +30,7 @@
import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
import android.content.Context;
+import android.os.Handler;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Slog;
@@ -45,15 +43,7 @@
import java.util.Objects;
/**
- * An implementation of {@link TimeZoneDetectorStrategy} that handle telephony and manual
- * suggestions. Suggestions are acted on or ignored as needed, dependent on the current "auto time
- * zone detection" setting.
- *
- * <p>For automatic detection, it keeps track of the most recent telephony suggestion from each
- * slotIndex and it uses the best suggestion based on a scoring algorithm. If several slotIndexes
- * provide the same score then the slotIndex with the lowest numeric value "wins". If the situation
- * changes and it is no longer possible to be confident about the time zone, slotIndexes must have
- * an empty suggestion submitted in order to "withdraw" their previous suggestion.
+ * The real implementation of {@link TimeZoneDetectorStrategy}.
*
* <p>Most public methods are marked synchronized to ensure thread safety around internal state.
*/
@@ -61,48 +51,27 @@
/**
* Used by {@link TimeZoneDetectorStrategyImpl} to interact with device configuration / settings
- * / system properties. It can be faked for testing different scenarios.
+ * / system properties. It can be faked for testing.
*
* <p>Note: Because the settings / system properties-derived values can currently be modified
- * independently and from different threads (and processes!), their use are prone to race
- * conditions. That will be true until the responsibility for setting their values is moved to
- * {@link TimeZoneDetectorStrategyImpl} (which is thread safe).
+ * independently and from different threads (and processes!), their use is prone to race
+ * conditions.
*/
@VisibleForTesting
public interface Callback {
/**
- * Returns the capabilities for the user.
+ * Sets a {@link ConfigurationChangeListener} that will be invoked when there are any
+ * changes that could affect time zone detection. This is invoked during system server
+ * setup.
*/
- @NonNull
- TimeZoneCapabilities getCapabilities(@UserIdInt int userId);
+ void setConfigChangeListener(@NonNull ConfigurationChangeListener listener);
- /**
- * Returns the configuration for the user.
- * @param userId
- */
- @NonNull
- TimeZoneConfiguration getConfiguration(int userId);
+ /** Returns the current user at the instant it is called. */
+ @UserIdInt int getCurrentUserId();
- /**
- * Sets the configuration for the user. This method handles storage only, the configuration
- * must have been validated by the caller and be complete.
- *
- * @throws IllegalArgumentException if {@link TimeZoneConfiguration#isComplete()}
- * returns {@code false}
- */
- void setConfiguration(@UserIdInt int userId, @NonNull TimeZoneConfiguration configuration);
-
- /**
- * Returns true if automatic time zone detection is currently enabled.
- */
- boolean isAutoDetectionEnabled();
-
- /**
- * Returns whether geolocation can be used for time zone detection when {@link
- * #isAutoDetectionEnabled()} returns {@code true}.
- */
- boolean isGeoDetectionEnabled();
+ /** Returns the {@link ConfigurationInternal} for the specified user. */
+ ConfigurationInternal getConfigurationInternal(@UserIdInt int userId);
/**
* Returns true if the device has had an explicit time zone set.
@@ -118,6 +87,13 @@
* Sets the device's time zone.
*/
void setDeviceTimeZone(@NonNull String zoneId);
+
+ /**
+ * Stores the configuration properties contained in {@code newConfiguration}.
+ * All checks about user capabilities must be done by the caller and
+ * {@link TimeZoneConfiguration#isComplete()} must be {@code true}.
+ */
+ void storeConfiguration(TimeZoneConfiguration newConfiguration);
}
private static final String LOG_TAG = "TimeZoneDetectorStrategy";
@@ -189,9 +165,9 @@
@NonNull
private final Callback mCallback;
- /** Non-null after {@link #setStrategyListener(StrategyListener)} is called. */
- @Nullable
- private StrategyListener mListener;
+ @GuardedBy("this")
+ @NonNull
+ private List<ConfigurationChangeListener> mConfigChangeListeners = new ArrayList<>();
/**
* A log that records the decisions / decision metadata that affected the device's time zone.
@@ -211,7 +187,8 @@
new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
/**
- * The latest geolocation suggestion received.
+ * The latest geolocation suggestion received. If the user disabled geolocation time zone
+ * detection then the latest suggestion is cleared.
*/
@GuardedBy("this")
private ReferenceWithHistory<GeolocationTimeZoneSuggestion> mLatestGeoLocationSuggestion =
@@ -223,113 +200,120 @@
/**
* Creates a new instance of {@link TimeZoneDetectorStrategyImpl}.
*/
- public static TimeZoneDetectorStrategyImpl create(Context context) {
- Callback timeZoneDetectionServiceHelper = new TimeZoneDetectorCallbackImpl(context);
- return new TimeZoneDetectorStrategyImpl(timeZoneDetectionServiceHelper);
+ public static TimeZoneDetectorStrategyImpl create(
+ @NonNull Context context, @NonNull Handler handler,
+ boolean geolocationTimeZoneDetectionEnabled) {
+
+ TimeZoneDetectorCallbackImpl callback = new TimeZoneDetectorCallbackImpl(
+ context, handler, geolocationTimeZoneDetectionEnabled);
+ return new TimeZoneDetectorStrategyImpl(callback);
}
@VisibleForTesting
- public TimeZoneDetectorStrategyImpl(Callback callback) {
+ public TimeZoneDetectorStrategyImpl(@NonNull Callback callback) {
mCallback = Objects.requireNonNull(callback);
+ mCallback.setConfigChangeListener(this::handleConfigChanged);
}
/**
- * Sets a listener that allows the strategy to communicate with the surrounding service. This
- * must be called before the instance is used and must only be called once.
+ * Adds a listener that allows the strategy to communicate with the surrounding service /
+ * internal. This must be called before the instance is used.
*/
@Override
- public synchronized void setStrategyListener(@NonNull StrategyListener listener) {
- if (mListener != null) {
- throw new IllegalStateException("Strategy already has a listener");
- }
- mListener = Objects.requireNonNull(listener);
+ public synchronized void addConfigChangeListener(
+ @NonNull ConfigurationChangeListener listener) {
+ Objects.requireNonNull(listener);
+ mConfigChangeListeners.add(listener);
}
@Override
@NonNull
- public synchronized TimeZoneCapabilities getCapabilities(@UserIdInt int userId) {
- return mCallback.getCapabilities(userId);
+ public ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
+ return mCallback.getConfigurationInternal(userId);
}
@Override
@NonNull
- public synchronized TimeZoneConfiguration getConfiguration(@UserIdInt int userId) {
- return mCallback.getConfiguration(userId);
+ public synchronized ConfigurationInternal getCurrentUserConfigurationInternal() {
+ int currentUserId = mCallback.getCurrentUserId();
+ return getConfigurationInternal(currentUserId);
}
@Override
public synchronized boolean updateConfiguration(
- @UserIdInt int userId, @NonNull TimeZoneConfiguration configurationChanges) {
- Objects.requireNonNull(configurationChanges);
+ @NonNull TimeZoneConfiguration requestedConfiguration) {
+ Objects.requireNonNull(requestedConfiguration);
- // Validate the requested configuration changes before applying any of them.
- TimeZoneCapabilities capabilities = mCallback.getCapabilities(userId);
- boolean canManageTimeZoneDetection =
- capabilities.getConfigureAutoDetectionEnabled() >= CAPABILITY_NOT_APPLICABLE;
- if (!canManageTimeZoneDetection
- && containsAutoTimeDetectionProperties(configurationChanges)) {
+ int userId = requestedConfiguration.getUserId();
+ TimeZoneCapabilities capabilities = getConfigurationInternal(userId).createCapabilities();
+
+ // Create a new configuration builder, and copy across the mutable properties users are
+ // able to modify. Other properties are therefore ignored.
+ final TimeZoneConfiguration newConfiguration =
+ capabilities.applyUpdate(requestedConfiguration);
+ if (newConfiguration == null) {
+ // The changes could not be made due to
return false;
}
- // Create a complete configuration by merging the existing and new (possibly partial)
- // configuration.
- final TimeZoneConfiguration oldConfiguration = mCallback.getConfiguration(userId);
- final TimeZoneConfiguration newConfiguration =
- new TimeZoneConfiguration.Builder(oldConfiguration)
- .mergeProperties(configurationChanges)
- .build();
+ // Store the configuration / notify as needed. This will cause the mCallback to invoke
+ // handleConfigChanged() asynchronously.
+ mCallback.storeConfiguration(newConfiguration);
- // Set the configuration / notify as needed.
- boolean configurationChanged = !oldConfiguration.equals(newConfiguration);
- if (configurationChanged) {
- mCallback.setConfiguration(userId, newConfiguration);
-
- String logMsg = "Configuration changed:"
- + "oldConfiguration=" + oldConfiguration
- + ", configuration=" + configurationChanges
- + ", newConfiguration=" + newConfiguration;
- mTimeZoneChangesLog.log(logMsg);
- if (DBG) {
- Slog.d(LOG_TAG, logMsg);
- }
- mListener.onConfigurationChanged();
+ TimeZoneConfiguration oldConfiguration = capabilities.getConfiguration();
+ String logMsg = "Configuration changed:"
+ + " oldConfiguration=" + oldConfiguration
+ + ", newConfiguration=" + newConfiguration;
+ mTimeZoneChangesLog.log(logMsg);
+ if (DBG) {
+ Slog.d(LOG_TAG, logMsg);
}
return true;
}
- private static boolean containsAutoTimeDetectionProperties(
- @NonNull TimeZoneConfiguration configuration) {
- return configuration.hasProperty(PROPERTY_AUTO_DETECTION_ENABLED)
- || configuration.hasProperty(PROPERTY_GEO_DETECTION_ENABLED);
- }
-
@Override
public synchronized void suggestGeolocationTimeZone(
@NonNull GeolocationTimeZoneSuggestion suggestion) {
+
+ int currentUserId = mCallback.getCurrentUserId();
+ ConfigurationInternal currentUserConfig = mCallback.getConfigurationInternal(currentUserId);
if (DBG) {
- Slog.d(LOG_TAG, "Geolocation suggestion received. newSuggestion=" + suggestion);
+ Slog.d(LOG_TAG, "Geolocation suggestion received."
+ + " currentUserConfig=" + currentUserConfig
+ + " newSuggestion=" + suggestion);
}
-
Objects.requireNonNull(suggestion);
- mLatestGeoLocationSuggestion.set(suggestion);
- // Now perform auto time zone detection. The new suggestion may be used to modify the time
- // zone setting.
- if (mCallback.isGeoDetectionEnabled()) {
+ if (currentUserConfig.getGeoDetectionEnabledBehavior()) {
+ // Only store a geolocation suggestion if geolocation detection is currently enabled.
+ mLatestGeoLocationSuggestion.set(suggestion);
+
+ // Now perform auto time zone detection. The new suggestion may be used to modify the
+ // time zone setting.
String reason = "New geolocation time zone suggested. suggestion=" + suggestion;
- doAutoTimeZoneDetection(reason);
+ doAutoTimeZoneDetection(currentUserConfig, reason);
}
}
@Override
public synchronized boolean suggestManualTimeZone(
@UserIdInt int userId, @NonNull ManualTimeZoneSuggestion suggestion) {
+
+ int currentUserId = mCallback.getCurrentUserId();
+ if (userId != currentUserId) {
+ Slog.w(LOG_TAG, "Manual suggestion received but user != current user, userId=" + userId
+ + " suggestion=" + suggestion);
+
+ // Only listen to changes from the current user.
+ return false;
+ }
+
Objects.requireNonNull(suggestion);
String timeZoneId = suggestion.getZoneId();
String cause = "Manual time suggestion received: suggestion=" + suggestion;
- TimeZoneCapabilities capabilities = mCallback.getCapabilities(userId);
+ TimeZoneCapabilities capabilities = getConfigurationInternal(userId).createCapabilities();
if (capabilities.getSuggestManualTimeZone() != CAPABILITY_POSSESSED) {
Slog.i(LOG_TAG, "User does not have the capability needed to set the time zone manually"
+ ", capabilities=" + capabilities
@@ -345,8 +329,12 @@
@Override
public synchronized void suggestTelephonyTimeZone(
@NonNull TelephonyTimeZoneSuggestion suggestion) {
+
+ int currentUserId = mCallback.getCurrentUserId();
+ ConfigurationInternal currentUserConfig = mCallback.getConfigurationInternal(currentUserId);
if (DBG) {
- Slog.d(LOG_TAG, "Telephony suggestion received. newSuggestion=" + suggestion);
+ Slog.d(LOG_TAG, "Telephony suggestion received. currentUserConfig=" + currentUserConfig
+ + " newSuggestion=" + suggestion);
}
Objects.requireNonNull(suggestion);
@@ -360,9 +348,9 @@
// Now perform auto time zone detection. The new suggestion may be used to modify the time
// zone setting.
- if (!mCallback.isGeoDetectionEnabled()) {
+ if (!currentUserConfig.getGeoDetectionEnabledBehavior()) {
String reason = "New telephony time zone suggested. suggestion=" + suggestion;
- doAutoTimeZoneDetection(reason);
+ doAutoTimeZoneDetection(currentUserConfig, reason);
}
}
@@ -392,15 +380,15 @@
* Performs automatic time zone detection.
*/
@GuardedBy("this")
- private void doAutoTimeZoneDetection(@NonNull String detectionReason) {
- if (!mCallback.isAutoDetectionEnabled()) {
- // Avoid doing unnecessary work with this (race-prone) check.
+ private void doAutoTimeZoneDetection(
+ @NonNull ConfigurationInternal currentUserConfig, @NonNull String detectionReason) {
+ if (!currentUserConfig.getAutoDetectionEnabledBehavior()) {
+ // Avoid doing unnecessary work.
return;
}
- // Use the right suggestions based on the current configuration. This check is potentially
- // race-prone until this value is set via a call to TimeZoneDetectorStrategy.
- if (mCallback.isGeoDetectionEnabled()) {
+ // Use the right suggestions based on the current configuration.
+ if (currentUserConfig.getGeoDetectionEnabledBehavior()) {
doGeolocationTimeZoneDetection(detectionReason);
} else {
doTelephonyTimeZoneDetection(detectionReason);
@@ -480,35 +468,18 @@
// Paranoia: Every suggestion above the SCORE_USAGE_THRESHOLD should have a non-null time
// zone ID.
- String newZoneId = bestTelephonySuggestion.suggestion.getZoneId();
- if (newZoneId == null) {
+ String zoneId = bestTelephonySuggestion.suggestion.getZoneId();
+ if (zoneId == null) {
Slog.w(LOG_TAG, "Empty zone suggestion scored higher than expected. This is an error:"
+ " bestTelephonySuggestion=" + bestTelephonySuggestion
+ " detectionReason=" + detectionReason);
return;
}
- String zoneId = bestTelephonySuggestion.suggestion.getZoneId();
String cause = "Found good suggestion."
+ ", bestTelephonySuggestion=" + bestTelephonySuggestion
+ ", detectionReason=" + detectionReason;
- setAutoDeviceTimeZoneIfRequired(zoneId, cause);
- }
-
- @GuardedBy("this")
- private void setAutoDeviceTimeZoneIfRequired(@NonNull String newZoneId, @NonNull String cause) {
- Objects.requireNonNull(newZoneId);
- Objects.requireNonNull(cause);
-
- if (!mCallback.isAutoDetectionEnabled()) {
- if (DBG) {
- Slog.d(LOG_TAG, "Auto time zone detection is not enabled."
- + ", newZoneId=" + newZoneId
- + ", cause=" + cause);
- }
- return;
- }
- setDeviceTimeZoneIfRequired(newZoneId, cause);
+ setDeviceTimeZoneIfRequired(zoneId, cause);
}
@GuardedBy("this")
@@ -582,13 +553,39 @@
return findBestTelephonySuggestion();
}
- @Override
- public synchronized void handleAutoTimeZoneConfigChanged() {
+ private synchronized void handleConfigChanged() {
if (DBG) {
- Slog.d(LOG_TAG, "handleAutoTimeZoneConfigChanged()");
+ Slog.d(LOG_TAG, "handleConfigChanged()");
}
- doAutoTimeZoneDetection("handleAutoTimeZoneConfigChanged()");
+ clearGeolocationSuggestionIfNeeded();
+
+ for (ConfigurationChangeListener listener : mConfigChangeListeners) {
+ listener.onChange();
+ }
+ }
+
+ @GuardedBy("this")
+ private void clearGeolocationSuggestionIfNeeded() {
+ // This method is called whenever the user changes or the config for any user changes. We
+ // don't know what happened, so we capture the current user's config, check to see if we
+ // need to clear state associated with a previous user, and rerun detection.
+ int currentUserId = mCallback.getCurrentUserId();
+ ConfigurationInternal currentUserConfig = mCallback.getConfigurationInternal(currentUserId);
+
+ GeolocationTimeZoneSuggestion latestGeoLocationSuggestion =
+ mLatestGeoLocationSuggestion.get();
+ if (latestGeoLocationSuggestion != null
+ && !currentUserConfig.getGeoDetectionEnabledBehavior()) {
+ // The current user's config has geodetection disabled, so clear the latest suggestion.
+ // This is done to ensure we only ever keep a geolocation suggestion if the user has
+ // said it is ok to do so.
+ mLatestGeoLocationSuggestion.set(null);
+ mTimeZoneChangesLog.log(
+ "clearGeolocationSuggestionIfNeeded: Cleared latest Geolocation suggestion.");
+ }
+
+ doAutoTimeZoneDetection(currentUserConfig, "clearGeolocationSuggestionIfNeeded()");
}
@Override
@@ -604,11 +601,14 @@
ipw.println("TimeZoneDetectorStrategy:");
ipw.increaseIndent(); // level 1
- ipw.println("mCallback.isAutoDetectionEnabled()=" + mCallback.isAutoDetectionEnabled());
+ int currentUserId = mCallback.getCurrentUserId();
+ ipw.println("mCallback.getCurrentUserId()=" + currentUserId);
+ ConfigurationInternal configuration = mCallback.getConfigurationInternal(currentUserId);
+ ipw.println("mCallback.getConfiguration(currentUserId)=" + configuration);
+ ipw.println("[Capabilities=" + configuration.createCapabilities() + "]");
ipw.println("mCallback.isDeviceTimeZoneInitialized()="
+ mCallback.isDeviceTimeZoneInitialized());
ipw.println("mCallback.getDeviceTimeZone()=" + mCallback.getDeviceTimeZone());
- ipw.println("mCallback.isGeoDetectionEnabled()=" + mCallback.isGeoDetectionEnabled());
ipw.println("Time zone change log:");
ipw.increaseIndent(); // level 2
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 1536473..4c2d0d0 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -700,8 +700,8 @@
touchableRegion.getBounds(touchableFrame);
RectF windowFrame = mTempRectF;
windowFrame.set(touchableFrame);
- windowFrame.offset(-windowState.getFrameLw().left,
- -windowState.getFrameLw().top);
+ windowFrame.offset(-windowState.getFrame().left,
+ -windowState.getFrame().top);
matrix.mapRect(windowFrame);
Region windowBounds = mTempRegion2;
windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
@@ -730,7 +730,7 @@
}
// Count letterbox into nonMagnifiedBounds
- if (windowState.isLetterboxedForDisplayCutoutLw()) {
+ if (windowState.isLetterboxedForDisplayCutout()) {
Region letterboxBounds = getLetterboxBounds(windowState);
nonMagnifiedBounds.op(letterboxBounds, Region.Op.UNION);
availableBounds.op(letterboxBounds, Region.Op.DIFFERENCE);
@@ -1429,11 +1429,11 @@
// Account for all space in the task, whether the windows in it are
// touchable or not. The modal window blocks all touches from the task's
// area.
- unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
+ unaccountedSpace.op(windowState.getDisplayFrame(), unaccountedSpace,
Region.Op.REVERSE_DIFFERENCE);
} else {
// If a window has tap exclude region, we need to account it.
- final Region displayRegion = new Region(windowState.getDisplayFrameLw());
+ final Region displayRegion = new Region(windowState.getDisplayFrame());
final Region tapExcludeRegion = new Region();
windowState.getTapExcludeRegion(tapExcludeRegion);
displayRegion.op(tapExcludeRegion, displayRegion,
@@ -1470,7 +1470,7 @@
// Move to origin as all transforms are captured by the matrix.
RectF windowFrame = mTempRectF;
windowFrame.set(rect);
- windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
+ windowFrame.offset(-windowState.getFrame().left, -windowState.getFrame().top);
matrix.mapRect(windowFrame);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 76473d08..56261c4 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -110,9 +110,13 @@
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONTAINERS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SWITCH;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.ActivityRecordProto.ALL_DRAWN;
@@ -145,9 +149,6 @@
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONTAINERS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -1096,15 +1097,15 @@
private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
if (!attachedToProcess()) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
- "Can't report activity moved to display - client not running, activityRecord="
- + this + ", displayId=" + displayId);
+ ProtoLog.w(WM_DEBUG_SWITCH, "Can't report activity moved "
+ + "to display - client not running, activityRecord=%s, displayId=%d",
+ this, displayId);
return;
}
try {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Reporting activity moved to display" + ", activityRecord=" + this
- + ", displayId=" + displayId + ", config=" + config);
+ ProtoLog.v(WM_DEBUG_SWITCH, "Reporting activity moved to "
+ + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId,
+ config);
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
MoveToDisplayItem.obtain(displayId, config));
@@ -1115,14 +1116,13 @@
private void scheduleConfigurationChanged(Configuration config) {
if (!attachedToProcess()) {
- if (DEBUG_CONFIGURATION) Slog.w(TAG,
- "Can't report activity configuration update - client not running"
- + ", activityRecord=" + this);
+ ProtoLog.w(WM_DEBUG_CONFIGURATION, "Can't report activity configuration "
+ + "update - client not running, activityRecord=%s", this);
return;
}
try {
- if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
- + config);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, "
+ + "config: %s", this, config);
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
ActivityConfigurationChangeItem.obtain(config));
@@ -1334,7 +1334,7 @@
if (w == null || winHint != null && w != winHint) {
return;
}
- final boolean surfaceReady = w.isDrawnLw() // Regular case
+ final boolean surfaceReady = w.isDrawn() // Regular case
|| w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
|| w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
final boolean needsLetterbox = surfaceReady && w.isLetterboxedAppWindow() && fillsParent();
@@ -1355,7 +1355,7 @@
: inMultiWindowMode()
? task.getBounds()
: getRootTask().getParent().getBounds();
- mLetterbox.layout(spaceToFill, w.getFrameLw(), mTmpPoint);
+ mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint);
} else if (mLetterbox != null) {
mLetterbox.hide();
}
@@ -1949,10 +1949,8 @@
startingWindow = null;
startingDisplayed = false;
if (surface == null) {
- ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
- "startingWindow was set but startingSurface==null, couldn't "
- + "remove");
-
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "startingWindow was set but "
+ + "startingSurface==null, couldn't remove");
return;
}
} else {
@@ -1962,9 +1960,10 @@
return;
}
+
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s"
- + " startingView=%s Callers=%s",
- this, startingWindow, startingSurface, Debug.getCallers(5));
+ + " startingView=%s Callers=%s", this, startingWindow, startingSurface,
+ Debug.getCallers(5));
// Use the same thread to remove the window as we used to add it, as otherwise we end up
@@ -2399,9 +2398,8 @@
*/
boolean moveFocusableActivityToTop(String reason) {
if (!isFocusable()) {
- if (DEBUG_FOCUS) {
- Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
- }
+ ProtoLog.d(WM_DEBUG_FOCUS, "moveActivityStackToFront: unfocusable "
+ + "activity=%s", this);
return false;
}
@@ -2414,15 +2412,11 @@
if (mRootWindowContainer.getTopResumedActivity() == this
&& getDisplayContent().mFocusedApp == this) {
- if (DEBUG_FOCUS) {
- Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
- }
+ ProtoLog.d(WM_DEBUG_FOCUS, "moveActivityStackToFront: already on top, "
+ + "activity=%s", this);
return !isState(RESUMED);
}
-
- if (DEBUG_FOCUS) {
- Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
- }
+ ProtoLog.d(WM_DEBUG_FOCUS, "moveActivityStackToFront: activity=%s", this);
stack.moveToFront(reason, task);
// Report top activity change to tracking services and WM
@@ -2798,10 +2792,8 @@
mRootWindowContainer.resumeFocusedStacksTopActivities();
}
- if (DEBUG_CONTAINERS) {
- Slog.d(TAG_CONTAINERS, "destroyIfPossible: r=" + this + " destroy returned removed="
- + activityRemoved);
- }
+ ProtoLog.d(WM_DEBUG_CONTAINERS, "destroyIfPossible: r=%s destroy returned "
+ + "removed=%s", this, activityRemoved);
return activityRemoved;
}
@@ -2935,10 +2927,9 @@
finishActivityResults(Activity.RESULT_CANCELED,
null /* resultData */, null /* resultGrants */);
makeFinishingLocked();
- if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE) {
- Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " from stack, reason="
- + reason + ", callers=" + Debug.getCallers(5));
- }
+
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing activity %s from stack, reason= %s "
+ + "callers=%s", this, reason, Debug.getCallers(5));
takeFromHistory();
removeTimeouts();
@@ -2978,7 +2969,7 @@
void destroyed(String reason) {
removeDestroyTimeout();
- if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + this);
+ ProtoLog.d(WM_DEBUG_CONTAINERS, "activityDestroyedLocked: r=%s", this);
if (!isState(DESTROYING, DESTROYED)) {
throw new IllegalStateException(
@@ -3179,12 +3170,9 @@
remove = false;
}
if (remove) {
- if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
- Slog.i(TAG_ADD_REMOVE, "Removing activity " + this
- + " hasSavedState=" + mHaveState + " stateNotNeeded=" + stateNotNeeded
- + " finishing=" + finishing + " state=" + mState
- + " callers=" + Debug.getCallers(5));
- }
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing activity %s hasSavedState=%b "
+ + "stateNotNeeded=%s finishing=%b state=%s callers=%s", this,
+ mHaveState, stateNotNeeded, finishing, mState, Debug.getCallers(5));
if (!finishing || (app != null && app.isRemoved())) {
Slog.w(TAG, "Force removing " + this + ": app died, no saved state");
EventLogTags.writeWmFinishActivity(mUserId, System.identityHashCode(this),
@@ -4296,7 +4284,7 @@
} else {
// If we are being set visible, and the starting window is not yet displayed,
// then make sure it doesn't get displayed.
- if (startingWindow != null && !startingWindow.isDrawnLw()) {
+ if (startingWindow != null && !startingWindow.isDrawn()) {
startingWindow.clearPolicyVisibilityFlag(LEGACY_POLICY_VISIBILITY);
startingWindow.mLegacyPolicyVisibilityAfterAnim = false;
}
@@ -5596,9 +5584,9 @@
if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
final boolean isAnimationSet = isAnimating(TRANSITION | PARENTS,
ANIMATION_TYPE_APP_TRANSITION);
- Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
+ Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawn()
+ ", isAnimationSet=" + isAnimationSet);
- if (!w.isDrawnLw()) {
+ if (!w.isDrawn()) {
Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
+ " pv=" + w.isVisibleByPolicy()
+ " mDrawState=" + winAnimator.drawStateToString()
@@ -5613,7 +5601,7 @@
if (findMainWindow(false /* includeStartingApp */) != w) {
mNumInterestingWindows++;
}
- if (w.isDrawnLw()) {
+ if (w.isDrawn()) {
mNumDrawnWindows++;
if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
@@ -5626,7 +5614,7 @@
isInterestingAndDrawn = true;
}
}
- } else if (w.isDrawnLw()) {
+ } else if (w.isDrawn()) {
// The starting window for this container is drawn.
mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(this);
startingDisplayed = true;
@@ -6155,7 +6143,7 @@
if (win == null) {
return;
}
- final Rect frame = win.getRelativeFrameLw();
+ final Rect frame = win.getRelativeFrame();
final int thumbnailDrawableRes = task.mUserId == mWmService.mCurrentUserId
? R.drawable.ic_account_circle
: R.drawable.ic_corp_badge;
@@ -6181,7 +6169,7 @@
// destination of the thumbnail header animation. If this is a full screen
// window scenario, we use the whole display as the target.
WindowState win = findMainWindow();
- Rect appRect = win != null ? win.getContentFrameLw() :
+ final Rect appRect = win != null ? win.getContentFrame() :
new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
final Rect insets = win != null ? win.getContentInsets() : null;
final Configuration displayConfig = mDisplayContent.getConfiguration();
@@ -7007,27 +6995,27 @@
boolean ignoreVisibility) {
final Task stack = getRootTask();
if (stack.mConfigWillChange) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Skipping config check (will change): " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Skipping config check "
+ + "(will change): %s", this);
return true;
}
// We don't worry about activities that are finishing.
if (finishing) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Configuration doesn't matter in finishing " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration doesn't matter "
+ + "in finishing %s", this);
stopFreezingScreenLocked(false);
return true;
}
if (!ignoreVisibility && (mState == STOPPING || mState == STOPPED || !shouldBeVisible())) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Skipping config check invisible: " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Skipping config check "
+ + "invisible: %s", this);
return true;
}
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Ensuring correct configuration: " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Ensuring correct "
+ + "configuration: %s", this);
final int newDisplayId = getDisplayId();
final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
@@ -7043,8 +7031,8 @@
// the combine configurations are equal, but would otherwise differ in the override config
mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Configuration & display unchanged in " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
+ + "unchanged in %s", this);
return true;
}
@@ -7064,14 +7052,14 @@
// No need to relaunch or schedule new config for activity that hasn't been launched
// yet. We do, however, return after applying the config to activity record, so that
// it will use it for launch transaction.
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Skipping config check for initializing activity: " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Skipping config check for "
+ + "initializing activity: %s", this);
return true;
}
if (changes == 0 && !forceNewConfig) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Configuration no differences in " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration no differences in %s",
+ this);
// There are no significant differences, so we won't relaunch but should still deliver
// the new configuration to the client process.
if (displayChanged) {
@@ -7082,26 +7070,23 @@
return true;
}
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Configuration changes for " + this + ", allChanges="
- + Configuration.configurationDiffToString(changes));
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration changes for %s, "
+ + "allChanges=%s", this, Configuration.configurationDiffToString(changes));
// If the activity isn't currently running, just leave the new configuration and it will
// pick that up next time it starts.
if (!attachedToProcess()) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Configuration doesn't matter not running " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration doesn't matter not running %s", this);
stopFreezingScreenLocked(false);
forceNewConfig = false;
return true;
}
// Figure out how to handle the changes between the configurations.
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Checking to restart " + info.name + ": changed=0x"
- + Integer.toHexString(changes) + ", handles=0x"
- + Integer.toHexString(info.getRealConfigChanged())
- + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Checking to restart %s: changed=0x%s, "
+ + "handles=0x%s, mLastReportedConfiguration=%s", info.name,
+ Integer.toHexString(changes), Integer.toHexString(info.getRealConfigChanged()),
+ mLastReportedConfiguration);
if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
@@ -7118,20 +7103,20 @@
mRelaunchReason = RELAUNCH_REASON_NONE;
}
if (!attachedToProcess()) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Config is destroying non-running " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION,
+ "Config is destroying non-running %s", this);
destroyImmediately("config");
} else if (mState == PAUSING) {
// A little annoying: we are waiting for this activity to finish pausing. Let's not
// do anything now, but just flag that it needs to be restarted when done pausing.
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Config is skipping already pausing " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION,
+ "Config is skipping already pausing %s", this);
deferRelaunchUntilPaused = true;
preserveWindowOnDeferredRelaunch = preserveWindow;
return true;
} else {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Config is relaunching " + this);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Config is relaunching %s",
+ this);
if (DEBUG_STATES && !mVisibleRequested) {
Slog.v(TAG_STATES, "Config is relaunching invisible activity " + this
+ " called by " + Debug.getCallers(4));
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 4c93b9e..be7a6ae 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -56,12 +56,12 @@
import static android.os.Process.INVALID_UID;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
@@ -116,6 +116,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.power.ShutdownCheckPoints;
@@ -669,10 +670,8 @@
if (stack != null) {
stack.mConfigWillChange = globalConfigWillChange;
}
- if (DEBUG_CONFIGURATION) {
- Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
- + globalConfigWillChange);
- }
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
+ + "will change = %b", globalConfigWillChange);
final long origId = Binder.clearCallingIdentity();
@@ -695,10 +694,9 @@
if (stack != null) {
stack.mConfigWillChange = false;
}
- if (DEBUG_CONFIGURATION) {
- Slog.v(TAG_CONFIGURATION,
+ ProtoLog.v(WM_DEBUG_CONFIGURATION,
"Updating to new configuration after starting activity.");
- }
+
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
index da0bfd6..3c562a6 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
@@ -43,12 +43,6 @@
// Enable all debug log categories for activities.
private static final boolean DEBUG_ALL_ACTIVITIES = DEBUG_ALL || false;
- static final boolean DEBUG_ADD_REMOVE = DEBUG_ALL_ACTIVITIES || false;
- public static final boolean DEBUG_CONFIGURATION = DEBUG_ALL || false;
- static final boolean DEBUG_CONTAINERS = DEBUG_ALL_ACTIVITIES || false;
- static final boolean DEBUG_FOCUS = false;
- static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
- static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2adaa52..6a8cbfb 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -66,6 +66,10 @@
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.TRANSIT_NONE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IMMERSIVE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
import static com.android.server.am.ActivityManagerService.MY_PID;
import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
@@ -92,10 +96,6 @@
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
@@ -242,6 +242,7 @@
import com.android.internal.os.TransferPipe;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
@@ -813,7 +814,7 @@
// in-place.
updateConfigurationLocked(configuration, null, true);
final Configuration globalConfig = getGlobalConfiguration();
- if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Initial config: %s", globalConfig);
// Load resources only after the current configuration has been set.
final Resources res = mContext.getResources();
@@ -1960,7 +1961,7 @@
// update associated state if we're frontmost
if (r.isFocusedActivityOnDisplay()) {
- if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
+ ProtoLog.d(WM_DEBUG_IMMERSIVE, "Frontmost changed immersion: %s", r);
applyUpdateLockStateLocked(r);
}
}
@@ -1974,8 +1975,8 @@
final boolean nextState = r != null && r.immersive;
mH.post(() -> {
if (mUpdateLock.isHeld() != nextState) {
- if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
- "Applying new update lock state '" + nextState + "' for " + r);
+ ProtoLog.d(WM_DEBUG_IMMERSIVE, "Applying new update lock state '%s' for %s",
+ nextState, r);
if (nextState) {
mUpdateLock.acquire();
} else {
@@ -2176,7 +2177,7 @@
@Override
public void setFocusedStack(int stackId) {
mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
- if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
+ ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedStack: stackId=%d", stackId);
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -2198,7 +2199,7 @@
@Override
public void setFocusedTask(int taskId) {
mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
- if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
+ ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedTask: taskId=%d", taskId);
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -3013,7 +3014,7 @@
}
private void startLockTaskModeLocked(@Nullable Task task, boolean isSystemCaller) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
+ ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskModeLocked: %s", task);
if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
return;
}
@@ -3075,8 +3076,7 @@
"updateLockTaskPackages()");
}
synchronized (mGlobalLock) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowlisting " + userId + ":"
- + Arrays.toString(packages));
+ ProtoLog.w(WM_DEBUG_LOCKTASK, "Allowlisting %d:%s", userId, Arrays.toString(packages));
getLockTaskController().updateLockTaskPackages(userId, packages);
}
}
@@ -4001,9 +4001,9 @@
@Override
public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
- if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
- + Arrays.toString(horizontalSizeConfiguration) + " "
- + Arrays.toString(verticalSizeConfigurations));
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Report configuration: %s %s %s",
+ token, Arrays.toString(horizontalSizeConfiguration),
+ Arrays.toString(verticalSizeConfigurations));
synchronized (mGlobalLock) {
ActivityRecord record = ActivityRecord.isInStackLocked(token);
if (record == null) {
@@ -4497,8 +4497,8 @@
"updateLockTaskFeatures()");
}
synchronized (mGlobalLock) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
- Integer.toHexString(flags));
+ ProtoLog.w(WM_DEBUG_LOCKTASK, "Allowing features %d:0x%s",
+ userId, Integer.toHexString(flags));
getLockTaskController().updateLockTaskFeatures(userId, flags);
}
}
@@ -5183,8 +5183,8 @@
return 0;
}
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
- "Updating global configuration to: " + values);
+ ProtoLog.i(WM_DEBUG_CONFIGURATION, "Updating global configuration "
+ + "to: %s", values);
writeConfigurationChanged(changes);
FrameworkStatsLog.write(FrameworkStatsLog.RESOURCE_CONFIGURATION_CHANGED,
values.colorMode,
@@ -5262,10 +5262,8 @@
for (int i = pidMap.size() - 1; i >= 0; i--) {
final int pid = pidMap.keyAt(i);
final WindowProcessController app = pidMap.get(pid);
- if (DEBUG_CONFIGURATION) {
- Slog.v(TAG_CONFIGURATION, "Update process config of "
- + app.mName + " to new config " + configCopy);
- }
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Update process config of %s to new "
+ + "config %s", app.mName, configCopy);
app.onConfigurationChanged(configCopy);
}
@@ -6563,10 +6561,8 @@
if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) return;
if (pid == MY_PID || pid < 0) {
- if (DEBUG_CONFIGURATION) {
- Slog.w(TAG,
+ ProtoLog.w(WM_DEBUG_CONFIGURATION,
"Trying to update display configuration for system/invalid process.");
- }
return;
}
synchronized (mGlobalLock) {
@@ -6574,18 +6570,14 @@
mRootWindowContainer.getDisplayContent(displayId);
if (displayContent == null) {
// Call might come when display is not yet added or has been removed.
- if (DEBUG_CONFIGURATION) {
- Slog.w(TAG, "Trying to update display configuration for non-existing "
- + "displayId=" + displayId);
- }
+ ProtoLog.w(WM_DEBUG_CONFIGURATION, "Trying to update display "
+ + "configuration for non-existing displayId=%d", displayId);
return;
}
final WindowProcessController process = mProcessMap.getProcess(pid);
if (process == null) {
- if (DEBUG_CONFIGURATION) {
- Slog.w(TAG, "Trying to update display configuration for invalid "
- + "process, pid=" + pid);
- }
+ ProtoLog.w(WM_DEBUG_CONFIGURATION, "Trying to update display "
+ + "configuration for invalid process, pid=%d", pid);
return;
}
process.registerDisplayConfigurationListener(displayContent);
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index c144755..8568d5f 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -222,12 +222,12 @@
}
protected boolean skipAnimation() {
- return !mWin.isDrawnLw();
+ return !mWin.isDrawn();
}
private @StatusBarManager.WindowVisibleState int computeStateLw(
boolean wasVis, boolean wasAnim, WindowState win, boolean change) {
- if (win.isDrawnLw()) {
+ if (win.isDrawn()) {
final boolean vis = win.isVisibleLw();
final boolean anim = win.isAnimatingLw();
if (mState == StatusBarManager.WINDOW_STATE_HIDING && !change && !vis) {
@@ -264,7 +264,7 @@
}
boolean checkHiddenLw() {
- if (mWin != null && mWin.isDrawnLw()) {
+ if (mWin != null && mWin.isDrawn()) {
if (!mWin.isVisibleLw() && !mWin.isAnimatingLw()) {
updateStateLw(StatusBarManager.WINDOW_STATE_HIDDEN);
}
@@ -291,7 +291,7 @@
} else if (mWin == null) {
if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar doesn't exist");
return false;
- } else if (mWin.isDisplayedLw()) {
+ } else if (mWin.isDisplayed()) {
if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar already visible");
return false;
} else {
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 167afab..7e55f0a 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -37,6 +37,7 @@
import android.util.SparseArray;
import android.util.Xml;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.FastXmlSerializer;
import org.xmlpull.v1.XmlPullParser;
@@ -333,8 +334,8 @@
}
try {
if (app.hasThread()) {
- if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
- + app.mName + " new compat " + ci);
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s "
+ + "new compat %s", app.mName, ci);
app.getThread().updatePackageCompatibilityInfo(packageName, ci);
}
} catch (Exception e) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0215ead..2f7cc69 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -694,7 +694,7 @@
// Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
// wasting time and funky changes while a window is animating away.
final boolean gone = (mTmpWindow != null && mWmService.mPolicy.canBeHiddenByKeyguardLw(w))
- || w.isGoneForLayoutLw();
+ || w.isGoneForLayout();
if (DEBUG_LAYOUT && !w.mLayoutAttached) {
Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame
@@ -742,7 +742,7 @@
if (firstLayout) {
// The client may compute its actual requested size according to the first layout,
// so we still request the window to resize if the current frame is empty.
- if (!w.getFrameLw().isEmpty()) {
+ if (!w.getFrame().isEmpty()) {
w.updateLastFrames();
}
w.updateLastInsetValues();
@@ -753,9 +753,9 @@
w.mActivityRecord.layoutLetterbox(w);
}
- if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw()
+ if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrame()
+ " mContainingFrame=" + w.getContainingFrame()
- + " mDisplayFrame=" + w.getDisplayFrameLw());
+ + " mDisplayFrame=" + w.getDisplayFrame());
}
};
@@ -780,9 +780,9 @@
w.prelayout();
getDisplayPolicy().layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
w.mLayoutSeq = mLayoutSeq;
- if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw()
+ if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrame()
+ " mContainingFrame=" + w.getContainingFrame()
- + " mDisplayFrame=" + w.getDisplayFrameLw());
+ + " mDisplayFrame=" + w.getDisplayFrame());
}
}
};
@@ -807,7 +807,7 @@
w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;
if (!mTmpApplySurfaceChangesTransactionState.obscured) {
- final boolean isDisplayed = w.isDisplayedLw();
+ final boolean isDisplayed = w.isDisplayed();
if (isDisplayed && w.isObscuringDisplay()) {
// This window completely covers everything behind it, so we want to leave all
@@ -2549,7 +2549,7 @@
return;
}
- if (w.isOnScreen() && w.isVisibleLw() && w.getFrameLw().contains(x, y)) {
+ if (w.isOnScreen() && w.isVisibleLw() && w.getFrame().contains(x, y)) {
targetWindowType[0] = w.mAttrs.type;
return;
}
@@ -2747,7 +2747,7 @@
void adjustForImeIfNeeded() {
final WindowState imeWin = mInputMethodWindow;
final boolean imeVisible = imeWin != null && imeWin.isVisibleLw()
- && imeWin.isDisplayedLw();
+ && imeWin.isDisplayed();
final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
}
@@ -3364,7 +3364,7 @@
// Now, a special case -- if the last target's window is in the process of exiting, but
// not removed, keep on the last target to avoid IME flicker. The exception is if the
// current target is home since we want opening apps to become the IME target right away.
- if (curTarget != null && !curTarget.mRemoved && curTarget.isDisplayedLw()
+ if (curTarget != null && !curTarget.mRemoved && curTarget.isDisplayed()
&& curTarget.isClosing() && !curTarget.isActivityTypeHome()) {
if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Not changing target till current window is"
+ " closing and not removed");
@@ -3647,7 +3647,7 @@
final WindowState visibleNotDrawnWindow = getWindow(w -> {
final boolean isVisible = w.isVisible() && !w.mObscured;
- final boolean isDrawn = w.isDrawnLw();
+ final boolean isDrawn = w.isDrawn();
if (isVisible && !isDrawn) {
ProtoLog.d(WM_DEBUG_BOOT,
"DisplayContent: boot is waiting for window of type %d to be drawn",
@@ -4599,9 +4599,9 @@
DisplayContent dc = this;
do {
final WindowState displayParent = dc.getParentWindow();
- location.x += displayParent.getFrameLw().left
+ location.x += displayParent.getFrame().left
+ (dc.getLocationInParentWindow().x * displayParent.mGlobalScale + 0.5f);
- location.y += displayParent.getFrameLw().top
+ location.y += displayParent.getFrame().top
+ (dc.getLocationInParentWindow().y * displayParent.mGlobalScale + 0.5f);
dc = displayParent.getDisplayContent();
} while (dc != null && dc.getParentWindow() != null);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 40fc25b..1c147c2 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -195,13 +195,13 @@
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy;
-import com.android.server.policy.WindowManagerPolicy.InputConsumer;
import com.android.server.policy.WindowManagerPolicy.NavigationBarPosition;
import com.android.server.policy.WindowManagerPolicy.ScreenOnListener;
import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
import com.android.server.policy.WindowOrientationListener;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wallpaper.WallpaperManagerInternal;
+import com.android.server.wm.InputMonitor.EventReceiverInputConsumer;
import com.android.server.wm.utils.InsetUtils;
import java.io.PrintWriter;
@@ -416,7 +416,7 @@
private boolean mAllowLockscreenWhenOn;
@VisibleForTesting
- InputConsumer mInputConsumer = null;
+ EventReceiverInputConsumer mInputConsumer;
private PointerLocationView mPointerLocationView;
@@ -462,7 +462,7 @@
}
break;
case MSG_DISPOSE_INPUT_CONSUMER:
- disposeInputConsumer((InputConsumer) msg.obj);
+ disposeInputConsumer((EventReceiverInputConsumer) msg.obj);
break;
case MSG_ENABLE_POINTER_LOCATION:
enablePointerLocation();
@@ -1126,7 +1126,7 @@
// For IME we use regular frame.
(displayFrames, windowState, inOutFrame) ->
- inOutFrame.set(windowState.getFrameLw()));
+ inOutFrame.set(windowState.getFrame()));
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_GESTURES, win,
(displayFrames, windowState, inOutFrame) -> {
@@ -1203,11 +1203,11 @@
// IME should not provide frame which is smaller than the nav bar frame. Otherwise,
// nav bar might be overlapped with the content of the client when IME is shown.
sTmpRect.set(inOutFrame);
- sTmpRect.intersectUnchecked(mNavigationBar.getFrameLw());
- inOutFrame.inset(windowState.getGivenContentInsetsLw());
+ sTmpRect.intersectUnchecked(mNavigationBar.getFrame());
+ inOutFrame.inset(windowState.mGivenContentInsets);
inOutFrame.union(sTmpRect);
} else {
- inOutFrame.inset(windowState.getGivenContentInsetsLw());
+ inOutFrame.inset(windowState.mGivenContentInsets);
}
};
}
@@ -2075,7 +2075,7 @@
// In case we forced the window to draw behind the navigation bar, restrict df to
// DF.Restricted to simulate old compat behavior.
- Rect parentDisplayFrame = attached.getDisplayFrameLw();
+ Rect parentDisplayFrame = attached.getDisplayFrame();
final WindowManager.LayoutParams attachedAttrs = attached.mAttrs;
if ((attachedAttrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0
&& (attachedAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
@@ -2096,14 +2096,14 @@
// setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag.
// Otherwise, use the overscan frame.
cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0
- ? attached.getContentFrameLw() : parentDisplayFrame);
+ ? attached.getContentFrame() : parentDisplayFrame);
} else {
// If the window is resizing, then we want to base the content frame on our attached
// content frame to resize...however, things can be tricky if the attached window is
// NOT in resize mode, in which case its content frame will be larger.
// Ungh. So to deal with that, make sure the content frame we end up using is not
// covering the IM dock.
- cf.set(attached.getContentFrameLw());
+ cf.set(attached.getContentFrame());
if (attached.isVoiceInteraction()) {
cf.intersectUnchecked(displayFrames.mVoiceContent);
} else if (win.isInputMethodTarget() || attached.isInputMethodTarget()) {
@@ -2111,11 +2111,11 @@
}
}
df.set(insetDecors ? parentDisplayFrame : cf);
- vf.set(attached.getVisibleFrameLw());
+ vf.set(attached.getVisibleFrame());
}
// The LAYOUT_IN_SCREEN flag is used to determine whether the attached window should be
// positioned relative to its parent or the entire screen.
- pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrameLw() : df);
+ pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrame() : df);
}
private void applyStableConstraints(int sysui, int fl, Rect r, DisplayFrames displayFrames) {
@@ -2217,8 +2217,8 @@
vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING
? displayFrames.mCurrent : displayFrames.mDock);
} else {
- pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrameLw() : df);
- vf.set(attached.getVisibleFrameLw());
+ pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrame() : df);
+ vf.set(attached.getVisibleFrame());
}
cf.set(adjust != SOFT_INPUT_ADJUST_RESIZE
? displayFrames.mDock : displayFrames.mContent);
@@ -2623,12 +2623,10 @@
win.computeFrame(displayFrames);
// Dock windows carve out the bottom of the screen, so normal windows
// can't appear underneath them.
- if (type == TYPE_INPUT_METHOD && win.isVisibleLw()
- && !win.getGivenInsetsPendingLw()) {
+ if (type == TYPE_INPUT_METHOD && win.isVisibleLw() && !win.mGivenInsetsPending) {
offsetInputMethodWindowLw(win, displayFrames);
}
- if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw()
- && !win.getGivenInsetsPendingLw()) {
+ if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw() && !win.mGivenInsetsPending) {
offsetVoiceInputWindowLw(win, displayFrames);
}
}
@@ -2645,8 +2643,8 @@
final int navBarPosition = navigationBarPosition(displayFrames.mDisplayWidth,
displayFrames.mDisplayHeight, rotation);
- int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
- top += win.getGivenContentInsetsLw().top;
+ int top = Math.max(win.getDisplayFrame().top, win.getContentFrame().top);
+ top += win.mGivenContentInsets.top;
displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom, top);
if (navBarPosition == NAV_BAR_BOTTOM) {
// Always account for the nav bar frame height on the bottom since in all navigation
@@ -2658,8 +2656,8 @@
displayFrames.mUnrestricted.bottom - navFrameHeight);
}
displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
- top = win.getVisibleFrameLw().top;
- top += win.getGivenVisibleInsetsLw().top;
+ top = win.getVisibleFrame().top;
+ top += win.mGivenVisibleInsets.top;
displayFrames.mCurrent.bottom = Math.min(displayFrames.mCurrent.bottom, top);
if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom="
+ displayFrames.mDock.bottom + " mContentBottom="
@@ -2667,8 +2665,8 @@
}
private void offsetVoiceInputWindowLw(WindowState win, DisplayFrames displayFrames) {
- int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
- top += win.getGivenContentInsetsLw().top;
+ int top = Math.max(win.getDisplayFrame().top, win.getContentFrame().top);
+ top += win.mGivenContentInsets.top;
displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
}
@@ -2729,8 +2727,7 @@
if (win.isDreamWindow()) {
// If the lockscreen was showing when the dream started then wait
// for the dream to draw before hiding the lockscreen.
- if (!mDreamingLockscreen
- || (win.isVisibleLw() && win.hasDrawnLw())) {
+ if (!mDreamingLockscreen || (win.isVisibleLw() && win.hasDrawn())) {
mShowingDream = true;
appWindow = true;
}
@@ -2916,7 +2913,7 @@
final InsetsSource request = mTopFullscreenOpaqueWindowState.getRequestedInsetsState()
.peekSource(ITYPE_STATUS_BAR);
if (WindowManagerDebugConfig.DEBUG) {
- Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw());
+ Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrame());
Slog.d(TAG, "attr: " + attrs + " request: " + request);
}
return (fl & LayoutParams.FLAG_FULLSCREEN) != 0
@@ -3398,7 +3395,7 @@
mImmersiveModeConfirmation.confirmCurrentPrompt();
}
- private void disposeInputConsumer(InputConsumer inputConsumer) {
+ private void disposeInputConsumer(EventReceiverInputConsumer inputConsumer) {
if (inputConsumer != null) {
inputConsumer.dispose();
}
@@ -4171,6 +4168,6 @@
return false;
}
- return Rect.intersects(targetWindow.getFrameLw(), navBarWindow.getFrameLw());
+ return Rect.intersects(targetWindow.getFrame(), navBarWindow.getFrame());
}
}
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 86e2698..f0f3385 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -93,7 +93,7 @@
|| (mImeTargetFromIme != null
&& isImeTargetFromDisplayContentAndImeSame()
&& mWin != null
- && mWin.isDrawnLw()
+ && mWin.isDrawn()
&& !mWin.mGivenInsetsPending)) {
mIsImeLayoutDrawn = true;
// show IME if InputMethodService requested it to be shown.
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 16c4942..fb511e0 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -61,7 +61,6 @@
import android.view.SurfaceControl;
import com.android.internal.protolog.common.ProtoLog;
-import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
import java.util.Set;
@@ -95,8 +94,11 @@
*/
private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();
- private static final class EventReceiverInputConsumer extends InputConsumerImpl
- implements WindowManagerPolicy.InputConsumer {
+ /**
+ * Representation of a input consumer that the policy has added to the window manager to consume
+ * input events going to windows below it.
+ */
+ static final class EventReceiverInputConsumer extends InputConsumerImpl {
private InputMonitor mInputMonitor;
private final InputEventReceiver mInputEventReceiver;
@@ -111,8 +113,8 @@
mClientChannel, looper);
}
- @Override
- public void dismiss() {
+ /** Removes the input consumer from the window manager. */
+ void dismiss() {
synchronized (mService.mGlobalLock) {
mInputMonitor.mInputConsumers.remove(mName);
hide(mInputMonitor.mInputTransaction);
@@ -120,8 +122,8 @@
}
}
- @Override
- public void dispose() {
+ /** Disposes the input consumer and input receiver from the associated thread. */
+ void dispose() {
synchronized (mService.mGlobalLock) {
disposeChannelsLw(mInputMonitor.mInputTransaction);
mInputEventReceiver.dispose();
@@ -225,7 +227,7 @@
}
}
- WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
+ EventReceiverInputConsumer createInputConsumer(Looper looper, String name,
InputEventReceiver.Factory inputEventReceiverFactory) {
if (!name.contentEquals(INPUT_CONSUMER_NAVIGATION)) {
throw new IllegalArgumentException("Illegal input consumer : " + name
@@ -289,7 +291,7 @@
inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
inputWindowHandle.displayId = child.getDisplayId();
- final Rect frame = child.getFrameLw();
+ final Rect frame = child.getFrame();
inputWindowHandle.frameLeft = frame.left;
inputWindowHandle.frameTop = frame.top;
inputWindowHandle.frameRight = frame.right;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index d1eb795..e00c9e7 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -173,7 +173,7 @@
// frame may not yet determined that server side doesn't think the window is ready to
// visible. (i.e. No surface, pending insets that were given during layout, etc..)
if (mServerVisible) {
- mTmpRect.set(mWin.getFrameLw());
+ mTmpRect.set(mWin.getFrame());
if (mFrameProvider != null) {
mFrameProvider.accept(mWin.getDisplayContent().mDisplayFrames, mWin, mTmpRect);
} else {
@@ -185,14 +185,14 @@
mSource.setFrame(mTmpRect);
if (mImeFrameProvider != null) {
- mImeOverrideFrame.set(mWin.getFrameLw());
+ mImeOverrideFrame.set(mWin.getFrame());
mImeFrameProvider.accept(mWin.getDisplayContent().mDisplayFrames, mWin,
mImeOverrideFrame);
}
if (mWin.mGivenVisibleInsets.left != 0 || mWin.mGivenVisibleInsets.top != 0
|| mWin.mGivenVisibleInsets.right != 0 || mWin.mGivenVisibleInsets.bottom != 0) {
- mTmpRect.set(mWin.getFrameLw());
+ mTmpRect.set(mWin.getFrame());
mTmpRect.inset(mWin.mGivenVisibleInsets);
mSource.setVisibleFrame(mTmpRect);
} else {
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 8ef57f7..c8d7693 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -29,7 +29,7 @@
import static android.os.UserHandle.USER_CURRENT;
import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -65,6 +65,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
@@ -448,7 +449,7 @@
* unlike {@link #stopLockTaskMode(Task, boolean, int)}, it doesn't perform the checks.
*/
void clearLockedTasks(String reason) {
- if (DEBUG_LOCKTASK) Slog.i(TAG_LOCKTASK, "clearLockedTasks: " + reason);
+ ProtoLog.i(WM_DEBUG_LOCKTASK, "clearLockedTasks: %s", reason);
if (!mLockTaskModeTasks.isEmpty()) {
clearLockedTask(mLockTaskModeTasks.get(0));
}
@@ -490,10 +491,10 @@
if (!mLockTaskModeTasks.remove(task)) {
return;
}
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: removed " + task);
+ ProtoLog.d(WM_DEBUG_LOCKTASK, "removeLockedTask: removed %s", task);
if (mLockTaskModeTasks.isEmpty()) {
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
- " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
+ ProtoLog.d(WM_DEBUG_LOCKTASK, "removeLockedTask: task=%s last task, "
+ + "reverting locktask mode. Callers=%s", task, Debug.getCallers(3));
mHandler.post(() -> performStopLockTask(task.mUserId));
}
}
@@ -558,7 +559,7 @@
if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
// startLockTask() called by app, but app is not part of lock task allowlist. Show
// app pinning request. We will come back here with isSystemCaller true.
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
+ ProtoLog.w(WM_DEBUG_LOCKTASK, "Mode default, asking user");
StatusBarManagerInternal statusBarManager = LocalServices.getService(
StatusBarManagerInternal.class);
if (statusBarManager != null) {
@@ -569,8 +570,7 @@
}
// System can only initiate screen pinning, not full lock task mode
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
- isSystemCaller ? "Locking pinned" : "Locking fully");
+ ProtoLog.w(WM_DEBUG_LOCKTASK, "%s", isSystemCaller ? "Locking pinned" : "Locking fully");
setLockTaskMode(task, isSystemCaller ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED,
"startLockTask", true);
}
@@ -584,7 +584,7 @@
String reason, boolean andResume) {
// Should have already been checked, but do it again.
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ ProtoLog.w(WM_DEBUG_LOCKTASK,
"setLockTaskMode: Can't lock due to auth");
return;
}
@@ -602,8 +602,8 @@
task.mUserId,
lockTaskModeState));
}
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskMode: Locking to " + task +
- " Callers=" + Debug.getCallers(4));
+ ProtoLog.w(WM_DEBUG_LOCKTASK, "setLockTaskMode: Locking to %s Callers=%s",
+ task, Debug.getCallers(4));
if (!mLockTaskModeTasks.contains(task)) {
mLockTaskModeTasks.add(task);
@@ -672,8 +672,8 @@
}
// Terminate locked tasks that have recently lost allowlist authorization.
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
- lockedTask + " mLockTaskAuth()=" + lockedTask.lockTaskAuthToString());
+ ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: removing %s"
+ + " mLockTaskAuth()=%s", lockedTask, lockedTask.lockTaskAuthToString());
removeLockedTask(lockedTask);
lockedTask.performClearTaskLocked();
taskChanged = true;
@@ -686,8 +686,8 @@
if (mLockTaskModeTasks.isEmpty() && task!= null
&& task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
// This task must have just been authorized.
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
- "onLockTaskPackagesUpdated: starting new locktask task=" + task);
+ ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: starting new "
+ + "locktask task=%s", task);
setLockTaskMode(task, LOCK_TASK_MODE_LOCKED, "package updated", false);
taskChanged = true;
}
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index cc5ed36..c3953b4 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -16,9 +16,8 @@
package com.android.server.wm;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.wm.Task.TAG_ADD_REMOVE;
import static com.android.server.wm.Task.TAG_TASKS;
import android.app.ActivityOptions;
@@ -27,6 +26,7 @@
import android.os.Debug;
import android.util.Slog;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -218,8 +218,8 @@
if (takeOptions) {
noOptions = takeOption(p, noOptions);
}
- if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, "Removing activity " + p + " from task="
- + mTask + " adding to task=" + targetTask + " Callers=" + Debug.getCallers(4));
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing activity %s from task=%s "
+ + "adding to task=%s Callers=%s", p, mTask, targetTask, Debug.getCallers(4));
if (DEBUG_TASKS) Slog.v(TAG_TASKS,
"Pushing next activity " + p + " out to target's task " + target);
p.reparent(targetTask, position, "resetTargetTaskIfNeeded");
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 6dfbd21..21e30ce 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1106,14 +1106,14 @@
final WindowManager.LayoutParams attrs = w.mAttrs;
final int attrFlags = attrs.flags;
final boolean onScreen = w.isOnScreen();
- final boolean canBeSeen = w.isDisplayedLw();
+ final boolean canBeSeen = w.isDisplayed();
final int privateflags = attrs.privateFlags;
boolean displayHasContent = false;
ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
"handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w"
+ ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
- w, w.mHasSurface, onScreen, w.isDisplayedLw(), w.mAttrs.userActivityTimeout);
+ w, w.mHasSurface, onScreen, w.isDisplayed(), w.mAttrs.userActivityTimeout);
if (w.mHasSurface && onScreen) {
if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
mUserActivityTimeout = w.mAttrs.userActivityTimeout;
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 6cf9432..7b5b0ad 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -99,9 +99,8 @@
// the task's profile
return;
}
- if (!mAllowed && !task.isActivityTypeHome()) {
- // Skip if the caller isn't allowed to fetch this task, except for the home
- // task which we always return.
+ if (!mAllowed) {
+ // Skip if the caller isn't allowed to fetch this task
return;
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e77a535..19bf451 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -79,6 +79,7 @@
import static com.android.internal.policy.DecorView.DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP;
import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
@@ -87,9 +88,7 @@
import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
@@ -1651,8 +1650,8 @@
* Reorder the history stack so that the passed activity is brought to the front.
*/
final void moveActivityToFrontLocked(ActivityRecord newTop) {
- if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, "Removing and adding activity "
- + newTop + " to stack at top callers=" + Debug.getCallers(4));
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing and adding activity %s to stack at top "
+ + "callers=%s", newTop, Debug.getCallers(4));
positionChildAtTop(newTop);
updateEffectiveIntent();
@@ -1951,8 +1950,8 @@
? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
break;
}
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this
- + " mLockTaskAuth=" + lockTaskAuthToString());
+ ProtoLog.d(WM_DEBUG_LOCKTASK, "setLockTaskAuth: task=%s mLockTaskAuth=%s", this,
+ lockTaskAuthToString());
}
@Override
@@ -6370,7 +6369,8 @@
// Here it is! Now, if this is not yet visible (occluded by another task) to the
// user, then just add it without starting; it will get started when the user
// navigates back to it.
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task,
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s "
+ + "callers: %s", r, task,
new RuntimeException("here").fillInStackTrace());
rTask.positionChildAtTop(r);
ActivityOptions.abort(options);
@@ -6392,8 +6392,8 @@
task = activityTask;
// Slot the activity into the history stack and proceed
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
- new RuntimeException("here").fillInStackTrace());
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to stack to task %s "
+ + "callers: %s", r, task, new RuntimeException("here").fillInStackTrace());
task.positionChildAtTop(r);
// The transition animation and starting window are not needed if {@code allowMoveToFront}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index dbbb7ff..e3112ef 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -483,7 +483,7 @@
final InsetsState insetsState =
new InsetsState(insetsPolicy.getInsetsForDispatch(mainWindow));
mergeInsetsSources(insetsState, mainWindow.getRequestedInsetsState());
- final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrameLw(), insetsState);
+ final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState);
final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription(),
mHighResTaskSnapshotScale, insetsState);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 6e00ab4..ce13867 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -308,7 +308,7 @@
float defaultWallpaperX = wallpaperWin.isRtl() ? 1f : 0f;
float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : defaultWallpaperX;
float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
- int availw = wallpaperWin.getFrameLw().right - wallpaperWin.getFrameLw().left - dw;
+ int availw = wallpaperWin.getFrame().right - wallpaperWin.getFrame().left - dw;
int offset = availw > 0 ? -(int)(availw * wpx + .5f) : 0;
if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
offset += mLastWallpaperDisplayOffsetX;
@@ -323,7 +323,7 @@
float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
- int availh = wallpaperWin.getFrameLw().bottom - wallpaperWin.getFrameLw().top - dh;
+ int availh = wallpaperWin.getFrame().bottom - wallpaperWin.getFrame().top - dh;
offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0;
if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
offset += mLastWallpaperDisplayOffsetY;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2ce16b2..c45ccb6 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1848,7 +1848,7 @@
}
// We use the visible frame, because we want the animation to morph the window from what
// was visible to the user to the final destination of the new window.
- Rect frame = replacedWindow.getVisibleFrameLw();
+ Rect frame = replacedWindow.getVisibleFrame();
// We treat this as if this activity was opening, so we can trigger the app transition
// animation and piggy-back on existing transition animation infrastructure.
final DisplayContent dc = activity.getDisplayContent();
@@ -2069,7 +2069,7 @@
outDisplayFrame.setEmpty();
return;
}
- outDisplayFrame.set(win.getDisplayFrameLw());
+ outDisplayFrame.set(win.getDisplayFrame());
if (win.inSizeCompatMode()) {
outDisplayFrame.scale(win.mInvGlobalScale);
}
@@ -2389,7 +2389,7 @@
if (displayPolicy.areSystemBarsForcedShownLw(win)) {
result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
}
- if (!win.isGoneForLayoutLw()) {
+ if (!win.isGoneForLayout()) {
win.mResizedWhileGone = false;
}
@@ -2419,7 +2419,7 @@
win.getInsetsForRelayout(outContentInsets, outVisibleInsets,
outStableInsets);
outCutout.set(win.getWmDisplayCutout().getDisplayCutout());
- outBackdropFrame.set(win.getBackdropFrame(win.getFrameLw()));
+ outBackdropFrame.set(win.getBackdropFrame(win.getFrame()));
outInsetsState.set(win.getInsetsState(), win.isClientLocal());
if (DEBUG) {
Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
@@ -2883,11 +2883,6 @@
}
@Override
- public WindowManagerPolicy.WindowState getInputMethodWindowLw() {
- return mRoot.getCurrentInputMethodWindow();
- }
-
- @Override
public void notifyKeyguardTrustedChanged() {
mAtmInternal.notifyKeyguardTrustedChanged();
}
@@ -5481,7 +5476,7 @@
// Window has been removed or hidden; no draw will now happen, so stop waiting.
ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win);
container.mWaitingForDrawn.remove(win);
- } else if (win.hasDrawnLw()) {
+ } else if (win.hasDrawn()) {
// Window is now drawn (and shown).
ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win);
container.mWaitingForDrawn.remove(win);
@@ -7356,7 +7351,7 @@
synchronized (mGlobalLock) {
WindowState windowState = mWindowMap.get(token);
if (windowState != null) {
- outBounds.set(windowState.getFrameLw());
+ outBounds.set(windowState.getFrame());
} else {
outBounds.setEmpty();
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index bb9cf2e..c5ebace 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -22,9 +22,9 @@
import static android.os.IInputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerService.MY_PID;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
@@ -72,6 +72,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.HeavyWeightSwitcherActivity;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.Watchdog;
import com.android.server.wm.ActivityTaskManagerService.HotPath;
@@ -1348,9 +1349,8 @@
}
return;
}
- if (DEBUG_CONFIGURATION) {
- Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName + " new config " + config);
- }
+ ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s new config %s", mName,
+ config);
if (Build.IS_DEBUGGABLE && mHasImeService) {
// TODO (b/135719017): Temporary log for debugging IME service.
Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 69d3821..9ff33b1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1009,8 +1009,8 @@
getDisplayContent().reapplyMagnificationSpec();
}
- @Override
- public int getOwningUid() {
+ /** Returns the uid of the app that owns this window. */
+ int getOwningUid() {
return mOwnerUid;
}
@@ -1024,8 +1024,12 @@
return mOwnerCanAddInternalSystemWindow;
}
- @Override
- public boolean canAcquireSleepToken() {
+ /**
+ * Returns {@code true} if the window owner has the permission to acquire a sleep token when
+ * it's visible. That is, they have the permission
+ * {@link androidManifest.permission#DEVICE_POWER}.
+ */
+ boolean canAcquireSleepToken() {
return mSession.mCanAcquireSleepToken;
}
@@ -1046,7 +1050,7 @@
void computeFrame(DisplayFrames displayFrames) {
getLayoutingWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout);
- computeFrameLw();
+ computeFrame();
// Update the source frame to provide insets to other windows during layout. If the
// simulated frames exist, then this is not computing a stable result so just skip.
if (mControllableInsetProvider != null && mSimulatedWindowFrames == null) {
@@ -1054,8 +1058,10 @@
}
}
- @Override
- public void computeFrameLw() {
+ /**
+ * Perform standard frame computation. The result can be obtained with getFrame() if so desired.
+ */
+ void computeFrame() {
if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
// This window is being replaced and either already got information that it's being
// removed or we are still waiting for some information. Because of this we don't
@@ -1283,32 +1289,41 @@
}
}
- @Override
- public Rect getFrameLw() {
+ /** Retrieves the current frame of the window that the application sees. */
+ Rect getFrame() {
return mWindowFrames.mFrame;
}
/** Accessor for testing */
- Rect getRelativeFrameLw() {
+ Rect getRelativeFrame() {
return mWindowFrames.mRelFrame;
}
- @Override
- public Rect getDisplayFrameLw() {
+ /** Retrieves the frame of the display that this window was last laid out in. */
+ Rect getDisplayFrame() {
return mWindowFrames.mDisplayFrame;
}
- @Override
- public Rect getContentFrameLw() {
+ /**
+ * Retrieves the frame of the content area that this window was last laid out in. This is the
+ * area in which the content of the window should be placed. It will be smaller than the display
+ * frame to account for screen decorations such as a status bar or soft keyboard.
+ */
+ Rect getContentFrame() {
return mWindowFrames.mContentFrame;
}
- @Override
- public Rect getVisibleFrameLw() {
+ /**
+ * Retrieves the frame of the visible area that this window was last laid out in. This is the
+ * area of the screen in which the window will actually be fully visible. It will be smaller
+ * than the content frame to account for transient UI elements blocking it such as an input
+ * method's candidates UI.
+ */
+ Rect getVisibleFrame() {
return mWindowFrames.mVisibleFrame;
}
- Rect getStableFrameLw() {
+ Rect getStableFrame() {
return mWindowFrames.mStableFrame;
}
@@ -1337,32 +1352,17 @@
}
@Override
- public boolean getGivenInsetsPendingLw() {
- return mGivenInsetsPending;
- }
-
- @Override
- public Rect getGivenContentInsetsLw() {
- return mGivenContentInsets;
- }
-
- @Override
- public Rect getGivenVisibleInsetsLw() {
- return mGivenVisibleInsets;
- }
-
- @Override
public WindowManager.LayoutParams getAttrs() {
return mAttrs;
}
- @Override
- public int getSystemUiVisibility() {
+ /** Retrieves the current system UI visibility flags associated with this window. */
+ int getSystemUiVisibility() {
return mSystemUiVisibility;
}
- @Override
- public int getSurfaceLayer() {
+ /** Gets the layer at which this window's surface will be Z-ordered. */
+ int getSurfaceLayer() {
return mLayer;
}
@@ -1376,8 +1376,8 @@
return mActivityRecord != null ? mActivityRecord.appToken : null;
}
- @Override
- public boolean isVoiceInteraction() {
+ /** Returns true if this window is participating in voice interaction. */
+ boolean isVoiceInteraction() {
return mActivityRecord != null && mActivityRecord.mVoiceInteraction;
}
@@ -1391,7 +1391,7 @@
*/
void updateResizingWindowIfNeeded() {
final WindowStateAnimator winAnimator = mWinAnimator;
- if (!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) {
+ if (!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayout()) {
return;
}
@@ -1464,7 +1464,7 @@
mWmService.mResizingWindows.add(this);
}
} else if (getOrientationChanging()) {
- if (isDrawnLw()) {
+ if (isDrawn()) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Orientation not waiting for draw in %s, surfaceController %s", this,
winAnimator.mSurfaceController);
@@ -1639,9 +1639,16 @@
: DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
}
- @Override
- public boolean hasAppShownWindows() {
- return mActivityRecord != null && (mActivityRecord.firstWindowDrawn || mActivityRecord.startingDisplayed);
+ /**
+ * Returns true if, at any point, the application token associated with this window has actually
+ * displayed any windows. This is most useful with the "starting up" window to determine if any
+ * windows were displayed when it is closed.
+ *
+ * @return {@code true} if one or more windows have been displayed, else false.
+ */
+ boolean hasAppShownWindows() {
+ return mActivityRecord != null
+ && (mActivityRecord.firstWindowDrawn || mActivityRecord.startingDisplayed);
}
boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
@@ -1663,7 +1670,7 @@
@Override
boolean hasContentToDisplay() {
- if (!mAppFreezing && isDrawnLw() && (mViewVisibility == View.VISIBLE
+ if (!mAppFreezing && isDrawn() && (mViewVisibility == View.VISIBLE
|| (isAnimating(TRANSITION | PARENTS)
&& !getDisplayContent().mAppTransition.isTransitionSet()))) {
return true;
@@ -1851,10 +1858,9 @@
* Like isOnScreen, but returns false if the surface hasn't yet
* been drawn.
*/
- @Override
- public boolean isDisplayedLw() {
+ boolean isDisplayed() {
final ActivityRecord atoken = mActivityRecord;
- return isDrawnLw() && isVisibleByPolicy()
+ return isDrawn() && isVisibleByPolicy()
&& ((!isParentWindowHidden() && (atoken == null || atoken.mVisibleRequested))
|| isAnimating(TRANSITION | PARENTS));
}
@@ -1867,8 +1873,8 @@
return isAnimating(TRANSITION | PARENTS);
}
- @Override
- public boolean isGoneForLayoutLw() {
+ /** Returns {@code true} if this window considered to be gone for purposes of layout. */
+ boolean isGoneForLayout() {
final ActivityRecord atoken = mActivityRecord;
return mViewVisibility == View.GONE
|| !mRelayoutCalled
@@ -1895,11 +1901,11 @@
}
/**
- * Returns true if the window has a surface that it has drawn a
- * complete UI in to.
+ * Returns true if the window has a surface that it has drawn a complete UI in to. Note that
+ * this is different from {@link #hasDrawn()} in that it also returns true if the window is
+ * READY_TO_SHOW, but was not yet promoted to HAS_DRAWN.
*/
- @Override
- public boolean isDrawnLw() {
+ boolean isDrawn() {
return mHasSurface && !mDestroying &&
(mWinAnimator.mDrawState == READY_TO_SHOW || mWinAnimator.mDrawState == HAS_DRAWN);
}
@@ -1914,7 +1920,7 @@
// to determine if it's occluding apps.
return ((!mIsWallpaper && mAttrs.format == PixelFormat.OPAQUE)
|| (mIsWallpaper && mWallpaperVisible))
- && isDrawnLw() && !isAnimating(TRANSITION | PARENTS);
+ && isDrawn() && !isAnimating(TRANSITION | PARENTS);
}
/** @see WindowManagerInternal#waitForAllWindowsDrawn */
@@ -1929,7 +1935,7 @@
return;
}
if (mAttrs.type == TYPE_APPLICATION_STARTING) {
- if (isDrawnLw()) {
+ if (isDrawn()) {
// Unnecessary to redraw a drawn starting window.
return;
}
@@ -2016,11 +2022,11 @@
@Override
void onResize() {
final ArrayList<WindowState> resizingWindows = mWmService.mResizingWindows;
- if (mHasSurface && !isGoneForLayoutLw() && !resizingWindows.contains(this)) {
+ if (mHasSurface && !isGoneForLayout() && !resizingWindows.contains(this)) {
ProtoLog.d(WM_DEBUG_RESIZE, "onResize: Resizing %s", this);
resizingWindows.add(this);
}
- if (isGoneForLayoutLw()) {
+ if (isGoneForLayout()) {
mResizedWhileGone = true;
}
@@ -2514,7 +2520,7 @@
/** Returns true if the replacement window was removed. */
boolean removeReplacedWindowIfNeeded(WindowState replacement) {
- if (mWillReplaceWindow && mReplacementWindow == replacement && replacement.hasDrawnLw()) {
+ if (mWillReplaceWindow && mReplacementWindow == replacement && replacement.hasDrawn()) {
replacement.mSkipEnterAnimationForSeamlessReplacement = false;
removeReplacedWindow();
return true;
@@ -2748,7 +2754,7 @@
mLayoutNeeded = true;
}
- if (isDrawnLw() && mToken.okToAnimate()) {
+ if (isDrawn() && mToken.okToAnimate()) {
mWinAnimator.applyEnterAnimationLocked();
}
}
@@ -2873,8 +2879,8 @@
return getWindowConfiguration().keepVisibleDeadAppWindowOnScreen();
}
- @Override
- public boolean canReceiveKeys() {
+ /** Returns {@code true} if this window desires key events. */
+ boolean canReceiveKeys() {
return canReceiveKeys(false /* fromUserTouch */);
}
@@ -2923,8 +2929,13 @@
&& recentsAnimationController.shouldApplyInputConsumer(mActivityRecord);
}
- @Override
- public boolean hasDrawnLw() {
+ /**
+ * Returns {@code true} if this window has been shown on screen at some time in the past.
+ *
+ * @deprecated Use {@link #isDrawnLw} or any of the other drawn/visibility methods.
+ */
+ @Deprecated
+ boolean hasDrawn() {
return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN;
}
@@ -3158,8 +3169,8 @@
}
}
- @Override
- public boolean isAlive() {
+ /** Checks whether the process hosting this window is currently alive. */
+ boolean isAlive() {
return mClient.asBinder().isBinderAlive();
}
@@ -3339,16 +3350,6 @@
mLastExclusionLogUptimeMillis[EXCLUSION_RIGHT] = now;
}
- @Override
- public boolean isDefaultDisplay() {
- final DisplayContent displayContent = getDisplayContent();
- if (displayContent == null) {
- // Only a window that was on a non-default display can be detached from it.
- return false;
- }
- return displayContent.isDefaultDisplay;
- }
-
/** @return {@code true} if this window can be shown to all users. */
boolean showForAllUsers() {
@@ -3408,10 +3409,10 @@
// All window frames that are fullscreen extend above status bar, but some don't extend
// below navigation bar. Thus, check for display frame for top/left and stable frame for
// bottom right.
- if (win.getFrameLw().left <= win.getDisplayFrameLw().left
- && win.getFrameLw().top <= win.getDisplayFrameLw().top
- && win.getFrameLw().right >= win.getStableFrameLw().right
- && win.getFrameLw().bottom >= win.getStableFrameLw().bottom) {
+ if (win.getFrame().left <= win.getDisplayFrame().left
+ && win.getFrame().top <= win.getDisplayFrame().top
+ && win.getFrame().right >= win.getStableFrame().right
+ && win.getFrame().bottom >= win.getStableFrame().bottom) {
// Is a fullscreen window, like the clock alarm. Show to everyone.
return true;
}
@@ -3781,11 +3782,11 @@
* is transitioning into/out-of fullscreen. */
boolean isLetterboxedAppWindow() {
return !inMultiWindowMode() && !matchesDisplayBounds()
- || isLetterboxedForDisplayCutoutLw();
+ || isLetterboxedForDisplayCutout();
}
- @Override
- public boolean isLetterboxedForDisplayCutoutLw() {
+ /** Returns {@code true} if the window is letterboxed for the display cutout. */
+ boolean isLetterboxedForDisplayCutout() {
if (mActivityRecord == null) {
// Only windows with an ActivityRecord are letterboxed.
return false;
@@ -3889,7 +3890,7 @@
// background.
return (getDisplayContent().mDividerControllerLocked.isResizing()
|| mActivityRecord != null && !mActivityRecord.mFrozenBounds.isEmpty()) &&
- !task.inFreeformWindowingMode() && !isGoneForLayoutLw();
+ !task.inFreeformWindowingMode() && !isGoneForLayout();
}
@@ -4305,7 +4306,7 @@
private boolean isParentWindowGoneForLayout() {
final WindowState parent = getParentWindow();
- return parent != null && parent.isGoneForLayoutLw();
+ return parent != null && parent.isGoneForLayout();
}
void setWillReplaceWindow(boolean animate) {
@@ -4418,8 +4419,7 @@
return null;
}
- @Override
- public int getRotationAnimationHint() {
+ int getRotationAnimationHint() {
if (mActivityRecord != null) {
return mActivityRecord.mRotationAnimationHint;
} else {
@@ -4875,7 +4875,7 @@
}
boolean hasVisibleNotDrawnWallpaper() {
- if (mWallpaperVisible && !isDrawnLw()) {
+ if (mWallpaperVisible && !isDrawn()) {
return true;
}
for (int j = mChildren.size() - 1; j >= 0; --j) {
@@ -4899,9 +4899,9 @@
return;
}
if (DEBUG_VISIBILITY) {
- Slog.v(TAG, "Win " + this + ": isDrawn=" + isDrawnLw()
+ Slog.v(TAG, "Win " + this + ": isDrawn=" + isDrawn()
+ ", animating=" + isAnimating(TRANSITION | PARENTS));
- if (!isDrawnLw()) {
+ if (!isDrawn()) {
Slog.v(TAG, "Not displayed: s=" + mWinAnimator.mSurfaceController
+ " pv=" + isVisibleByPolicy()
+ " mDrawState=" + mWinAnimator.mDrawState
@@ -4912,7 +4912,7 @@
}
results.numInteresting++;
- if (isDrawnLw()) {
+ if (isDrawn()) {
results.numDrawn++;
if (!isAnimating(TRANSITION | PARENTS)) {
results.numVisible++;
@@ -5048,7 +5048,7 @@
int relayoutVisibleWindow(int result, int attrChanges) {
final boolean wasVisible = isVisibleLw();
- result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
+ result |= (!wasVisible || !isDrawn()) ? RELAYOUT_RES_FIRST_TIME : 0;
if (mAnimatingExit) {
Slog.d(TAG, "relayoutVisibleWindow: " + this + " mAnimatingExit=true, mRemoveOnExit="
@@ -5620,15 +5620,14 @@
return !mTapExcludeRegion.isEmpty();
}
- @Override
- public boolean isInputMethodTarget() {
+ boolean isInputMethodTarget() {
return getDisplayContent().mInputMethodTarget == this;
}
long getFrameNumber() {
// Return the frame number in which changes requested in this layout will be rendered or
// -1 if we do not expect the frame to be rendered.
- return getFrameLw().isEmpty() ? -1 : mFrameNumber;
+ return getFrame().isEmpty() ? -1 : mFrameNumber;
}
void setFrameNumber(long frameNumber) {
@@ -5691,8 +5690,8 @@
return mWindowFrames.mVisibleInsets;
}
- @Override
- public WindowFrames getWindowFrames() {
+ /** Returns the {@link WindowFrames} associated with this {@link WindowState}. */
+ WindowFrames getWindowFrames() {
return mWindowFrames;
}
@@ -5800,7 +5799,7 @@
// won't exactly match the final freeform window frame (e.g. when overlapping with
// the status bar). In that case we need to use the final frame.
if (inFreeformWindowingMode()) {
- outFrame.set(getFrameLw());
+ outFrame.set(getFrame());
} else if (isLetterboxedAppWindow() || mToken.isFixedRotationTransforming()) {
// 1. The letterbox surfaces should be animated with the owner activity, so use task
// bounds to include them.
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 6f48342..1bd712c 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -526,13 +526,13 @@
if (DEBUG) {
Slog.v(TAG, "Got surface: " + mSurfaceController
- + ", set left=" + w.getFrameLw().left + " top=" + w.getFrameLw().top);
+ + ", set left=" + w.getFrame().left + " top=" + w.getFrame().top);
}
if (SHOW_LIGHT_TRANSACTIONS) {
Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
WindowManagerService.logSurface(w, "CREATE pos=("
- + w.getFrameLw().left + "," + w.getFrameLw().top + ") ("
+ + w.getFrame().left + "," + w.getFrame().top + ") ("
+ width + "x" + height + ")" + " HIDE", false);
}
@@ -896,7 +896,7 @@
// There is no need to wait for an animation change if our window is gone for layout
// already as we'll never be visible.
- if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
+ if (w.getOrientationChanging() && w.isGoneForLayout()) {
ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change skips hidden %s", w);
w.setOrientationChanging(false);
}
@@ -920,7 +920,7 @@
// really hidden (gone for layout), there is no point in still waiting for it.
// Note that this does introduce a potential glitch if the window becomes unhidden
// before it has drawn for the new orientation.
- if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
+ if (w.getOrientationChanging() && w.isGoneForLayout()) {
w.setOrientationChanging(false);
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Orientation change skips hidden %s", w);
@@ -998,7 +998,7 @@
}
if (w.getOrientationChanging()) {
- if (!w.isDrawnLw()) {
+ if (!w.isDrawn()) {
mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
mAnimator.mLastWindowFreezeSource = w;
ProtoLog.v(WM_DEBUG_ORIENTATION,
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index b3f3a5e..9aca848 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -40,14 +40,12 @@
namespace android {
static JavaVM* sJvm = nullptr;
-
static jmethodID sMethodIdOnComplete;
-
static struct {
jfieldID id;
jfieldID scale;
jfieldID delay;
-} gPrimitiveClassInfo;
+} sPrimitiveClassInfo;
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
@@ -77,100 +75,117 @@
static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
-static inline void callVibrationOnComplete(jobject vibration) {
- if (vibration == nullptr) {
- return;
+class NativeVibratorService {
+public:
+ NativeVibratorService(JNIEnv* env, jobject callbackListener)
+ : mController(std::make_unique<vibrator::HalController>()),
+ mCallbackListener(env->NewGlobalRef(callbackListener)) {
+ LOG_ALWAYS_FATAL_IF(mCallbackListener == nullptr,
+ "Unable to create global reference to vibration callback handler");
}
- auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
- jniEnv->CallVoidMethod(vibration, sMethodIdOnComplete);
- jniEnv->DeleteGlobalRef(vibration);
-}
+
+ ~NativeVibratorService() {
+ auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
+ jniEnv->DeleteGlobalRef(mCallbackListener);
+ }
+
+ vibrator::HalController* controller() const { return mController.get(); }
+
+ std::function<void()> createCallback(jlong vibrationId) {
+ return [vibrationId, this]() {
+ auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
+ jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, vibrationId);
+ };
+ }
+
+private:
+ const std::unique_ptr<vibrator::HalController> mController;
+ const jobject mCallbackListener;
+};
static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
aidl::CompositeEffect effect;
effect.primitive = static_cast<aidl::CompositePrimitive>(
- env->GetIntField(primitive, gPrimitiveClassInfo.id));
- effect.scale = static_cast<float>(env->GetFloatField(primitive, gPrimitiveClassInfo.scale));
- effect.delayMs = static_cast<int32_t>(env->GetIntField(primitive, gPrimitiveClassInfo.delay));
+ env->GetIntField(primitive, sPrimitiveClassInfo.id));
+ effect.scale = static_cast<float>(env->GetFloatField(primitive, sPrimitiveClassInfo.scale));
+ effect.delayMs = static_cast<int32_t>(env->GetIntField(primitive, sPrimitiveClassInfo.delay));
return effect;
}
-static void destroyVibratorController(void* rawVibratorController) {
- vibrator::HalController* vibratorController =
- reinterpret_cast<vibrator::HalController*>(rawVibratorController);
- if (vibratorController) {
- delete vibratorController;
+static void destroyNativeService(void* servicePtr) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service) {
+ delete service;
}
}
-static jlong vibratorInit(JNIEnv* /* env */, jclass /* clazz */) {
- std::unique_ptr<vibrator::HalController> controller =
- std::make_unique<vibrator::HalController>();
- controller->init();
- return reinterpret_cast<jlong>(controller.release());
+static jlong vibratorInit(JNIEnv* env, jclass /* clazz */, jobject callbackListener) {
+ std::unique_ptr<NativeVibratorService> service =
+ std::make_unique<NativeVibratorService>(env, callbackListener);
+ service->controller()->init();
+ return reinterpret_cast<jlong>(service.release());
}
static jlong vibratorGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) {
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyVibratorController));
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeService));
}
-static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorExists failed because controller was not initialized");
+static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorExists failed because native service was not initialized");
return JNI_FALSE;
}
- return controller->ping().isOk() ? JNI_TRUE : JNI_FALSE;
+ return service->controller()->ping().isOk() ? JNI_TRUE : JNI_FALSE;
}
-static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, jlong timeoutMs,
- jobject vibration) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorOn failed because controller was not initialized");
+static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong timeoutMs,
+ jlong vibrationId) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorOn failed because native service was not initialized");
return;
}
- jobject vibrationRef = vibration == nullptr ? vibration : MakeGlobalRefOrDie(env, vibration);
- auto callback = [vibrationRef]() { callVibrationOnComplete(vibrationRef); };
- controller->on(std::chrono::milliseconds(timeoutMs), callback);
+ auto callback = service->createCallback(vibrationId);
+ service->controller()->on(std::chrono::milliseconds(timeoutMs), callback);
}
-static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorOff failed because controller was not initialized");
+static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorOff failed because native service was not initialized");
return;
}
- controller->off();
+ service->controller()->off();
}
-static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
+static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
jint amplitude) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorSetAmplitude failed because controller was not initialized");
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorSetAmplitude failed because native service was not initialized");
return;
}
- controller->setAmplitude(static_cast<int32_t>(amplitude));
+ service->controller()->setAmplitude(static_cast<int32_t>(amplitude));
}
-static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
+static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
jboolean enabled) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorSetExternalControl failed because controller was not initialized");
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorSetExternalControl failed because native service was not initialized");
return;
}
- controller->setExternalControl(enabled);
+ service->controller()->setExternalControl(enabled);
}
-static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorGetSupportedEffects failed because controller was not initialized");
+static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorGetSupportedEffects failed because native service was not initialized");
return nullptr;
}
- auto result = controller->getSupportedEffects();
+ auto result = service->controller()->getSupportedEffects();
if (!result.isOk()) {
return nullptr;
}
@@ -181,14 +196,13 @@
return effects;
}
-static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */,
- jlong controllerPtr) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorGetSupportedPrimitives failed because controller was not initialized");
+static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorGetSupportedPrimitives failed because native service was not initialized");
return nullptr;
}
- auto result = controller->getSupportedPrimitives();
+ auto result = service->controller()->getSupportedPrimitives();
if (!result.isOk()) {
return nullptr;
}
@@ -199,26 +213,25 @@
return primitives;
}
-static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
- jlong effect, jlong strength, jobject vibration) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorPerformEffect failed because controller was not initialized");
+static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong effect,
+ jlong strength, jlong vibrationId) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorPerformEffect failed because native service was not initialized");
return -1;
}
aidl::Effect effectType = static_cast<aidl::Effect>(effect);
aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength);
- jobject vibrationRef = vibration == nullptr ? vibration : MakeGlobalRefOrDie(env, vibration);
- auto callback = [vibrationRef]() { callVibrationOnComplete(vibrationRef); };
- auto result = controller->performEffect(effectType, effectStrength, callback);
+ auto callback = service->createCallback(vibrationId);
+ auto result = service->controller()->performEffect(effectType, effectStrength, callback);
return result.isOk() ? result.value().count() : -1;
}
-static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
- jobjectArray composition, jobject vibration) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorPerformComposedEffect failed because controller was not initialized");
+static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
+ jobjectArray composition, jlong vibrationId) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorPerformComposedEffect failed because native service was not initialized");
return;
}
size_t size = env->GetArrayLength(composition);
@@ -227,54 +240,52 @@
jobject element = env->GetObjectArrayElement(composition, i);
effects.push_back(effectFromJavaPrimitive(env, element));
}
- jobject vibrationRef = vibration == nullptr ? vibration : MakeGlobalRefOrDie(env, vibration);
- auto callback = [vibrationRef]() { callVibrationOnComplete(vibrationRef); };
- controller->performComposedEffect(effects, callback);
+ auto callback = service->createCallback(vibrationId);
+ service->controller()->performComposedEffect(effects, callback);
}
-static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorGetCapabilities failed because controller was not initialized");
+static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorGetCapabilities failed because native service was not initialized");
return 0;
}
- auto result = controller->getCapabilities();
+ auto result = service->controller()->getCapabilities();
return result.isOk() ? static_cast<jlong>(result.value()) : 0;
}
-static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, jlong id,
+static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong id,
jlong effect, jlong strength) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorAlwaysOnEnable failed because controller was not initialized");
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorAlwaysOnEnable failed because native service was not initialized");
return;
}
- controller->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
- static_cast<aidl::EffectStrength>(strength));
+ service->controller()->alwaysOnEnable(static_cast<int32_t>(id),
+ static_cast<aidl::Effect>(effect),
+ static_cast<aidl::EffectStrength>(strength));
}
-static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
- jlong id) {
- vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
- if (controller == nullptr) {
- ALOGE("vibratorAlwaysOnDisable failed because controller was not initialized");
+static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong id) {
+ NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("vibratorAlwaysOnDisable failed because native service was not initialized");
return;
}
- controller->alwaysOnDisable(static_cast<int32_t>(id));
+ service->controller()->alwaysOnDisable(static_cast<int32_t>(id));
}
static const JNINativeMethod method_table[] = {
- {"vibratorInit", "()J", (void*)vibratorInit},
+ {"vibratorInit", "(Lcom/android/server/VibratorService$OnCompleteListener;)J",
+ (void*)vibratorInit},
{"vibratorGetFinalizer", "()J", (void*)vibratorGetFinalizer},
{"vibratorExists", "(J)Z", (void*)vibratorExists},
- {"vibratorOn", "(JJLcom/android/server/VibratorService$Vibration;)V", (void*)vibratorOn},
+ {"vibratorOn", "(JJJ)V", (void*)vibratorOn},
{"vibratorOff", "(J)V", (void*)vibratorOff},
{"vibratorSetAmplitude", "(JI)V", (void*)vibratorSetAmplitude},
- {"vibratorPerformEffect", "(JJJLcom/android/server/VibratorService$Vibration;)J",
- (void*)vibratorPerformEffect},
+ {"vibratorPerformEffect", "(JJJJ)J", (void*)vibratorPerformEffect},
{"vibratorPerformComposedEffect",
- "(J[Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/"
- "VibratorService$Vibration;)V",
+ "(J[Landroid/os/VibrationEffect$Composition$PrimitiveEffect;J)V",
(void*)vibratorPerformComposedEffect},
{"vibratorGetSupportedEffects", "(J)[I", (void*)vibratorGetSupportedEffects},
{"vibratorGetSupportedPrimitives", "(J)[I", (void*)vibratorGetSupportedPrimitives},
@@ -284,18 +295,17 @@
{"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable},
};
-int register_android_server_VibratorService(JavaVM* vm, JNIEnv* env) {
- sJvm = vm;
- sMethodIdOnComplete =
- GetMethodIDOrDie(env,
- FindClassOrDie(env, "com/android/server/VibratorService$Vibration"),
- "onComplete", "()V");
+int register_android_server_VibratorService(JavaVM* jvm, JNIEnv* env) {
+ sJvm = jvm;
+ jclass listenerClass =
+ FindClassOrDie(env, "com/android/server/VibratorService$OnCompleteListener");
+ sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(J)V");
jclass primitiveClass =
FindClassOrDie(env, "android/os/VibrationEffect$Composition$PrimitiveEffect");
- gPrimitiveClassInfo.id = GetFieldIDOrDie(env, primitiveClass, "id", "I");
- gPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F");
- gPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I");
+ sPrimitiveClassInfo.id = GetFieldIDOrDie(env, primitiveClass, "id", "I");
+ sPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F");
+ sPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I");
return jniRegisterNativeMethods(env, "com/android/server/VibratorService", method_table,
NELEM(method_table));
diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
index b7a36f2..8d4f2aa 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
@@ -20,12 +20,13 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.gt;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.intThat;
-import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
@@ -167,7 +168,7 @@
@Test
public void createService_initializesNativeService() {
createService();
- verify(mNativeWrapperMock).vibratorInit();
+ verify(mNativeWrapperMock).vibratorInit(notNull());
verify(mNativeWrapperMock).vibratorOff();
}
@@ -294,7 +295,7 @@
assertTrue(service.isVibrating());
verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorOn(eq(100L), any(VibratorService.Vibration.class));
+ verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
verify(mNativeWrapperMock).vibratorSetAmplitude(eq(128));
}
@@ -307,7 +308,7 @@
assertTrue(service.isVibrating());
verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorOn(eq(100L), any(VibratorService.Vibration.class));
+ verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
verify(mNativeWrapperMock, never()).vibratorSetAmplitude(anyInt());
}
@@ -321,10 +322,8 @@
vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorPerformEffect(
- eq((long) VibrationEffect.EFFECT_CLICK),
- eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG),
- any(VibratorService.Vibration.class));
+ verify(mNativeWrapperMock).vibratorPerformEffect(eq((long) VibrationEffect.EFFECT_CLICK),
+ eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), gt(0L));
}
@Test
@@ -343,7 +342,7 @@
verify(mNativeWrapperMock).vibratorOff();
verify(mNativeWrapperMock).vibratorPerformComposedEffect(
- primitivesCaptor.capture(), any(VibratorService.Vibration.class));
+ primitivesCaptor.capture(), gt(0L));
// Check all primitive effect fields are passed down to the HAL.
assertEquals(1, primitivesCaptor.getValue().length);
@@ -368,7 +367,7 @@
// Wait for VibrateThread to turn vibrator ON with total timing and no callback.
Thread.sleep(5);
- verify(mNativeWrapperMock).vibratorOn(eq(30L), isNull());
+ verify(mNativeWrapperMock).vibratorOn(eq(30L), eq(0L));
// First amplitude set right away.
verify(mNativeWrapperMock).vibratorSetAmplitude(eq(100));
@@ -384,11 +383,11 @@
@Test
public void vibrate_withOneShotAndNativeCallbackTriggered_finishesVibration() {
- doAnswer(invocation -> {
- ((VibratorService.Vibration) invocation.getArgument(1)).onComplete();
- return null;
- }).when(mNativeWrapperMock).vibratorOn(anyLong(), any(VibratorService.Vibration.class));
VibratorService service = createService();
+ doAnswer(invocation -> {
+ service.onVibrationComplete(invocation.getArgument(1));
+ return null;
+ }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
@@ -396,7 +395,7 @@
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(100L),
- any(VibratorService.Vibration.class));
+ gt(0L));
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
}
@@ -404,12 +403,11 @@
public void vibrate_withPrebakedAndNativeCallbackTriggered_finishesVibration() {
when(mNativeWrapperMock.vibratorGetSupportedEffects())
.thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
- doAnswer(invocation -> {
- ((VibratorService.Vibration) invocation.getArgument(2)).onComplete();
- return 10_000L; // 10s
- }).when(mNativeWrapperMock).vibratorPerformEffect(
- anyLong(), anyLong(), any(VibratorService.Vibration.class));
VibratorService service = createService();
+ doAnswer(invocation -> {
+ service.onVibrationComplete(invocation.getArgument(2));
+ return 10_000L; // 10s
+ }).when(mNativeWrapperMock).vibratorPerformEffect(anyLong(), anyLong(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
@@ -419,7 +417,7 @@
inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformEffect(
eq((long) VibrationEffect.EFFECT_CLICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG),
- any(VibratorService.Vibration.class));
+ gt(0L));
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
}
@@ -436,20 +434,19 @@
Thread.sleep(15);
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(3L), isNull());
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(2L), isNull());
+ inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(3L), eq(0L));
+ inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(2L), eq(0L));
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
}
@Test
public void vibrate_withComposedAndNativeCallbackTriggered_finishesVibration() {
mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
- doAnswer(invocation -> {
- ((VibratorService.Vibration) invocation.getArgument(1)).onComplete();
- return null;
- }).when(mNativeWrapperMock).vibratorPerformComposedEffect(
- any(), any(VibratorService.Vibration.class));
VibratorService service = createService();
+ doAnswer(invocation -> {
+ service.onVibrationComplete(invocation.getArgument(1));
+ return null;
+ }).when(mNativeWrapperMock).vibratorPerformComposedEffect(any(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
VibrationEffect effect = VibrationEffect.startComposition()
@@ -460,32 +457,7 @@
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformComposedEffect(
- any(VibrationEffect.Composition.PrimitiveEffect[].class),
- any(VibratorService.Vibration.class));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- }
-
- @Test
- public void vibrate_whenBinderDies_cancelsVibration() {
- mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
- doAnswer(invocation -> {
- ((VibratorService.Vibration) invocation.getArgument(1)).binderDied();
- return null;
- }).when(mNativeWrapperMock).vibratorPerformComposedEffect(
- any(), any(VibratorService.Vibration.class));
- VibratorService service = createService();
- Mockito.clearInvocations(mNativeWrapperMock);
-
- VibrationEffect effect = VibrationEffect.startComposition()
- .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 10)
- .compose();
- vibrate(service, effect);
-
- InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformComposedEffect(
- any(VibrationEffect.Composition.PrimitiveEffect[].class),
- any(VibratorService.Vibration.class));
+ any(VibrationEffect.Composition.PrimitiveEffect[].class), gt(0L));
inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
}
@@ -513,12 +485,11 @@
@Test
public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
- doAnswer(invocation -> {
- ((VibratorService.Vibration) invocation.getArgument(1)).onComplete();
- return null;
- }).when(mNativeWrapperMock).vibratorOn(anyLong(), any(VibratorService.Vibration.class));
VibratorService service = createService();
-
+ doAnswer(invocation -> {
+ service.onVibrationComplete(invocation.getArgument(1));
+ return null;
+ }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
service.registerVibratorStateListener(mVibratorStateListenerMock);
verify(mVibratorStateListenerMock).onVibrating(false);
Mockito.clearInvocations(mVibratorStateListenerMock);
@@ -569,15 +540,15 @@
verify(mNativeWrapperMock).vibratorPerformEffect(
eq((long) VibrationEffect.EFFECT_CLICK),
- eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), any());
+ eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), anyLong());
verify(mNativeWrapperMock).vibratorPerformEffect(
eq((long) VibrationEffect.EFFECT_TICK),
- eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), any());
+ eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), anyLong());
verify(mNativeWrapperMock).vibratorPerformEffect(
eq((long) VibrationEffect.EFFECT_DOUBLE_CLICK),
- eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), any());
+ eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), anyLong());
verify(mNativeWrapperMock, never()).vibratorPerformEffect(
- eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), any());
+ eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), anyLong());
}
@Test
@@ -644,7 +615,7 @@
// Ringtone vibration is off, so only the other 3 are propagated to native.
verify(mNativeWrapperMock, times(3)).vibratorPerformComposedEffect(
- primitivesCaptor.capture(), any());
+ primitivesCaptor.capture(), anyLong());
List<VibrationEffect.Composition.PrimitiveEffect[]> values =
primitivesCaptor.getAllValues();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index 763654d..dda81ff 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -187,7 +187,7 @@
moveEachPointers(mLastEvent, p(10, 10), p(10, 10));
send(mLastEvent);
goToStateClearFrom(STATE_DRAGGING_2FINGERS);
- assertCapturedEvents(ACTION_DOWN, ACTION_MOVE, ACTION_MOVE, ACTION_UP);
+ assertCapturedEvents(ACTION_DOWN, ACTION_MOVE, ACTION_MOVE, ACTION_MOVE, ACTION_UP);
}
@Test
@@ -288,7 +288,7 @@
assertState(STATE_DRAGGING);
goToStateClearFrom(STATE_DRAGGING_2FINGERS);
assertState(STATE_CLEAR);
- assertCapturedEvents(ACTION_DOWN, ACTION_UP);
+ assertCapturedEvents(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
assertCapturedEventsNoHistory();
}
@@ -301,6 +301,7 @@
assertState(STATE_CLEAR);
assertCapturedEvents(
/* goto dragging state */ ACTION_DOWN,
+ ACTION_MOVE,
/* leave dragging state */ ACTION_UP,
ACTION_DOWN,
ACTION_POINTER_DOWN,
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java
index 53c4d6f..f17173f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java
@@ -62,6 +62,32 @@
assertThat(message).isEqualTo(buildMessage("5F:81:21:00"));
}
+ @Test
+ public void buildSetOsdName_short() {
+ String deviceName = "abc";
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildSetOsdNameCommand(ADDR_PLAYBACK_1,
+ ADDR_TV, deviceName);
+ assertThat(message).isEqualTo(buildMessage("40:47:61:62:63"));
+ }
+
+ @Test
+ public void buildSetOsdName_maximumLength() {
+ String deviceName = "abcdefghijklmn";
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildSetOsdNameCommand(ADDR_PLAYBACK_1,
+ ADDR_TV, deviceName);
+ assertThat(message).isEqualTo(
+ buildMessage("40:47:61:62:63:64:65:66:67:68:69:6A:6B:6C:6D:6E"));
+ }
+
+ @Test
+ public void buildSetOsdName_tooLong() {
+ String deviceName = "abcdefghijklmnop";
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildSetOsdNameCommand(ADDR_PLAYBACK_1,
+ ADDR_TV, deviceName);
+ assertThat(message).isEqualTo(
+ buildMessage("40:47:61:62:63:64:65:66:67:68:69:6A:6B:6C:6D:6E"));
+ }
+
/**
* Build a CEC message from a hex byte string with bytes separated by {@code :}.
*
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
new file mode 100644
index 0000000..d7ed96f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
+import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.timezonedetector.TimeZoneCapabilities;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ConfigurationInternal} and the {@link TimeZoneCapabilities} and
+ * {@link android.app.timezonedetector.TimeZoneConfiguration} that can be generated from it.
+ */
+public class ConfigurationInternalTest {
+
+ private static final int ARBITRARY_USER_ID = 99999;
+
+ /**
+ * Tests when {@link ConfigurationInternal#isUserConfigAllowed()} and
+ * {@link ConfigurationInternal#isAutoDetectionSupported()} are both true.
+ */
+ @Test
+ public void test_unrestricted() {
+ ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionSupported(true)
+ .setAutoDetectionEnabled(true)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ {
+ ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
+ .setAutoDetectionEnabled(true)
+ .build();
+ assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
+ assertTrue(autoOnConfig.getGeoDetectionEnabledSetting());
+ assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior());
+ assertTrue(autoOnConfig.getGeoDetectionEnabledBehavior());
+
+ TimeZoneCapabilities capabilities = autoOnConfig.createCapabilities();
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabled());
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getSuggestManualTimeZone());
+ assertEquals(autoOnConfig.asConfiguration(), capabilities.getConfiguration());
+ assertTrue(capabilities.getConfiguration().isAutoDetectionEnabled());
+ assertTrue(capabilities.getConfiguration().isGeoDetectionEnabled());
+ }
+
+ {
+ ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
+ .setAutoDetectionEnabled(false)
+ .build();
+ assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
+ assertTrue(autoOffConfig.getGeoDetectionEnabledSetting());
+ assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
+ assertFalse(autoOffConfig.getGeoDetectionEnabledBehavior());
+
+ TimeZoneCapabilities capabilities = autoOffConfig.createCapabilities();
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabled());
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabled());
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
+ assertEquals(autoOffConfig.asConfiguration(), capabilities.getConfiguration());
+ assertFalse(capabilities.getConfiguration().isAutoDetectionEnabled());
+ assertTrue(capabilities.getConfiguration().isGeoDetectionEnabled());
+ }
+ }
+
+ /** Tests when {@link ConfigurationInternal#isUserConfigAllowed()} is false */
+ @Test
+ public void test_restricted() {
+ ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setUserConfigAllowed(false)
+ .setAutoDetectionSupported(true)
+ .setAutoDetectionEnabled(true)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ {
+ ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
+ .setAutoDetectionEnabled(true)
+ .build();
+ assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
+ assertTrue(autoOnConfig.getGeoDetectionEnabledSetting());
+ assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior());
+ assertTrue(autoOnConfig.getGeoDetectionEnabledBehavior());
+
+ TimeZoneCapabilities capabilities = autoOnConfig.createCapabilities();
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureGeoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSuggestManualTimeZone());
+ assertEquals(autoOnConfig.asConfiguration(), capabilities.getConfiguration());
+ assertTrue(capabilities.getConfiguration().isAutoDetectionEnabled());
+ assertTrue(capabilities.getConfiguration().isGeoDetectionEnabled());
+ }
+
+ {
+ ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
+ .setAutoDetectionEnabled(false)
+ .build();
+ assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
+ assertTrue(autoOffConfig.getGeoDetectionEnabledSetting());
+ assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
+ assertFalse(autoOffConfig.getGeoDetectionEnabledBehavior());
+
+ TimeZoneCapabilities capabilities = autoOffConfig.createCapabilities();
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureGeoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSuggestManualTimeZone());
+ assertEquals(autoOffConfig.asConfiguration(), capabilities.getConfiguration());
+ assertFalse(capabilities.getConfiguration().isAutoDetectionEnabled());
+ assertTrue(capabilities.getConfiguration().isGeoDetectionEnabled());
+ }
+ }
+
+ /** Tests when {@link ConfigurationInternal#isAutoDetectionSupported()} is false. */
+ @Test
+ public void test_autoDetectNotSupported() {
+ ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionSupported(false)
+ .setAutoDetectionEnabled(true)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+ {
+ ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
+ .setAutoDetectionEnabled(true)
+ .build();
+ assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
+ assertTrue(autoOnConfig.getGeoDetectionEnabledSetting());
+ assertFalse(autoOnConfig.getAutoDetectionEnabledBehavior());
+ assertFalse(autoOnConfig.getGeoDetectionEnabledBehavior());
+
+ TimeZoneCapabilities capabilities = autoOnConfig.createCapabilities();
+ assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabled());
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
+ assertEquals(autoOnConfig.asConfiguration(), capabilities.getConfiguration());
+ assertTrue(capabilities.getConfiguration().isAutoDetectionEnabled());
+ assertTrue(capabilities.getConfiguration().isGeoDetectionEnabled());
+ }
+ {
+ ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
+ .setAutoDetectionEnabled(false)
+ .build();
+ assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
+ assertTrue(autoOffConfig.getGeoDetectionEnabledSetting());
+ assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
+ assertFalse(autoOffConfig.getGeoDetectionEnabledBehavior());
+
+ TimeZoneCapabilities capabilities = autoOffConfig.createCapabilities();
+ assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabled());
+ assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabled());
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
+ assertEquals(autoOffConfig.asConfiguration(), capabilities.getConfiguration());
+ assertFalse(capabilities.getConfiguration().isAutoDetectionEnabled());
+ assertTrue(capabilities.getConfiguration().isGeoDetectionEnabled());
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
index e5e9311..4ef2082 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -32,56 +33,64 @@
class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
- private StrategyListener mListener;
+ private ConfigurationChangeListener mConfigurationChangeListener;
// Fake state
- private TimeZoneCapabilities mCapabilities;
- private TimeZoneConfiguration mConfiguration;
+ private ConfigurationInternal mConfigurationInternal;
// Call tracking.
private GeolocationTimeZoneSuggestion mLastGeolocationSuggestion;
private ManualTimeZoneSuggestion mLastManualSuggestion;
private TelephonyTimeZoneSuggestion mLastTelephonySuggestion;
- private boolean mHandleAutoTimeZoneConfigChangedCalled;
private boolean mDumpCalled;
private final List<Dumpable> mDumpables = new ArrayList<>();
@Override
- public void setStrategyListener(@NonNull StrategyListener listener) {
- mListener = listener;
+ public void addConfigChangeListener(@NonNull ConfigurationChangeListener listener) {
+ if (mConfigurationChangeListener != null) {
+ fail("Fake only supports one listener");
+ }
+ mConfigurationChangeListener = listener;
}
@Override
- public TimeZoneCapabilities getCapabilities(@UserIdInt int userId) {
- return mCapabilities;
+ public ConfigurationInternal getConfigurationInternal(int userId) {
+ if (mConfigurationInternal.getUserId() != userId) {
+ fail("Fake only supports one user");
+ }
+ return mConfigurationInternal;
}
@Override
- public boolean updateConfiguration(
- @UserIdInt int userId, @NonNull TimeZoneConfiguration configuration) {
- assertNotNull(mConfiguration);
- assertNotNull(configuration);
+ public ConfigurationInternal getCurrentUserConfigurationInternal() {
+ return mConfigurationInternal;
+ }
- // Simulate the strategy's behavior: the new configuration will be the old configuration
- // merged with the new.
- TimeZoneConfiguration oldConfiguration = mConfiguration;
- TimeZoneConfiguration newConfiguration =
- new TimeZoneConfiguration.Builder(mConfiguration)
- .mergeProperties(configuration)
- .build();
+ @Override
+ public boolean updateConfiguration(@NonNull TimeZoneConfiguration requestedChanges) {
+ assertNotNull(mConfigurationInternal);
+ assertNotNull(requestedChanges);
- if (newConfiguration.equals(oldConfiguration)) {
+ // Simulate the real strategy's behavior: the new configuration will be updated to be the
+ // old configuration merged with the new if the user has the capability to up the settings.
+ // Then, if the configuration changed, the change listener is invoked.
+ TimeZoneCapabilities capabilities = mConfigurationInternal.createCapabilities();
+ TimeZoneConfiguration newConfiguration = capabilities.applyUpdate(requestedChanges);
+ if (newConfiguration == null) {
return false;
}
- mConfiguration = newConfiguration;
- mListener.onConfigurationChanged();
+
+ if (!newConfiguration.equals(capabilities.getConfiguration())) {
+ mConfigurationInternal = mConfigurationInternal.merge(newConfiguration);
+
+ // Note: Unlike the real strategy, the listeners is invoked synchronously.
+ mConfigurationChangeListener.onChange();
+ }
return true;
}
- @Override
- @NonNull
- public TimeZoneConfiguration getConfiguration(@UserIdInt int userId) {
- return mConfiguration;
+ public void simulateConfigurationChangeForTests() {
+ mConfigurationChangeListener.onChange();
}
@Override
@@ -103,11 +112,6 @@
}
@Override
- public void handleAutoTimeZoneConfigChanged() {
- mHandleAutoTimeZoneConfigChangedCalled = true;
- }
-
- @Override
public void addDumpable(Dumpable dumpable) {
mDumpables.add(dumpable);
}
@@ -117,19 +121,14 @@
mDumpCalled = true;
}
- void initializeConfiguration(TimeZoneConfiguration configuration) {
- mConfiguration = configuration;
- }
-
- void initializeCapabilities(TimeZoneCapabilities capabilities) {
- mCapabilities = capabilities;
+ void initializeConfiguration(ConfigurationInternal configurationInternal) {
+ mConfigurationInternal = configurationInternal;
}
void resetCallTracking() {
mLastGeolocationSuggestion = null;
mLastManualSuggestion = null;
mLastTelephonySuggestion = null;
- mHandleAutoTimeZoneConfigChangedCalled = false;
mDumpCalled = false;
}
@@ -146,10 +145,6 @@
assertEquals(expectedSuggestion, mLastTelephonySuggestion);
}
- void verifyHandleAutoTimeZoneConfigChangedCalled() {
- assertTrue(mHandleAutoTimeZoneConfigChangedCalled);
- }
-
void verifyDumpCalled() {
assertTrue(mDumpCalled);
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TestCallerIdentityInjector.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TestCallerIdentityInjector.java
new file mode 100644
index 0000000..f45b3a8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TestCallerIdentityInjector.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.annotation.UserIdInt;
+
+/** A fake {@link CallerIdentityInjector} used in tests. */
+public class TestCallerIdentityInjector implements CallerIdentityInjector {
+
+ private long mToken = 9999L;
+ private int mCallingUserId;
+ private Integer mCurrentCallingUserId;
+
+ public void initializeCallingUserId(@UserIdInt int userId) {
+ mCallingUserId = userId;
+ mCurrentCallingUserId = userId;
+ }
+
+ @Override
+ public int getCallingUserId() {
+ assertNotNull("callingUserId has been cleared", mCurrentCallingUserId);
+ return mCurrentCallingUserId;
+ }
+
+ @Override
+ public long clearCallingIdentity() {
+ mCurrentCallingUserId = null;
+ return mToken;
+ }
+
+ @Override
+ public void restoreCallingIdentity(long token) {
+ assertEquals(token, mToken);
+ mCurrentCallingUserId = mCallingUserId;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java
index e9d57e5..918babc 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java
@@ -16,6 +16,7 @@
package com.android.server.timezonedetector;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import android.content.Context;
@@ -85,6 +86,18 @@
mFakeTimeZoneDetectorStrategy.verifyHasDumpable(stubbedDumpable);
}
+ @Test
+ public void testAddConfigurationListener() throws Exception {
+ boolean[] changeCalled = new boolean[2];
+ mTimeZoneDetectorInternal.addConfigurationListener(() -> changeCalled[0] = true);
+ mTimeZoneDetectorInternal.addConfigurationListener(() -> changeCalled[1] = true);
+
+ mFakeTimeZoneDetectorStrategy.simulateConfigurationChangeForTests();
+
+ assertTrue(changeCalled[0]);
+ assertTrue(changeCalled[1]);
+ }
+
private static GeolocationTimeZoneSuggestion createGeolocationTimeZoneSuggestion() {
return new GeolocationTimeZoneSuggestion(ARBITRARY_ZONE_IDS);
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
index 3a1ec4f..27b04b6 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -16,8 +16,6 @@
package com.android.server.timezonedetector;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
@@ -36,7 +34,6 @@
import android.app.timezonedetector.ITimeZoneConfigurationListener;
import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
-import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -65,6 +62,7 @@
private TimeZoneDetectorService mTimeZoneDetectorService;
private HandlerThread mHandlerThread;
private TestHandler mTestHandler;
+ private TestCallerIdentityInjector mTestCallerIdentityInjector;
@Before
@@ -76,10 +74,14 @@
mHandlerThread.start();
mTestHandler = new TestHandler(mHandlerThread.getLooper());
+ mTestCallerIdentityInjector = new TestCallerIdentityInjector();
+ mTestCallerIdentityInjector.initializeCallingUserId(ARBITRARY_USER_ID);
+
mFakeTimeZoneDetectorStrategy = new FakeTimeZoneDetectorStrategy();
mTimeZoneDetectorService = new TimeZoneDetectorService(
- mMockContext, mTestHandler, mFakeTimeZoneDetectorStrategy);
+ mMockContext, mTestHandler, mTestCallerIdentityInjector,
+ mFakeTimeZoneDetectorStrategy);
}
@After
@@ -107,40 +109,12 @@
public void testGetCapabilities() {
doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
- TimeZoneCapabilities capabilities = createTimeZoneCapabilities();
- mFakeTimeZoneDetectorStrategy.initializeCapabilities(capabilities);
-
- assertEquals(capabilities, mTimeZoneDetectorService.getCapabilities());
-
- verify(mMockContext).enforceCallingPermission(
- eq(android.Manifest.permission.WRITE_SECURE_SETTINGS),
- anyString());
- }
-
- @Test(expected = SecurityException.class)
- public void testGetConfiguration_withoutPermission() {
- doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingPermission(anyString(), any());
-
- try {
- mTimeZoneDetectorService.getConfiguration();
- fail();
- } finally {
- verify(mMockContext).enforceCallingPermission(
- eq(android.Manifest.permission.WRITE_SECURE_SETTINGS),
- anyString());
- }
- }
-
- @Test
- public void testGetConfiguration() {
- doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
-
- TimeZoneConfiguration configuration =
- createTimeZoneConfiguration(false /* autoDetectionEnabled */);
+ ConfigurationInternal configuration =
+ createConfigurationInternal(true /* autoDetectionEnabled*/);
mFakeTimeZoneDetectorStrategy.initializeConfiguration(configuration);
- assertEquals(configuration, mTimeZoneDetectorService.getConfiguration());
+ assertEquals(configuration.createCapabilities(),
+ mTimeZoneDetectorService.getCapabilities());
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.WRITE_SECURE_SETTINGS),
@@ -181,10 +155,9 @@
@Test
public void testConfigurationChangeListenerRegistrationAndCallbacks() throws Exception {
- TimeZoneConfiguration autoDetectDisabledConfiguration =
- createTimeZoneConfiguration(false /* autoDetectionEnabled */);
-
- mFakeTimeZoneDetectorStrategy.initializeConfiguration(autoDetectDisabledConfiguration);
+ ConfigurationInternal initialConfiguration =
+ createConfigurationInternal(false /* autoDetectionEnabled */);
+ mFakeTimeZoneDetectorStrategy.initializeConfiguration(initialConfiguration);
IBinder mockListenerBinder = mock(IBinder.class);
ITimeZoneConfigurationListener mockListener = mock(ITimeZoneConfigurationListener.class);
@@ -210,13 +183,12 @@
// Simulate the configuration being changed and verify the mockListener was notified.
TimeZoneConfiguration autoDetectEnabledConfiguration =
createTimeZoneConfiguration(true /* autoDetectionEnabled */);
-
mTimeZoneDetectorService.updateConfiguration(autoDetectEnabledConfiguration);
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.WRITE_SECURE_SETTINGS),
anyString());
- verify(mockListener).onChange(autoDetectEnabledConfiguration);
+ verify(mockListener).onChange();
verifyNoMoreInteractions(mockListenerBinder, mockListener, mMockContext);
reset(mockListenerBinder, mockListener, mMockContext);
}
@@ -242,12 +214,14 @@
{
doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
+ TimeZoneConfiguration autoDetectDisabledConfiguration =
+ createTimeZoneConfiguration(false /* autoDetectionEnabled */);
mTimeZoneDetectorService.updateConfiguration(autoDetectDisabledConfiguration);
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.WRITE_SECURE_SETTINGS),
anyString());
- verify(mockListener, never()).onChange(any());
+ verify(mockListener, never()).onChange();
verifyNoMoreInteractions(mockListenerBinder, mockListener, mMockContext);
reset(mockListenerBinder, mockListener, mMockContext);
}
@@ -379,33 +353,22 @@
mFakeTimeZoneDetectorStrategy.verifyDumpCalled();
}
- @Test
- public void testHandleAutoTimeZoneConfigChanged() throws Exception {
- mTimeZoneDetectorService.handleAutoTimeZoneConfigChanged();
- mTestHandler.assertTotalMessagesEnqueued(1);
- mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeZoneDetectorStrategy.verifyHandleAutoTimeZoneConfigChangedCalled();
-
- mFakeTimeZoneDetectorStrategy.resetCallTracking();
-
- mTimeZoneDetectorService.handleAutoTimeZoneConfigChanged();
- mTestHandler.assertTotalMessagesEnqueued(2);
- mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeZoneDetectorStrategy.verifyHandleAutoTimeZoneConfigChangedCalled();
- }
-
- private static TimeZoneConfiguration createTimeZoneConfiguration(
- boolean autoDetectionEnabled) {
- return new TimeZoneConfiguration.Builder()
+ private static TimeZoneConfiguration createTimeZoneConfiguration(boolean autoDetectionEnabled) {
+ return new TimeZoneConfiguration.Builder(ARBITRARY_USER_ID)
.setAutoDetectionEnabled(autoDetectionEnabled)
.build();
}
- private static TimeZoneCapabilities createTimeZoneCapabilities() {
- return new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
- .setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
- .setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
- .setSuggestManualTimeZone(CAPABILITY_POSSESSED)
+ private static ConfigurationInternal createConfigurationInternal(boolean autoDetectionEnabled) {
+ // Default geo detection settings from auto detection settings - they are not important to
+ // the tests.
+ final boolean geoDetectionEnabled = autoDetectionEnabled;
+ return new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setAutoDetectionSupported(true)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionEnabled(autoDetectionEnabled)
+ .setLocationEnabled(geoDetectionEnabled)
+ .setGeoDetectionEnabled(geoDetectionEnabled)
.build();
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index a6caa42..2bee5e5 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -23,10 +23,6 @@
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
-import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_HIGH;
import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_HIGHEST;
@@ -37,9 +33,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -47,7 +43,6 @@
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion.MatchType;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion.Quality;
-import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
import android.util.IndentingPrintWriter;
@@ -61,7 +56,6 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -94,192 +88,149 @@
TELEPHONY_SCORE_HIGHEST),
};
- private static final TimeZoneConfiguration CONFIG_AUTO_ENABLED =
- new TimeZoneConfiguration.Builder()
- .setAutoDetectionEnabled(true)
- .build();
-
- private static final TimeZoneConfiguration CONFIG_AUTO_DISABLED =
- new TimeZoneConfiguration.Builder()
+ private static final ConfigurationInternal CONFIG_INT_USER_RESTRICTED_AUTO_DISABLED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setUserConfigAllowed(false)
+ .setAutoDetectionSupported(true)
.setAutoDetectionEnabled(false)
- .build();
-
- private static final TimeZoneConfiguration CONFIG_GEO_DETECTION_DISABLED =
- new TimeZoneConfiguration.Builder()
+ .setLocationEnabled(true)
.setGeoDetectionEnabled(false)
.build();
- private static final TimeZoneConfiguration CONFIG_GEO_DETECTION_ENABLED =
- new TimeZoneConfiguration.Builder()
+ private static final ConfigurationInternal CONFIG_INT_USER_RESTRICTED_AUTO_ENABLED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setUserConfigAllowed(false)
+ .setAutoDetectionSupported(true)
+ .setAutoDetectionEnabled(true)
+ .setLocationEnabled(true)
.setGeoDetectionEnabled(true)
.build();
+ private static final ConfigurationInternal CONFIG_INT_AUTO_DETECT_NOT_SUPPORTED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionSupported(false)
+ .setAutoDetectionEnabled(false)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(false)
+ .build();
+
+ private static final ConfigurationInternal CONFIG_INT_AUTO_DISABLED_GEO_DISABLED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionSupported(true)
+ .setAutoDetectionEnabled(false)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(false)
+ .build();
+
+ private static final ConfigurationInternal CONFIG_INT_AUTO_DISABLED_GEO_ENABLED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionSupported(true)
+ .setAutoDetectionEnabled(false)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+
+ private static final ConfigurationInternal CONFIG_INT_AUTO_ENABLED_GEO_DISABLED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setAutoDetectionSupported(true)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionEnabled(true)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(false)
+ .build();
+
+ private static final ConfigurationInternal CONFIG_INT_AUTO_ENABLED_GEO_ENABLED =
+ new ConfigurationInternal.Builder(USER_ID)
+ .setAutoDetectionSupported(true)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionEnabled(true)
+ .setLocationEnabled(true)
+ .setGeoDetectionEnabled(true)
+ .build();
+
+ private static final TimeZoneConfiguration CONFIG_AUTO_DISABLED =
+ createConfig(false /* autoDetection */, null);
+ private static final TimeZoneConfiguration CONFIG_AUTO_ENABLED =
+ createConfig(true /* autoDetection */, null);
+ private static final TimeZoneConfiguration CONFIG_GEO_DETECTION_ENABLED =
+ createConfig(null, true /* geoDetection */);
+ private static final TimeZoneConfiguration CONFIG_GEO_DETECTION_DISABLED =
+ createConfig(null, false /* geoDetection */);
+
private TimeZoneDetectorStrategyImpl mTimeZoneDetectorStrategy;
private FakeCallback mFakeCallback;
- private MockStrategyListener mMockStrategyListener;
+ private MockConfigChangeListener mMockConfigChangeListener;
+
@Before
public void setUp() {
mFakeCallback = new FakeCallback();
- mMockStrategyListener = new MockStrategyListener();
+ mMockConfigChangeListener = new MockConfigChangeListener();
mTimeZoneDetectorStrategy = new TimeZoneDetectorStrategyImpl(mFakeCallback);
- mFakeCallback.setStrategyForSettingsCallbacks(mTimeZoneDetectorStrategy);
- mTimeZoneDetectorStrategy.setStrategyListener(mMockStrategyListener);
+ mTimeZoneDetectorStrategy.addConfigChangeListener(mMockConfigChangeListener);
}
@Test
- public void testGetCapabilities() {
- new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- TimeZoneCapabilities expectedCapabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(expectedCapabilities, mTimeZoneDetectorStrategy.getCapabilities(USER_ID));
- }
-
- @Test
- public void testGetConfiguration() {
- new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- TimeZoneConfiguration expectedConfiguration = mFakeCallback.getConfiguration(USER_ID);
- assertTrue(expectedConfiguration.isComplete());
- assertEquals(expectedConfiguration, mTimeZoneDetectorStrategy.getConfiguration(USER_ID));
- }
-
- @Test
- public void testCapabilitiesTestInfra_unrestricted() {
- Script script = new Script();
-
- script.initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- {
- // Check the fake test infra is doing what is expected.
- TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabled());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getSuggestManualTimeZone());
- }
-
- script.initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- {
- // Check the fake test infra is doing what is expected.
- TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabled());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabled());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
- }
- }
-
- @Test
- public void testCapabilitiesTestInfra_restricted() {
- Script script = new Script();
-
- script.initializeUser(USER_ID, UserCase.RESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- {
- // Check the fake test infra is doing what is expected.
- TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureGeoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSuggestManualTimeZone());
- }
-
- script.initializeUser(USER_ID, UserCase.RESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- {
- // Check the fake test infra is doing what is expected.
- TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureGeoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSuggestManualTimeZone());
- }
- }
-
- @Test
- public void testCapabilitiesTestInfra_autoDetectNotSupported() {
- Script script = new Script();
-
- script.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- {
- // Check the fake test infra is doing what is expected.
- TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabled());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
- }
-
- script.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
- {
- // Check the fake test infra is doing what is expected.
- TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
- assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabled());
- assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabled());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
- }
+ public void testGetCurrentUserConfiguration() {
+ new Script().initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED);
+ ConfigurationInternal expectedConfiguration =
+ mFakeCallback.getConfigurationInternal(USER_ID);
+ assertEquals(expectedConfiguration,
+ mTimeZoneDetectorStrategy.getCurrentUserConfigurationInternal());
}
@Test
public void testUpdateConfiguration_unrestricted() {
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ Script script = new Script().initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED);
// Set the configuration with auto detection enabled.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, true /* expectedResult */);
// Nothing should have happened: it was initialized in this state.
script.verifyConfigurationNotChanged();
// Update the configuration with auto detection disabled.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_DISABLED, true /* expectedResult */);
// The settings should have been changed and the StrategyListener onChange() called.
- script.verifyConfigurationChangedAndReset(USER_ID,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ script.verifyConfigurationChangedAndReset(CONFIG_INT_AUTO_DISABLED_GEO_DISABLED);
// Update the configuration with auto detection enabled.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, true /* expectedResult */);
// The settings should have been changed and the StrategyListener onChange() called.
- script.verifyConfigurationChangedAndReset(USER_ID,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ script.verifyConfigurationChangedAndReset(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED);
// Update the configuration to enable geolocation time zone detection.
script.simulateUpdateConfiguration(
- USER_ID, CONFIG_GEO_DETECTION_ENABLED, true /* expectedResult */);
+ CONFIG_GEO_DETECTION_ENABLED, true /* expectedResult */);
// The settings should have been changed and the StrategyListener onChange() called.
- script.verifyConfigurationChangedAndReset(USER_ID,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED));
+ script.verifyConfigurationChangedAndReset(CONFIG_INT_AUTO_ENABLED_GEO_ENABLED);
}
@Test
public void testUpdateConfiguration_restricted() {
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.RESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ Script script = new Script().initializeConfig(CONFIG_INT_USER_RESTRICTED_AUTO_ENABLED);
// Try to update the configuration with auto detection disabled.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_DISABLED, false /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_DISABLED, false /* expectedResult */);
// The settings should not have been changed: user shouldn't have the capabilities.
script.verifyConfigurationNotChanged();
// Update the configuration with auto detection enabled.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, false /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, false /* expectedResult */);
// The settings should not have been changed: user shouldn't have the capabilities.
script.verifyConfigurationNotChanged();
- // Update the configuration to enable geolocation time zone detection.
+ // Try to update the configuration to enable geolocation time zone detection.
script.simulateUpdateConfiguration(
- USER_ID, CONFIG_GEO_DETECTION_ENABLED, false /* expectedResult */);
+ CONFIG_GEO_DETECTION_ENABLED, false /* expectedResult */);
// The settings should not have been changed: user shouldn't have the capabilities.
script.verifyConfigurationNotChanged();
@@ -287,20 +238,16 @@
@Test
public void testUpdateConfiguration_autoDetectNotSupported() {
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ Script script = new Script().initializeConfig(CONFIG_INT_AUTO_DETECT_NOT_SUPPORTED);
// Try to update the configuration with auto detection disabled.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_DISABLED, false /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_DISABLED, false /* expectedResult */);
// The settings should not have been changed: user shouldn't have the capabilities.
script.verifyConfigurationNotChanged();
// Update the configuration with auto detection enabled.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, false /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, false /* expectedResult */);
// The settings should not have been changed: user shouldn't have the capabilities.
script.verifyConfigurationNotChanged();
@@ -313,8 +260,7 @@
TelephonyTimeZoneSuggestion slotIndex2TimeZoneSuggestion =
createEmptySlotIndex2Suggestion();
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
script.simulateTelephonyTimeZoneSuggestion(slotIndex1TimeZoneSuggestion)
@@ -359,9 +305,7 @@
TelephonyTestCase testCase2 = newTelephonyTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH);
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ Script script = new Script().initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED);
// A low quality suggestions will not be taken: The device time zone setting is left
// uninitialized.
@@ -426,8 +370,7 @@
for (TelephonyTestCase testCase : TELEPHONY_TEST_CASES) {
// Start with the device in a known state.
- script.initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ script.initializeConfig(CONFIG_INT_AUTO_DISABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
TelephonyTimeZoneSuggestion suggestion =
@@ -447,8 +390,7 @@
mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
// Toggling the time zone setting on should cause the device setting to be set.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED,
- true /* expectedResult */);
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, true /* expectedResult */);
// When time zone detection is already enabled the suggestion (if it scores highly
// enough) should be set immediately.
@@ -465,8 +407,7 @@
mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
// Toggling the time zone setting should off should do nothing.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
+ script.simulateUpdateConfiguration(CONFIG_AUTO_DISABLED, true /* expectedResult */)
.verifyTimeZoneNotChanged();
// Assert internal service state.
@@ -480,8 +421,7 @@
@Test
public void testTelephonySuggestionsSingleSlotId() {
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
for (TelephonyTestCase testCase : TELEPHONY_TEST_CASES) {
@@ -546,8 +486,7 @@
TELEPHONY_SCORE_NONE);
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID)
// Initialize the latest suggestions as empty so we don't need to worry about nulls
// below for the first loop.
@@ -632,9 +571,7 @@
*/
@Test
public void testTelephonySuggestionStrategyDoesNotAssumeCurrentSetting_autoTelephony() {
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
+ Script script = new Script().initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED);
TelephonyTestCase testCase = newTelephonyTestCase(
MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH);
@@ -652,40 +589,39 @@
// Toggling time zone detection should set the device time zone only if the current setting
// value is different from the most recent telephony suggestion.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
+ script.simulateUpdateConfiguration(CONFIG_AUTO_DISABLED, true /* expectedResult */)
.verifyTimeZoneNotChanged()
- .simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
+ .simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, true /* expectedResult */)
.verifyTimeZoneNotChanged();
// Simulate a user turning auto detection off, a new suggestion being made while auto
// detection is off, and the user turning it on again.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
+ script.simulateUpdateConfiguration(CONFIG_AUTO_DISABLED, true /* expectedResult */)
.simulateTelephonyTimeZoneSuggestion(newYorkSuggestion)
.verifyTimeZoneNotChanged();
// Latest suggestion should be used.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(newYorkSuggestion);
}
@Test
- public void testManualSuggestion_autoDetectionEnabled_autoTelephony() {
- checkManualSuggestion_autoDetectionEnabled(false /* geoDetectionEnabled */);
+ public void testManualSuggestion_unrestricted_autoDetectionEnabled_autoTelephony() {
+ checkManualSuggestion_unrestricted_autoDetectionEnabled(false /* geoDetectionEnabled */);
}
@Test
- public void testManualSuggestion_autoDetectionEnabled_autoGeo() {
- checkManualSuggestion_autoDetectionEnabled(true /* geoDetectionEnabled */);
+ public void testManualSuggestion_unrestricted_autoDetectionEnabled_autoGeo() {
+ checkManualSuggestion_unrestricted_autoDetectionEnabled(true /* geoDetectionEnabled */);
}
- private void checkManualSuggestion_autoDetectionEnabled(boolean geoDetectionEnabled) {
- TimeZoneConfiguration geoTzEnabledConfig =
- new TimeZoneConfiguration.Builder()
+ private void checkManualSuggestion_unrestricted_autoDetectionEnabled(
+ boolean geoDetectionEnabled) {
+ ConfigurationInternal geoTzEnabledConfig =
+ new ConfigurationInternal.Builder(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED)
.setGeoDetectionEnabled(geoDetectionEnabled)
.build();
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(geoTzEnabledConfig))
+ .initializeConfig(geoTzEnabledConfig)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
// Auto time zone detection is enabled so the manual suggestion should be ignored.
@@ -697,35 +633,19 @@
@Test
public void testManualSuggestion_restricted_simulateAutoTimeZoneEnabled() {
Script script = new Script()
- .initializeUser(USER_ID, UserCase.RESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_USER_RESTRICTED_AUTO_ENABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
- // Auto time zone detection is enabled so the manual suggestion should be ignored.
+ // User is restricted so the manual suggestion should be ignored.
script.simulateManualTimeZoneSuggestion(
USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
- .verifyTimeZoneNotChanged();
- }
-
- @Test
- public void testManualSuggestion_autoDetectNotSupported_simulateAutoTimeZoneEnabled() {
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
- .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
-
- // Auto time zone detection is enabled so the manual suggestion should be ignored.
- ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
- script.simulateManualTimeZoneSuggestion(
- USER_ID, manualSuggestion, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset(manualSuggestion);
+ .verifyTimeZoneNotChanged();
}
@Test
public void testManualSuggestion_unrestricted_autoTimeZoneDetectionDisabled() {
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_DISABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
// Auto time zone detection is disabled so the manual suggestion should be used.
@@ -738,8 +658,7 @@
@Test
public void testManualSuggestion_restricted_autoTimeZoneDetectionDisabled() {
Script script = new Script()
- .initializeUser(USER_ID, UserCase.RESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_USER_RESTRICTED_AUTO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
// Restricted users do not have the capability.
@@ -750,10 +669,9 @@
}
@Test
- public void testManualSuggestion_autoDetectNotSupported_autoTimeZoneDetectionDisabled() {
+ public void testManualSuggestion_autoDetectNotSupported() {
Script script = new Script()
- .initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_DETECT_NOT_SUPPORTED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
// Unrestricted users have the capability.
@@ -765,9 +683,7 @@
@Test
public void testGeoSuggestion_uncertain() {
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
+ Script script = new Script().initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_ENABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
GeolocationTimeZoneSuggestion uncertainSuggestion = createUncertainGeoLocationSuggestion();
@@ -783,8 +699,7 @@
@Test
public void testGeoSuggestion_noZones() {
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_ENABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
GeolocationTimeZoneSuggestion noZonesSuggestion = createGeoLocationSuggestion(list());
@@ -802,8 +717,7 @@
createGeoLocationSuggestion(list("Europe/London"));
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_ENABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
script.simulateGeolocationTimeZoneSuggestion(suggestion)
@@ -828,8 +742,7 @@
createGeoLocationSuggestion(list("Europe/Paris"));
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_ENABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
script.simulateGeolocationTimeZoneSuggestion(londonOnlySuggestion)
@@ -856,72 +769,27 @@
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
}
- /**
- * Confirms that toggling the auto time zone detection enabled setting has the expected behavior
- * when the strategy is "opinionated" and "un-opinionated" when in geolocation detection is
- * enabled.
- */
@Test
- public void testTogglingAutoDetectionEnabled_autoGeo() {
- GeolocationTimeZoneSuggestion geolocationSuggestion =
+ public void testGeoSuggestion_togglingGeoDetectionClearsLastSuggestion() {
+ GeolocationTimeZoneSuggestion suggestion =
createGeoLocationSuggestion(list("Europe/London"));
- GeolocationTimeZoneSuggestion uncertainGeolocationSuggestion =
- createUncertainGeoLocationSuggestion();
- ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_ENABLED))
+ .initializeConfig(CONFIG_INT_AUTO_ENABLED_GEO_ENABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
- script.simulateGeolocationTimeZoneSuggestion(geolocationSuggestion);
-
- // When time zone detection is not enabled, the time zone suggestion will not be set.
- script.verifyTimeZoneNotChanged();
-
- // Assert internal service state.
- assertEquals(geolocationSuggestion,
- mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
-
- // Toggling the time zone setting on should cause the device setting to be set.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
+ script.simulateGeolocationTimeZoneSuggestion(suggestion)
.verifyTimeZoneChangedAndReset("Europe/London");
- // Toggling the time zone setting should off should do nothing because the device is now
- // set to that time zone.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
- .verifyTimeZoneNotChanged()
- .simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
- .verifyTimeZoneNotChanged();
+ // Assert internal service state.
+ assertEquals(suggestion, mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
- // Now toggle auto time zone setting, and confirm it is opinionated.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
- .simulateManualTimeZoneSuggestion(
- USER_ID, manualSuggestion, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset(manualSuggestion)
- .simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset("Europe/London");
-
- // Now withdraw the geolocation suggestion, and assert the strategy is no longer
- // opinionated.
- /* expectedResult */
- script.simulateGeolocationTimeZoneSuggestion(uncertainGeolocationSuggestion)
- .verifyTimeZoneNotChanged()
- .simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
- .verifyTimeZoneNotChanged()
- .simulateManualTimeZoneSuggestion(
- USER_ID, manualSuggestion, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset(manualSuggestion)
- .simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
- .verifyTimeZoneNotChanged();
+ // Turn off geo detection and verify the latest suggestion is cleared.
+ script.simulateUpdateConfiguration(CONFIG_GEO_DETECTION_DISABLED, true)
+ .verifyConfigurationChangedAndReset(CONFIG_INT_AUTO_ENABLED_GEO_DISABLED);
// Assert internal service state.
- assertEquals(uncertainGeolocationSuggestion,
- mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
+ assertNull(mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
}
/**
@@ -937,88 +805,48 @@
"Europe/Paris");
Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_DISABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
// Add suggestions. Nothing should happen as time zone detection is disabled.
script.simulateGeolocationTimeZoneSuggestion(geolocationSuggestion)
.verifyTimeZoneNotChanged();
+
+ // Geolocation suggestions are only stored when geolocation detection is enabled.
+ assertNull(mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
+
script.simulateTelephonyTimeZoneSuggestion(telephonySuggestion)
.verifyTimeZoneNotChanged();
- // Assert internal service state.
- assertEquals(geolocationSuggestion,
- mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
+ // Telephony suggestions are always stored.
assertEquals(telephonySuggestion,
mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1).suggestion);
// Toggling the time zone detection enabled setting on should cause the device setting to be
// set from the telephony signal, as we've started with geolocation time zone detection
// disabled.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
+ script.simulateUpdateConfiguration(CONFIG_AUTO_ENABLED, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(telephonySuggestion);
- // Changing the detection to enable geo detection should cause the device tz setting to
- // change to the geo suggestion.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_GEO_DETECTION_ENABLED, true /* expectedResult */)
+ // Changing the detection to enable geo detection won't cause the device tz setting to
+ // change because the geo suggestion is empty.
+ script.simulateUpdateConfiguration(CONFIG_GEO_DETECTION_ENABLED, true /* expectedResult */)
+ .verifyTimeZoneNotChanged()
+ .simulateGeolocationTimeZoneSuggestion(geolocationSuggestion)
.verifyTimeZoneChangedAndReset(geolocationSuggestion.getZoneIds().get(0));
// Changing the detection to disable geo detection should cause the device tz setting to
// change to the telephony suggestion.
- script.simulateUpdateConfiguration(
- USER_ID, CONFIG_GEO_DETECTION_DISABLED, true /* expectedResult */)
+ script.simulateUpdateConfiguration(CONFIG_GEO_DETECTION_DISABLED, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(telephonySuggestion);
- }
- /**
- * The {@link TimeZoneDetectorStrategyImpl.Callback} is left to detect whether changing the time
- * zone is actually necessary. This test proves that the strategy doesn't assume it knows the
- * current setting.
- */
- @Test
- public void testTimeZoneDetectorStrategyDoesNotAssumeCurrentSetting_autoGeo() {
- GeolocationTimeZoneSuggestion losAngelesSuggestion =
- createGeoLocationSuggestion(list("America/Los_Angeles"));
- GeolocationTimeZoneSuggestion newYorkSuggestion =
- createGeoLocationSuggestion(list("America/New_York"));
-
- Script script = new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED));
-
- // Initialization.
- script.simulateGeolocationTimeZoneSuggestion(losAngelesSuggestion)
- .verifyTimeZoneChangedAndReset("America/Los_Angeles");
- // Suggest it again - it should not be set because it is already set.
- script.simulateGeolocationTimeZoneSuggestion(losAngelesSuggestion)
- .verifyTimeZoneNotChanged();
-
- // Toggling time zone detection should set the device time zone only if the current setting
- // value is different from the most recent telephony suggestion.
- /* expectedResult */
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
- .verifyTimeZoneNotChanged()
- .simulateUpdateConfiguration(
- USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
- .verifyTimeZoneNotChanged();
-
- // Simulate a user turning auto detection off, a new suggestion being made while auto
- // detection is off, and the user turning it on again.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
- .simulateGeolocationTimeZoneSuggestion(newYorkSuggestion)
- .verifyTimeZoneNotChanged();
- // Latest suggestion should be used.
- script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset("America/New_York");
+ assertNull(mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
}
@Test
public void testAddDumpable() {
new Script()
- .initializeUser(USER_ID, UserCase.UNRESTRICTED,
- CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
+ .initializeConfig(CONFIG_INT_AUTO_DISABLED_GEO_DISABLED)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
AtomicBoolean dumpCalled = new AtomicBoolean(false);
@@ -1069,25 +897,26 @@
return suggestion;
}
+ private static TimeZoneConfiguration createConfig(
+ @Nullable Boolean autoDetection, @Nullable Boolean geoDetection) {
+ TimeZoneConfiguration.Builder builder = new TimeZoneConfiguration.Builder(USER_ID);
+ if (autoDetection != null) {
+ builder.setAutoDetectionEnabled(autoDetection);
+ }
+ if (geoDetection != null) {
+ builder.setGeoDetectionEnabled(geoDetection);
+ }
+ return builder.build();
+ }
+
static class FakeCallback implements TimeZoneDetectorStrategyImpl.Callback {
- private TimeZoneCapabilities mCapabilities;
- private final TestState<UserConfiguration> mConfiguration = new TestState<>();
+ private final TestState<ConfigurationInternal> mConfigurationInternal = new TestState<>();
private final TestState<String> mTimeZoneId = new TestState<>();
- private TimeZoneDetectorStrategyImpl mStrategy;
+ private ConfigurationChangeListener mConfigChangeListener;
- void setStrategyForSettingsCallbacks(TimeZoneDetectorStrategyImpl strategy) {
- assertNotNull(strategy);
- mStrategy = strategy;
- }
-
- void initializeUser(@UserIdInt int userId, TimeZoneCapabilities capabilities,
- TimeZoneConfiguration configuration) {
- assertEquals(userId, capabilities.getUserId());
- mCapabilities = capabilities;
- assertTrue("Configuration must be complete when initializing, config=" + configuration,
- configuration.isComplete());
- mConfiguration.init(new UserConfiguration(userId, configuration));
+ void initializeConfig(ConfigurationInternal configurationInternal) {
+ mConfigurationInternal.init(configurationInternal);
}
void initializeTimeZoneSetting(String zoneId) {
@@ -1095,43 +924,22 @@
}
@Override
- public TimeZoneCapabilities getCapabilities(@UserIdInt int userId) {
- assertEquals(userId, mCapabilities.getUserId());
- return mCapabilities;
+ public void setConfigChangeListener(ConfigurationChangeListener listener) {
+ mConfigChangeListener = listener;
}
@Override
- public TimeZoneConfiguration getConfiguration(@UserIdInt int userId) {
- UserConfiguration latest = mConfiguration.getLatest();
- assertEquals(userId, latest.userId);
- return latest.configuration;
- }
-
- @Override
- public void setConfiguration(@UserIdInt int userId, TimeZoneConfiguration newConfig) {
- assertNotNull(newConfig);
- assertTrue(newConfig.isComplete());
-
- UserConfiguration latestUserConfig = mConfiguration.getLatest();
- assertEquals(userId, latestUserConfig.userId);
- TimeZoneConfiguration oldConfig = latestUserConfig.configuration;
-
- mConfiguration.set(new UserConfiguration(userId, newConfig));
-
- if (!newConfig.equals(oldConfig)) {
- // Simulate what happens when the auto detection configuration is changed.
- mStrategy.handleAutoTimeZoneConfigChanged();
+ public ConfigurationInternal getConfigurationInternal(int userId) {
+ ConfigurationInternal configuration = mConfigurationInternal.getLatest();
+ if (userId != configuration.getUserId()) {
+ fail("FakeCallback does not support multiple users.");
}
+ return configuration;
}
@Override
- public boolean isAutoDetectionEnabled() {
- return mConfiguration.getLatest().configuration.isAutoDetectionEnabled();
- }
-
- @Override
- public boolean isGeoDetectionEnabled() {
- return mConfiguration.getLatest().configuration.isGeoDetectionEnabled();
+ public int getCurrentUserId() {
+ return mConfigurationInternal.getLatest().getUserId();
}
@Override
@@ -1149,9 +957,25 @@
mTimeZoneId.set(zoneId);
}
+ @Override
+ public void storeConfiguration(TimeZoneConfiguration newConfiguration) {
+ ConfigurationInternal oldConfiguration = mConfigurationInternal.getLatest();
+ if (newConfiguration.getUserId() != oldConfiguration.getUserId()) {
+ fail("FakeCallback does not support multiple users");
+ }
+
+ ConfigurationInternal mergedConfiguration = oldConfiguration.merge(newConfiguration);
+ if (!mergedConfiguration.equals(oldConfiguration)) {
+ mConfigurationInternal.set(mergedConfiguration);
+
+ // Note: Unlike the real callback impl, the listener is invoked synchronously.
+ mConfigChangeListener.onChange();
+ }
+ }
+
void assertKnownUser(int userId) {
- assertEquals(userId, mCapabilities.getUserId());
- assertEquals(userId, mConfiguration.getLatest().userId);
+ assertEquals("FakeCallback does not support multiple users",
+ mConfigurationInternal.getLatest().getUserId(), userId);
}
void assertTimeZoneNotChanged() {
@@ -1166,43 +990,7 @@
void commitAllChanges() {
mTimeZoneId.commitLatest();
- mConfiguration.commitLatest();
- }
- }
-
- private static final class UserConfiguration {
- public final @UserIdInt int userId;
- public final TimeZoneConfiguration configuration;
-
- UserConfiguration(int userId, TimeZoneConfiguration configuration) {
- this.userId = userId;
- this.configuration = configuration;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- UserConfiguration that = (UserConfiguration) o;
- return userId == that.userId
- && Objects.equals(configuration, that.configuration);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(userId, configuration);
- }
-
- @Override
- public String toString() {
- return "UserConfiguration{"
- + "userId=" + userId
- + ", configuration=" + configuration
- + '}';
+ mConfigurationInternal.commitLatest();
}
}
@@ -1255,64 +1043,14 @@
}
}
- /** Simulated user test cases. */
- enum UserCase {
- /** A catch-all for users that can set auto time zone config. */
- UNRESTRICTED,
- /** A catch-all for users that can't set auto time zone config. */
- RESTRICTED,
- /**
- * Like {@link #UNRESTRICTED}, but auto tz detection is not
- * supported on the device.
- */
- AUTO_DETECT_NOT_SUPPORTED,
- }
-
- /**
- * Creates a {@link TimeZoneCapabilities} object for a user in the specific role with the
- * supplied configuration.
- */
- private static TimeZoneCapabilities createCapabilities(
- int userId, UserCase userCase, TimeZoneConfiguration configuration) {
- switch (userCase) {
- case UNRESTRICTED: {
- int suggestManualTimeZoneCapability = configuration.isAutoDetectionEnabled()
- ? CAPABILITY_NOT_APPLICABLE : CAPABILITY_POSSESSED;
- return new TimeZoneCapabilities.Builder(userId)
- .setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
- .setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
- .setSuggestManualTimeZone(suggestManualTimeZoneCapability)
- .build();
- }
- case RESTRICTED: {
- return new TimeZoneCapabilities.Builder(userId)
- .setConfigureAutoDetectionEnabled(CAPABILITY_NOT_ALLOWED)
- .setConfigureGeoDetectionEnabled(CAPABILITY_NOT_ALLOWED)
- .setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED)
- .build();
- }
- case AUTO_DETECT_NOT_SUPPORTED: {
- return new TimeZoneCapabilities.Builder(userId)
- .setConfigureAutoDetectionEnabled(CAPABILITY_NOT_SUPPORTED)
- .setConfigureGeoDetectionEnabled(CAPABILITY_NOT_SUPPORTED)
- .setSuggestManualTimeZone(CAPABILITY_POSSESSED)
- .build();
- }
- default:
- throw new AssertionError(userCase + " not recognized");
- }
- }
-
/**
* A "fluent" class allows reuse of code in tests: initialization, simulation and verification
* logic.
*/
private class Script {
- Script initializeUser(
- @UserIdInt int userId, UserCase userCase, TimeZoneConfiguration configuration) {
- TimeZoneCapabilities capabilities = createCapabilities(userId, userCase, configuration);
- mFakeCallback.initializeUser(userId, capabilities, configuration);
+ Script initializeConfig(ConfigurationInternal configuration) {
+ mFakeCallback.initializeConfig(configuration);
return this;
}
@@ -1326,10 +1064,9 @@
* the return value.
*/
Script simulateUpdateConfiguration(
- @UserIdInt int userId, TimeZoneConfiguration configuration,
- boolean expectedResult) {
+ TimeZoneConfiguration configuration, boolean expectedResult) {
assertEquals(expectedResult,
- mTimeZoneDetectorStrategy.updateConfiguration(userId, configuration));
+ mTimeZoneDetectorStrategy.updateConfiguration(configuration));
return this;
}
@@ -1392,16 +1129,14 @@
/**
* Verifies that the configuration has been changed to the expected value.
*/
- Script verifyConfigurationChangedAndReset(
- @UserIdInt int userId, TimeZoneConfiguration expected) {
- mFakeCallback.mConfiguration.assertHasBeenSet();
- UserConfiguration expectedUserConfig = new UserConfiguration(userId, expected);
- assertEquals(expectedUserConfig, mFakeCallback.mConfiguration.getLatest());
+ Script verifyConfigurationChangedAndReset(ConfigurationInternal expected) {
+ mFakeCallback.mConfigurationInternal.assertHasBeenSet();
+ assertEquals(expected, mFakeCallback.mConfigurationInternal.getLatest());
mFakeCallback.commitAllChanges();
// Also confirm the listener triggered.
- mMockStrategyListener.verifyOnConfigurationChangedCalled();
- mMockStrategyListener.reset();
+ mMockConfigChangeListener.verifyOnChangeCalled();
+ mMockConfigChangeListener.reset();
return this;
}
@@ -1410,10 +1145,10 @@
* {@link TimeZoneConfiguration} have been changed.
*/
Script verifyConfigurationNotChanged() {
- mFakeCallback.mConfiguration.assertHasNotBeenSet();
+ mFakeCallback.mConfigurationInternal.assertHasNotBeenSet();
// Also confirm the listener did not trigger.
- mMockStrategyListener.verifyOnConfigurationChangedNotCalled();
+ mMockConfigChangeListener.verifyOnChangeNotCalled();
return this;
}
@@ -1448,24 +1183,24 @@
return new TelephonyTestCase(matchType, quality, expectedScore);
}
- private static class MockStrategyListener implements TimeZoneDetectorStrategy.StrategyListener {
- private boolean mOnConfigurationChangedCalled;
+ private static class MockConfigChangeListener implements ConfigurationChangeListener {
+ private boolean mOnChangeCalled;
@Override
- public void onConfigurationChanged() {
- mOnConfigurationChangedCalled = true;
+ public void onChange() {
+ mOnChangeCalled = true;
}
- void verifyOnConfigurationChangedCalled() {
- assertTrue(mOnConfigurationChangedCalled);
+ void verifyOnChangeCalled() {
+ assertTrue(mOnChangeCalled);
}
- void verifyOnConfigurationChangedNotCalled() {
- assertFalse(mOnConfigurationChangedCalled);
+ void verifyOnChangeNotCalled() {
+ assertFalse(mOnChangeCalled);
}
void reset() {
- mOnConfigurationChangedCalled = false;
+ mOnChangeCalled = false;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index d54b4a0..f8baf84 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1110,7 +1110,7 @@
performLayout(mDisplayContent);
// The frame is empty because the requested height is zero.
- assertTrue(win.getFrameLw().isEmpty());
+ assertTrue(win.getFrame().isEmpty());
// The window should be scheduled to resize then the client may report a new non-empty size.
win.updateResizingWindowIfNeeded();
assertThat(mWm.mResizingWindows).contains(win);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 0675c6d..2d834ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -114,7 +114,7 @@
mWindow = spy(createWindow(null, TYPE_APPLICATION, "window"));
// We only test window frames set by DisplayPolicy, so here prevents computeFrameLw from
// changing those frames.
- doNothing().when(mWindow).computeFrameLw();
+ doNothing().when(mWindow).computeFrame();
final WindowManager.LayoutParams attrs = mWindow.mAttrs;
attrs.width = MATCH_PARENT;
@@ -179,7 +179,7 @@
WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
- win.getFrameLw().set(0, 0, 500, 100);
+ win.getFrame().set(0, 0, 500, 100);
addWindow(win);
InsetsStateController controller = mDisplayContent.getInsetsStateController();
@@ -207,7 +207,7 @@
mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
- win.getFrameLw().set(0, 0, 500, 100);
+ win.getFrame().set(0, 0, 500, 100);
addWindow(win);
mDisplayContent.getInsetsStateController().onPostLayout();
@@ -232,7 +232,7 @@
WindowState win1 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel1");
win1.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
win1.mAttrs.gravity = Gravity.TOP;
- win1.getFrameLw().set(0, 0, 200, 500);
+ win1.getFrame().set(0, 0, 200, 500);
addWindow(win1);
assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_TOP);
@@ -241,7 +241,7 @@
WindowState win2 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel2");
win2.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
win2.mAttrs.gravity = Gravity.BOTTOM;
- win2.getFrameLw().set(0, 0, 200, 500);
+ win2.getFrame().set(0, 0, 200, 500);
addWindow(win2);
assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_BOTTOM);
@@ -250,7 +250,7 @@
WindowState win3 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel3");
win3.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
win3.mAttrs.gravity = Gravity.LEFT;
- win3.getFrameLw().set(0, 0, 200, 500);
+ win3.getFrame().set(0, 0, 200, 500);
addWindow(win3);
assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_LEFT);
@@ -259,7 +259,7 @@
WindowState win4 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel4");
win4.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
win4.mAttrs.gravity = Gravity.RIGHT;
- win4.getFrameLw().set(0, 0, 200, 500);
+ win4.getFrame().set(0, 0, 200, 500);
addWindow(win4);
assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_RIGHT);
@@ -274,11 +274,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -290,11 +290,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -306,11 +306,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -322,11 +322,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -342,11 +342,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -362,11 +362,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -381,11 +381,11 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@@ -402,10 +402,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
}
@Test
@@ -422,10 +422,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
}
@Test
@@ -442,10 +442,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@Test
@@ -462,10 +462,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@Test
@@ -484,10 +484,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
}
@Test
@@ -506,10 +506,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
}
@Test
@@ -529,10 +529,10 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
}
@@ -549,11 +549,11 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrame(),
DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
@@ -570,11 +570,11 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
+ assertInsetBy(mWindow.getStableFrame(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+ assertInsetBy(mWindow.getContentFrame(),
NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
}
@Test
@@ -594,8 +594,8 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrame(),
DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@@ -615,7 +615,7 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
}
@Test
@@ -636,8 +636,8 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrame(),
DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@@ -655,11 +655,11 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
@@ -676,12 +676,12 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0,
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
+ assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
@@ -698,11 +698,11 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
@@ -719,11 +719,11 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
+ assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@Test
@@ -740,11 +740,11 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@Test
@@ -904,34 +904,34 @@
updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT);
// Decor on bottom
updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT,
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT,
DECOR_WINDOW_INSET);
// Decor on the left
updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0,
+ assertInsetBy(mWindow.getContentFrame(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
// Decor on the right
updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET,
+ assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET,
NAV_BAR_HEIGHT);
// Decor not allowed as inset
updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
}
private void updateDecorWindow(WindowState decorWindow, int width, int height, int gravity) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 4483f8c..b50530e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -297,7 +297,7 @@
final WindowState navigationBar = createNavigationBarWindow();
- navigationBar.getFrameLw().set(new Rect(100, 200, 200, 300));
+ navigationBar.getFrame().set(new Rect(100, 200, 200, 300));
assertFalse("Freeform is overlapping with navigation bar",
DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
@@ -377,7 +377,7 @@
mDisplayContent.setInputMethodWindowLocked(mImeWindow);
mImeWindow.mAttrs.setFitInsetsSides(Side.all() & ~Side.BOTTOM);
- mImeWindow.getGivenContentInsetsLw().set(0, displayInfo.logicalHeight, 0, 0);
+ mImeWindow.mGivenContentInsets.set(0, displayInfo.logicalHeight, 0, 0);
mImeWindow.getControllableInsetProvider().setServerVisible(true);
displayPolicy.beginLayoutLw(mDisplayContent.mDisplayFrames, 0 /* UI mode */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 1d6dd0b..a0fa936 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -61,7 +61,7 @@
@Test
public void testPostLayout() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
statusBar.mHasSurface = true;
mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
@@ -76,9 +76,9 @@
@Test
public void testPostLayout_givenInsets() {
final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
- ime.getFrameLw().set(0, 0, 500, 100);
- ime.getGivenContentInsetsLw().set(0, 0, 0, 60);
- ime.getGivenVisibleInsetsLw().set(0, 0, 0, 75);
+ ime.getFrame().set(0, 0, 500, 100);
+ ime.mGivenContentInsets.set(0, 0, 0, 60);
+ ime.mGivenVisibleInsets.set(0, 0, 0, 75);
ime.mHasSurface = true;
mProvider.setWindow(ime, null, null);
mProvider.onPostLayout();
@@ -94,7 +94,7 @@
@Test
public void testPostLayout_invisible() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
assertEquals(Insets.NONE, mProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
@@ -104,7 +104,7 @@
@Test
public void testPostLayout_frameProvider() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
statusBar.mHasSurface = true;
mProvider.setWindow(statusBar,
(displayFrames, windowState, rect) -> {
@@ -118,7 +118,7 @@
public void testUpdateControlForTarget() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
// We must not have control or control target before we have the insets source window.
mProvider.updateControlForTarget(target, true /* force */);
@@ -163,7 +163,7 @@
public void testUpdateControlForFakeTarget() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForFakeTarget(target);
assertNotNull(mProvider.getControl(target));
@@ -176,7 +176,7 @@
public void testUpdateSourceFrameForIme() {
final WindowState inputMethod = createWindow(null, TYPE_INPUT_METHOD, "inputMethod");
- inputMethod.getFrameLw().set(new Rect(0, 400, 500, 500));
+ inputMethod.getFrame().set(new Rect(0, 400, 500, 500));
mImeProvider.setWindow(inputMethod, null, null);
mImeProvider.setServerVisible(false);
@@ -190,7 +190,7 @@
mImeProvider.setServerVisible(true);
mImeSource.setVisible(true);
mImeProvider.updateSourceFrame();
- assertEquals(inputMethod.getFrameLw(), mImeSource.getFrame());
+ assertEquals(inputMethod.getFrame(), mImeSource.getFrame());
insets = mImeSource.calculateInsets(new Rect(0, 0, 500, 500),
false /* ignoreVisibility */);
assertEquals(Insets.of(0, 0, 0, 100), insets);
@@ -200,7 +200,7 @@
public void testInsetsModified() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForTarget(target, false /* force */);
InsetsState state = new InsetsState();
@@ -213,7 +213,7 @@
public void testInsetsModified_noControl() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
mProvider.setWindow(statusBar, null, null);
InsetsState state = new InsetsState();
state.getSource(ITYPE_STATUS_BAR).setVisible(false);
@@ -224,7 +224,7 @@
@Test
public void testInsetGeometries() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- statusBar.getFrameLw().set(0, 0, 500, 100);
+ statusBar.getFrame().set(0, 0, 500, 100);
statusBar.mHasSurface = true;
mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
@@ -236,7 +236,7 @@
false /* ignoreVisibility */));
// Don't apply left insets if window is left-of inset-window but still overlaps
- statusBar.getFrameLw().set(100, 0, 0, 0);
+ statusBar.getFrame().set(100, 0, 0, 0);
assertEquals(Insets.of(0, 0, 0, 0),
mProvider.getSource().calculateInsets(new Rect(-100, 0, 400, 500),
false /* ignoreVisibility */));
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 4a8e8da..dc85904 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -86,11 +86,6 @@
}
@Override
- public int getMaxWallpaperLayer() {
- return 0;
- }
-
- @Override
public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
return attrs.type == TYPE_NOTIFICATION_SHADE;
}
@@ -377,11 +372,6 @@
}
@Override
- public boolean isTopLevelWindow(int windowType) {
- return false;
- }
-
- @Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index ed9e270..63367ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -133,8 +133,8 @@
int expectedWidth = (int) (wallpaperWidth * (displayHeight / (double) wallpaperHeight));
// Check that the wallpaper is correctly scaled
- assertEquals(new Rect(0, 0, expectedWidth, displayHeight), wallpaperWindow.getFrameLw());
- Rect portraitFrame = wallpaperWindow.getFrameLw();
+ assertEquals(new Rect(0, 0, expectedWidth, displayHeight), wallpaperWindow.getFrame());
+ Rect portraitFrame = wallpaperWindow.getFrame();
// Rotate the display
dc.getDisplayRotation().updateOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, true);
@@ -149,7 +149,7 @@
// Check that the wallpaper has the same frame in landscape than in portrait
assertEquals(Configuration.ORIENTATION_LANDSCAPE, dc.getConfiguration().orientation);
- assertEquals(portraitFrame, wallpaperWindow.getFrameLw());
+ assertEquals(portraitFrame, wallpaperWindow.getFrame());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index eb2aa41..ca3626d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -89,29 +89,29 @@
}
private void assertFrame(WindowState w, Rect frame) {
- assertEquals(w.getFrameLw(), frame);
+ assertEquals(w.getFrame(), frame);
}
private void assertFrame(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getFrameLw(), left, top, right, bottom);
+ assertRect(w.getFrame(), left, top, right, bottom);
}
private void assertRelFrame(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getRelativeFrameLw(), left, top, right, bottom);
+ assertRect(w.getRelativeFrame(), left, top, right, bottom);
}
private void assertContentFrame(WindowState w, Rect expectedRect) {
- assertRect(w.getContentFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ assertRect(w.getContentFrame(), expectedRect.left, expectedRect.top, expectedRect.right,
expectedRect.bottom);
}
private void assertVisibleFrame(WindowState w, Rect expectedRect) {
- assertRect(w.getVisibleFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ assertRect(w.getVisibleFrame(), expectedRect.left, expectedRect.top, expectedRect.right,
expectedRect.bottom);
}
private void assertStableFrame(WindowState w, Rect expectedRect) {
- assertRect(w.getStableFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ assertRect(w.getStableFrame(), expectedRect.left, expectedRect.top, expectedRect.right,
expectedRect.bottom);
}
@@ -155,7 +155,7 @@
// the difference between mFrame and ContentFrame. Visible
// and stable frames work the same way.
w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 0, 0, 1000, 1000);
assertRelFrame(w, 0, 0, 1000, 1000);
assertContentInset(w, 0, topContentInset, 0, bottomContentInset);
@@ -170,14 +170,14 @@
w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT
w.mRequestedWidth = 100;
w.mRequestedHeight = 100;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 100, 100, 200, 200);
assertRelFrame(w, 100, 100, 200, 200);
assertContentInset(w, 0, 0, 0, 0);
// In this case the frames are shrunk to the window frame.
- assertContentFrame(w, w.getFrameLw());
- assertVisibleFrame(w, w.getFrameLw());
- assertStableFrame(w, w.getFrameLw());
+ assertContentFrame(w, w.getFrame());
+ assertVisibleFrame(w, w.getFrame());
+ assertStableFrame(w, w.getFrame());
}
@Test
@@ -193,7 +193,7 @@
// Here the window has FILL_PARENT, FILL_PARENT
// so we expect it to fill the entire available frame.
w.getWindowFrames().setFrames(pf, pf, pf, pf, pf, pf);
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 0, 0, 1000, 1000);
assertRelFrame(w, 0, 0, 1000, 1000);
@@ -202,14 +202,14 @@
// and we use mRequestedWidth/mRequestedHeight
w.mAttrs.width = 300;
w.mAttrs.height = 300;
- w.computeFrameLw();
+ w.computeFrame();
// Explicit width and height without requested width/height
// gets us nothing.
assertFrame(w, 0, 0, 0, 0);
w.mRequestedWidth = 300;
w.mRequestedHeight = 300;
- w.computeFrameLw();
+ w.computeFrame();
// With requestedWidth/Height we can freely choose our size within the
// parent bounds.
assertFrame(w, 0, 0, 300, 300);
@@ -222,14 +222,14 @@
w.mRequestedWidth = -1;
w.mAttrs.width = 100;
w.mAttrs.height = 100;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 0, 0, 100, 100);
w.mAttrs.flags = 0;
// But sizes too large will be clipped to the containing frame
w.mRequestedWidth = 1200;
w.mRequestedHeight = 1200;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 0, 0, 1000, 1000);
// Before they are clipped though windows will be shifted
@@ -237,7 +237,7 @@
w.mAttrs.y = 300;
w.mRequestedWidth = 1000;
w.mRequestedHeight = 1000;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 0, 0, 1000, 1000);
// If there is room to move around in the parent frame the window will be shifted according
@@ -247,18 +247,18 @@
w.mRequestedWidth = 300;
w.mRequestedHeight = 300;
w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 700, 0, 1000, 300);
assertRelFrame(w, 700, 0, 1000, 300);
w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 700, 700, 1000, 1000);
assertRelFrame(w, 700, 700, 1000, 1000);
// Window specified x and y are interpreted as offsets in the opposite
// direction of gravity
w.mAttrs.x = 100;
w.mAttrs.y = 100;
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, 600, 600, 900, 900);
assertRelFrame(w, 600, 600, 900, 900);
}
@@ -285,12 +285,12 @@
final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
final WindowFrames windowFrames = w.getWindowFrames();
windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
- w.computeFrameLw();
+ w.computeFrame();
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
- assertEquals(resolvedTaskBounds, w.getFrameLw());
- assertEquals(0, w.getRelativeFrameLw().left);
- assertEquals(0, w.getRelativeFrameLw().top);
+ assertEquals(resolvedTaskBounds, w.getFrame());
+ assertEquals(0, w.getRelativeFrame().left);
+ assertEquals(0, w.getRelativeFrame().top);
assertContentFrame(w, resolvedTaskBounds);
assertContentInset(w, 0, 0, 0, 0);
@@ -300,10 +300,10 @@
final int cfBottom = logicalHeight / 2;
final Rect cf = new Rect(0, 0, cfRight, cfBottom);
windowFrames.setFrames(pf, pf, cf, cf, pf, cf);
- w.computeFrameLw();
- assertEquals(resolvedTaskBounds, w.getFrameLw());
- assertEquals(0, w.getRelativeFrameLw().left);
- assertEquals(0, w.getRelativeFrameLw().top);
+ w.computeFrame();
+ assertEquals(resolvedTaskBounds, w.getFrame());
+ assertEquals(0, w.getRelativeFrame().left);
+ assertEquals(0, w.getRelativeFrame().top);
int contentInsetRight = resolvedTaskBounds.right - cfRight;
int contentInsetBottom = resolvedTaskBounds.bottom - cfBottom;
assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
@@ -334,12 +334,12 @@
final WindowFrames windowFrames = w.getWindowFrames();
windowFrames.setFrames(pf, df, cf, vf, dcf, sf);
- w.computeFrameLw();
+ w.computeFrame();
assertPolicyCrop(w, 0, cf.top, logicalWidth, cf.bottom);
windowFrames.mDecorFrame.setEmpty();
// Likewise with no decor frame we would get no crop
- w.computeFrameLw();
+ w.computeFrame();
assertPolicyCrop(w, 0, 0, logicalWidth, logicalHeight);
// Now we set up a window which doesn't fill the entire decor frame.
@@ -353,7 +353,7 @@
w.mAttrs.height = logicalHeight / 2;
w.mRequestedWidth = logicalWidth / 2;
w.mRequestedHeight = logicalHeight / 2;
- w.computeFrameLw();
+ w.computeFrame();
// Normally the crop is shrunk from the decor frame
// to the computed window frame.
@@ -390,7 +390,7 @@
final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
final WindowFrames windowFrames = w.getWindowFrames();
windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
- w.computeFrameLw();
+ w.computeFrame();
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -408,7 +408,7 @@
task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
task.setBounds(null);
windowFrames.setFrames(pf, pf, cf, cf, pf, cf);
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, cf);
assertContentFrame(w, cf);
assertContentInset(w, 0, 0, 0, 0);
@@ -430,7 +430,7 @@
final WindowFrames windowFrames = w.getWindowFrames();
windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
windowFrames.setDisplayCutout(cutout);
- w.computeFrameLw();
+ w.computeFrame();
assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetTop(), 50);
assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetBottom(), 0);
@@ -469,20 +469,20 @@
task.setBounds(winRect);
w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
- w.computeFrameLw();
+ w.computeFrame();
final Rect expected = new Rect(winRect.left, cf.bottom - winRect.height(),
winRect.right, cf.bottom);
- assertEquals(expected, w.getFrameLw());
- assertEquals(expected, w.getContentFrameLw());
- assertEquals(expected, w.getVisibleFrameLw());
+ assertEquals(expected, w.getFrame());
+ assertEquals(expected, w.getContentFrame());
+ assertEquals(expected, w.getVisibleFrame());
// Now check that it won't get moved beyond the top and then has appropriate insets
winRect.bottom = 600;
task.setBounds(winRect);
w.setBounds(winRect);
w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
- w.computeFrameLw();
+ w.computeFrame();
assertFrame(w, winRect.left, 0, winRect.right, winRect.height());
expected.top = 0;
@@ -492,8 +492,8 @@
// Check that it's moved back without ime insets
w.getWindowFrames().setFrames(pf, df, pf, pf, dcf, sf);
- w.computeFrameLw();
- assertEquals(winRect, w.getFrameLw());
+ w.computeFrame();
+ assertEquals(winRect, w.getFrame());
}
private WindowState createWindow() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index f095fd4..9603d28 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -479,7 +479,7 @@
app.mHasSurface = true;
app.mSurfaceControl = mock(SurfaceControl.class);
try {
- app.getFrameLw().set(10, 20, 60, 80);
+ app.getFrame().set(10, 20, 60, 80);
app.updateSurfacePosition(t);
app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true);
@@ -519,7 +519,7 @@
new Rect(95, 378, 105, 400));
wf.setDisplayCutout(new WmDisplayCutout(cutout, new Size(200, 400)));
- app.computeFrameLw();
+ app.computeFrame();
assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
}
@@ -633,7 +633,7 @@
final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
final DisplayContent dc = createNewDisplay();
- win0.getFrameLw().offsetTo(PARENT_WINDOW_OFFSET, 0);
+ win0.getFrame().offsetTo(PARENT_WINDOW_OFFSET, 0);
dc.reparentDisplayContent(win0, win0.getSurfaceControl());
dc.updateLocation(win0, DISPLAY_IN_PARENT_WINDOW_OFFSET, 0);
@@ -644,7 +644,7 @@
win1.mHasSurface = true;
win1.mSurfaceControl = mock(SurfaceControl.class);
win1.mAttrs.surfaceInsets.set(1, 2, 3, 4);
- win1.getFrameLw().offsetTo(WINDOW_OFFSET, 0);
+ win1.getFrame().offsetTo(WINDOW_OFFSET, 0);
win1.updateSurfacePosition(t);
win1.getTransformationMatrix(values, matrix);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index f86d8f1..38c4e0a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -1131,7 +1131,7 @@
}
@Override
- public boolean isGoneForLayoutLw() {
+ public boolean isGoneForLayout() {
return false;
}