summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/textclassifier/Android.bp2
-rwxr-xr-xapi/system-current.txt4
-rw-r--r--config/hiddenapi-force-blocked.txt (renamed from config/hiddenapi-force-blacklist.txt)0
-rw-r--r--config/hiddenapi-max-target-o.txt (renamed from config/hiddenapi-greylist-max-o.txt)0
-rw-r--r--config/hiddenapi-max-target-p.txt (renamed from config/hiddenapi-greylist-max-p.txt)0
-rw-r--r--config/hiddenapi-max-target-q.txt (renamed from config/hiddenapi-greylist-max-q.txt)0
-rw-r--r--config/hiddenapi-unsupported-packages.txt (renamed from config/hiddenapi-greylist-packages.txt)0
-rw-r--r--config/hiddenapi-unsupported.txt (renamed from config/hiddenapi-greylist.txt)0
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java65
-rw-r--r--core/java/android/app/UiModeManager.java3
-rw-r--r--core/java/android/app/people/ConversationChannel.java97
-rw-r--r--core/java/android/app/people/IPeopleManager.aidl42
-rw-r--r--core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java2
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/content/pm/PackageManager.java6
-rw-r--r--core/java/android/permission/PermissionManager.java4
-rw-r--r--core/java/android/provider/Settings.java7
-rw-r--r--core/java/android/view/ViewRootImpl.java25
-rw-r--r--core/java/android/webkit/PacProcessor.java35
-rw-r--r--core/java/android/webkit/WebViewFactoryProvider.java17
-rw-r--r--non-updatable-api/system-current.txt4
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java2
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/PrimarySwitchController.java (renamed from packages/SettingsLib/Tile/src/com/android/settingslib/drawer/MasterSwitchController.java)4
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java (renamed from packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java)84
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java10
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java4
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/PrimarySwitchControllerTest.java (renamed from packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/MasterSwitchControllerTest.java)10
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java6
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java (renamed from packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java)76
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompatTest.java30
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java28
-rw-r--r--packages/SimAppDialog/Android.bp3
-rw-r--r--packages/SimAppDialog/AndroidManifest.xml2
-rw-r--r--packages/SimAppDialog/res/layout/install_carrier_app_activity.xml19
-rw-r--r--packages/SimAppDialog/res/layout/install_carrier_app_footer.xml43
-rw-r--r--packages/SimAppDialog/res/values/styles.xml26
-rw-r--r--packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java2
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java24
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java24
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java14
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java158
-rw-r--r--services/core/java/com/android/server/am/ProcessStatsService.java287
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java8
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java261
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java2
-rw-r--r--services/core/java/com/android/server/media/HandlerExecutor.java45
-rw-r--r--services/core/java/com/android/server/media/MediaSession2Record.java1
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java38
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java20
-rw-r--r--services/core/java/com/android/server/pm/Settings.java32
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java174
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java9
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotSurface.java14
-rw-r--r--services/people/java/com/android/server/people/PeopleService.java39
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java2
-rw-r--r--services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java14
-rw-r--r--services/tests/wmtests/AndroidManifest.xml1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java52
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt5
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java189
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl6
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java6
-rw-r--r--wifi/tests/src/android/net/wifi/WifiManagerTest.java20
78 files changed, 1661 insertions, 747 deletions
diff --git a/apct-tests/perftests/textclassifier/Android.bp b/apct-tests/perftests/textclassifier/Android.bp
index 9f795a7ed54a..c40e0252cb7e 100644
--- a/apct-tests/perftests/textclassifier/Android.bp
+++ b/apct-tests/perftests/textclassifier/Android.bp
@@ -19,7 +19,7 @@ android_test {
"androidx.test.rules",
"androidx.annotation_annotation",
"apct-perftests-utils",
- "collector-device-lib-platform",
+ "collector-device-lib",
],
data: [":perfetto_artifacts"],
platform_apis: true,
diff --git a/api/system-current.txt b/api/system-current.txt
index 56059dd9d864..88fe40a93010 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -12732,6 +12732,9 @@ package android.webkit {
public interface PacProcessor {
method @Nullable public String findProxyForUrl(@NonNull String);
method @NonNull public static android.webkit.PacProcessor getInstance();
+ method @NonNull public static android.webkit.PacProcessor getInstanceForNetwork(long);
+ method public default long getNetworkHandle();
+ method public default void releasePacProcessor();
method public boolean setProxyScript(@NonNull String);
}
@@ -12871,6 +12874,7 @@ package android.webkit {
method public android.webkit.CookieManager getCookieManager();
method public android.webkit.GeolocationPermissions getGeolocationPermissions();
method @NonNull public default android.webkit.PacProcessor getPacProcessor();
+ method @NonNull public default android.webkit.PacProcessor getPacProcessorForNetwork(long);
method public android.webkit.ServiceWorkerController getServiceWorkerController();
method public android.webkit.WebViewFactoryProvider.Statics getStatics();
method @Deprecated public android.webkit.TokenBindingService getTokenBindingService();
diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blocked.txt
index b328f2ac1955..b328f2ac1955 100644
--- a/config/hiddenapi-force-blacklist.txt
+++ b/config/hiddenapi-force-blocked.txt
diff --git a/config/hiddenapi-greylist-max-o.txt b/config/hiddenapi-max-target-o.txt
index 023bf3876228..023bf3876228 100644
--- a/config/hiddenapi-greylist-max-o.txt
+++ b/config/hiddenapi-max-target-o.txt
diff --git a/config/hiddenapi-greylist-max-p.txt b/config/hiddenapi-max-target-p.txt
index 351e71dd9538..351e71dd9538 100644
--- a/config/hiddenapi-greylist-max-p.txt
+++ b/config/hiddenapi-max-target-p.txt
diff --git a/config/hiddenapi-greylist-max-q.txt b/config/hiddenapi-max-target-q.txt
index 4832dd184ec5..4832dd184ec5 100644
--- a/config/hiddenapi-greylist-max-q.txt
+++ b/config/hiddenapi-max-target-q.txt
diff --git a/config/hiddenapi-greylist-packages.txt b/config/hiddenapi-unsupported-packages.txt
index 986d2591a007..986d2591a007 100644
--- a/config/hiddenapi-greylist-packages.txt
+++ b/config/hiddenapi-unsupported-packages.txt
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-unsupported.txt
index a3543dc7f4ee..a3543dc7f4ee 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-unsupported.txt
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index bca6f39e1ded..54f3f1026050 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -215,7 +215,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
private long mMisses = 0;
@GuardedBy("mLock")
- private long mMissDisabled[] = new long[]{ 0, 0, 0 };
+ private long mSkips[] = new long[]{ 0, 0, 0 };
@GuardedBy("mLock")
private long mMissOverflow = 0;
@@ -223,6 +223,9 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
@GuardedBy("mLock")
private long mHighWaterMark = 0;
+ @GuardedBy("mLock")
+ private long mClears = 0;
+
// Most invalidation is done in a static context, so the counters need to be accessible.
@GuardedBy("sCorkLock")
private static final HashMap<String, Long> sInvalidates = new HashMap<>();
@@ -273,6 +276,13 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
*/
private volatile SystemProperties.Handle mPropertyHandle;
+ /**
+ * The name by which this cache is known. This should normally be the
+ * binder call that is being cached, but the constructors default it to
+ * the property name.
+ */
+ private final String mCacheName;
+
@GuardedBy("mLock")
private final LinkedHashMap<Query, Result> mCache;
@@ -297,9 +307,23 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
*
* @param maxEntries Maximum number of entries to cache; LRU discard
* @param propertyName Name of the system property holding the cache invalidation nonce
+ * Defaults the cache name to the property name.
*/
public PropertyInvalidatedCache(int maxEntries, @NonNull String propertyName) {
+ this(maxEntries, propertyName, propertyName);
+ }
+
+ /**
+ * Make a new property invalidated cache.
+ *
+ * @param maxEntries Maximum number of entries to cache; LRU discard
+ * @param propertyName Name of the system property holding the cache invalidation nonce
+ * @param cacheName Name of this cache in debug and dumpsys
+ */
+ public PropertyInvalidatedCache(int maxEntries, @NonNull String propertyName,
+ @NonNull String cacheName) {
mPropertyName = propertyName;
+ mCacheName = cacheName;
mMaxEntries = maxEntries;
mCache = new LinkedHashMap<Query, Result>(
2 /* start small */,
@@ -320,7 +344,6 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
};
synchronized (sCorkLock) {
sCaches.put(this, null);
- sInvalidates.put(propertyName, (long) 0);
}
}
@@ -333,6 +356,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
Log.d(TAG, "clearing cache for " + mPropertyName);
}
mCache.clear();
+ mClears++;
}
}
@@ -413,7 +437,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
// Do not bother collecting statistics if the cache is
// locally disabled.
synchronized (mLock) {
- mMissDisabled[(int) currentNonce]++;
+ mSkips[(int) currentNonce]++;
}
}
@@ -742,12 +766,16 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
boolean alreadyQueued = mUncorkDeadlineMs >= 0;
if (DEBUG) {
Log.w(TAG, String.format(
- "autoCork mUncorkDeadlineMs=%s", mUncorkDeadlineMs));
+ "autoCork %s mUncorkDeadlineMs=%s", mPropertyName,
+ mUncorkDeadlineMs));
}
mUncorkDeadlineMs = SystemClock.uptimeMillis() + mAutoCorkDelayMs;
if (!alreadyQueued) {
getHandlerLocked().sendEmptyMessageAtTime(0, mUncorkDeadlineMs);
PropertyInvalidatedCache.corkInvalidations(mPropertyName);
+ } else {
+ final long count = sCorkedInvalidates.getOrDefault(mPropertyName, (long) 0);
+ sCorkedInvalidates.put(mPropertyName, count + 1);
}
}
}
@@ -756,7 +784,8 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
synchronized (mLock) {
if (DEBUG) {
Log.w(TAG, String.format(
- "handleMsesage mUncorkDeadlineMs=%s", mUncorkDeadlineMs));
+ "handleMsesage %s mUncorkDeadlineMs=%s",
+ mPropertyName, mUncorkDeadlineMs));
}
if (mUncorkDeadlineMs < 0) {
@@ -816,7 +845,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
* method is public so clients can use it.
*/
public String cacheName() {
- return mPropertyName;
+ return mCacheName;
}
/**
@@ -864,16 +893,20 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
}
synchronized (mLock) {
- pw.println(String.format(" Cache Property Name: %s", cacheName()));
- pw.println(String.format(" Hits: %d, Misses: %d, Invalidates: %d, Overflows: %d",
- mHits, mMisses, invalidateCount, mMissOverflow));
- pw.println(String.format(" Miss-corked: %d, Miss-unset: %d, Miss-other: %d," +
- " CorkedInvalidates: %d",
- mMissDisabled[NONCE_CORKED], mMissDisabled[NONCE_UNSET],
- mMissDisabled[NONCE_DISABLED], corkedInvalidates));
- pw.println(String.format(" Last Observed Nonce: %d", mLastSeenNonce));
- pw.println(String.format(" Current Size: %d, Max Size: %d, HW Mark: %d",
- mCache.size(), mMaxEntries, mHighWaterMark));
+ pw.println(String.format(" Cache Name: %s", cacheName()));
+ pw.println(String.format(" Property: %s", mPropertyName));
+ final long skips = mSkips[NONCE_CORKED] + mSkips[NONCE_UNSET] + mSkips[NONCE_DISABLED];
+ pw.println(String.format(" Hits: %d, Misses: %d, Skips: %d, Clears: %d",
+ mHits, mMisses, skips, mClears));
+ pw.println(String.format(" Skip-corked: %d, Skip-unset: %d, Skip-other: %d",
+ mSkips[NONCE_CORKED], mSkips[NONCE_UNSET],
+ mSkips[NONCE_DISABLED]));
+ pw.println(String.format(
+ " Nonce: 0x%016x, Invalidates: %d, CorkedInvalidates: %d",
+ mLastSeenNonce, invalidateCount, corkedInvalidates));
+ pw.println(String.format(
+ " Current Size: %d, Max Size: %d, HW Mark: %d, Overflows: %d",
+ mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow));
pw.println(String.format(" Enabled: %s", mDisabled ? "false" : "true"));
Set<Map.Entry<Query, Result>> cacheEntries = mCache.entrySet();
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 7c6eff143724..06d1b74abc86 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -510,6 +510,9 @@ public class UiModeManager {
}
/**
+ * Activating night mode for the current user
+ *
+ * @return {@code true} if the change is successful
* @hide
*/
public boolean setNightModeActivated(boolean active) {
diff --git a/core/java/android/app/people/ConversationChannel.java b/core/java/android/app/people/ConversationChannel.java
new file mode 100644
index 000000000000..39c5c85e456c
--- /dev/null
+++ b/core/java/android/app/people/ConversationChannel.java
@@ -0,0 +1,97 @@
+/*
+ * 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 android.app.people;
+
+import android.app.NotificationChannel;
+import android.content.pm.ShortcutInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The non-customized notification channel of a conversation. It contains the information to render
+ * the conversation and allows the user to open and customize the conversation setting.
+ *
+ * @hide
+ */
+public final class ConversationChannel implements Parcelable {
+
+ private ShortcutInfo mShortcutInfo;
+ private NotificationChannel mParentNotificationChannel;
+ private long mLastEventTimestamp;
+ private boolean mHasActiveNotifications;
+
+ public static final Creator<ConversationChannel> CREATOR = new Creator<ConversationChannel>() {
+ @Override
+ public ConversationChannel createFromParcel(Parcel in) {
+ return new ConversationChannel(in);
+ }
+
+ @Override
+ public ConversationChannel[] newArray(int size) {
+ return new ConversationChannel[size];
+ }
+ };
+
+ public ConversationChannel(ShortcutInfo shortcutInfo,
+ NotificationChannel parentNotificationChannel, long lastEventTimestamp,
+ boolean hasActiveNotifications) {
+ mShortcutInfo = shortcutInfo;
+ mParentNotificationChannel = parentNotificationChannel;
+ mLastEventTimestamp = lastEventTimestamp;
+ mHasActiveNotifications = hasActiveNotifications;
+ }
+
+ public ConversationChannel(Parcel in) {
+ mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader());
+ mParentNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader());
+ mLastEventTimestamp = in.readLong();
+ mHasActiveNotifications = in.readBoolean();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mShortcutInfo, flags);
+ dest.writeParcelable(mParentNotificationChannel, flags);
+ dest.writeLong(mLastEventTimestamp);
+ dest.writeBoolean(mHasActiveNotifications);
+ }
+
+ public ShortcutInfo getShortcutInfo() {
+ return mShortcutInfo;
+ }
+
+ public NotificationChannel getParentNotificationChannel() {
+ return mParentNotificationChannel;
+ }
+
+ public long getLastEventTimestamp() {
+ return mLastEventTimestamp;
+ }
+
+ /**
+ * Whether this conversation has any active notifications. If it's true, the shortcut for this
+ * conversation can't be uncached until all its active notifications are dismissed.
+ */
+ public boolean hasActiveNotifications() {
+ return mHasActiveNotifications;
+ }
+}
diff --git a/core/java/android/app/people/IPeopleManager.aidl b/core/java/android/app/people/IPeopleManager.aidl
new file mode 100644
index 000000000000..61dac0d64422
--- /dev/null
+++ b/core/java/android/app/people/IPeopleManager.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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 android.app.people;
+
+import android.content.pm.ParceledListSlice;
+import android.net.Uri;
+import android.os.IBinder;
+
+/**
+ * System private API for talking with the people service.
+ * {@hide}
+ */
+interface IPeopleManager {
+ /**
+ * Returns the recent conversations. The conversations that have customized notification
+ * settings are excluded from the returned list.
+ */
+ ParceledListSlice getRecentConversations();
+
+ /**
+ * Removes the specified conversation from the recent conversations list and uncaches the
+ * shortcut associated with the conversation.
+ */
+ void removeRecentConversation(in String packageName, int userId, in String shortcutId);
+
+ /** Removes all the recent conversations and uncaches their cached shortcuts. */
+ void removeAllRecentConversations();
+}
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
index 6bd365fad6f6..0770aff4e9bb 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
@@ -117,7 +117,7 @@ public final class TimeZoneDetectorImpl implements TimeZoneDetector {
}
private void notifyConfigurationListeners(@NonNull TimeZoneConfiguration configuration) {
- ArraySet<TimeZoneConfigurationListener> configurationListeners;
+ final ArraySet<TimeZoneConfigurationListener> configurationListeners;
synchronized (this) {
configurationListeners = new ArraySet<>(mConfigurationListeners);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 16cdf2334ad8..52b04675b7a5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3496,6 +3496,7 @@ public abstract class Context {
//@hide: TIME_ZONE_DETECTOR_SERVICE,
PERMISSION_SERVICE,
LIGHTS_SERVICE,
+ //@hide: PEOPLE_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -5189,6 +5190,14 @@ public abstract class Context {
public static final String SMS_SERVICE = "sms";
/**
+ * Use with {@link #getSystemService(String)} to access people service.
+ *
+ * @see #getSystemService(String)
+ * @hide
+ */
+ public static final String PEOPLE_SERVICE = "people";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 42a610700051..e08af5534afd 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -8089,7 +8089,8 @@ public abstract class PackageManager {
private static final PropertyInvalidatedCache<ApplicationInfoQuery, ApplicationInfo>
sApplicationInfoCache =
new PropertyInvalidatedCache<ApplicationInfoQuery, ApplicationInfo>(
- 16, PermissionManager.CACHE_KEY_PACKAGE_INFO) {
+ 16, PermissionManager.CACHE_KEY_PACKAGE_INFO,
+ "getApplicationInfo") {
@Override
protected ApplicationInfo recompute(ApplicationInfoQuery query) {
return getApplicationInfoAsUserUncached(
@@ -8190,7 +8191,8 @@ public abstract class PackageManager {
private static final PropertyInvalidatedCache<PackageInfoQuery, PackageInfo>
sPackageInfoCache =
new PropertyInvalidatedCache<PackageInfoQuery, PackageInfo>(
- 32, PermissionManager.CACHE_KEY_PACKAGE_INFO) {
+ 32, PermissionManager.CACHE_KEY_PACKAGE_INFO,
+ "getPackageInfo") {
@Override
protected PackageInfo recompute(PackageInfoQuery query) {
return getPackageInfoAsUserUncached(
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index bf3d46fa4a44..0c190719af57 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -608,7 +608,7 @@ public final class PermissionManager {
/** @hide */
private static final PropertyInvalidatedCache<PermissionQuery, Integer> sPermissionCache =
new PropertyInvalidatedCache<PermissionQuery, Integer>(
- 16, CACHE_KEY_PACKAGE_INFO) {
+ 16, CACHE_KEY_PACKAGE_INFO, "checkPermission") {
@Override
protected Integer recompute(PermissionQuery query) {
return checkPermissionUncached(query.permission, query.pid, query.uid);
@@ -689,7 +689,7 @@ public final class PermissionManager {
private static PropertyInvalidatedCache<PackageNamePermissionQuery, Integer>
sPackageNamePermissionCache =
new PropertyInvalidatedCache<PackageNamePermissionQuery, Integer>(
- 16, CACHE_KEY_PACKAGE_INFO) {
+ 16, CACHE_KEY_PACKAGE_INFO, "checkPackageNamePermission") {
@Override
protected Integer recompute(PackageNamePermissionQuery query) {
return checkPackageNamePermissionUncached(
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5acc11a868bf..660455e59a4a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7912,6 +7912,13 @@ public final class Settings {
public static final String TAPS_APP_TO_EXIT = "taps_app_to_exit";
/**
+ * Internal use, one handed mode tutorial showed times.
+ * @hide
+ */
+ public static final String ONE_HANDED_TUTORIAL_SHOW_COUNT =
+ "one_handed_tutorial_show_count";
+
+ /**
* The current night mode that has been selected by the user. Owned
* and controlled by UiModeManagerService. Constants are as per
* UiModeManager.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 64ddb2f4d9d9..3f02d701f71f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1814,19 +1814,13 @@ public final class ViewRootImpl implements ViewParent,
/**
* Called after window layout to update the bounds surface. If the surface insets have changed
* or the surface has resized, update the bounds surface.
- *
- * @param shouldReparent Whether it should reparent the bounds layer to the main SurfaceControl.
*/
- private void updateBoundsLayer(boolean shouldReparent) {
+ private void updateBoundsLayer() {
if (mBoundsLayer != null) {
setBoundsLayerCrop();
- mTransaction.deferTransactionUntil(mBoundsLayer, getRenderSurfaceControl(),
- mSurface.getNextFrameNumber());
-
- if (shouldReparent) {
- mTransaction.reparent(mBoundsLayer, getRenderSurfaceControl());
- }
- mTransaction.apply();
+ mTransaction.deferTransactionUntil(mBoundsLayer,
+ getRenderSurfaceControl(), mSurface.getNextFrameNumber())
+ .apply();
}
}
@@ -2905,16 +2899,7 @@ public final class ViewRootImpl implements ViewParent,
}
if (surfaceSizeChanged || surfaceReplaced || surfaceCreated || windowAttributesChanged) {
- // If the surface has been replaced, there's a chance the bounds layer is not parented
- // to the new layer. When updating bounds layer, also reparent to the main VRI
- // SurfaceControl to ensure it's correctly placed in the hierarchy.
- //
- // This needs to be done on the client side since WMS won't reparent the children to the
- // new surface if it thinks the app is closing. WMS gets the signal that the app is
- // stopping, but on the client side it doesn't get stopped since it's restarted quick
- // enough. WMS doesn't want to keep around old children since they will leak when the
- // client creates new children.
- updateBoundsLayer(surfaceReplaced);
+ updateBoundsLayer();
}
final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
diff --git a/core/java/android/webkit/PacProcessor.java b/core/java/android/webkit/PacProcessor.java
index 5ef450fa65dd..7e7b987f72f3 100644
--- a/core/java/android/webkit/PacProcessor.java
+++ b/core/java/android/webkit/PacProcessor.java
@@ -19,7 +19,7 @@ package android.webkit;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-
+import android.net.Network;
/**
* Class to evaluate PAC scripts.
@@ -40,6 +40,20 @@ public interface PacProcessor {
}
/**
+ * Returns PacProcessor instance associated with the {@link Network}.
+ * The host resolution is done on this {@link Network}.
+ *
+ * @param networkHandle a handle representing {@link Network} handle.
+ * @return PacProcessor instance for the specified network.
+ * @see Network#getNetworkHandle
+ * @see Network#fromNetworkHandle
+ */
+ @NonNull
+ static PacProcessor getInstanceForNetwork(long networkHandle) {
+ return WebViewFactory.getProvider().getPacProcessorForNetwork(networkHandle);
+ }
+
+ /**
* Set PAC script to use.
*
* @param script PAC script.
@@ -55,4 +69,23 @@ public interface PacProcessor {
*/
@Nullable
String findProxyForUrl(@NonNull String url);
+
+ /**
+ * Stops support for this {@link PacProcessor} and release its resources.
+ * No methods of this class must be called after calling this method.
+ */
+ default void releasePacProcessor() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Returns a network handle associated with this {@link PacProcessor}.
+ *
+ * @return a network handle or 0 if a network is unspecified.
+ * @see Network#getNetworkHandle
+ * @see Network#fromNetworkHandle
+ */
+ default long getNetworkHandle() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
}
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index f7c3ec09dd67..f1863e319689 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
+import android.net.Network;
import android.net.Uri;
import java.util.List;
@@ -175,7 +176,7 @@ public interface WebViewFactoryProvider {
WebViewDatabase getWebViewDatabase(Context context);
/**
- * Gets the singleton PacProcessor instance.
+ * Gets the default PacProcessor instance.
* @return the PacProcessor instance
*/
@NonNull
@@ -184,6 +185,20 @@ public interface WebViewFactoryProvider {
}
/**
+ * Returns PacProcessor instance associated with the {@link Network}.
+ * The host resolution is done on this {@link Network}.
+ *
+ * @param networkHandle a network handle representing the {@link Network}.
+ * @return the {@link PacProcessor} instance associated with {@link Network}.
+ * @see Network#getNetworkHandle
+ * @see Network#fromNetworkHandle
+ */
+ @NonNull
+ default PacProcessor getPacProcessorForNetwork(long networkHandle) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
* Gets the classloader used to load internal WebView implementation classes. This interface
* should only be used by the WebView Support Library.
*/
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index 844e929774a1..10887fabb5c7 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -11575,6 +11575,9 @@ package android.webkit {
public interface PacProcessor {
method @Nullable public String findProxyForUrl(@NonNull String);
method @NonNull public static android.webkit.PacProcessor getInstance();
+ method @NonNull public static android.webkit.PacProcessor getInstanceForNetwork(long);
+ method public default long getNetworkHandle();
+ method public default void releasePacProcessor();
method public boolean setProxyScript(@NonNull String);
}
@@ -11714,6 +11717,7 @@ package android.webkit {
method public android.webkit.CookieManager getCookieManager();
method public android.webkit.GeolocationPermissions getGeolocationPermissions();
method @NonNull public default android.webkit.PacProcessor getPacProcessor();
+ method @NonNull public default android.webkit.PacProcessor getPacProcessorForNetwork(long);
method public android.webkit.ServiceWorkerController getServiceWorkerController();
method public android.webkit.WebViewFactoryProvider.Statics getStatics();
method @Deprecated public android.webkit.TokenBindingService getTokenBindingService();
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
index 5dcb9de4755e..a2cd0446d1e8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
@@ -39,7 +39,7 @@ import javax.inject.Singleton;
/**
* A class that detects unsafe apps.
- * An app is considered safe if is a system app or installed through whitelisted sources.
+ * An app is considered safe if is a system app or installed through allowed sources.
*/
@Singleton
public class SideLoadedAppDetector {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/MasterSwitchController.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/PrimarySwitchController.java
index a12aa83e9d4b..a08f566b8375 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/MasterSwitchController.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/PrimarySwitchController.java
@@ -19,9 +19,9 @@ package com.android.settingslib.drawer;
import android.os.Bundle;
/**
- * A controller that manages event for master switch.
+ * A controller that manages event for Primary switch.
*/
-public abstract class MasterSwitchController extends SwitchController {
+public abstract class PrimarySwitchController extends SwitchController {
@Override
protected final MetaData getMetaData() {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java
index 73f1a904b04b..f2b3e30dc252 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java
@@ -88,7 +88,7 @@ public abstract class SwitchesProvider extends ContentProvider {
controller.setAuthority(mAuthority);
mControllerMap.put(key, controller);
- if (!(controller instanceof MasterSwitchController)) {
+ if (!(controller instanceof PrimarySwitchController)) {
mSwitchDataList.add(controller.getBundle());
}
});
@@ -116,7 +116,7 @@ public abstract class SwitchesProvider extends ContentProvider {
switch (method) {
case METHOD_GET_SWITCH_DATA:
- if (!(controller instanceof MasterSwitchController)) {
+ if (!(controller instanceof PrimarySwitchController)) {
return controller.getBundle();
}
break;
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
index f757aa4e4dab..b29595eab5c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
@@ -24,7 +24,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.AbstractPreferenceController;
/**
- * This controller is used handle changes for the master switch in the developer options page.
+ * This controller is used handle changes for the primary switch in the developer options page.
*
* All Preference Controllers that are a part of the developer options page should inherit this
* class.
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
index 3c647a7ec465..c501b3aab4d4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
@@ -34,44 +34,50 @@ import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.ArrayUtils;
/**
- * Handles getting/changing the whitelist for the exceptions to battery saving features.
+ * Handles getting/changing the allowlist for the exceptions to battery saving features.
*/
-public class PowerWhitelistBackend {
+public class PowerAllowlistBackend {
- private static final String TAG = "PowerWhitelistBackend";
+ private static final String TAG = "PowerAllowlistBackend";
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
- private static PowerWhitelistBackend sInstance;
+ private static PowerAllowlistBackend sInstance;
private final Context mAppContext;
private final IDeviceIdleController mDeviceIdleService;
- private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
- private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
+ private final ArraySet<String> mAllowlistedApps = new ArraySet<>();
+ private final ArraySet<String> mSysAllowlistedApps = new ArraySet<>();
private final ArraySet<String> mDefaultActiveApps = new ArraySet<>();
- public PowerWhitelistBackend(Context context) {
+ public PowerAllowlistBackend(Context context) {
this(context, IDeviceIdleController.Stub.asInterface(
ServiceManager.getService(DEVICE_IDLE_SERVICE)));
}
@VisibleForTesting
- PowerWhitelistBackend(Context context, IDeviceIdleController deviceIdleService) {
+ PowerAllowlistBackend(Context context, IDeviceIdleController deviceIdleService) {
mAppContext = context.getApplicationContext();
mDeviceIdleService = deviceIdleService;
refreshList();
}
- public int getWhitelistSize() {
- return mWhitelistedApps.size();
+ public int getAllowlistSize() {
+ return mAllowlistedApps.size();
}
- public boolean isSysWhitelisted(String pkg) {
- return mSysWhitelistedApps.contains(pkg);
+ /**
+ * Check if target package is in System allow list
+ */
+ public boolean isSysAllowlisted(String pkg) {
+ return mSysAllowlistedApps.contains(pkg);
}
- public boolean isWhitelisted(String pkg) {
- if (mWhitelistedApps.contains(pkg)) {
+ /**
+ * Check if target package is in allow list
+ */
+ public boolean isAllowlisted(String pkg) {
+ if (mAllowlistedApps.contains(pkg)) {
return true;
}
@@ -87,7 +93,7 @@ public class PowerWhitelistBackend {
*/
public boolean isDefaultActiveApp(String pkg) {
// Additionally, check if pkg is default dialer/sms. They are considered essential apps and
- // should be automatically whitelisted (otherwise user may be able to set restriction on
+ // should be automatically allowlisted (otherwise user may be able to set restriction on
// them, leading to bad device behavior.)
if (mDefaultActiveApps.contains(pkg)) {
@@ -103,12 +109,17 @@ public class PowerWhitelistBackend {
return false;
}
- public boolean isWhitelisted(String[] pkgs) {
+ /**
+ *
+ * @param pkgs a list of packageName
+ * @return true when one of package is in allow list
+ */
+ public boolean isAllowlisted(String[] pkgs) {
if (ArrayUtils.isEmpty(pkgs)) {
return false;
}
for (String pkg : pkgs) {
- if (isWhitelisted(pkg)) {
+ if (isAllowlisted(pkg)) {
return true;
}
}
@@ -116,40 +127,51 @@ public class PowerWhitelistBackend {
return false;
}
+ /**
+ * Add app into power save allow list.
+ * @param pkg packageName
+ */
public void addApp(String pkg) {
try {
mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
- mWhitelistedApps.add(pkg);
+ mAllowlistedApps.add(pkg);
} catch (RemoteException e) {
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
}
}
+ /**
+ * Remove package from power save allow list.
+ * @param pkg
+ */
public void removeApp(String pkg) {
try {
mDeviceIdleService.removePowerSaveWhitelistApp(pkg);
- mWhitelistedApps.remove(pkg);
+ mAllowlistedApps.remove(pkg);
} catch (RemoteException e) {
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
}
}
+ /**
+ * Refresh all of lists
+ */
@VisibleForTesting
public void refreshList() {
- mSysWhitelistedApps.clear();
- mWhitelistedApps.clear();
+ mSysAllowlistedApps.clear();
+ mAllowlistedApps.clear();
mDefaultActiveApps.clear();
if (mDeviceIdleService == null) {
return;
}
try {
- final String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
- for (String app : whitelistedApps) {
- mWhitelistedApps.add(app);
+ final String[] allowlistedApps = mDeviceIdleService.getFullPowerWhitelist();
+ for (String app : allowlistedApps) {
+ mAllowlistedApps.add(app);
}
- final String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
- for (String app : sysWhitelistedApps) {
- mSysWhitelistedApps.add(app);
+ final String[] sysAllowlistedApps = mDeviceIdleService.getSystemPowerWhitelist();
+ for (String app : sysAllowlistedApps) {
+ mSysAllowlistedApps.add(app);
}
final boolean hasTelephony = mAppContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TELEPHONY);
@@ -171,9 +193,13 @@ public class PowerWhitelistBackend {
}
}
- public static PowerWhitelistBackend getInstance(Context context) {
+ /**
+ * @param context
+ * @return a PowerAllowlistBackend object
+ */
+ public static PowerAllowlistBackend getInstance(Context context) {
if (sInstance == null) {
- sInstance = new PowerWhitelistBackend(context);
+ sInstance = new PowerAllowlistBackend(context);
}
return sInstance;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
index 4941f7e42bf6..8ac434957cd9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
@@ -135,7 +135,7 @@ public class AppRestrictionsHelper {
// Ignore
}
} else {
- // Blacklist all other apps, system or downloaded
+ // Denylist all other apps, system or downloaded
try {
ApplicationInfo info = mIPm.getApplicationInfo(packageName, 0, userId);
if (info != null) {
@@ -258,11 +258,11 @@ public class AppRestrictionsHelper {
}
}
- // Establish master/slave relationship for entries that share a package name
+ // Establish primary/secondary relationship for entries that share a package name
HashMap<String,SelectableAppInfo> packageMap = new HashMap<String,SelectableAppInfo>();
for (SelectableAppInfo info : mVisibleApps) {
if (packageMap.containsKey(info.packageName)) {
- info.masterEntry = packageMap.get(info.packageName);
+ info.primaryEntry = packageMap.get(info.packageName);
} else {
packageMap.put(info.packageName, info);
}
@@ -366,12 +366,12 @@ public class AppRestrictionsHelper {
public CharSequence appName;
public CharSequence activityName;
public Drawable icon;
- public SelectableAppInfo masterEntry;
+ public SelectableAppInfo primaryEntry;
@Override
public String toString() {
return packageName + ": appName=" + appName + "; activityName=" + activityName
- + "; icon=" + icon + "; masterEntry=" + masterEntry;
+ + "; icon=" + icon + "; primaryEntry=" + primaryEntry;
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index 11c799ea9df5..94e28f2b5e22 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -290,12 +290,12 @@ public class RestrictedLockUtilsTest {
@Test
public void sendShowAdminSupportDetailsIntent_extraRestrictionProvided() {
EnforcedAdmin enforcedAdmin = new EnforcedAdmin();
- enforcedAdmin.enforcedRestriction = "Dummy";
+ enforcedAdmin.enforcedRestriction = "Fake";
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, enforcedAdmin);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
- assertThat(intentCaptor.getValue().getExtra(EXTRA_RESTRICTION)).isEqualTo("Dummy");
+ assertThat(intentCaptor.getValue().getExtra(EXTRA_RESTRICTION)).isEqualTo("Fake");
}
@Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/MasterSwitchControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/PrimarySwitchControllerTest.java
index 69d0f2e71c17..9e4cde866ef2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/MasterSwitchControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/PrimarySwitchControllerTest.java
@@ -23,16 +23,16 @@ import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
-public class MasterSwitchControllerTest {
+public class PrimarySwitchControllerTest {
@Rule
public final ExpectedException thrown = ExpectedException.none();
- private MasterSwitchController mController;
+ private PrimarySwitchController mController;
@Before
public void setUp() {
- mController = new TestMasterSwitchController("123");
+ mController = new TestPrimarySwitchController("123");
}
@Test
@@ -49,11 +49,11 @@ public class MasterSwitchControllerTest {
mController.getBundle();
}
- static class TestMasterSwitchController extends MasterSwitchController {
+ static class TestPrimarySwitchController extends PrimarySwitchController {
private String mKey;
- TestMasterSwitchController(String key) {
+ TestPrimarySwitchController(String key) {
mKey = key;
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java
index a740e683642a..bd0100b67a94 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/SwitchesProviderTest.java
@@ -35,7 +35,7 @@ import android.content.Context;
import android.content.pm.ProviderInfo;
import android.os.Bundle;
-import com.android.settingslib.drawer.MasterSwitchControllerTest.TestMasterSwitchController;
+import com.android.settingslib.drawer.PrimarySwitchControllerTest.TestPrimarySwitchController;
import com.android.settingslib.drawer.SwitchController.MetaData;
import org.junit.Before;
@@ -124,8 +124,8 @@ public class SwitchesProviderTest {
}
@Test
- public void getSwitchData_shouldNotReturnMasterSwitchData() {
- final SwitchController controller = new TestMasterSwitchController("123");
+ public void getSwitchData_shouldNotReturnPrimarySwitchData() {
+ final SwitchController controller = new TestPrimarySwitchController("123");
mSwitchesProvider.addSwitchController(controller);
mSwitchesProvider.attachInfo(mContext, mProviderInfo);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java
index 20908925feff..4f11fb1f782f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java
@@ -47,7 +47,7 @@ import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowDefaultDialerManager.class, ShadowSmsApplication.class})
-public class PowerWhitelistBackendTest {
+public class PowerAllowlistBackendTest {
private static final String PACKAGE_ONE = "com.example.packageone";
private static final String PACKAGE_TWO = "com.example.packagetwo";
@@ -56,7 +56,7 @@ public class PowerWhitelistBackendTest {
private IDeviceIdleController mDeviceIdleService;
@Mock
private DevicePolicyManager mDevicePolicyManager;
- private PowerWhitelistBackend mPowerWhitelistBackend;
+ private PowerAllowlistBackend mPowerAllowlistBackend;
private ShadowPackageManager mPackageManager;
private Context mContext;
@@ -74,81 +74,81 @@ public class PowerWhitelistBackendTest {
mPackageManager.setSystemFeature(PackageManager.FEATURE_TELEPHONY, true);
doReturn(mDevicePolicyManager).when(mContext).getSystemService(DevicePolicyManager.class);
- mPowerWhitelistBackend = new PowerWhitelistBackend(mContext, mDeviceIdleService);
+ mPowerAllowlistBackend = new PowerAllowlistBackend(mContext, mDeviceIdleService);
}
@Test
- public void testIsWhitelisted() throws Exception {
+ public void testIsAllowlisted() throws Exception {
doReturn(new String[] {PACKAGE_ONE}).when(mDeviceIdleService).getFullPowerWhitelist();
- mPowerWhitelistBackend.refreshList();
+ mPowerAllowlistBackend.refreshList();
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_ONE})).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_TWO})).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_TWO)).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_ONE})).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_TWO})).isFalse();
- mPowerWhitelistBackend.addApp(PACKAGE_TWO);
+ mPowerAllowlistBackend.addApp(PACKAGE_TWO);
verify(mDeviceIdleService, atLeastOnce()).addPowerSaveWhitelistApp(PACKAGE_TWO);
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_TWO)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(
new String[] {PACKAGE_ONE, PACKAGE_TWO})).isTrue();
- mPowerWhitelistBackend.removeApp(PACKAGE_TWO);
+ mPowerAllowlistBackend.removeApp(PACKAGE_TWO);
verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_TWO);
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_ONE})).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_TWO})).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_TWO)).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_ONE})).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_TWO})).isFalse();
- mPowerWhitelistBackend.removeApp(PACKAGE_ONE);
+ mPowerAllowlistBackend.removeApp(PACKAGE_ONE);
verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_ONE);
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE)).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_TWO)).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(
new String[] {PACKAGE_ONE, PACKAGE_TWO})).isFalse();
}
@Test
- public void isWhitelisted_shouldWhitelistDefaultSms() {
+ public void isAllowlisted_shouldAllowlistDefaultSms() {
final String testSms = "com.android.test.defaultsms";
ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver"));
- mPowerWhitelistBackend.refreshList();
+ mPowerAllowlistBackend.refreshList();
- assertThat(mPowerWhitelistBackend.isWhitelisted(testSms)).isTrue();
- assertThat(mPowerWhitelistBackend.isDefaultActiveApp(testSms)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(testSms)).isTrue();
+ assertThat(mPowerAllowlistBackend.isDefaultActiveApp(testSms)).isTrue();
}
@Test
- public void isWhitelisted_shouldWhitelistDefaultDialer() {
+ public void isAllowlisted_shouldAllowlistDefaultDialer() {
final String testDialer = "com.android.test.defaultdialer";
ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer);
- mPowerWhitelistBackend.refreshList();
+ mPowerAllowlistBackend.refreshList();
- assertThat(mPowerWhitelistBackend.isWhitelisted(testDialer)).isTrue();
- assertThat(mPowerWhitelistBackend.isDefaultActiveApp(testDialer)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(testDialer)).isTrue();
+ assertThat(mPowerAllowlistBackend.isDefaultActiveApp(testDialer)).isTrue();
}
@Test
- public void isWhitelisted_shouldWhitelistActiveDeviceAdminApp() {
+ public void isAllowlisted_shouldAllowlistActiveDeviceAdminApp() {
doReturn(true).when(mDevicePolicyManager).packageHasActiveAdmins(PACKAGE_ONE);
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
- assertThat(mPowerWhitelistBackend.isDefaultActiveApp(PACKAGE_ONE)).isTrue();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE)).isTrue();
+ assertThat(mPowerAllowlistBackend.isDefaultActiveApp(PACKAGE_ONE)).isTrue();
}
@Test
- public void testIsSystemWhitelisted() throws Exception {
+ public void testIsSystemAllowlisted() throws Exception {
doReturn(new String[] {PACKAGE_ONE}).when(mDeviceIdleService).getSystemPowerWhitelist();
- mPowerWhitelistBackend.refreshList();
+ mPowerAllowlistBackend.refreshList();
- assertThat(mPowerWhitelistBackend.isSysWhitelisted(PACKAGE_ONE)).isTrue();
- assertThat(mPowerWhitelistBackend.isSysWhitelisted(PACKAGE_TWO)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isFalse();
+ assertThat(mPowerAllowlistBackend.isSysAllowlisted(PACKAGE_ONE)).isTrue();
+ assertThat(mPowerAllowlistBackend.isSysAllowlisted(PACKAGE_TWO)).isFalse();
+ assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE)).isFalse();
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompatTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompatTest.java
index b930aa6ee1bd..84d722ad16df 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompatTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompatTest.java
@@ -197,61 +197,61 @@ public class InputMethodAndSubtypeUtilCompatTest {
public void isValidSystemNonAuxAsciiCapableIme() {
// System IME w/ no subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(true, false)))
+ createFakeIme(true, false)))
.isFalse();
// System IME w/ non-Aux and non-ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(true, false, createDummySubtype("keyboard", false, false))))
+ createFakeIme(true, false, createFakeSubtype("keyboard", false, false))))
.isFalse();
// System IME w/ non-Aux and ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(true, false, createDummySubtype("keyboard", false, true))))
+ createFakeIme(true, false, createFakeSubtype("keyboard", false, true))))
.isTrue();
// System IME w/ Aux and ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(true, true, createDummySubtype("keyboard", true, true))))
+ createFakeIme(true, true, createFakeSubtype("keyboard", true, true))))
.isFalse();
// System IME w/ non-Aux and ASCII-capable "voice" subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(true, false, createDummySubtype("voice", false, true))))
+ createFakeIme(true, false, createFakeSubtype("voice", false, true))))
.isFalse();
// System IME w/ non-Aux and non-ASCII-capable subtype + Non-Aux and ASCII-capable subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(true, false,
- createDummySubtype("keyboard", false, true),
- createDummySubtype("keyboard", false, false))))
+ createFakeIme(true, false,
+ createFakeSubtype("keyboard", false, true),
+ createFakeSubtype("keyboard", false, false))))
.isTrue();
// Non-system IME w/ non-Aux and ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
- createDummyIme(false, false, createDummySubtype("keyboard", false, true))))
+ createFakeIme(false, false, createFakeSubtype("keyboard", false, true))))
.isFalse();
}
- private static InputMethodInfo createDummyIme(boolean isSystem, boolean isAuxIme,
+ private static InputMethodInfo createFakeIme(boolean isSystem, boolean isAuxIme,
InputMethodSubtype... subtypes) {
final ResolveInfo ri = new ResolveInfo();
final ServiceInfo si = new ServiceInfo();
final ApplicationInfo ai = new ApplicationInfo();
- ai.packageName = "com.example.android.dummyime";
+ ai.packageName = "com.example.android.fakeime";
ai.enabled = true;
ai.flags |= (isSystem ? ApplicationInfo.FLAG_SYSTEM : 0);
si.applicationInfo = ai;
si.enabled = true;
- si.packageName = "com.example.android.dummyime";
- si.name = "Dummy IME";
+ si.packageName = "com.example.android.fakeime";
+ si.name = "Fake IME";
si.exported = true;
- si.nonLocalizedLabel = "Dummy IME";
+ si.nonLocalizedLabel = "Fake IME";
ri.serviceInfo = si;
return new InputMethodInfo(ri, isAuxIme, "", Arrays.asList(subtypes), 1, false);
}
- private static InputMethodSubtype createDummySubtype(
+ private static InputMethodSubtype createFakeSubtype(
String mode, boolean isAuxiliary, boolean isAsciiCapable) {
return new InputMethodSubtypeBuilder()
.setSubtypeNameResId(0)
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java
index 5171dda9bff7..97d87051402e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java
@@ -195,55 +195,55 @@ public class InputMethodAndSubtypeUtilTest {
public void isValidNonAuxAsciiCapableIme() {
// IME w/ no subtype
assertThat(InputMethodAndSubtypeUtil.isValidNonAuxAsciiCapableIme(
- createDummyIme(false)))
+ createFakeIme(false)))
.isFalse();
// IME w/ non-Aux and non-ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtil.isValidNonAuxAsciiCapableIme(
- createDummyIme(false, createDummySubtype("keyboard", false, false))))
+ createFakeIme(false, createFakeSubtype("keyboard", false, false))))
.isFalse();
// IME w/ non-Aux and ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtil.isValidNonAuxAsciiCapableIme(
- createDummyIme(false, createDummySubtype("keyboard", false, true))))
+ createFakeIme(false, createFakeSubtype("keyboard", false, true))))
.isTrue();
// IME w/ Aux and ASCII-capable "keyboard" subtype
assertThat(InputMethodAndSubtypeUtil.isValidNonAuxAsciiCapableIme(
- createDummyIme(true, createDummySubtype("keyboard", true, true))))
+ createFakeIme(true, createFakeSubtype("keyboard", true, true))))
.isFalse();
// IME w/ non-Aux and ASCII-capable "voice" subtype
assertThat(InputMethodAndSubtypeUtil.isValidNonAuxAsciiCapableIme(
- createDummyIme(false, createDummySubtype("voice", false, true))))
+ createFakeIme(false, createFakeSubtype("voice", false, true))))
.isFalse();
// IME w/ non-Aux and non-ASCII-capable subtype + Non-Aux and ASCII-capable subtype
assertThat(InputMethodAndSubtypeUtil.isValidNonAuxAsciiCapableIme(
- createDummyIme(false,
- createDummySubtype("keyboard", false, true),
- createDummySubtype("keyboard", false, false))))
+ createFakeIme(false,
+ createFakeSubtype("keyboard", false, true),
+ createFakeSubtype("keyboard", false, false))))
.isTrue();
}
- private static InputMethodInfo createDummyIme(boolean isAuxIme,
+ private static InputMethodInfo createFakeIme(boolean isAuxIme,
InputMethodSubtype... subtypes) {
final ResolveInfo ri = new ResolveInfo();
final ServiceInfo si = new ServiceInfo();
final ApplicationInfo ai = new ApplicationInfo();
- ai.packageName = "com.example.android.dummyime";
+ ai.packageName = "com.example.android.fakeime";
ai.enabled = true;
si.applicationInfo = ai;
si.enabled = true;
- si.packageName = "com.example.android.dummyime";
- si.name = "Dummy IME";
+ si.packageName = "com.example.android.fakeime";
+ si.name = "Fake IME";
si.exported = true;
- si.nonLocalizedLabel = "Dummy IME";
+ si.nonLocalizedLabel = "Fake IME";
ri.serviceInfo = si;
return new InputMethodInfo(ri, isAuxIme, "", Arrays.asList(subtypes), 1, false);
}
- private static InputMethodSubtype createDummySubtype(
+ private static InputMethodSubtype createFakeSubtype(
String mode, boolean isAuxiliary, boolean isAsciiCapable) {
return new InputMethodSubtypeBuilder()
.setSubtypeNameResId(0)
diff --git a/packages/SimAppDialog/Android.bp b/packages/SimAppDialog/Android.bp
index 176035f73b65..1c680bb9d25e 100644
--- a/packages/SimAppDialog/Android.bp
+++ b/packages/SimAppDialog/Android.bp
@@ -7,7 +7,8 @@ android_app {
static_libs: [
"androidx.legacy_legacy-support-v4",
- "setup-wizard-lib",
+ "setupcompat",
+ "setupdesign",
],
resource_dirs: ["res"],
diff --git a/packages/SimAppDialog/AndroidManifest.xml b/packages/SimAppDialog/AndroidManifest.xml
index 873f6c5bac54..e7368f35ed5a 100644
--- a/packages/SimAppDialog/AndroidManifest.xml
+++ b/packages/SimAppDialog/AndroidManifest.xml
@@ -23,7 +23,7 @@
android:name=".InstallCarrierAppActivity"
android:exported="true"
android:permission="android.permission.NETWORK_SETTINGS"
- android:theme="@style/SuwThemeGlif.Light">
+ android:theme="@style/SudThemeGlif.Light">
</activity>
</application>
</manifest>
diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
index 12f9bb6b13ea..68113dbf5df0 100644
--- a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
+++ b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
@@ -14,18 +14,17 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_signal_cellular_alt_rounded"
- app:suwHeaderText="@string/install_carrier_app_title"
- app:suwFooter="@layout/install_carrier_app_footer">
+ app:sucHeaderText="@string/install_carrier_app_title">
<LinearLayout
- style="@style/SuwContentFrame"
+ style="@style/SudContentFrame"
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -33,12 +32,12 @@
<TextView
android:id="@+id/install_carrier_app_description"
- style="@style/SuwDescription.Glif"
+ style="@style/SudDescription.Glif"
android:text="@string/install_carrier_app_description_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:id="@+id/illo_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -47,12 +46,12 @@
<ImageView
android:src="@drawable/illo_sim_app_dialog"
- style="@style/SuwContentIllustration"
+ style="@style/SudContentIllustration"
android:contentDescription="@string/install_carrier_app_image_content_description"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- </com.android.setupwizardlib.view.FillContentLayout>
-</LinearLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
+ </LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml b/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml
deleted file mode 100644
index 10dcb77a6584..000000000000
--- a/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-
-<com.android.setupwizardlib.view.ButtonBarLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/footer"
- style="@style/SuwGlifButtonBar.Stackable"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <Button
- android:id="@+id/skip_button"
- style="@style/SuwGlifButton.Secondary"
- android:text="@string/install_carrier_app_defer_action"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1"/>
-
- <Button
- android:id="@+id/download_button"
- style="@style/SuwGlifButton.Primary"
- android:text="@string/install_carrier_app_download_action"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-</com.android.setupwizardlib.view.ButtonBarLayout>
diff --git a/packages/SimAppDialog/res/values/styles.xml b/packages/SimAppDialog/res/values/styles.xml
new file mode 100644
index 000000000000..824e3802aca1
--- /dev/null
+++ b/packages/SimAppDialog/res/values/styles.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+
+ <style name="SetupWizardPartnerResource">
+ <!-- Disable to use partner overlay theme for outside setupwizard flow. -->
+ <item name="sucUsePartnerResource">false</item>
+ <!-- Enable heavy theme style inside setupwizard flow. -->
+ <item name="sudUsePartnerHeavyTheme">true</item>
+ </style>
+
+</resources>
diff --git a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
index abe82a885a94..0b6f9bb4f9e0 100644
--- a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
+++ b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
@@ -17,14 +17,17 @@ package com.android.simappdialog;
import android.app.Activity;
import android.content.Intent;
+import android.content.res.Resources;
import android.os.Bundle;
import android.sysprop.SetupWizardProperties;
import android.text.TextUtils;
import android.view.View;
-import android.widget.Button;
import android.widget.TextView;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+import com.google.android.setupcompat.template.FooterBarMixin;
+import com.google.android.setupcompat.template.FooterButton;
+import com.google.android.setupdesign.GlifLayout;
+import com.google.android.setupdesign.util.ThemeResolver;
/**
* Activity that gives a user the choice to download the SIM app or defer until a later time
@@ -35,7 +38,7 @@ import com.android.setupwizardlib.util.WizardManagerHelper;
* Can display the carrier app name if its passed into the intent with key
* {@link #BUNDLE_KEY_CARRIER_NAME}
*/
-public class InstallCarrierAppActivity extends Activity implements View.OnClickListener {
+public class InstallCarrierAppActivity extends Activity {
/**
* Key for the carrier app name that will be displayed as the app to download. If unset, a
* default description will be used
@@ -50,20 +53,33 @@ public class InstallCarrierAppActivity extends Activity implements View.OnClickL
protected void onCreate(Bundle icicle) {
// Setup theme for aosp/pixel
setTheme(
- WizardManagerHelper.getThemeRes(
- SetupWizardProperties.theme().orElse(""),
- R.style.SuwThemeGlif_Light
- )
- );
+ new ThemeResolver.Builder()
+ .setDefaultTheme(R.style.SudThemeGlifV3_Light)
+ .build()
+ .resolve(SetupWizardProperties.theme().orElse(""),
+ /* suppressDayNight= */ false));
super.onCreate(icicle);
setContentView(R.layout.install_carrier_app_activity);
- Button notNowButton = findViewById(R.id.skip_button);
- notNowButton.setOnClickListener(this);
+ GlifLayout layout = findViewById(R.id.setup_wizard_layout);
+ FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
+ mixin.setSecondaryButton(
+ new FooterButton.Builder(this)
+ .setText(R.string.install_carrier_app_defer_action)
+ .setListener(this::onSkipButtonClick)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SudGlifButton_Secondary)
+ .build());
+
+ mixin.setPrimaryButton(
+ new FooterButton.Builder(this)
+ .setText(R.string.install_carrier_app_download_action)
+ .setListener(this::onDownloadButtonClick)
+ .setButtonType(FooterButton.ButtonType.OTHER)
+ .setTheme(R.style.SudGlifButton_Primary)
+ .build());
- Button downloadButton = findViewById(R.id.download_button);
- downloadButton.setOnClickListener(this);
// Show/hide illo depending on whether one was provided in a resource overlay
boolean showIllo = getResources().getBoolean(R.bool.show_sim_app_dialog_illo);
@@ -82,15 +98,17 @@ public class InstallCarrierAppActivity extends Activity implements View.OnClickL
}
@Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.skip_button:
- finish(DEFER_RESULT);
- break;
- case R.id.download_button:
- finish(DOWNLOAD_RESULT);
- break;
- }
+ protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
+ theme.applyStyle(R.style.SetupWizardPartnerResource, true);
+ super.onApplyThemeResource(theme, resid, first);
+ }
+
+ protected void onSkipButtonClick(View view) {
+ finish(DEFER_RESULT);
+ }
+
+ protected void onDownloadButtonClick(View view) {
+ finish(DOWNLOAD_RESULT);
}
private void finish(int resultCode) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index d0f61817d1cc..fa0d2ba84b4e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -310,7 +310,6 @@ public class BubbleExpandedView extends LinearLayout {
// Set ActivityView's alpha value as zero, since there is no view content to be shown.
setContentVisibility(false);
- mActivityViewContainer.setBackgroundColor(Color.WHITE);
mActivityViewContainer.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
@@ -439,9 +438,11 @@ public class BubbleExpandedView extends LinearLayout {
}
void applyThemeAttrs() {
- final TypedArray ta = mContext.obtainStyledAttributes(
- new int[] {android.R.attr.dialogCornerRadius});
+ final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
+ android.R.attr.dialogCornerRadius,
+ android.R.attr.colorBackgroundFloating});
mCornerRadius = ta.getDimensionPixelSize(0, 0);
+ mActivityViewContainer.setBackgroundColor(ta.getColor(1, Color.WHITE));
ta.recycle();
if (mActivityView != null && ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
index 8a67da53e6a2..b28730d004f6 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
@@ -16,11 +16,13 @@
package com.android.systemui.onehanded;
+import android.content.ContentResolver;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
+import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -48,12 +50,15 @@ import javax.inject.Singleton;
@Singleton
public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Dumpable {
private static final String TAG = "OneHandedTutorialHandler";
+ private static final int MAX_TUTORIAL_SHOW_COUNT = 2;
private final Rect mLastUpdatedBounds = new Rect();
private final WindowManager mWindowManager;
private View mTutorialView;
private Point mDisplaySize = new Point();
private Handler mUpdateHandler;
+ private ContentResolver mContentResolver;
+ private boolean mCanShowTutorial;
/**
* Container of the tutorial panel showing at outside region when one handed starting
@@ -71,6 +76,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Du
@Inject
public OneHandedTutorialHandler(Context context) {
context.getDisplay().getRealSize(mDisplaySize);
+ mContentResolver = context.getContentResolver();
mUpdateHandler = new Handler();
mWindowManager = context.getSystemService(WindowManager.class);
mTargetViewContainer = new FrameLayout(context);
@@ -79,12 +85,20 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Du
R.fraction.config_one_handed_offset, 1, 1));
mTutorialView = LayoutInflater.from(context).inflate(R.xml.one_handed_tutorial, null);
mTargetViewContainer.addView(mTutorialView);
- createOrUpdateTutorialTarget();
+ mCanShowTutorial = (Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT)
+ ? false : true;
+ if (mCanShowTutorial) {
+ createOrUpdateTutorialTarget();
+ }
}
@Override
public void onStartFinished(Rect bounds) {
- mUpdateHandler.post(() -> updateFinished(View.VISIBLE, 0f));
+ mUpdateHandler.post(() -> {
+ updateFinished(View.VISIBLE, 0f);
+ updateTutorialCount();
+ });
}
@Override
@@ -94,10 +108,23 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Du
}
private void updateFinished(int visible, float finalPosition) {
+ if (!canShowTutorial()) {
+ return;
+ }
+
mTargetViewContainer.setVisibility(visible);
mTargetViewContainer.setTranslationY(finalPosition);
}
+ private void updateTutorialCount() {
+ int showCount = Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0);
+ showCount = Math.min(MAX_TUTORIAL_SHOW_COUNT, showCount + 1);
+ mCanShowTutorial = showCount < MAX_TUTORIAL_SHOW_COUNT;
+ Settings.Secure.putInt(mContentResolver,
+ Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, showCount);
+ }
+
/**
* Adds the tutorial target view to the WindowManager and update its layout, so it's ready
* to be animated in.
@@ -153,7 +180,19 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Du
pw.println(mLastUpdatedBounds);
}
+ private boolean canShowTutorial() {
+ if (!mCanShowTutorial) {
+ mTargetViewContainer.setVisibility(View.GONE);
+ return false;
+ }
+
+ return true;
+ }
+
private void onAnimationUpdate(float value) {
+ if (!canShowTutorial()) {
+ return;
+ }
mTargetViewContainer.setVisibility(View.VISIBLE);
mTargetViewContainer.setTransitionGroup(true);
mTargetViewContainer.setTranslationY(value - mTargetViewContainer.getHeight());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 3264429a1723..d8548decc5f4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -67,7 +67,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements
private static final String PATTERN_HOUR_MINUTE = "h:mm a";
private static final String PATTERN_HOUR_NINUTE_24 = "HH:mm";
- private final ColorDisplayManager mManager;
+ private ColorDisplayManager mManager;
private final LocationController mLocationController;
private final NightDisplayListenerModule.Builder mNightDisplayListenerBuilder;
private NightDisplayListener mListener;
@@ -126,6 +126,8 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements
mListener.setCallback(null);
}
+ mManager = getHost().getUserContext().getSystemService(ColorDisplayManager.class);
+
// Make a new controller for the new user.
mListener = mNightDisplayListenerBuilder.setUser(newUserId).build();
if (mIsListening) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
index 07b841ffb6f7..78975a4798ce 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -58,10 +58,9 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a");
private final Icon mIcon = ResourceIcon.get(
com.android.internal.R.drawable.ic_qs_ui_mode_night);
- private final UiModeManager mUiModeManager;
+ private UiModeManager mUiModeManager;
private final BatteryController mBatteryController;
private final LocationController mLocationController;
-
@Inject
public UiModeNightTile(
QSHost host,
@@ -78,7 +77,7 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
activityStarter, qsLogger);
mBatteryController = batteryController;
- mUiModeManager = mContext.getSystemService(UiModeManager.class);
+ mUiModeManager = host.getUserContext().getSystemService(UiModeManager.class);
mLocationController = locationController;
configurationController.observe(getLifecycle(), this);
batteryController.observe(getLifecycle(), this);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 4007abb39903..d40b666860e9 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -78,6 +78,22 @@ public class Divider extends SystemUI {
onUndockingTask();
}
}
+
+ @Override
+ public void onActivityForcedResizable(String packageName, int taskId,
+ int reason) {
+ mDividerController.onActivityForcedResizable(packageName, taskId, reason);
+ }
+
+ @Override
+ public void onActivityDismissingDockedStack() {
+ mDividerController.onActivityDismissingSplitScreen();
+ }
+
+ @Override
+ public void onActivityLaunchOnSecondaryDisplayFailed() {
+ mDividerController.onActivityLaunchOnSecondaryDisplayFailed();
+ }
}
);
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
index 81649f608581..1ee8abb411b9 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
@@ -50,8 +50,7 @@ import java.util.function.Consumer;
/**
* Controls the docked stack divider.
*/
-public class DividerController implements DividerView.DividerCallbacks,
- DisplayController.OnDisplaysChangedListener {
+public class DividerController implements DisplayController.OnDisplaysChangedListener {
static final boolean DEBUG = false;
private static final String TAG = "Divider";
@@ -257,8 +256,8 @@ public class DividerController implements DividerView.DividerCallbacks,
mView = (DividerView)
LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
- mView.injectDependencies(mWindowManager, mDividerState, this, mSplits, mSplitLayout,
- mImePositionProcessor, mWindowManagerProxy);
+ mView.injectDependencies(mWindowManager, mDividerState, mForcedResizableController, mSplits,
+ mSplitLayout, mImePositionProcessor, mWindowManagerProxy);
mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, null /* transaction */);
final int size = dctx.getResources().getDimensionPixelSize(
@@ -397,7 +396,22 @@ public class DividerController implements DividerView.DividerCallbacks,
}
}
- /** Called when there's a task undocking. */
+ /** Called when there's an activity forced resizable. */
+ public void onActivityForcedResizable(String packageName, int taskId, int reason) {
+ mForcedResizableController.activityForcedResizable(packageName, taskId, reason);
+ }
+
+ /** Called when there's an activity dismissing split screen. */
+ public void onActivityDismissingSplitScreen() {
+ mForcedResizableController.activityDismissingSplitScreen();
+ }
+
+ /** Called when there's an activity launch on secondary display failed. */
+ public void onActivityLaunchOnSecondaryDisplayFailed() {
+ mForcedResizableController.activityLaunchOnSecondaryDisplayFailed();
+ }
+
+ /** Called when there's a task undocking. */
public void onUndockingTask() {
if (mView != null) {
mView.onUndockingTask();
@@ -426,17 +440,7 @@ public class DividerController implements DividerView.DividerCallbacks,
mForcedResizableController.onAppTransitionFinished();
}
- @Override
- public void onDraggingStart() {
- mForcedResizableController.onDraggingStart();
- }
-
- @Override
- public void onDraggingEnd() {
- mForcedResizableController.onDraggingEnd();
- }
-
- /** Dumps current status of Divider.*/
+ /** Dumps current status of Split Screen. */
public void dump(PrintWriter pw) {
pw.print(" mVisible="); pw.println(mVisible);
pw.print(" mMinimized="); pw.println(mMinimized);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index f412cc00981b..ff8bab07db05 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -28,15 +28,13 @@ import android.util.ArraySet;
import android.widget.Toast;
import com.android.systemui.R;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.function.Consumer;
/**
* Controller that decides when to show the {@link ForcedResizableInfoActivity}.
*/
-public class ForcedResizableInfoActivityController {
+final class ForcedResizableInfoActivityController implements DividerView.DividerCallbacks {
private static final String SELF_PACKAGE_NAME = "com.android.systemui";
@@ -47,12 +45,7 @@ public class ForcedResizableInfoActivityController {
private final ArraySet<String> mPackagesShownInSession = new ArraySet<>();
private boolean mDividerDragging;
- private final Runnable mTimeoutRunnable = new Runnable() {
- @Override
- public void run() {
- showPending();
- }
- };
+ private final Runnable mTimeoutRunnable = this::showPending;
private final Consumer<Boolean> mDockedStackExistsListener = exists -> {
if (!exists) {
@@ -78,44 +71,28 @@ public class ForcedResizableInfoActivityController {
public ForcedResizableInfoActivityController(Context context,
DividerController dividerController) {
mContext = context;
- ActivityManagerWrapper.getInstance().registerTaskStackListener(
- new TaskStackChangeListener() {
- @Override
- public void onActivityForcedResizable(String packageName, int taskId,
- int reason) {
- activityForcedResizable(packageName, taskId, reason);
- }
-
- @Override
- public void onActivityDismissingDockedStack() {
- activityDismissingDockedStack();
- }
-
- @Override
- public void onActivityLaunchOnSecondaryDisplayFailed() {
- activityLaunchOnSecondaryDisplayFailed();
- }
- });
dividerController.registerInSplitScreenListener(mDockedStackExistsListener);
}
- public void onAppTransitionFinished() {
- if (!mDividerDragging) {
- showPending();
- }
- }
-
- void onDraggingStart() {
+ @Override
+ public void onDraggingStart() {
mDividerDragging = true;
mHandler.removeCallbacks(mTimeoutRunnable);
}
- void onDraggingEnd() {
+ @Override
+ public void onDraggingEnd() {
mDividerDragging = false;
showPending();
}
- private void activityForcedResizable(String packageName, int taskId, int reason) {
+ void onAppTransitionFinished() {
+ if (!mDividerDragging) {
+ showPending();
+ }
+ }
+
+ void activityForcedResizable(String packageName, int taskId, int reason) {
if (debounce(packageName)) {
return;
}
@@ -123,12 +100,12 @@ public class ForcedResizableInfoActivityController {
postTimeout();
}
- private void activityDismissingDockedStack() {
+ void activityDismissingSplitScreen() {
Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
Toast.LENGTH_SHORT).show();
}
- private void activityLaunchOnSecondaryDisplayFailed() {
+ void activityLaunchOnSecondaryDisplayFailed() {
Toast.makeText(mContext, R.string.activity_launch_on_secondary_display_failed_text,
Toast.LENGTH_SHORT).show();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 6297052550c3..8c5e2ceaeadf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -375,6 +375,34 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
};
+ private static class NavBarViewAttachedListener implements View.OnAttachStateChangeListener {
+ private NavigationBarFragment mFragment;
+ private FragmentListener mListener;
+
+ NavBarViewAttachedListener(NavigationBarFragment fragment, FragmentListener listener) {
+ mFragment = fragment;
+ mListener = listener;
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
+ fragmentHost.getFragmentManager().beginTransaction()
+ .replace(R.id.navigation_bar_frame, mFragment, TAG)
+ .commit();
+ fragmentHost.addTagListener(TAG, mListener);
+ mFragment = null;
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
+ fragmentHost.removeTagListener(TAG, mListener);
+ FragmentHostManager.removeAndDestroy(v);
+ v.removeOnAttachStateChangeListener(this);
+ }
+ }
+
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
@Override
@@ -1470,26 +1498,10 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + navigationBarView);
if (navigationBarView == null) return null;
- navigationBarView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- final NavigationBarFragment fragment =
- FragmentHostManager.get(v).create(NavigationBarFragment.class);
- final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
- fragmentHost.getFragmentManager().beginTransaction()
- .replace(R.id.navigation_bar_frame, fragment, TAG)
- .commit();
- fragmentHost.addTagListener(TAG, listener);
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
- fragmentHost.removeTagListener(TAG, listener);
- FragmentHostManager.removeAndDestroy(v);
- navigationBarView.removeOnAttachStateChangeListener(this);
- }
- });
+ NavigationBarFragment fragment = FragmentHostManager.get(navigationBarView)
+ .create(NavigationBarFragment.class);
+ navigationBarView.addOnAttachStateChangeListener(new NavBarViewAttachedListener(fragment,
+ listener));
context.getSystemService(WindowManager.class).addView(navigationBarView, lp);
return navigationBarView;
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
index b5f98ad47c09..89297fd83bb0 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
@@ -54,7 +54,7 @@ public class UsbAccessoryUriActivity extends AlertActivity
String uriString = intent.getStringExtra("uri");
mUri = (uriString == null ? null : Uri.parse(uriString));
- // sanity check before displaying dialog
+ // Exception check before displaying dialog
if (mUri == null) {
Log.e(TAG, "could not parse Uri " + uriString);
finish();
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index df9dee89f5a2..6dbb1e922f60 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -137,6 +137,7 @@ final class UiModeManagerService extends SystemService {
int mCurUiMode = 0;
private int mSetUiMode = 0;
private boolean mHoldingConfiguration = false;
+ private int mCurrentUser;
private Configuration mConfiguration = new Configuration();
boolean mSystemReady;
@@ -325,6 +326,7 @@ final class UiModeManagerService extends SystemService {
@Override
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mCurrentUser = to.getUserIdentifier();
getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver);
verifySetupWizardCompleted();
}
@@ -727,16 +729,30 @@ final class UiModeManagerService extends SystemService {
@Override
public boolean setNightModeActivated(boolean active) {
+ if (isNightModeLocked() && (getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
+ != PackageManager.PERMISSION_GRANTED)) {
+ Slog.e(TAG, "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission");
+ return false;
+ }
+ final int user = Binder.getCallingUserHandle().getIdentifier();
+ if (user != mCurrentUser && getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS)
+ != PackageManager.PERMISSION_GRANTED) {
+ Slog.e(TAG, "Target user is not current user,"
+ + " INTERACT_ACROSS_USERS permission is required");
+ return false;
+
+ }
synchronized (mLock) {
- final int user = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) {
unregisterScreenOffEventLocked();
mOverrideNightModeOff = !active;
mOverrideNightModeOn = active;
- mOverrideNightModeUser = user;
- persistNightModeOverrides(user);
+ mOverrideNightModeUser = mCurrentUser;
+ persistNightModeOverrides(mCurrentUser);
} else if (mNightMode == UiModeManager.MODE_NIGHT_NO
&& active) {
mNightMode = UiModeManager.MODE_NIGHT_YES;
@@ -746,7 +762,7 @@ final class UiModeManagerService extends SystemService {
}
updateConfigurationLocked();
applyConfigurationExternallyLocked();
- persistNightMode(user);
+ persistNightMode(mCurrentUser);
return true;
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e546a2812caa..91a1487c5245 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1956,7 +1956,7 @@ public class ActivityManagerService extends IActivityManager.Stub
nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
}
memInfo.readMemInfo();
- synchronized (ActivityManagerService.this) {
+ synchronized (mProcessStats.mLock) {
if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
+ (SystemClock.uptimeMillis()-start) + "ms");
final long cachedKb = memInfo.getCachedSizeKb();
@@ -7048,9 +7048,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mUsageStatsService.prepareShutdown();
}
mBatteryStatsService.shutdown();
- synchronized (this) {
- mProcessStats.shutdownLocked();
- }
+ mProcessStats.shutdown();
return timedout;
}
@@ -12352,7 +12350,7 @@ public class ActivityManagerService extends IActivityManager.Stub
MemInfoReader memInfo = new MemInfoReader();
memInfo.readMemInfo();
if (nativeProcTotalPss > 0) {
- synchronized (this) {
+ synchronized (mProcessStats.mLock) {
final long cachedKb = memInfo.getCachedSizeKb();
final long freeKb = memInfo.getFreeSizeKb();
final long zramKb = memInfo.getZramTotalSizeKb();
@@ -12934,7 +12932,7 @@ public class ActivityManagerService extends IActivityManager.Stub
MemInfoReader memInfo = new MemInfoReader();
memInfo.readMemInfo();
if (nativeProcTotalPss > 0) {
- synchronized (this) {
+ synchronized (mProcessStats.mLock) {
final long cachedKb = memInfo.getCachedSizeKb();
final long freeKb = memInfo.getFreeSizeKb();
final long zramKb = memInfo.getZramTotalSizeKb();
@@ -16505,9 +16503,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override public void run() {
- synchronized (mService) {
- mProcessStats.writeStateAsyncLocked();
- }
+ mProcessStats.writeStateAsync();
}
}
@@ -16557,9 +16553,13 @@ public class ActivityManagerService extends IActivityManager.Stub
}
mLastMemoryLevel = memFactor;
mLastNumProcesses = mProcessList.getLruSizeLocked();
- boolean allChanged = mProcessStats.setMemFactorLocked(
- memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
- final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+ boolean allChanged;
+ int trackerMemFactor;
+ synchronized (mProcessStats.mLock) {
+ allChanged = mProcessStats.setMemFactorLocked(
+ memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
+ trackerMemFactor = mProcessStats.getMemFactorLocked();
+ }
if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
if (mLowRamStartTime == 0) {
mLowRamStartTime = now;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index f0343e1d807c..bf15f1737cfc 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -659,13 +659,15 @@ public final class OomAdjuster {
updateUidsLocked(activeUids, nowElapsed);
- if (mService.mProcessStats.shouldWriteNowLocked(now)) {
- mService.mHandler.post(new ActivityManagerService.ProcStatsRunnable(mService,
- mService.mProcessStats));
- }
+ synchronized (mService.mProcessStats.mLock) {
+ if (mService.mProcessStats.shouldWriteNowLocked(now)) {
+ mService.mHandler.post(new ActivityManagerService.ProcStatsRunnable(mService,
+ mService.mProcessStats));
+ }
- // Run this after making sure all procstates are updated.
- mService.mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
+ // Run this after making sure all procstates are updated.
+ mService.mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
+ }
if (DEBUG_OOM_ADJ) {
final long duration = SystemClock.uptimeMillis() - now;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 1647fdaa57b6..e3e13391a8b0 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -673,30 +673,33 @@ class ProcessRecord implements WindowProcessListener {
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
if (thread == null) {
- final ProcessState origBase = baseProcessTracker;
- if (origBase != null) {
- origBase.setState(ProcessStats.STATE_NOTHING,
- tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList.mPkgList);
- for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
- uid, processName, pkgList.keyAt(ipkg),
- ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
- pkgList.valueAt(ipkg).appVersion);
- }
- origBase.makeInactive();
- }
- baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,
- info.longVersionCode, processName);
- baseProcessTracker.makeActive();
- for (int i=0; i<pkgList.size(); i++) {
- ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
- if (holder.state != null && holder.state != origBase) {
- holder.state.makeInactive();
+ synchronized (tracker.mLock) {
+ final ProcessState origBase = baseProcessTracker;
+ if (origBase != null) {
+ origBase.setState(ProcessStats.STATE_NOTHING,
+ tracker.getMemFactorLocked(), SystemClock.uptimeMillis(),
+ pkgList.mPkgList);
+ for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
+ uid, processName, pkgList.keyAt(ipkg),
+ ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
+ pkgList.valueAt(ipkg).appVersion);
+ }
+ origBase.makeInactive();
}
- tracker.updateProcessStateHolderLocked(holder, pkgList.keyAt(i), info.uid,
+ baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,
info.longVersionCode, processName);
- if (holder.state != baseProcessTracker) {
- holder.state.makeActive();
+ baseProcessTracker.makeActive();
+ for (int i = 0, ipkg = pkgList.size(); i < ipkg; i++) {
+ ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
+ if (holder.state != null && holder.state != origBase) {
+ holder.state.makeInactive();
+ }
+ tracker.updateProcessStateHolderLocked(holder, pkgList.keyAt(i), info.uid,
+ info.longVersionCode, processName);
+ if (holder.state != baseProcessTracker) {
+ holder.state.makeActive();
+ }
}
}
}
@@ -707,27 +710,30 @@ class ProcessRecord implements WindowProcessListener {
public void makeInactive(ProcessStatsService tracker) {
thread = null;
mWindowProcessController.setThread(null);
- final ProcessState origBase = baseProcessTracker;
- if (origBase != null) {
+ synchronized (tracker.mLock) {
+ final ProcessState origBase = baseProcessTracker;
if (origBase != null) {
- origBase.setState(ProcessStats.STATE_NOTHING,
- tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList.mPkgList);
- for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
- uid, processName, pkgList.keyAt(ipkg),
- ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
- pkgList.valueAt(ipkg).appVersion);
+ if (origBase != null) {
+ origBase.setState(ProcessStats.STATE_NOTHING,
+ tracker.getMemFactorLocked(), SystemClock.uptimeMillis(),
+ pkgList.mPkgList);
+ for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
+ uid, processName, pkgList.keyAt(ipkg),
+ ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
+ pkgList.valueAt(ipkg).appVersion);
+ }
+ origBase.makeInactive();
}
- origBase.makeInactive();
- }
- baseProcessTracker = null;
- for (int i=0; i<pkgList.size(); i++) {
- ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
- if (holder.state != null && holder.state != origBase) {
- holder.state.makeInactive();
+ baseProcessTracker = null;
+ for (int i = 0, ipkg = pkgList.size(); i < ipkg; i++) {
+ ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
+ if (holder.state != null && holder.state != origBase) {
+ holder.state.makeInactive();
+ }
+ holder.pkg = null;
+ holder.state = null;
}
- holder.pkg = null;
- holder.state = null;
}
}
}
@@ -1026,17 +1032,19 @@ class ProcessRecord implements WindowProcessListener {
*/
public boolean addPackage(String pkg, long versionCode, ProcessStatsService tracker) {
if (!pkgList.containsKey(pkg)) {
- ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
- versionCode);
- if (baseProcessTracker != null) {
- tracker.updateProcessStateHolderLocked(holder, pkg, info.uid, versionCode,
- processName);
- pkgList.put(pkg, holder);
- if (holder.state != baseProcessTracker) {
- holder.state.makeActive();
+ synchronized (tracker.mLock) {
+ ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
+ versionCode);
+ if (baseProcessTracker != null) {
+ tracker.updateProcessStateHolderLocked(holder, pkg, info.uid, versionCode,
+ processName);
+ pkgList.put(pkg, holder);
+ if (holder.state != baseProcessTracker) {
+ holder.state.makeActive();
+ }
+ } else {
+ pkgList.put(pkg, holder);
}
- } else {
- pkgList.put(pkg, holder);
}
return true;
}
@@ -1072,31 +1080,33 @@ class ProcessRecord implements WindowProcessListener {
public void resetPackageList(ProcessStatsService tracker) {
final int N = pkgList.size();
if (baseProcessTracker != null) {
- long now = SystemClock.uptimeMillis();
- baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
- tracker.getMemFactorLocked(), now, pkgList.mPkgList);
- for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
- uid, processName, pkgList.keyAt(ipkg),
- ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
- pkgList.valueAt(ipkg).appVersion);
- }
- if (N != 1) {
- for (int i=0; i<N; i++) {
- ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
- if (holder.state != null && holder.state != baseProcessTracker) {
- holder.state.makeInactive();
- }
-
+ synchronized (tracker.mLock) {
+ long now = SystemClock.uptimeMillis();
+ baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
+ tracker.getMemFactorLocked(), now, pkgList.mPkgList);
+ for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
+ uid, processName, pkgList.keyAt(ipkg),
+ ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
+ pkgList.valueAt(ipkg).appVersion);
}
- pkgList.clear();
- ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
- info.longVersionCode);
- tracker.updateProcessStateHolderLocked(holder, info.packageName, info.uid,
- info.longVersionCode, processName);
- pkgList.put(info.packageName, holder);
- if (holder.state != baseProcessTracker) {
- holder.state.makeActive();
+ if (N != 1) {
+ for (int i = 0; i < N; i++) {
+ ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
+ if (holder.state != null && holder.state != baseProcessTracker) {
+ holder.state.makeInactive();
+ }
+
+ }
+ pkgList.clear();
+ ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
+ info.longVersionCode);
+ tracker.updateProcessStateHolderLocked(holder, info.packageName, info.uid,
+ info.longVersionCode, processName);
+ pkgList.put(info.packageName, holder);
+ if (holder.state != baseProcessTracker) {
+ holder.state.makeActive();
+ }
}
}
} else if (N != 1) {
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index a168af5ad842..4e8c386a3c66 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -71,33 +71,62 @@ public final class ProcessStatsService extends IProcessStats.Stub {
final ActivityManagerService mAm;
final File mBaseDir;
- ProcessStats mProcessStats;
+
+ // Note: The locking order of the below 3 locks should be:
+ // mLock, mPendingWriteLock, mFileLock
+
+ // The lock object to protect the internal state/structures
+ final Object mLock = new Object();
+
+ // The lock object to protect the access to pending writes
+ final Object mPendingWriteLock = new Object();
+
+ // The lock object to protect the access to all of the file read/write
+ final ReentrantLock mFileLock = new ReentrantLock();
+
+ @GuardedBy("mLock")
+ final ProcessStats mProcessStats;
+
+ @GuardedBy("mFileLock")
AtomicFile mFile;
+
+ @GuardedBy("mLock")
boolean mCommitPending;
+
+ @GuardedBy("mLock")
boolean mShuttingDown;
+
+ @GuardedBy("mLock")
int mLastMemOnlyState = -1;
boolean mMemFactorLowered;
- final ReentrantLock mWriteLock = new ReentrantLock();
- final Object mPendingWriteLock = new Object();
+ @GuardedBy("mPendingWriteLock")
AtomicFile mPendingWriteFile;
+
+ @GuardedBy("mPendingWriteLock")
Parcel mPendingWrite;
+
+ @GuardedBy("mPendingWriteLock")
boolean mPendingWriteCommitted;
+
+ @GuardedBy("mLock")
long mLastWriteTime;
/** For CTS to inject the screen state. */
- @GuardedBy("mAm")
+ @GuardedBy("mLock")
Boolean mInjectedScreenState;
public ProcessStatsService(ActivityManagerService am, File file) {
mAm = am;
mBaseDir = file;
mBaseDir.mkdirs();
- mProcessStats = new ProcessStats(true);
- updateFile();
+ synchronized (mLock) {
+ mProcessStats = new ProcessStats(true);
+ updateFileLocked();
+ }
SystemProperties.addChangeCallback(new Runnable() {
@Override public void run() {
- synchronized (mAm) {
+ synchronized (mLock) {
if (mProcessStats.evaluateSystemProperties(false)) {
mProcessStats.mFlags |= ProcessStats.FLAG_SYSPROPS;
writeStateLocked(true, true);
@@ -121,32 +150,33 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
- @GuardedBy("mAm")
- public void updateProcessStateHolderLocked(ProcessStats.ProcessStateHolder holder,
+ @GuardedBy("mLock")
+ void updateProcessStateHolderLocked(ProcessStats.ProcessStateHolder holder,
String packageName, int uid, long versionCode, String processName) {
holder.pkg = mProcessStats.getPackageStateLocked(packageName, uid, versionCode);
holder.state = mProcessStats.getProcessStateLocked(holder.pkg, processName);
}
- @GuardedBy("mAm")
- public ProcessState getProcessStateLocked(String packageName,
+ @GuardedBy("mLock")
+ ProcessState getProcessStateLocked(String packageName,
int uid, long versionCode, String processName) {
return mProcessStats.getProcessStateLocked(packageName, uid, versionCode, processName);
}
- @GuardedBy("mAm")
- public ServiceState getServiceStateLocked(String packageName, int uid,
+ ServiceState getServiceState(String packageName, int uid,
long versionCode, String processName, String className) {
- return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
- className);
+ synchronized (mLock) {
+ return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
+ className);
+ }
}
- public boolean isMemFactorLowered() {
+ boolean isMemFactorLowered() {
return mMemFactorLowered;
}
- @GuardedBy("mAm")
- public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
+ @GuardedBy("mLock")
+ boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
mMemFactorLowered = memFactor < mLastMemOnlyState;
mLastMemOnlyState = memFactor;
if (mInjectedScreenState != null) {
@@ -184,24 +214,24 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return false;
}
- @GuardedBy("mAm")
- public int getMemFactorLocked() {
+ @GuardedBy("mLock")
+ int getMemFactorLocked() {
return mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING ? mProcessStats.mMemFactor : 0;
}
- @GuardedBy("mAm")
- public void addSysMemUsageLocked(long cachedMem, long freeMem, long zramMem, long kernelMem,
+ @GuardedBy("mLock")
+ void addSysMemUsageLocked(long cachedMem, long freeMem, long zramMem, long kernelMem,
long nativeMem) {
mProcessStats.addSysMemUsage(cachedMem, freeMem, zramMem, kernelMem, nativeMem);
}
- @GuardedBy("mAm")
- public void updateTrackingAssociationsLocked(int curSeq, long now) {
+ @GuardedBy("mLock")
+ void updateTrackingAssociationsLocked(int curSeq, long now) {
mProcessStats.updateTrackingAssociationsLocked(curSeq, now);
}
- @GuardedBy("mAm")
- public boolean shouldWriteNowLocked(long now) {
+ @GuardedBy("mLock")
+ boolean shouldWriteNowLocked(long now) {
if (now > (mLastWriteTime+WRITE_PERIOD)) {
if (SystemClock.elapsedRealtime()
> (mProcessStats.mTimePeriodStartRealtime+ProcessStats.COMMIT_PERIOD) &&
@@ -214,25 +244,27 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return false;
}
- @GuardedBy("mAm")
- public void shutdownLocked() {
+ void shutdown() {
Slog.w(TAG, "Writing process stats before shutdown...");
- mProcessStats.mFlags |= ProcessStats.FLAG_SHUTDOWN;
- writeStateSyncLocked();
- mShuttingDown = true;
+ synchronized (mLock) {
+ mProcessStats.mFlags |= ProcessStats.FLAG_SHUTDOWN;
+ writeStateSyncLocked();
+ mShuttingDown = true;
+ }
}
- @GuardedBy("mAm")
- public void writeStateAsyncLocked() {
- writeStateLocked(false);
+ void writeStateAsync() {
+ synchronized (mLock) {
+ writeStateLocked(false);
+ }
}
- @GuardedBy("mAm")
- public void writeStateSyncLocked() {
+ @GuardedBy("mLock")
+ private void writeStateSyncLocked() {
writeStateLocked(true);
}
- @GuardedBy("mAm")
+ @GuardedBy("mLock")
private void writeStateLocked(boolean sync) {
if (mShuttingDown) {
return;
@@ -242,8 +274,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
writeStateLocked(sync, commitPending);
}
- @GuardedBy("mAm")
- public void writeStateLocked(boolean sync, final boolean commit) {
+ @GuardedBy("mLock")
+ private void writeStateLocked(boolean sync, final boolean commit) {
final long totalTime;
synchronized (mPendingWriteLock) {
final long now = SystemClock.uptimeMillis();
@@ -255,13 +287,13 @@ public final class ProcessStatsService extends IProcessStats.Stub {
mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
}
mProcessStats.writeToParcel(mPendingWrite, 0);
- mPendingWriteFile = new AtomicFile(mFile.getBaseFile());
+ mPendingWriteFile = new AtomicFile(getCurrentFile());
mPendingWriteCommitted = commit;
}
if (commit) {
mProcessStats.resetSafely();
- updateFile();
- mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
+ updateFileLocked();
+ scheduleRequestPssAllProcs(true, false);
}
mLastWriteTime = SystemClock.uptimeMillis();
totalTime = SystemClock.uptimeMillis() - now;
@@ -279,14 +311,37 @@ public final class ProcessStatsService extends IProcessStats.Stub {
performWriteState(totalTime);
}
- private void updateFile() {
- mFile = new AtomicFile(new File(mBaseDir, STATE_FILE_PREFIX
- + mProcessStats.mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
+ private void scheduleRequestPssAllProcs(boolean always, boolean memLowered) {
+ mAm.mHandler.post(() -> {
+ synchronized (mAm) {
+ mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), always, memLowered);
+ }
+ });
+ }
+
+ @GuardedBy("mLock")
+ private void updateFileLocked() {
+ mFileLock.lock();
+ try {
+ mFile = new AtomicFile(new File(mBaseDir, STATE_FILE_PREFIX
+ + mProcessStats.mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
+ } finally {
+ mFileLock.unlock();
+ }
mLastWriteTime = SystemClock.uptimeMillis();
}
- void performWriteState(long initialTime) {
- if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile());
+ private File getCurrentFile() {
+ mFileLock.lock();
+ try {
+ return mFile.getBaseFile();
+ } finally {
+ mFileLock.unlock();
+ }
+ }
+
+ private void performWriteState(long initialTime) {
+ if (DEBUG) Slog.d(TAG, "Performing write to " + getCurrentFile());
Parcel data;
AtomicFile file;
synchronized (mPendingWriteLock) {
@@ -298,7 +353,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
mPendingWrite = null;
mPendingWriteFile = null;
- mWriteLock.lock();
+ mFileLock.lock();
}
final long startTime = SystemClock.uptimeMillis();
@@ -316,13 +371,13 @@ public final class ProcessStatsService extends IProcessStats.Stub {
file.failWrite(stream);
} finally {
data.recycle();
- trimHistoricStatesWriteLocked();
- mWriteLock.unlock();
+ trimHistoricStatesWriteLF();
+ mFileLock.unlock();
}
}
- @GuardedBy("mAm")
- boolean readLocked(ProcessStats stats, AtomicFile file) {
+ @GuardedBy("mFileLock")
+ private boolean readLF(ProcessStats stats, AtomicFile file) {
try {
FileInputStream stream = file.openRead();
stats.read(stream);
@@ -387,7 +442,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return true;
}
- private ArrayList<String> getCommittedFiles(int minNum, boolean inclCurrent,
+ @GuardedBy("mFileLock")
+ private ArrayList<String> getCommittedFilesLF(int minNum, boolean inclCurrent,
boolean inclCheckedIn) {
File[] files = mBaseDir.listFiles();
if (files == null || files.length <= minNum) {
@@ -414,9 +470,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return filesArray;
}
- @GuardedBy("mAm")
- public void trimHistoricStatesWriteLocked() {
- ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES, false, true);
+ @GuardedBy("mFileLock")
+ private void trimHistoricStatesWriteLF() {
+ ArrayList<String> filesArray = getCommittedFilesLF(MAX_HISTORIC_STATES, false, true);
if (filesArray == null) {
return;
}
@@ -427,8 +483,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
- @GuardedBy("mAm")
- boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
+ @GuardedBy("mLock")
+ private boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
boolean sepProcStates, int[] procStates, long now, String reqPackage) {
ArrayList<ProcessState> procs = mProcessStats.collectProcessesLocked(
@@ -502,20 +558,21 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return res;
}
+ @Override
public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
mAm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
- synchronized (mAm) {
+ synchronized (mLock) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
mProcessStats.writeToParcel(current, now, 0);
}
- mWriteLock.lock();
+ mFileLock.lock();
try {
if (historic != null) {
- ArrayList<String> files = getCommittedFiles(0, false, true);
+ ArrayList<String> files = getCommittedFilesLF(0, false, true);
if (files != null) {
for (int i=files.size()-1; i>=0; i--) {
try {
@@ -529,7 +586,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
return current.marshall();
}
@@ -563,9 +620,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
long newHighWaterMark = highWaterMarkMs;
- mWriteLock.lock();
+ mFileLock.lock();
try {
- ArrayList<String> files = getCommittedFiles(0, false, true);
+ ArrayList<String> files = getCommittedFilesLF(0, false, true);
if (files != null) {
String highWaterMarkStr =
DateFormat.format("yyyy-MM-dd-HH-mm-ss", highWaterMarkMs).toString();
@@ -612,7 +669,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} catch (IOException e) {
Slog.w(TAG, "Failure opening procstat file", e);
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
return newHighWaterMark;
}
@@ -625,7 +682,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return mAm.mConstants.MIN_ASSOC_LOG_DURATION;
}
- private ParcelFileDescriptor protoToParcelFileDescriptor(ProcessStats stats, int section)
+ private static ParcelFileDescriptor protoToParcelFileDescriptor(ProcessStats stats, int section)
throws IOException {
final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
Thread thr = new Thread("ProcessStats pipe output") {
@@ -645,12 +702,13 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return fds[0];
}
+ @Override
public ParcelFileDescriptor getStatsOverTime(long minTime) {
mAm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
long curTime;
- synchronized (mAm) {
+ synchronized (mLock) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
@@ -658,11 +716,11 @@ public final class ProcessStatsService extends IProcessStats.Stub {
curTime = mProcessStats.mTimePeriodEndRealtime
- mProcessStats.mTimePeriodStartRealtime;
}
- mWriteLock.lock();
+ mFileLock.lock();
try {
if (curTime < minTime) {
// Need to add in older stats to reach desired time.
- ArrayList<String> files = getCommittedFiles(0, false, true);
+ ArrayList<String> files = getCommittedFilesLF(0, false, true);
if (files != null && files.size() > 0) {
current.setDataPosition(0);
ProcessStats stats = ProcessStats.CREATOR.createFromParcel(current);
@@ -673,7 +731,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
AtomicFile file = new AtomicFile(new File(files.get(i)));
i--;
ProcessStats moreStats = new ProcessStats(false);
- readLocked(moreStats, file);
+ readLF(moreStats, file);
if (moreStats.mReadError == null) {
stats.add(moreStats);
StringBuilder sb = new StringBuilder();
@@ -712,13 +770,14 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} catch (IOException e) {
Slog.w(TAG, "Failed building output pipe", e);
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
return null;
}
+ @Override
public int getCurrentMemoryState() {
- synchronized (mAm) {
+ synchronized (mLock) {
return mLastMemOnlyState;
}
}
@@ -947,7 +1006,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} else if ("--current".equals(arg)) {
currentOnly = true;
} else if ("--commit".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
writeStateLocked(true, true);
pw.println("Process stats committed.");
@@ -962,29 +1021,39 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
section = parseSectionOptions(args[i]);
} else if ("--clear".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mProcessStats.resetSafely();
- mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
- ArrayList<String> files = getCommittedFiles(0, true, true);
- if (files != null) {
- for (int fi=0; fi<files.size(); fi++) {
- (new File(files.get(fi))).delete();
+ scheduleRequestPssAllProcs(true, false);
+ mFileLock.lock();
+ try {
+ ArrayList<String> files = getCommittedFilesLF(0, true, true);
+ if (files != null) {
+ for (int fi = files.size() - 1; fi >= 0; fi--) {
+ (new File(files.get(fi))).delete();
+ }
}
+ } finally {
+ mFileLock.unlock();
}
pw.println("All process stats cleared.");
quit = true;
}
} else if ("--write".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
writeStateSyncLocked();
pw.println("Process stats written.");
quit = true;
}
} else if ("--read".equals(arg)) {
- synchronized (mAm) {
- readLocked(mProcessStats, mFile);
- pw.println("Process stats read.");
- quit = true;
+ synchronized (mLock) {
+ mFileLock.lock();
+ try {
+ readLF(mProcessStats, mFile);
+ pw.println("Process stats read.");
+ quit = true;
+ } finally {
+ mFileLock.unlock();
+ }
}
} else if ("--start-testing".equals(arg)) {
synchronized (mAm) {
@@ -999,17 +1068,17 @@ public final class ProcessStatsService extends IProcessStats.Stub {
quit = true;
}
} else if ("--pretend-screen-on".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mInjectedScreenState = true;
}
quit = true;
} else if ("--pretend-screen-off".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mInjectedScreenState = false;
}
quit = true;
} else if ("--stop-pretend-screen".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mInjectedScreenState = null;
}
quit = true;
@@ -1060,7 +1129,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
pw.println();
- synchronized (mAm) {
+ synchronized (mLock) {
dumpFilteredProcessesCsvLocked(pw, null,
csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
csvSepProcStats, csvProcStats, now, reqPackage);
@@ -1090,14 +1159,26 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return;
} else if (lastIndex > 0) {
pw.print("LAST STATS AT INDEX "); pw.print(lastIndex); pw.println(":");
- ArrayList<String> files = getCommittedFiles(0, false, true);
- if (lastIndex >= files.size()) {
- pw.print("Only have "); pw.print(files.size()); pw.println(" data sets");
- return;
+
+ ArrayList<String> files;
+ AtomicFile file;
+ ProcessStats processStats;
+
+ mFileLock.lock();
+ try {
+ files = getCommittedFilesLF(0, false, true);
+ if (lastIndex >= files.size()) {
+ pw.print("Only have "); pw.print(files.size()); pw.println(" data sets");
+ return;
+ }
+ file = new AtomicFile(new File(files.get(lastIndex)));
+ processStats = new ProcessStats(false);
+ readLF(processStats, file);
+ } finally {
+ mFileLock.unlock();
}
- AtomicFile file = new AtomicFile(new File(files.get(lastIndex)));
- ProcessStats processStats = new ProcessStats(false);
- readLocked(processStats, file);
+
+ // No lock is needed now, since only us have the access to the 'processStats'.
if (processStats.mReadError != null) {
if (isCheckin || isCompact) pw.print("err,");
pw.print("Failure reading "); pw.print(files.get(lastIndex));
@@ -1118,7 +1199,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
dumpAll, activeOnly, section);
if (dumpAll) {
- pw.print(" mFile="); pw.println(mFile.getBaseFile());
+ pw.print(" mFile="); pw.println(getCurrentFile());
}
} else {
processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
@@ -1129,9 +1210,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
boolean sepNeeded = false;
if ((dumpAll || isCheckin) && !currentOnly) {
- mWriteLock.lock();
+ mFileLock.lock();
try {
- ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
+ ArrayList<String> files = getCommittedFilesLF(0, false, !isCheckin);
if (files != null) {
int start = isCheckin ? 0 : (files.size() - maxNum);
if (start < 0) {
@@ -1142,7 +1223,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
try {
AtomicFile file = new AtomicFile(new File(files.get(i)));
ProcessStats processStats = new ProcessStats(false);
- readLocked(processStats, file);
+ readLF(processStats, file);
if (processStats.mReadError != null) {
if (isCheckin || isCompact) pw.print("err,");
pw.print("Failure reading "); pw.print(files.get(i));
@@ -1188,11 +1269,11 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
}
if (!isCheckin) {
- synchronized (mAm) {
+ synchronized (mLock) {
if (isCompact) {
mProcessStats.dumpCheckinLocked(pw, reqPackage, section);
} else {
@@ -1204,7 +1285,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
dumpAll, activeOnly, section);
if (dumpAll) {
- pw.print(" mFile="); pw.println(mFile.getBaseFile());
+ pw.print(" mFile="); pw.println(getCurrentFile());
}
} else {
mProcessStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
@@ -1249,7 +1330,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
// dump current procstats
long now;
- synchronized (mAm) {
+ synchronized (mLock) {
now = SystemClock.uptimeMillis();
final long token = proto.start(ProcessStatsServiceDumpProto.PROCSTATS_NOW);
mProcessStats.dumpDebug(proto, now, ProcessStats.REPORT_ALL);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 022b04d89774..4a2703056871 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -528,8 +528,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
return tracker;
}
if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
- tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
- serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.longVersionCode,
+ tracker = ams.mProcessStats.getServiceState(serviceInfo.packageName,
+ serviceInfo.applicationInfo.uid,
+ serviceInfo.applicationInfo.longVersionCode,
serviceInfo.processName, serviceInfo.name);
tracker.applyNewOwner(this);
}
@@ -546,7 +547,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
public void makeRestarting(int memFactor, long now) {
if (restartTracker == null) {
if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
- restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
+ restartTracker = ams.mProcessStats.getServiceState(
+ serviceInfo.packageName,
serviceInfo.applicationInfo.uid,
serviceInfo.applicationInfo.longVersionCode,
serviceInfo.processName, serviceInfo.name);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 1f85d1046523..1c93d4eb599b 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -48,6 +48,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
+import android.net.DnsResolver;
import android.net.INetworkManagementEventObserver;
import android.net.Ikev2VpnProfile;
import android.net.IpPrefix;
@@ -79,6 +80,7 @@ import android.net.ipsec.ike.IkeSessionParams;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.INetworkManagementService;
@@ -123,6 +125,7 @@ import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
@@ -134,6 +137,8 @@ import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -190,6 +195,7 @@ public class Vpn {
// automated reconnection
private final Context mContext;
+ @VisibleForTesting final Dependencies mDeps;
private final NetworkInfo mNetworkInfo;
@VisibleForTesting protected String mPackage;
private int mOwnerUID;
@@ -252,17 +258,143 @@ public class Vpn {
// Handle of the user initiating VPN.
private final int mUserHandle;
+ interface RetryScheduler {
+ void checkInterruptAndDelay(boolean sleepLonger) throws InterruptedException;
+ }
+
+ static class Dependencies {
+ public void startService(final String serviceName) {
+ SystemService.start(serviceName);
+ }
+
+ public void stopService(final String serviceName) {
+ SystemService.stop(serviceName);
+ }
+
+ public boolean isServiceRunning(final String serviceName) {
+ return SystemService.isRunning(serviceName);
+ }
+
+ public boolean isServiceStopped(final String serviceName) {
+ return SystemService.isStopped(serviceName);
+ }
+
+ public File getStateFile() {
+ return new File("/data/misc/vpn/state");
+ }
+
+ public void sendArgumentsToDaemon(
+ final String daemon, final LocalSocket socket, final String[] arguments,
+ final RetryScheduler retryScheduler) throws IOException, InterruptedException {
+ final LocalSocketAddress address = new LocalSocketAddress(
+ daemon, LocalSocketAddress.Namespace.RESERVED);
+
+ // Wait for the socket to connect.
+ while (true) {
+ try {
+ socket.connect(address);
+ break;
+ } catch (Exception e) {
+ // ignore
+ }
+ retryScheduler.checkInterruptAndDelay(true /* sleepLonger */);
+ }
+ socket.setSoTimeout(500);
+
+ final OutputStream out = socket.getOutputStream();
+ for (String argument : arguments) {
+ byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
+ if (bytes.length >= 0xFFFF) {
+ throw new IllegalArgumentException("Argument is too large");
+ }
+ out.write(bytes.length >> 8);
+ out.write(bytes.length);
+ out.write(bytes);
+ retryScheduler.checkInterruptAndDelay(false /* sleepLonger */);
+ }
+ out.write(0xFF);
+ out.write(0xFF);
+
+ // Wait for End-of-File.
+ final InputStream in = socket.getInputStream();
+ while (true) {
+ try {
+ if (in.read() == -1) {
+ break;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ retryScheduler.checkInterruptAndDelay(true /* sleepLonger */);
+ }
+ }
+
+ @NonNull
+ public InetAddress resolve(final String endpoint)
+ throws ExecutionException, InterruptedException {
+ try {
+ return InetAddress.parseNumericAddress(endpoint);
+ } catch (IllegalArgumentException e) {
+ // Endpoint is not numeric : fall through and resolve
+ }
+
+ final CancellationSignal cancellationSignal = new CancellationSignal();
+ try {
+ final DnsResolver resolver = DnsResolver.getInstance();
+ final CompletableFuture<InetAddress> result = new CompletableFuture();
+ final DnsResolver.Callback<List<InetAddress>> cb =
+ new DnsResolver.Callback<List<InetAddress>>() {
+ @Override
+ public void onAnswer(@NonNull final List<InetAddress> answer,
+ final int rcode) {
+ if (answer.size() > 0) {
+ result.complete(answer.get(0));
+ } else {
+ result.completeExceptionally(
+ new UnknownHostException(endpoint));
+ }
+ }
+
+ @Override
+ public void onError(@Nullable final DnsResolver.DnsException error) {
+ // Unfortunately UnknownHostException doesn't accept a cause, so
+ // print a message here instead. Only show the summary, not the
+ // full stack trace.
+ Log.e(TAG, "Async dns resolver error : " + error);
+ result.completeExceptionally(new UnknownHostException(endpoint));
+ }
+ };
+ resolver.query(null /* network, null for default */, endpoint,
+ DnsResolver.FLAG_EMPTY, r -> r.run(), cancellationSignal, cb);
+ return result.get();
+ } catch (final ExecutionException e) {
+ Log.e(TAG, "Cannot resolve VPN endpoint : " + endpoint + ".", e);
+ throw e;
+ } catch (final InterruptedException e) {
+ Log.e(TAG, "Legacy VPN was interrupted while resolving the endpoint", e);
+ cancellationSignal.cancel();
+ throw e;
+ }
+ }
+
+ public boolean checkInterfacePresent(final Vpn vpn, final String iface) {
+ return vpn.jniCheck(iface) == 0;
+ }
+ }
+
public Vpn(Looper looper, Context context, INetworkManagementService netService,
@UserIdInt int userHandle, @NonNull KeyStore keyStore) {
- this(looper, context, netService, userHandle, keyStore,
+ this(looper, context, new Dependencies(), netService, userHandle, keyStore,
new SystemServices(context), new Ikev2SessionCreator());
}
@VisibleForTesting
- protected Vpn(Looper looper, Context context, INetworkManagementService netService,
+ protected Vpn(Looper looper, Context context, Dependencies deps,
+ INetworkManagementService netService,
int userHandle, @NonNull KeyStore keyStore, SystemServices systemServices,
Ikev2SessionCreator ikev2SessionCreator) {
mContext = context;
+ mDeps = deps;
mNetd = netService;
mUserHandle = userHandle;
mLooper = looper;
@@ -2129,7 +2261,8 @@ public class Vpn {
}
/** This class represents the common interface for all VPN runners. */
- private abstract class VpnRunner extends Thread {
+ @VisibleForTesting
+ abstract class VpnRunner extends Thread {
protected VpnRunner(String name) {
super(name);
@@ -2638,7 +2771,7 @@ public class Vpn {
} catch (InterruptedException e) {
}
for (String daemon : mDaemons) {
- SystemService.stop(daemon);
+ mDeps.stopService(daemon);
}
}
agentDisconnect();
@@ -2655,21 +2788,55 @@ public class Vpn {
}
}
+ private void checkAndFixupArguments(@NonNull final InetAddress endpointAddress) {
+ final String endpointAddressString = endpointAddress.getHostAddress();
+ // Perform some safety checks before inserting the address in place.
+ // Position 0 in mDaemons and mArguments must be racoon, and position 1 must be mtpd.
+ if (!"racoon".equals(mDaemons[0]) || !"mtpd".equals(mDaemons[1])) {
+ throw new IllegalStateException("Unexpected daemons order");
+ }
+
+ // Respectively, the positions at which racoon and mtpd take the server address
+ // argument are 1 and 2. Not all types of VPN require both daemons however, and
+ // in that case the corresponding argument array is null.
+ if (mArguments[0] != null) {
+ if (!mProfile.server.equals(mArguments[0][1])) {
+ throw new IllegalStateException("Invalid server argument for racoon");
+ }
+ mArguments[0][1] = endpointAddressString;
+ }
+
+ if (mArguments[1] != null) {
+ if (!mProfile.server.equals(mArguments[1][2])) {
+ throw new IllegalStateException("Invalid server argument for mtpd");
+ }
+ mArguments[1][2] = endpointAddressString;
+ }
+ }
+
private void bringup() {
// Catch all exceptions so we can clean up a few things.
try {
+ // resolve never returns null. If it does because of some bug, it will be
+ // caught by the catch() block below and cleanup gracefully.
+ final InetAddress endpointAddress = mDeps.resolve(mProfile.server);
+
+ // Big hack : dynamically replace the address of the server in the arguments
+ // with the resolved address.
+ checkAndFixupArguments(endpointAddress);
+
// Initialize the timer.
mBringupStartTime = SystemClock.elapsedRealtime();
// Wait for the daemons to stop.
for (String daemon : mDaemons) {
- while (!SystemService.isStopped(daemon)) {
+ while (!mDeps.isServiceStopped(daemon)) {
checkInterruptAndDelay(true);
}
}
// Clear the previous state.
- File state = new File("/data/misc/vpn/state");
+ final File state = mDeps.getStateFile();
state.delete();
if (state.exists()) {
throw new IllegalStateException("Cannot delete the state");
@@ -2696,57 +2863,19 @@ public class Vpn {
// Start the daemon.
String daemon = mDaemons[i];
- SystemService.start(daemon);
+ mDeps.startService(daemon);
// Wait for the daemon to start.
- while (!SystemService.isRunning(daemon)) {
+ while (!mDeps.isServiceRunning(daemon)) {
checkInterruptAndDelay(true);
}
// Create the control socket.
mSockets[i] = new LocalSocket();
- LocalSocketAddress address = new LocalSocketAddress(
- daemon, LocalSocketAddress.Namespace.RESERVED);
-
- // Wait for the socket to connect.
- while (true) {
- try {
- mSockets[i].connect(address);
- break;
- } catch (Exception e) {
- // ignore
- }
- checkInterruptAndDelay(true);
- }
- mSockets[i].setSoTimeout(500);
-
- // Send over the arguments.
- OutputStream out = mSockets[i].getOutputStream();
- for (String argument : arguments) {
- byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
- if (bytes.length >= 0xFFFF) {
- throw new IllegalArgumentException("Argument is too large");
- }
- out.write(bytes.length >> 8);
- out.write(bytes.length);
- out.write(bytes);
- checkInterruptAndDelay(false);
- }
- out.write(0xFF);
- out.write(0xFF);
-
- // Wait for End-of-File.
- InputStream in = mSockets[i].getInputStream();
- while (true) {
- try {
- if (in.read() == -1) {
- break;
- }
- } catch (Exception e) {
- // ignore
- }
- checkInterruptAndDelay(true);
- }
+
+ // Wait for the socket to connect and send over the arguments.
+ mDeps.sendArgumentsToDaemon(daemon, mSockets[i], arguments,
+ this::checkInterruptAndDelay);
}
// Wait for the daemons to create the new state.
@@ -2754,7 +2883,7 @@ public class Vpn {
// Check if a running daemon is dead.
for (int i = 0; i < mDaemons.length; ++i) {
String daemon = mDaemons[i];
- if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
+ if (mArguments[i] != null && !mDeps.isServiceRunning(daemon)) {
throw new IllegalStateException(daemon + " is dead");
}
}
@@ -2764,7 +2893,8 @@ public class Vpn {
// Now we are connected. Read and parse the new state.
String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1);
if (parameters.length != 7) {
- throw new IllegalStateException("Cannot parse the state");
+ throw new IllegalStateException("Cannot parse the state: '"
+ + String.join("', '", parameters) + "'");
}
// Set the interface and the addresses in the config.
@@ -2793,20 +2923,15 @@ public class Vpn {
}
// Add a throw route for the VPN server endpoint, if one was specified.
- String endpoint = parameters[5].isEmpty() ? mProfile.server : parameters[5];
- if (!endpoint.isEmpty()) {
- try {
- InetAddress addr = InetAddress.parseNumericAddress(endpoint);
- if (addr instanceof Inet4Address) {
- mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 32), RTN_THROW));
- } else if (addr instanceof Inet6Address) {
- mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 128), RTN_THROW));
- } else {
- Log.e(TAG, "Unknown IP address family for VPN endpoint: " + endpoint);
- }
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Exception constructing throw route to " + endpoint + ": " + e);
- }
+ if (endpointAddress instanceof Inet4Address) {
+ mConfig.routes.add(new RouteInfo(
+ new IpPrefix(endpointAddress, 32), RTN_THROW));
+ } else if (endpointAddress instanceof Inet6Address) {
+ mConfig.routes.add(new RouteInfo(
+ new IpPrefix(endpointAddress, 128), RTN_THROW));
+ } else {
+ Log.e(TAG, "Unknown IP address family for VPN endpoint: "
+ + endpointAddress);
}
// Here is the last step and it must be done synchronously.
@@ -2818,7 +2943,7 @@ public class Vpn {
checkInterruptAndDelay(false);
// Check if the interface is gone while we are waiting.
- if (jniCheck(mConfig.interfaze) == 0) {
+ if (mDeps.checkInterfacePresent(Vpn.this, mConfig.interfaze)) {
throw new IllegalStateException(mConfig.interfaze + " is gone");
}
@@ -2849,7 +2974,7 @@ public class Vpn {
while (true) {
Thread.sleep(2000);
for (int i = 0; i < mDaemons.length; i++) {
- if (mArguments[i] != null && SystemService.isStopped(mDaemons[i])) {
+ if (mArguments[i] != null && mDeps.isServiceStopped(mDaemons[i])) {
return;
}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index e17cca423822..cea5a69526c6 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -88,7 +88,7 @@ class GnssNetworkConnectivityHandler {
// Default time limit in milliseconds for the ConnectivityManager to find a suitable
// network with SUPL connectivity or report an error.
- private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 10 * 1000;
+ private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 20 * 1000;
private static final int HASH_MAP_INITIAL_CAPACITY_TO_TRACK_CONNECTED_NETWORKS = 5;
diff --git a/services/core/java/com/android/server/media/HandlerExecutor.java b/services/core/java/com/android/server/media/HandlerExecutor.java
new file mode 100644
index 000000000000..7c9e72bcf384
--- /dev/null
+++ b/services/core/java/com/android/server/media/HandlerExecutor.java
@@ -0,0 +1,45 @@
+/*
+ * 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.media;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+
+/**
+ * An adapter {@link Executor} that posts all executed tasks onto the given
+ * {@link Handler}.
+ *
+ * @hide
+ */
+public class HandlerExecutor implements Executor {
+ private final Handler mHandler;
+
+ public HandlerExecutor(@NonNull Handler handler) {
+ mHandler = Objects.requireNonNull(handler);
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ if (!mHandler.post(command)) {
+ throw new RejectedExecutionException(mHandler + " is shutting down");
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java
index 5d1b74912546..162c388dadd1 100644
--- a/services/core/java/com/android/server/media/MediaSession2Record.java
+++ b/services/core/java/com/android/server/media/MediaSession2Record.java
@@ -20,7 +20,6 @@ import android.media.MediaController2;
import android.media.Session2CommandGroup;
import android.media.Session2Token;
import android.os.Handler;
-import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.ResultReceiver;
import android.os.UserHandle;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ba708229c7ed..05026a0cafb6 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -169,7 +169,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final int MSG_STREAM_VALIDATE_AND_COMMIT = 2;
private static final int MSG_INSTALL = 3;
private static final int MSG_ON_PACKAGE_INSTALLED = 4;
- private static final int MSG_SESSION_VERIFICATION_FAILURE = 5;
+ private static final int MSG_SESSION_VALIDATION_FAILURE = 5;
/** XML constants used for persisting a session */
static final String TAG_SESSION = "session";
@@ -475,10 +475,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
packageName, returnCode, message, extras);
break;
- case MSG_SESSION_VERIFICATION_FAILURE:
+ case MSG_SESSION_VALIDATION_FAILURE:
final int error = msg.arg1;
final String detailMessage = (String) msg.obj;
- onSessionVerificationFailure(error, detailMessage);
+ onSessionValidationFailure(error, detailMessage);
break;
}
@@ -1246,14 +1246,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// the parent
if (unrecoverableFailure != null) {
// {@link #streamValidateAndCommit()} calls
- // {@link #onSessionVerificationFailure(PackageManagerException)}, but we don't
+ // {@link #onSessionValidationFailure(PackageManagerException)}, but we don't
// expect it to ever do so for parent sessions. Call that on this parent to clean
// it up and notify listeners of the error.
- onSessionVerificationFailure(unrecoverableFailure);
+ onSessionValidationFailure(unrecoverableFailure);
// fail other child sessions that did not already fail
for (int i = nonFailingSessions.size() - 1; i >= 0; --i) {
PackageInstallerSession session = nonFailingSessions.get(i);
- session.onSessionVerificationFailure(unrecoverableFailure);
+ session.onSessionValidationFailure(unrecoverableFailure);
}
}
}
@@ -1575,11 +1575,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertMultiPackageConsistencyLocked(childSessions);
}
} catch (PackageManagerException e) {
- throw onSessionVerificationFailure(e);
+ throw onSessionValidationFailure(e);
} catch (Throwable e) {
// Convert all exceptions into package manager exceptions as only those are handled
// in the code above.
- throw onSessionVerificationFailure(new PackageManagerException(e));
+ throw onSessionValidationFailure(new PackageManagerException(e));
}
}
@@ -1613,20 +1613,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
return true;
} catch (PackageManagerException e) {
- throw onSessionVerificationFailure(e);
+ throw onSessionValidationFailure(e);
} catch (Throwable e) {
// Convert all exceptions into package manager exceptions as only those are handled
// in the code above.
- throw onSessionVerificationFailure(new PackageManagerException(e));
+ throw onSessionValidationFailure(new PackageManagerException(e));
}
}
- private PackageManagerException onSessionVerificationFailure(PackageManagerException e) {
- onSessionVerificationFailure(e.error, ExceptionUtils.getCompleteMessage(e));
+ private PackageManagerException onSessionValidationFailure(PackageManagerException e) {
+ onSessionValidationFailure(e.error, ExceptionUtils.getCompleteMessage(e));
return e;
}
- private void onSessionVerificationFailure(int error, String detailMessage) {
+ private void onSessionValidationFailure(int error, String detailMessage) {
// Session is sealed but could not be verified, we need to destroy it.
destroyInternal();
// Dispatch message to remove session from PackageInstallerService.
@@ -2990,7 +2990,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
mDataLoaderFinished = true;
}
- dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"Failure to obtain data loader");
return;
}
@@ -3040,7 +3040,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
mDataLoaderFinished = true;
}
- dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"Failed to prepare image.");
if (manualStartAndDestroy) {
dataLoader.destroy(dataLoaderId);
@@ -3061,7 +3061,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
mDataLoaderFinished = true;
}
- dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"DataLoader reported unrecoverable failure.");
break;
}
@@ -3117,7 +3117,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
mDataLoaderFinished = true;
}
- dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"Image is missing pages required for installation.");
break;
}
@@ -3142,8 +3142,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return false;
}
- private void dispatchSessionVerificationFailure(int error, String detailMessage) {
- mHandler.obtainMessage(MSG_SESSION_VERIFICATION_FAILURE, error, -1,
+ private void dispatchSessionValidationFailure(int error, String detailMessage) {
+ mHandler.obtainMessage(MSG_SESSION_VALIDATION_FAILURE, error, -1,
detailMessage).sendToTarget();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6c0fce75f0be..58a1648e51ad 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8551,6 +8551,15 @@ public class PackageManagerService extends IPackageManager.Stub
if (listUninstalled) {
list = new ArrayList<>(mSettings.mPackages.size());
for (PackageSetting ps : mSettings.mPackages.values()) {
+ if (listFactory) {
+ if (!ps.isSystem()) {
+ continue;
+ }
+ PackageSetting psDisabled = mSettings.getDisabledSystemPkgLPr(ps);
+ if (psDisabled != null) {
+ ps = psDisabled;
+ }
+ }
if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
continue;
}
@@ -8565,7 +8574,16 @@ public class PackageManagerService extends IPackageManager.Stub
} else {
list = new ArrayList<>(mPackages.size());
for (AndroidPackage p : mPackages.values()) {
- final PackageSetting ps = getPackageSetting(p.getPackageName());
+ PackageSetting ps = getPackageSetting(p.getPackageName());
+ if (listFactory) {
+ if (!p.isSystem()) {
+ continue;
+ }
+ PackageSetting psDisabled = mSettings.getDisabledSystemPkgLPr(ps);
+ if (psDisabled != null) {
+ ps = psDisabled;
+ }
+ }
if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 0061480c97f1..3e3e3c590491 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2695,7 +2695,7 @@ public final class Settings {
private void writePackageListLPrInternal(int creatingUserId) {
// Only derive GIDs for active users (not dying)
- final List<UserInfo> users = getUsers(UserManagerService.getInstance(), true);
+ final List<UserInfo> users = getActiveUsers(UserManagerService.getInstance(), true);
int[] userIds = new int[users.size()];
for (int i = 0; i < userIds.length; i++) {
userIds[i] = users.get(i).id;
@@ -4423,25 +4423,43 @@ public final class Settings {
}
/**
- * Return all users on the device, including partial or dying users.
+ * Returns all users on the device, including pre-created and dying users.
+ *
* @param userManager UserManagerService instance
* @return the list of users
*/
private static List<UserInfo> getAllUsers(UserManagerService userManager) {
- return getUsers(userManager, false);
+ return getUsers(userManager, /* excludeDying= */ false, /* excludePreCreated= */ false);
+ }
+
+ /**
+ * Returns the list of users on the device, excluding pre-created ones.
+ *
+ * @param userManager UserManagerService instance
+ * @param excludeDying Indicates whether to exclude any users marked for deletion.
+ *
+ * @return the list of users
+ */
+ private static List<UserInfo> getActiveUsers(UserManagerService userManager,
+ boolean excludeDying) {
+ return getUsers(userManager, excludeDying, /* excludePreCreated= */ true);
}
/**
- * Return the list of users on the device. Clear the calling identity before calling into
- * UserManagerService.
+ * Returns the list of users on the device.
+ *
* @param userManager UserManagerService instance
* @param excludeDying Indicates whether to exclude any users marked for deletion.
+ * @param excludePreCreated Indicates whether to exclude any pre-created users.
+ *
* @return the list of users
*/
- private static List<UserInfo> getUsers(UserManagerService userManager, boolean excludeDying) {
+ private static List<UserInfo> getUsers(UserManagerService userManager, boolean excludeDying,
+ boolean excludePreCreated) {
long id = Binder.clearCallingIdentity();
try {
- return userManager.getUsers(excludeDying);
+ return userManager.getUsers(/* excludePartial= */ true, excludeDying,
+ excludePreCreated);
} catch (NullPointerException npe) {
// packagemanager not yet initialized
} finally {
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index 3ec61fdda917..7467439905eb 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -18,7 +18,6 @@ package com.android.server.timezonedetector;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.UserIdInt;
import android.app.timezonedetector.ITimeZoneConfigurationListener;
import android.app.timezonedetector.ITimeZoneDetectorService;
import android.app.timezonedetector.ManualTimeZoneSuggestion;
@@ -38,6 +37,7 @@ 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;
@@ -60,7 +60,8 @@ import java.util.Objects;
* and making calls async, leaving the (consequently more testable) {@link TimeZoneDetectorStrategy}
* implementation to deal with the logic around time zone detection.
*/
-public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub {
+public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
+ implements IBinder.DeathRecipient {
private static final String TAG = "TimeZoneDetectorService";
@@ -104,9 +105,15 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
@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 ArrayList<ConfigListenerInfo> mConfigurationListeners = new ArrayList<>();
+ private final SparseArray<ArrayList<ITimeZoneConfigurationListener>> mConfigurationListeners =
+ new SparseArray<>();
private static TimeZoneDetectorService create(
@NonNull Context context, @NonNull Handler handler,
@@ -188,18 +195,23 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
Objects.requireNonNull(listener);
int userId = UserHandle.getCallingUserId();
- ConfigListenerInfo listenerInfo = new ConfigListenerInfo(userId, listener);
-
synchronized (mConfigurationListeners) {
- if (mConfigurationListeners.contains(listenerInfo)) {
+ ArrayList<ITimeZoneConfigurationListener> listeners =
+ mConfigurationListeners.get(userId);
+ if (listeners != null && listeners.contains(listener)) {
return;
}
try {
- // Ensure the reference to the listener is removed if the client process dies.
- listenerInfo.linkToDeath();
+ 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().
- mConfigurationListeners.add(listenerInfo);
+ listeners.add(listener);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to linkToDeath() for listener=" + listener, e);
}
@@ -213,21 +225,56 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
int userId = UserHandle.getCallingUserId();
synchronized (mConfigurationListeners) {
- ConfigListenerInfo toRemove = new ConfigListenerInfo(userId, listener);
- Iterator<ConfigListenerInfo> listenerIterator = mConfigurationListeners.iterator();
- while (listenerIterator.hasNext()) {
- ConfigListenerInfo currentListenerInfo = listenerIterator.next();
- if (currentListenerInfo.equals(toRemove)) {
- listenerIterator.remove();
-
- // Stop listening for the client process to die.
- try {
- currentListenerInfo.unlinkToDeath();
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to unlinkToDeath() for listener=" + listener, e);
+ boolean removedListener = false;
+ ArrayList<ITimeZoneConfigurationListener> userListeners =
+ mConfigurationListeners.get(userId);
+ if (userListeners.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
+ + ", but no listeners were removed."
+ + " mConfigurationListeners=" + mConfigurationListeners);
+ }
+ }
+ }
+
+ @Override
+ public void binderDied() {
+ // Should not be used as binderDied(IBinder who) is overridden.
+ Slog.wtf(TAG, "binderDied() called unexpectedly.");
+ }
+
+ /**
+ * Called when one of the ITimeZoneConfigurationListener processes dies before calling
+ * {@link #removeConfigurationListener(ITimeZoneConfigurationListener)}.
+ */
+ @Override
+ 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;
}
}
}
+ if (!removedListener) {
+ Slog.w(TAG, "Notified of binder death for who=" + who
+ + ", but did not remove any listeners."
+ + " mConfigurationListeners=" + mConfigurationListeners);
+ }
}
}
@@ -243,14 +290,24 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
// problem.
synchronized (mConfigurationListeners) {
- for (ConfigListenerInfo listenerInfo : mConfigurationListeners) {
+ final int userCount = mConfigurationListeners.size();
+ for (int userIndex = 0; userIndex < userCount; userIndex++) {
+ int userId = mConfigurationListeners.keyAt(userIndex);
TimeZoneConfiguration configuration =
- mTimeZoneDetectorStrategy.getConfiguration(listenerInfo.getUserId());
- try {
- listenerInfo.getListener().onChange(configuration);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to notify listener="
- + listenerInfo + " of updated configuration=" + configuration, e);
+ 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);
+ }
}
}
}
@@ -338,66 +395,5 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
(new TimeZoneDetectorShellCommand(this)).exec(
this, in, out, err, args, callback, resultReceiver);
}
-
- private class ConfigListenerInfo implements IBinder.DeathRecipient {
- private final @UserIdInt int mUserId;
- private final ITimeZoneConfigurationListener mListener;
-
- ConfigListenerInfo(
- @UserIdInt int userId, @NonNull ITimeZoneConfigurationListener listener) {
- this.mUserId = userId;
- this.mListener = Objects.requireNonNull(listener);
- }
-
- @UserIdInt int getUserId() {
- return mUserId;
- }
-
- ITimeZoneConfigurationListener getListener() {
- return mListener;
- }
-
- void linkToDeath() throws RemoteException {
- mListener.asBinder().linkToDeath(this, 0 /* flags */);
- }
-
- void unlinkToDeath() throws RemoteException {
- mListener.asBinder().unlinkToDeath(this, 0 /* flags */);
- }
-
- @Override
- public void binderDied() {
- synchronized (mConfigurationListeners) {
- Slog.i(TAG, "Configuration listener client died: " + this);
- mConfigurationListeners.remove(this);
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- ConfigListenerInfo that = (ConfigListenerInfo) o;
- return mUserId == that.mUserId
- && mListener.equals(that.mListener);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUserId, mListener);
- }
-
- @Override
- public String toString() {
- return "ConfigListenerInfo{"
- + "mUserId=" + mUserId
- + ", mListener=" + mListener
- + '}';
- }
- }
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index a05289f9f651..2c475e0b9bcb 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -130,6 +130,7 @@ import android.util.MergedConfiguration;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
+import android.view.Display;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -1090,9 +1091,9 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// Check if caller is already present on display
final boolean uidPresentOnDisplay = displayContent.isUidPresent(callingUid);
- final int displayOwnerUid = displayContent.mDisplay.getOwnerUid();
- if (displayContent.mDisplay.getType() == TYPE_VIRTUAL && displayOwnerUid != SYSTEM_UID) {
- // Limit launching on virtual displays, because their contents can be read from Surface
+ final Display display = displayContent.mDisplay;
+ if (!display.isTrusted()) {
+ // Limit launching on untrusted displays because their contents can be read from Surface
// by apps that created them.
if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1116,7 +1117,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
}
// Check if the caller is the owner of the display.
- if (displayOwnerUid == callingUid) {
+ if (display.getOwnerUid() == callingUid) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ " allow launch for owner of the display");
return true;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index f3c7a5dcb6d5..9b18ac8f7702 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.graphics.Color.WHITE;
import static android.graphics.Color.alpha;
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
@@ -142,6 +143,7 @@ class TaskSnapshotSurface implements StartingSurface {
private final Handler mHandler;
private boolean mSizeMismatch;
private final Paint mBackgroundPaint = new Paint();
+ private final int mActivityType;
private final int mStatusBarColor;
@VisibleForTesting final SystemBarBackgroundPainter mSystemBarBackgroundPainter;
private final int mOrientationOnCreation;
@@ -173,6 +175,7 @@ class TaskSnapshotSurface implements StartingSurface {
final int windowFlags;
final int windowPrivateFlags;
final int currentOrientation;
+ final int activityType;
final InsetsState insetsState;
synchronized (service.mGlobalLock) {
final WindowState mainWindow = activity.findMainWindow();
@@ -241,6 +244,7 @@ class TaskSnapshotSurface implements StartingSurface {
taskBounds = new Rect();
task.getBounds(taskBounds);
currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation;
+ activityType = activity.getActivityType();
final InsetsPolicy insetsPolicy = topFullscreenOpaqueWindow.getDisplayContent()
.getInsetsPolicy();
@@ -261,7 +265,8 @@ class TaskSnapshotSurface implements StartingSurface {
}
final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window,
surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, sysUiVis,
- windowFlags, windowPrivateFlags, taskBounds, currentOrientation, insetsState);
+ windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType,
+ insetsState);
window.setOuter(snapshotSurface);
try {
session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1,
@@ -282,7 +287,7 @@ class TaskSnapshotSurface implements StartingSurface {
TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl,
TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription,
int sysUiVis, int windowFlags, int windowPrivateFlags, Rect taskBounds,
- int currentOrientation, InsetsState insetsState) {
+ int currentOrientation, int activityType, InsetsState insetsState) {
mService = service;
mSurface = service.mSurfaceFactory.get();
mHandler = new Handler(mService.mH.getLooper());
@@ -298,6 +303,7 @@ class TaskSnapshotSurface implements StartingSurface {
windowPrivateFlags, sysUiVis, taskDescription, 1f, insetsState);
mStatusBarColor = taskDescription.getStatusBarColor();
mOrientationOnCreation = currentOrientation;
+ mActivityType = activityType;
mTransaction = mService.mTransactionFactory.get();
}
@@ -305,7 +311,9 @@ class TaskSnapshotSurface implements StartingSurface {
public void remove() {
synchronized (mService.mGlobalLock) {
final long now = SystemClock.uptimeMillis();
- if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) {
+ if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS
+ // Show the latest content as soon as possible for unlocking to home.
+ && mActivityType != ACTIVITY_TYPE_HOME) {
mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS);
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"Defer removing snapshot surface in %dms", (now - mShownTime));
diff --git a/services/people/java/com/android/server/people/PeopleService.java b/services/people/java/com/android/server/people/PeopleService.java
index 37bf66491882..33317a38853e 100644
--- a/services/people/java/com/android/server/people/PeopleService.java
+++ b/services/people/java/com/android/server/people/PeopleService.java
@@ -19,6 +19,8 @@ package com.android.server.people;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.people.ConversationChannel;
+import android.app.people.IPeopleManager;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionSessionId;
import android.app.prediction.AppTarget;
@@ -26,8 +28,11 @@ import android.app.prediction.AppTargetEvent;
import android.app.prediction.IPredictionCallback;
import android.content.Context;
import android.content.pm.ParceledListSlice;
+import android.os.Binder;
import android.os.CancellationSignal;
+import android.os.Process;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
@@ -35,6 +40,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.SystemService;
import com.android.server.people.data.DataManager;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -68,6 +74,7 @@ public class PeopleService extends SystemService {
@Override
public void onStart() {
+ publishBinderService(Context.PEOPLE_SERVICE, new BinderService());
publishLocalService(PeopleServiceInternal.class, new LocalService());
}
@@ -81,6 +88,38 @@ public class PeopleService extends SystemService {
mDataManager.onUserStopping(user.getUserIdentifier());
}
+ /**
+ * Enforces that only the system or root UID can make certain calls.
+ *
+ * @param message used as message if SecurityException is thrown
+ * @throws SecurityException if the caller is not system or root
+ */
+ private static void enforceSystemOrRoot(String message) {
+ int uid = Binder.getCallingUid();
+ if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) {
+ throw new SecurityException("Only system may " + message);
+ }
+ }
+
+ private final class BinderService extends IPeopleManager.Stub {
+
+ @Override
+ public ParceledListSlice<ConversationChannel> getRecentConversations() {
+ enforceSystemOrRoot("get recent conversations");
+ return new ParceledListSlice<>(new ArrayList<>());
+ }
+
+ @Override
+ public void removeRecentConversation(String packageName, int userId, String shortcutId) {
+ enforceSystemOrRoot("remove a recent conversation");
+ }
+
+ @Override
+ public void removeAllRecentConversations() {
+ enforceSystemOrRoot("remove all recent conversations");
+ }
+ }
+
@VisibleForTesting
final class LocalService extends PeopleServiceInternal {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 2a267c413c31..1b2711d3938b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -99,6 +99,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@@ -165,7 +166,7 @@ public class MockingOomAdjusterTests {
setFieldValue(ActivityManagerService.class, sService, "mHandler",
mock(ActivityManagerService.MainHandler.class));
setFieldValue(ActivityManagerService.class, sService, "mProcessStats",
- mock(ProcessStatsService.class));
+ new ProcessStatsService(sService, new File(sContext.getFilesDir(), "procstats")));
setFieldValue(ActivityManagerService.class, sService, "mBackupTargets",
mock(SparseArray.class));
setFieldValue(ActivityManagerService.class, sService, "mOomAdjProfiler",
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 153634548c17..8034cacc6923 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -170,7 +170,7 @@ public class TimeZoneDetectorServiceTest {
ITimeZoneConfigurationListener mockListener = mock(ITimeZoneConfigurationListener.class);
try {
mTimeZoneDetectorService.removeConfigurationListener(mockListener);
- fail();
+ fail("Expected a SecurityException");
} finally {
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.WRITE_SECURE_SETTINGS),
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 1d75967756c3..88b1d191dc4d 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.Manifest;
import android.app.AlarmManager;
import android.app.IUiModeManager;
import android.content.BroadcastReceiver;
@@ -24,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Handler;
@@ -67,6 +69,7 @@ import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -230,6 +233,17 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void setNightModeActivated_permissiontoChangeOtherUsers() throws RemoteException {
+ SystemService.TargetUser user = mock(SystemService.TargetUser.class);
+ doReturn(9).when(user).getUserIdentifier();
+ mUiManagerService.onUserSwitching(user, user);
+ when(mContext.checkCallingOrSelfPermission(
+ eq(Manifest.permission.INTERACT_ACROSS_USERS)))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ assertFalse(mService.setNightModeActivated(true));
+ }
+
+ @Test
public void autoNightModeSwitch_batterySaverOn() throws RemoteException {
mService.setNightMode(MODE_NIGHT_NO);
when(mTwilightState.isNight()).thenReturn(false);
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 4040fa6a675e..e3c795d03381 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -38,6 +38,7 @@
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.STATUS_BAR" />
+ <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
<application android:debuggable="true"
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index addf1ffe40c2..96b970056c98 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -38,7 +38,13 @@ import static org.mockito.ArgumentMatchers.eq;
import android.app.WaitResult;
import android.content.pm.ActivityInfo;
+import android.graphics.PixelFormat;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.ImageReader;
import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+import android.view.DisplayInfo;
import androidx.test.filters.MediumTest;
@@ -173,4 +179,50 @@ public class ActivityStackSupervisorTests extends WindowTestsBase {
verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskB.mTaskId) /* taskId */,
eq(true) /* focused */);
}
+
+ @Test
+ /** Ensures that a trusted virtual display can launch arbitrary activities. */
+ public void testTrustedVirtualDisplayCanLaunchActivities() {
+ final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
+ final Task stack = new StackBuilder(mRootWindowContainer)
+ .setDisplay(newDisplay).build();
+ final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
+ VirtualDisplay virtualDisplay = createVirtualDisplay(true);
+ final boolean allowed = mSupervisor.isCallerAllowedToLaunchOnDisplay(1234, 1234,
+ virtualDisplay.getDisplay().getDisplayId(), unresizableActivity.info);
+
+ assertThat(allowed).isTrue();
+ }
+
+ @Test
+ /** Ensures that an untrusted virtual display cannot launch arbitrary activities. */
+ public void testUntrustedVirtualDisplayCannotLaunchActivities() {
+ final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
+ final Task stack = new StackBuilder(mRootWindowContainer)
+ .setDisplay(newDisplay).build();
+ final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
+ VirtualDisplay virtualDisplay = createVirtualDisplay(false);
+ final boolean allowed = mSupervisor.isCallerAllowedToLaunchOnDisplay(1234, 1234,
+ virtualDisplay.getDisplay().getDisplayId(), unresizableActivity.info);
+
+ assertThat(allowed).isFalse();
+ }
+
+ private VirtualDisplay createVirtualDisplay(boolean trusted) {
+ final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
+ final DisplayInfo displayInfo = new DisplayInfo();
+ final Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
+ defaultDisplay.getDisplayInfo(displayInfo);
+ int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
+ if (trusted) {
+ flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
+ }
+
+ final ImageReader imageReader = ImageReader.newInstance(
+ displayInfo.logicalWidth, displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);
+
+ return dm.createVirtualDisplay("virtualDisplay", displayInfo.logicalWidth,
+ displayInfo.logicalHeight,
+ displayInfo.logicalDensityDpi, imageReader.getSurface(), flags);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index d950344538a0..b4a13375aeec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
@@ -87,7 +88,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
0 /* systemUiVisibility */, false /* isTranslucent */);
mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test",
createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0,
- taskBounds, ORIENTATION_PORTRAIT, new InsetsState());
+ taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState());
}
private static TaskDescription createTaskDescription(int background, int statusBar,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index 2e4d390ceb60..c0658fe4422e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -84,7 +84,7 @@ class CloseImeAutoOpenWindowToHomeTest(
navBarLayerIsAlwaysVisible(bugId = 140855415)
statusBarLayerIsAlwaysVisible(bugId = 140855415)
noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
- navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+ navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0, bugId = 140855415)
statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
imeLayerBecomesInvisible(bugId = 141458352)
imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index 1c0da4f920bb..dcf308533ee6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -92,7 +92,7 @@ open class CloseImeWindowToHomeTest(
navBarLayerIsAlwaysVisible(bugId = 140855415)
statusBarLayerIsAlwaysVisible(bugId = 140855415)
noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
- navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+ navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0, bugId = 140855415)
statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
imeLayerBecomesInvisible(bugId = 153739621)
imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index e078f266e5ed..91ec211805f7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -90,7 +90,7 @@ class OpenAppToSplitScreenTest(
navBarLayerIsAlwaysVisible()
statusBarLayerIsAlwaysVisible()
noUncoveredRegions(rotation)
- navBarLayerRotatesAndScales(rotation)
+ navBarLayerRotatesAndScales(rotation, bugId = 140855415)
statusBarLayerRotatesScales(rotation)
all("dividerLayerBecomesVisible") {
@@ -102,7 +102,8 @@ class OpenAppToSplitScreenTest(
eventLog {
focusChanges(testApp.`package`,
- "recents_animation_input_consumer", "NexusLauncherActivity")
+ "recents_animation_input_consumer", "NexusLauncherActivity",
+ bugId = 151179149)
}
}
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 4ccf79a0cb37..de1c5759ee87 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -30,6 +30,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -49,6 +50,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.NotificationManager;
@@ -65,6 +67,7 @@ import android.net.InetAddresses;
import android.net.IpPrefix;
import android.net.IpSecManager;
import android.net.LinkProperties;
+import android.net.LocalSocket;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
@@ -74,6 +77,7 @@ import android.net.VpnManager;
import android.net.VpnService;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Process;
@@ -101,13 +105,20 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
import java.net.Inet4Address;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
/**
@@ -133,7 +144,8 @@ public class VpnTest {
managedProfileA.profileGroupId = primaryUser.id;
}
- static final String TEST_VPN_PKG = "com.dummy.vpn";
+ static final String EGRESS_IFACE = "wlan0";
+ static final String TEST_VPN_PKG = "com.testvpn.vpn";
private static final String TEST_VPN_SERVER = "1.2.3.4";
private static final String TEST_VPN_IDENTITY = "identity";
private static final byte[] TEST_VPN_PSK = "psk".getBytes();
@@ -1012,31 +1024,190 @@ public class VpnTest {
// a subsequent CL.
}
- @Test
- public void testStartLegacyVpn() throws Exception {
+ public Vpn startLegacyVpn(final VpnProfile vpnProfile) throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser);
// Dummy egress interface
- final String egressIface = "DUMMY0";
final LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(egressIface);
+ lp.setInterfaceName(EGRESS_IFACE);
final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
- InetAddresses.parseNumericAddress("192.0.2.0"), egressIface);
+ InetAddresses.parseNumericAddress("192.0.2.0"), EGRESS_IFACE);
lp.addRoute(defaultRoute);
- vpn.startLegacyVpn(mVpnProfile, mKeyStore, lp);
+ vpn.startLegacyVpn(vpnProfile, mKeyStore, lp);
+ return vpn;
+ }
+ @Test
+ public void testStartPlatformVpn() throws Exception {
+ startLegacyVpn(mVpnProfile);
// TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in
- // a subsequent CL.
+ // a subsequent patch.
+ }
+
+ @Test
+ public void testStartRacoonNumericAddress() throws Exception {
+ startRacoon("1.2.3.4", "1.2.3.4");
+ }
+
+ @Test
+ public void testStartRacoonHostname() throws Exception {
+ startRacoon("hostname", "5.6.7.8"); // address returned by deps.resolve
+ }
+
+ public void startRacoon(final String serverAddr, final String expectedAddr)
+ throws Exception {
+ final ConditionVariable legacyRunnerReady = new ConditionVariable();
+ final VpnProfile profile = new VpnProfile("testProfile" /* key */);
+ profile.type = VpnProfile.TYPE_L2TP_IPSEC_PSK;
+ profile.name = "testProfileName";
+ profile.username = "userName";
+ profile.password = "thePassword";
+ profile.server = serverAddr;
+ profile.ipsecIdentifier = "id";
+ profile.ipsecSecret = "secret";
+ profile.l2tpSecret = "l2tpsecret";
+ when(mConnectivityManager.getAllNetworks())
+ .thenReturn(new Network[] { new Network(101) });
+ when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(),
+ anyInt(), any(), anyInt())).thenAnswer(invocation -> {
+ // The runner has registered an agent and is now ready.
+ legacyRunnerReady.open();
+ return new Network(102);
+ });
+ final Vpn vpn = startLegacyVpn(profile);
+ final TestDeps deps = (TestDeps) vpn.mDeps;
+ try {
+ // udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK
+ assertArrayEquals(
+ new String[] { EGRESS_IFACE, expectedAddr, "udppsk",
+ profile.ipsecIdentifier, profile.ipsecSecret, "1701" },
+ deps.racoonArgs.get(10, TimeUnit.SECONDS));
+ // literal values are hardcoded in Vpn.java for mtpd args
+ assertArrayEquals(
+ new String[] { EGRESS_IFACE, "l2tp", expectedAddr, "1701", profile.l2tpSecret,
+ "name", profile.username, "password", profile.password,
+ "linkname", "vpn", "refuse-eap", "nodefaultroute", "usepeerdns",
+ "idle", "1800", "mtu", "1400", "mru", "1400" },
+ deps.mtpdArgs.get(10, TimeUnit.SECONDS));
+ // Now wait for the runner to be ready before testing for the route.
+ legacyRunnerReady.block(10_000);
+ // In this test the expected address is always v4 so /32
+ final RouteInfo expectedRoute = new RouteInfo(new IpPrefix(expectedAddr + "/32"),
+ RouteInfo.RTN_THROW);
+ assertTrue("Routes lack the expected throw route (" + expectedRoute + ") : "
+ + vpn.mConfig.routes,
+ vpn.mConfig.routes.contains(expectedRoute));
+ } finally {
+ // Now interrupt the thread, unblock the runner and clean up.
+ vpn.mVpnRunner.exitVpnRunner();
+ deps.getStateFile().delete(); // set to delete on exit, but this deletes it earlier
+ vpn.mVpnRunner.join(10_000); // wait for up to 10s for the runner to die and cleanup
+ }
+ }
+
+ private static final class TestDeps extends Vpn.Dependencies {
+ public final CompletableFuture<String[]> racoonArgs = new CompletableFuture();
+ public final CompletableFuture<String[]> mtpdArgs = new CompletableFuture();
+ public final File mStateFile;
+
+ private final HashMap<String, Boolean> mRunningServices = new HashMap<>();
+
+ TestDeps() {
+ try {
+ mStateFile = File.createTempFile("vpnTest", ".tmp");
+ mStateFile.deleteOnExit();
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void startService(final String serviceName) {
+ mRunningServices.put(serviceName, true);
+ }
+
+ @Override
+ public void stopService(final String serviceName) {
+ mRunningServices.put(serviceName, false);
+ }
+
+ @Override
+ public boolean isServiceRunning(final String serviceName) {
+ return mRunningServices.getOrDefault(serviceName, false);
+ }
+
+ @Override
+ public boolean isServiceStopped(final String serviceName) {
+ return !isServiceRunning(serviceName);
+ }
+
+ @Override
+ public File getStateFile() {
+ return mStateFile;
+ }
+
+ @Override
+ public void sendArgumentsToDaemon(
+ final String daemon, final LocalSocket socket, final String[] arguments,
+ final Vpn.RetryScheduler interruptChecker) throws IOException {
+ if ("racoon".equals(daemon)) {
+ racoonArgs.complete(arguments);
+ } else if ("mtpd".equals(daemon)) {
+ writeStateFile(arguments);
+ mtpdArgs.complete(arguments);
+ } else {
+ throw new UnsupportedOperationException("Unsupported daemon : " + daemon);
+ }
+ }
+
+ private void writeStateFile(final String[] arguments) throws IOException {
+ mStateFile.delete();
+ mStateFile.createNewFile();
+ mStateFile.deleteOnExit();
+ final BufferedWriter writer = new BufferedWriter(
+ new FileWriter(mStateFile, false /* append */));
+ writer.write(EGRESS_IFACE);
+ writer.write("\n");
+ // addresses
+ writer.write("10.0.0.1/24\n");
+ // routes
+ writer.write("192.168.6.0/24\n");
+ // dns servers
+ writer.write("192.168.6.1\n");
+ // search domains
+ writer.write("vpn.searchdomains.com\n");
+ // endpoint - intentionally empty
+ writer.write("\n");
+ writer.flush();
+ writer.close();
+ }
+
+ @Override
+ @NonNull
+ public InetAddress resolve(final String endpoint) {
+ try {
+ // If a numeric IP address, return it.
+ return InetAddress.parseNumericAddress(endpoint);
+ } catch (IllegalArgumentException e) {
+ // Otherwise, return some token IP to test for.
+ return InetAddress.parseNumericAddress("5.6.7.8");
+ }
+ }
+
+ @Override
+ public boolean checkInterfacePresent(final Vpn vpn, final String iface) {
+ return true;
+ }
}
/**
* Mock some methods of vpn object.
*/
private Vpn createVpn(@UserIdInt int userId) {
- return new Vpn(Looper.myLooper(), mContext, mNetService,
+ return new Vpn(Looper.myLooper(), mContext, new TestDeps(), mNetService,
userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 3cdfb00d288c..e4937892e2f7 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -122,7 +122,7 @@ interface IWifiManager
DhcpInfo getDhcpInfo();
- void setScanAlwaysAvailable(boolean isAvailable);
+ void setScanAlwaysAvailable(boolean isAvailable, String packageName);
boolean isScanAlwaysAvailable();
@@ -142,9 +142,9 @@ interface IWifiManager
void updateInterfaceIpState(String ifaceName, int mode);
- boolean startSoftAp(in WifiConfiguration wifiConfig);
+ boolean startSoftAp(in WifiConfiguration wifiConfig, String packageName);
- boolean startTetheredHotspot(in SoftApConfiguration softApConfig);
+ boolean startTetheredHotspot(in SoftApConfiguration softApConfig, String packageName);
boolean stopSoftAp();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ae834f929691..b28b902910bf 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2802,7 +2802,7 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public void setScanAlwaysAvailable(boolean isAvailable) {
try {
- mService.setScanAlwaysAvailable(isAvailable);
+ mService.setScanAlwaysAvailable(isAvailable, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3035,7 +3035,7 @@ public class WifiManager {
})
public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
try {
- return mService.startSoftAp(wifiConfig);
+ return mService.startSoftAp(wifiConfig, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3059,7 +3059,7 @@ public class WifiManager {
})
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
try {
- return mService.startTetheredHotspot(softApConfig);
+ return mService.startTetheredHotspot(softApConfig, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index cba1690ac635..e7f1916c9e82 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -218,10 +218,10 @@ public class WifiManagerTest {
*/
@Test
public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
- when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
+ when(mWifiService.startSoftAp(mApConfig, TEST_PACKAGE_NAME)).thenReturn(true);
assertTrue(mWifiManager.startSoftAp(mApConfig));
- when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
+ when(mWifiService.startSoftAp(mApConfig, TEST_PACKAGE_NAME)).thenReturn(false);
assertFalse(mWifiManager.startSoftAp(mApConfig));
}
@@ -231,10 +231,10 @@ public class WifiManagerTest {
*/
@Test
public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
- when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
+ when(mWifiService.startSoftAp(null, TEST_PACKAGE_NAME)).thenReturn(true);
assertTrue(mWifiManager.startSoftAp(null));
- when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
+ when(mWifiService.startSoftAp(null, TEST_PACKAGE_NAME)).thenReturn(false);
assertFalse(mWifiManager.startSoftAp(null));
}
@@ -257,10 +257,12 @@ public class WifiManagerTest {
@Test
public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
SoftApConfiguration softApConfig = generatorTestSoftApConfig();
- when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
+ when(mWifiService.startTetheredHotspot(softApConfig, TEST_PACKAGE_NAME))
+ .thenReturn(true);
assertTrue(mWifiManager.startTetheredHotspot(softApConfig));
- when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
+ when(mWifiService.startTetheredHotspot(softApConfig, TEST_PACKAGE_NAME))
+ .thenReturn(false);
assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
}
@@ -270,10 +272,10 @@ public class WifiManagerTest {
*/
@Test
public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception {
- when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(true);
+ when(mWifiService.startTetheredHotspot(null, TEST_PACKAGE_NAME)).thenReturn(true);
assertTrue(mWifiManager.startTetheredHotspot(null));
- when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(false);
+ when(mWifiService.startTetheredHotspot(null, TEST_PACKAGE_NAME)).thenReturn(false);
assertFalse(mWifiManager.startTetheredHotspot(null));
}
@@ -2375,7 +2377,7 @@ public class WifiManagerTest {
@Test
public void testScanAvailable() throws Exception {
mWifiManager.setScanAlwaysAvailable(true);
- verify(mWifiService).setScanAlwaysAvailable(true);
+ verify(mWifiService).setScanAlwaysAvailable(true, TEST_PACKAGE_NAME);
when(mWifiService.isScanAlwaysAvailable()).thenReturn(false);
assertFalse(mWifiManager.isScanAlwaysAvailable());