Merge "Check for null receiver in biometric AuthController"
diff --git a/Android.bp b/Android.bp
index e0c3f96..8169d6d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -928,7 +928,8 @@
"--hide RequiresPermission " +
"--hide MissingPermission --hide BroadcastBehavior " +
"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
- "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo "
+ "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " +
+ "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.*"
// http://b/129765390 Rewrite links to "platform" or "technotes" folders
// which are siblings (and thus outside of) {@docRoot}.
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index c036c77..041825c 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -1,9 +1,9 @@
package com.android.server.usage;
+import android.annotation.UserIdInt;
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager.StandbyBuckets;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.Context;
import android.os.Looper;
@@ -33,6 +33,24 @@
}
}
+ /**
+ * Listener interface for notifications that an app's idle state changed.
+ */
+ abstract static class AppIdleStateChangeListener {
+
+ /** Callback to inform listeners that the idle state has changed to a new bucket. */
+ public abstract void onAppIdleStateChanged(String packageName, @UserIdInt int userId,
+ boolean idle, int bucket, int reason);
+
+ /**
+ * Optional callback to inform the listener that the app has transitioned into
+ * an active state due to user interaction.
+ */
+ public void onUserInteractionStarted(String packageName, @UserIdInt int userId) {
+ // No-op by default
+ }
+ }
+
void onBootPhase(int phase);
void postCheckIdleStates(int userId);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index c3ffad6..a1734d8 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -37,7 +37,6 @@
import android.app.job.JobWorkItem;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -103,6 +102,8 @@
import com.android.server.job.controllers.TimeController;
import com.android.server.job.restrictions.JobRestriction;
import com.android.server.job.restrictions.ThermalStatusRestriction;
+import com.android.server.usage.AppStandbyInternal;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import libcore.util.EmptyArray;
@@ -1295,7 +1296,9 @@
// Set up the app standby bucketing tracker
mStandbyTracker = new StandbyTracker();
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
- mUsageStats.addAppIdleStateChangeListener(mStandbyTracker);
+
+ AppStandbyInternal appStandby = LocalServices.getService(AppStandbyInternal.class);
+ appStandby.addListener(mStandbyTracker);
// The job store needs to call back
publishLocalService(JobSchedulerInternal.class, new LocalService());
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 14dce84..cda5244 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -35,8 +35,6 @@
import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.IUidObserver;
-import android.app.usage.UsageStatsManagerInternal;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -70,6 +68,8 @@
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobServiceContext;
import com.android.server.job.StateControllerProto;
+import com.android.server.usage.AppStandbyInternal;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.util.ArrayList;
import java.util.List;
@@ -574,9 +574,8 @@
mContext.registerReceiverAsUser(mPackageAddedReceiver, UserHandle.ALL, filter, null, null);
// Set up the app standby bucketing tracker
- UsageStatsManagerInternal usageStats = LocalServices.getService(
- UsageStatsManagerInternal.class);
- usageStats.addAppIdleStateChangeListener(new StandbyTracker());
+ AppStandbyInternal appStandby = LocalServices.getService(AppStandbyInternal.class);
+ appStandby.addListener(new StandbyTracker());
try {
ActivityManager.getService().registerUidObserver(mUidObserver,
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index ecc0459..bcd8be7 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -53,7 +53,6 @@
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager.StandbyBuckets;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -102,6 +101,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.usage.AppIdleHistory.AppUsageHistory;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.io.File;
import java.io.PrintWriter;
diff --git a/api/system-current.txt b/api/system-current.txt
index 9573478..9dcacaf 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4737,6 +4737,7 @@
method @Deprecated public boolean hasNoInternetAccess();
method @Deprecated public boolean isEphemeral();
method @Deprecated public boolean isNoInternetAccessExpected();
+ field @Deprecated public boolean allowAutojoin;
field @Deprecated public String creatorName;
field @Deprecated public int creatorUid;
field @Deprecated public String lastUpdateName;
@@ -4759,6 +4760,7 @@
public class WifiManager {
method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
+ method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void allowAutojoin(int, boolean);
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index d5e41f0..8bca87e6 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2822,12 +2822,12 @@
LongSparseArray.StringParcelling.class);
return new OpFeatureEntry.Builder(source.readBoolean(),
- (LongSparseLongArray) longSparseLongArrayParcelling.unparcel(source),
- (LongSparseLongArray) longSparseLongArrayParcelling.unparcel(source),
- (LongSparseLongArray) longSparseLongArrayParcelling.unparcel(source),
- (LongSparseLongArray) longSparseLongArrayParcelling.unparcel(source),
- (LongSparseArray<String>) longSparseStringArrayParcelling.unparcel(source),
- (LongSparseArray<String>) longSparseStringArrayParcelling.unparcel(source));
+ longSparseLongArrayParcelling.unparcel(source),
+ longSparseLongArrayParcelling.unparcel(source),
+ longSparseLongArrayParcelling.unparcel(source),
+ longSparseLongArrayParcelling.unparcel(source),
+ longSparseStringArrayParcelling.unparcel(source),
+ longSparseStringArrayParcelling.unparcel(source));
}
}
diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java
deleted file mode 100644
index f072167..0000000
--- a/core/java/android/content/pm/VerificationParams.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2012 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.content.pm;
-
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents verification parameters used to verify packages to be installed.
- *
- * @deprecated callers should migrate to {@link PackageInstaller}.
- * @hide
- */
-@Deprecated
-public class VerificationParams implements Parcelable {
- /** A constant used to indicate that a uid value is not present. */
- public static final int NO_UID = -1;
-
- /** What we print out first when toString() is called. */
- private static final String TO_STRING_PREFIX = "VerificationParams{";
-
- /** The location of the supplementary verification file. */
- private final Uri mVerificationURI;
-
- /** URI referencing where the package was downloaded from. */
- private final Uri mOriginatingURI;
-
- /** HTTP referrer URI associated with the originatingURI. */
- private final Uri mReferrer;
-
- /** UID of the application that the install request originated from. */
- private final int mOriginatingUid;
-
- /** UID of application requesting the install */
- private int mInstallerUid;
-
- /**
- * Creates verification specifications for installing with application verification.
- *
- * @param verificationURI The location of the supplementary verification
- * file. This can be a 'file:' or a 'content:' URI. May be {@code null}.
- * @param originatingURI URI referencing where the package was downloaded
- * from. May be {@code null}.
- * @param referrer HTTP referrer URI associated with the originatingURI.
- * May be {@code null}.
- * @param originatingUid UID of the application that the install request originated
- * from, or NO_UID if not present
- */
- public VerificationParams(Uri verificationURI, Uri originatingURI, Uri referrer,
- int originatingUid) {
- mVerificationURI = verificationURI;
- mOriginatingURI = originatingURI;
- mReferrer = referrer;
- mOriginatingUid = originatingUid;
- mInstallerUid = NO_UID;
- }
-
- public Uri getVerificationURI() {
- return mVerificationURI;
- }
-
- public Uri getOriginatingURI() {
- return mOriginatingURI;
- }
-
- public Uri getReferrer() {
- return mReferrer;
- }
-
- /** return NO_UID if not available */
- public int getOriginatingUid() {
- return mOriginatingUid;
- }
-
- /** @return NO_UID when not set */
- public int getInstallerUid() {
- return mInstallerUid;
- }
-
- public void setInstallerUid(int uid) {
- mInstallerUid = uid;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof VerificationParams)) {
- return false;
- }
-
- final VerificationParams other = (VerificationParams) o;
-
- if (mVerificationURI == null) {
- if (other.mVerificationURI != null) {
- return false;
- }
- } else if (!mVerificationURI.equals(other.mVerificationURI)) {
- return false;
- }
-
- if (mOriginatingURI == null) {
- if (other.mOriginatingURI != null) {
- return false;
- }
- } else if (!mOriginatingURI.equals(other.mOriginatingURI)) {
- return false;
- }
-
- if (mReferrer == null) {
- if (other.mReferrer != null) {
- return false;
- }
- } else if (!mReferrer.equals(other.mReferrer)) {
- return false;
- }
-
- if (mOriginatingUid != other.mOriginatingUid) {
- return false;
- }
-
- if (mInstallerUid != other.mInstallerUid) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int hash = 3;
-
- hash += 5 * (mVerificationURI == null ? 1 : mVerificationURI.hashCode());
- hash += 7 * (mOriginatingURI == null ? 1 : mOriginatingURI.hashCode());
- hash += 11 * (mReferrer == null ? 1 : mReferrer.hashCode());
- hash += 13 * mOriginatingUid;
- hash += 17 * mInstallerUid;
-
- return hash;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX);
-
- sb.append("mVerificationURI=");
- sb.append(mVerificationURI.toString());
- sb.append(",mOriginatingURI=");
- sb.append(mOriginatingURI.toString());
- sb.append(",mReferrer=");
- sb.append(mReferrer.toString());
- sb.append(",mOriginatingUid=");
- sb.append(mOriginatingUid);
- sb.append(",mInstallerUid=");
- sb.append(mInstallerUid);
- sb.append('}');
-
- return sb.toString();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mVerificationURI, 0);
- dest.writeParcelable(mOriginatingURI, 0);
- dest.writeParcelable(mReferrer, 0);
- dest.writeInt(mOriginatingUid);
- dest.writeInt(mInstallerUid);
- }
-
-
- private VerificationParams(Parcel source) {
- mVerificationURI = source.readParcelable(Uri.class.getClassLoader());
- mOriginatingURI = source.readParcelable(Uri.class.getClassLoader());
- mReferrer = source.readParcelable(Uri.class.getClassLoader());
- mOriginatingUid = source.readInt();
- mInstallerUid = source.readInt();
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<VerificationParams> CREATOR =
- new Parcelable.Creator<VerificationParams>() {
- public VerificationParams createFromParcel(Parcel source) {
- return new VerificationParams(source);
- }
-
- public VerificationParams[] newArray(int size) {
- return new VerificationParams[size];
- }
- };
-}
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index e78b796..73e17a6 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -17,7 +17,6 @@
package android.util;
import android.os.Parcel;
-import android.os.Parcelable;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
@@ -25,6 +24,8 @@
import libcore.util.EmptyArray;
+import java.util.Arrays;
+
/**
* SparseArray mapping longs to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more memory efficient
@@ -450,22 +451,25 @@
/**
* @hide
*/
- public static class StringParcelling implements com.android.internal.util.Parcelling {
+ public static class StringParcelling implements
+ com.android.internal.util.Parcelling<LongSparseArray<String>> {
@Override
- public void parcel(Object item, Parcel dest, int parcelFlags) {
- if (item == null) {
+ public void parcel(LongSparseArray<String> array, Parcel dest, int parcelFlags) {
+ if (array == null) {
dest.writeInt(-1);
return;
}
- LongSparseArray<String> array = (LongSparseArray<String>) item;
- dest.writeInt(array.mSize);
+ int size = array.mSize;
+
+ dest.writeInt(size);
dest.writeLongArray(array.mKeys);
- dest.writeStringArray((String[]) array.mValues);
+
+ dest.writeStringArray(Arrays.copyOfRange(array.mValues, 0, size, String[].class));
}
@Override
- public Object unparcel(Parcel source) {
+ public LongSparseArray<String> unparcel(Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
@@ -490,49 +494,4 @@
return array;
}
}
-
- /**
- * @hide
- */
- public static class Parcelling<T extends Parcelable> implements
- com.android.internal.util.Parcelling {
- @Override
- public void parcel(Object item, Parcel dest, int parcelFlags) {
- if (item == null) {
- dest.writeInt(-1);
- return;
- }
-
- LongSparseArray<T> array = (LongSparseArray<T>) item;
- dest.writeInt(array.mSize);
- dest.writeLongArray(array.mKeys);
- dest.writeParcelableArray((T[]) array.mValues, parcelFlags);
- }
-
- @Override
- public Object unparcel(Parcel source) {
- int size = source.readInt();
- if (size == -1) {
- return null;
- }
-
- LongSparseArray<T> array = new LongSparseArray<>(0);
- array.mSize = size;
- array.mKeys = source.createLongArray();
- array.mValues = source.readParcelableArray(null);
-
- // Make sure array is sane
- Preconditions.checkArgument(array.mKeys.length >= size);
- Preconditions.checkArgument(array.mValues.length >= size);
-
- if (size > 0) {
- long last = array.mKeys[0];
- for (int i = 1; i < size; i++) {
- Preconditions.checkArgument(last < array.mKeys[i]);
- }
- }
-
- return array;
- }
- }
}
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 9ffd4f0..a0edd04 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -289,22 +289,22 @@
/**
* @hide
*/
- public static class Parcelling implements com.android.internal.util.Parcelling {
+ public static class Parcelling implements
+ com.android.internal.util.Parcelling<LongSparseLongArray> {
@Override
- public void parcel(Object item, Parcel dest, int parcelFlags) {
- if (item == null) {
+ public void parcel(LongSparseLongArray array, Parcel dest, int parcelFlags) {
+ if (array == null) {
dest.writeInt(-1);
return;
}
- LongSparseLongArray array = (LongSparseLongArray) item;
dest.writeInt(array.mSize);
dest.writeLongArray(array.mKeys);
dest.writeLongArray(array.mValues);
}
@Override
- public Object unparcel(Parcel source) {
+ public LongSparseLongArray unparcel(Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
diff --git a/core/proto/android/server/notificationhistory.proto b/core/proto/android/server/notificationhistory.proto
index 148bd7e..1e6ee3f 100644
--- a/core/proto/android/server/notificationhistory.proto
+++ b/core/proto/android/server/notificationhistory.proto
@@ -46,7 +46,7 @@
// The uid of the package that posted the notification
optional int32 uid = 7;
- // The user id of the package that posted the notification
+ // The user id that the notification was posted to
optional int32 user_id = 8;
// The time at which the notification was posted
optional int64 posted_time_ms = 9;
@@ -71,19 +71,19 @@
optional ImageTypeEnum image_type = 1;
optional string image_bitmap_filename = 2;
optional int32 image_resource_id = 3;
- optional bytes image_data = 4;
- optional string image_uri = 5;
+ optional string image_resource_id_package = 4;
+ optional bytes image_data = 5;
+ optional int32 image_data_length = 6;
+ optional int32 image_data_offset = 7;
+ optional string image_uri = 8;
}
}
- // The time the last entry was written
- optional int64 end_time_ms = 1;
// Pool of strings to save space
- optional StringPool stringpool = 2;
+ optional StringPool string_pool = 1;
// Versioning fields
- optional int32 major_version = 3;
- optional int32 minor_version = 4;
+ optional int32 major_version = 2;
// List of historical notifications
- repeated Notification notification = 5;
+ repeated Notification notification = 3;
}
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index 2e1de79..40c5a85 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -32,6 +32,7 @@
optional UsbPortManagerProto port_manager = 3;
optional UsbAlsaManagerProto alsa_manager = 4;
optional UsbSettingsManagerProto settings_manager = 5;
+ optional UsbPermissionsManagerProto permissions_manager = 6;
}
message UsbDeviceManagerProto {
@@ -309,26 +310,12 @@
option (android.msg_privacy).dest = DEST_AUTOMATIC;
optional int32 user_id = 1;
- repeated UsbSettingsDevicePermissionProto device_permissions = 2;
- repeated UsbSettingsAccessoryPermissionProto accessory_permissions = 3;
+ reserved 2; // previously device_permissions, now unused
+ reserved 3; // previously accessory_permissions, now unused
repeated UsbDeviceAttachedActivities device_attached_activities = 4;
repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
}
-message UsbSettingsDevicePermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string device_name = 1;
- repeated int32 uids = 2;
-}
-
-message UsbSettingsAccessoryPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string accessory_description = 1;
- repeated int32 uids = 2;
-}
-
message UsbProfileGroupSettingsManagerProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -345,6 +332,63 @@
optional UserPackageProto user_package = 2;
}
+message UsbPermissionsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated UsbUserPermissionsManagerProto user_permissions = 1;
+}
+
+message UsbUserPermissionsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 user_id = 1;
+
+ repeated UsbDevicePermissionProto device_permissions = 2;
+ repeated UsbAccessoryPermissionProto accessory_permissions = 3;
+
+ repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
+ repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
+}
+
+message UsbDevicePermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Name of device set by manufacturer
+ // All devices of the same model have the same name
+ optional string device_name = 1;
+ repeated int32 uids = 2;
+}
+
+message UsbAccessoryPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Description of accessory set by manufacturer
+ // All accessories of the same model have the same description
+ optional string accessory_description = 1;
+ repeated int32 uids = 2;
+}
+
+message UsbDevicePersistentPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbDeviceFilterProto device_filter = 1;
+ repeated UsbUidPermissionProto permission_values = 2;
+}
+
+message UsbAccessoryPersistentPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbAccessoryFilterProto accessory_filter = 1;
+ repeated UsbUidPermissionProto permission_values = 2;
+}
+
+message UsbUidPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 uid = 1;
+ optional bool is_granted = 2;
+}
+
message UsbDeviceFilterProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
deleted file mode 100644
index f6527da..0000000
--- a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2012 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.content.pm;
-
-import android.net.Uri;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-
-import androidx.test.filters.LargeTest;
-
-/**
- * Tests the android.content.pm.VerificationParams class
- *
- * To test run:
- * ./development/testrunner/runtest.py frameworks-core -c android.content.pm.VerificationParamsTest
- */
-@LargeTest
-public class VerificationParamsTest extends AndroidTestCase {
-
- private final static String VERIFICATION_URI_STRING = "http://verification.uri/path";
- private final static String ORIGINATING_URI_STRING = "http://originating.uri/path";
- private final static String REFERRER_STRING = "http://referrer.uri/path";
- private final static int INSTALLER_UID = 42;
-
- private final static Uri VERIFICATION_URI = Uri.parse(VERIFICATION_URI_STRING);
- private final static Uri ORIGINATING_URI = Uri.parse(ORIGINATING_URI_STRING);
- private final static Uri REFERRER = Uri.parse(REFERRER_STRING);
-
- private final static int ORIGINATING_UID = 10042;
-
- public void testParcel() throws Exception {
- VerificationParams expected = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- Parcel parcel = Parcel.obtain();
- expected.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
-
- VerificationParams actual = VerificationParams.CREATOR.createFromParcel(parcel);
-
- assertEquals(VERIFICATION_URI, actual.getVerificationURI());
-
- assertEquals(ORIGINATING_URI, actual.getOriginatingURI());
-
- assertEquals(REFERRER, actual.getReferrer());
-
- assertEquals(ORIGINATING_UID, actual.getOriginatingUid());
- }
-
- public void testEquals_Success() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
-
- assertEquals(params1, params2);
- }
-
- public void testEquals_VerificationUri_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse("http://a.different.uri/"), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
-
- assertFalse(params1.equals(params2));
- }
-
- public void testEquals_OriginatingUri_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
-
- assertFalse(params1.equals(params2));
- }
-
- public void testEquals_Referrer_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse("http://a.different.uri/"), ORIGINATING_UID);
-
- assertFalse(params1.equals(params2));
- }
-
- public void testEquals_Originating_Uid_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), 12345);
-
- assertFalse(params1.equals(params2));
- }
-
- public void testEquals_InstallerUid_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
- params2.setInstallerUid(INSTALLER_UID);
-
- assertFalse(params1.equals(params2));
- }
-
- public void testHashCode_Success() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
-
- assertEquals(params1.hashCode(), params2.hashCode());
- }
-
- public void testHashCode_VerificationUri_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(null, Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
-
- assertFalse(params1.hashCode() == params2.hashCode());
- }
-
- public void testHashCode_OriginatingUri_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
-
- assertFalse(params1.hashCode() == params2.hashCode());
- }
-
- public void testHashCode_Referrer_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), null,
- ORIGINATING_UID);
-
- assertFalse(params1.hashCode() == params2.hashCode());
- }
-
- public void testHashCode_Originating_Uid_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), 12345);
-
- assertFalse(params1.hashCode() == params2.hashCode());
- }
-
- public void testHashCode_InstallerUid_Failure() throws Exception {
- VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
- REFERRER, ORIGINATING_UID);
-
- VerificationParams params2 = new VerificationParams(
- Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
- Uri.parse(REFERRER_STRING), ORIGINATING_UID);
- params2.setInstallerUid(INSTALLER_UID);
-
- assertFalse(params1.hashCode() == params2.hashCode());
- }
-}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
new file mode 100644
index 0000000..0228dc9
--- /dev/null
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Tuner is used to interact with tuner devices.
+ *
+ * @hide
+ */
+public final class Tuner implements AutoCloseable {
+ private static final String TAG = "MediaTvTuner";
+ private static final boolean DEBUG = false;
+
+ static {
+ System.loadLibrary("media_tv_tuner");
+ nativeInit();
+ }
+
+ public Tuner() {
+ nativeSetup();
+ }
+
+ private long mNativeContext; // used by native jMediaTuner
+
+ @Override
+ public void close() {}
+
+ /**
+ * Native Initialization.
+ */
+ private static native void nativeInit();
+
+ /**
+ * Native setup.
+ */
+ private native void nativeSetup();
+}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index b4edabf..a596d89 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -123,6 +123,30 @@
],
}
+cc_library_shared {
+ name: "libmedia_tv_tuner",
+ srcs: [
+ "android_media_tv_Tuner.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.tv.tuner@1.0",
+ "libandroid_runtime",
+ "liblog",
+ "libutils",
+ ],
+
+ export_include_dirs: ["."],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ "-Wunused",
+ "-Wunreachable-code",
+ ],
+}
+
subdirs = [
"audioeffect",
"soundpool",
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
new file mode 100644
index 0000000..d499eee
--- /dev/null
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "TvTuner-JNI"
+#include <utils/Log.h>
+
+#include "android_media_tv_Tuner.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+using ::android::hardware::tv::tuner::V1_0::ITuner;
+
+struct fields_t {
+ jfieldID context;
+};
+
+static fields_t gFields;
+
+namespace android {
+
+sp<ITuner> JTuner::mTuner;
+
+JTuner::JTuner(JNIEnv *env, jobject thiz)
+ : mClass(NULL) {
+ jclass clazz = env->GetObjectClass(thiz);
+ CHECK(clazz != NULL);
+
+ mClass = (jclass)env->NewGlobalRef(clazz);
+ mObject = env->NewWeakGlobalRef(thiz);
+ if (mTuner == NULL) {
+ mTuner = getTunerService();
+ }
+}
+
+JTuner::~JTuner() {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ env->DeleteGlobalRef(mClass);
+ mTuner = NULL;
+ mClass = NULL;
+ mObject = NULL;
+}
+
+sp<ITuner> JTuner::getTunerService() {
+ if (mTuner == nullptr) {
+ mTuner = ITuner::getService();
+
+ if (mTuner == nullptr) {
+ ALOGW("Failed to get tuner service.");
+ }
+ }
+ return mTuner;
+}
+
+} // namespace android
+
+////////////////////////////////////////////////////////////////////////////////
+
+using namespace android;
+
+static sp<JTuner> setTuner(JNIEnv *env, jobject thiz, const sp<JTuner> &tuner) {
+ sp<JTuner> old = (JTuner *)env->GetLongField(thiz, gFields.context);
+
+ if (tuner != NULL) {
+ tuner->incStrong(thiz);
+ }
+ if (old != NULL) {
+ old->decStrong(thiz);
+ }
+ env->SetLongField(thiz, gFields.context, (jlong)tuner.get());
+
+ return old;
+}
+
+static sp<JTuner> getTuner(JNIEnv *env, jobject thiz) {
+ return (JTuner *)env->GetLongField(thiz, gFields.context);
+}
+
+static void android_media_tv_Tuner_native_init(JNIEnv *env) {
+ jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
+ CHECK(clazz != NULL);
+
+ gFields.context = env->GetFieldID(clazz, "mNativeContext", "J");
+ CHECK(gFields.context != NULL);
+}
+
+static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
+ sp<JTuner> tuner = new JTuner(env, thiz);
+ setTuner(env,thiz, tuner);
+}
+
+static const JNINativeMethod gMethods[] = {
+ { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init },
+ { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup },
+};
+
+static int register_android_media_tv_Tuner(JNIEnv *env) {
+ return AndroidRuntime::registerNativeMethods(
+ env, "android/media/tv/tuner/Tuner", gMethods, NELEM(gMethods));
+}
+
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
+{
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ ALOGE("ERROR: GetEnv failed\n");
+ return result;
+ }
+ assert(env != NULL);
+
+ if (register_android_media_tv_Tuner(env) != JNI_OK) {
+ ALOGE("ERROR: Tuner native registration failed\n");
+ return result;
+ }
+ return JNI_VERSION_1_4;
+}
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
new file mode 100644
index 0000000..e7d5924
--- /dev/null
+++ b/media/jni/android_media_tv_Tuner.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_MEDIA_TV_TUNER_H_
+#define _ANDROID_MEDIA_TV_TUNER_H_
+
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <utils/RefBase.h>
+
+#include "jni.h"
+
+using ::android::hardware::tv::tuner::V1_0::ITuner;
+
+namespace android {
+
+struct JTuner : public RefBase {
+ JTuner(JNIEnv *env, jobject thiz);
+ sp<ITuner> getTunerService();
+protected:
+ virtual ~JTuner();
+
+private:
+ jclass mClass;
+ jweak mObject;
+ static sp<ITuner> mTuner;
+};
+
+} // namespace android
+
+#endif // _ANDROID_MEDIA_TV_TUNER_H_
diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
index 1cf48c5..0f964fd 100644
--- a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
@@ -31,14 +31,15 @@
android:paddingStart="@*android:dimen/car_padding_5"
android:paddingEnd="@*android:dimen/car_padding_5">
- <com.android.systemui.navigationbar.car.CarNavigationButton
+ <com.android.systemui.navigationbar.car.CarFacetButton
android:id="@+id/home"
android:layout_width="@*android:dimen/car_touch_target_size"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground"
- android:src="@drawable/car_ic_overview"
+ systemui:icon="@drawable/car_ic_overview"
systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- />
+ systemui:selectedIcon="@drawable/car_ic_overview_selected"
+ systemui:useMoreIcon="false"/>
</LinearLayout>
</com.android.systemui.navigationbar.car.CarNavigationBarView>
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
index 6fba1d5..63bc66a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
@@ -25,7 +25,6 @@
import android.os.ServiceManager;
import android.view.Display;
import android.view.Gravity;
-import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -37,8 +36,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.car.hvac.HvacController;
-import com.android.systemui.statusbar.car.hvac.TemperatureView;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -52,15 +49,13 @@
/** Navigation bars customized for the automotive use case. */
public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks {
- private final NavigationBarViewFactory mNavigationBarViewFactory;
+ private final CarNavigationBarController mCarNavigationBarController;
private final WindowManager mWindowManager;
private final DeviceProvisionedController mDeviceProvisionedController;
private final Lazy<FacetButtonTaskStackListener> mFacetButtonTaskStackListener;
private final Handler mMainHandler;
private final Lazy<KeyguardStateController> mKeyguardStateController;
- private final Lazy<CarFacetButtonController> mFacetButtonController;
private final Lazy<NavigationBarController> mNavigationBarController;
- private final Lazy<HvacController> mHvacController;
private IStatusBarService mBarService;
private CommandQueue mCommandQueue;
@@ -82,33 +77,23 @@
// it's open.
private boolean mDeviceIsSetUpForUser = true;
- // Configuration values for if nav bars should be shown.
- private boolean mShowBottom;
- private boolean mShowLeft;
- private boolean mShowRight;
-
-
@Inject
public CarNavigationBar(Context context,
- NavigationBarViewFactory navigationBarViewFactory,
+ CarNavigationBarController carNavigationBarController,
WindowManager windowManager,
DeviceProvisionedController deviceProvisionedController,
Lazy<FacetButtonTaskStackListener> facetButtonTaskStackListener,
@MainHandler Handler mainHandler,
Lazy<KeyguardStateController> keyguardStateController,
- Lazy<CarFacetButtonController> facetButtonController,
- Lazy<NavigationBarController> navigationBarController,
- Lazy<HvacController> hvacController) {
+ Lazy<NavigationBarController> navigationBarController) {
super(context);
- mNavigationBarViewFactory = navigationBarViewFactory;
+ mCarNavigationBarController = carNavigationBarController;
mWindowManager = windowManager;
mDeviceProvisionedController = deviceProvisionedController;
mFacetButtonTaskStackListener = facetButtonTaskStackListener;
mMainHandler = mainHandler;
mKeyguardStateController = keyguardStateController;
- mFacetButtonController = facetButtonController;
mNavigationBarController = navigationBarController;
- mHvacController = hvacController;
}
@Override
@@ -118,11 +103,6 @@
com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
mBottomNavBarVisible = false;
- // Read configuration.
- mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
- mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
- mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
-
// Get bar service.
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -157,7 +137,7 @@
mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
mActivityManagerWrapper.registerTaskStackListener(mFacetButtonTaskStackListener.get());
- mHvacController.get().connectToCarService();
+ mCarNavigationBarController.connectToHvac();
}
private void restartNavBarsIfNecessary() {
@@ -175,8 +155,7 @@
private void restartNavBars() {
// remove and reattach all hvac components such that we don't keep a reference to unused
// ui elements
- mHvacController.get().removeAllComponents();
- mFacetButtonController.get().removeAll();
+ mCarNavigationBarController.removeAllFromHvac();
if (mNavigationBarWindow != null) {
mNavigationBarWindow.removeAllViews();
@@ -199,10 +178,6 @@
if (mKeyguardStateController.get().isShowing()) {
updateNavBarForKeyguardContent();
}
-
- // CarFacetButtonController was reset therefore we need to re-add the status bar elements
- // to the controller.
- // TODO(hseog): Add facet buttons in status bar to controller.
}
private void createNavigationBar(RegisterStatusBarResult result) {
@@ -224,54 +199,30 @@
}
private void buildNavBarWindows() {
- if (mShowBottom) {
- mNavigationBarWindow = mNavigationBarViewFactory.getBottomWindow();
- }
-
- if (mShowLeft) {
- mLeftNavigationBarWindow = mNavigationBarViewFactory.getLeftWindow();
- }
-
- if (mShowRight) {
- mRightNavigationBarWindow = mNavigationBarViewFactory.getRightWindow();
- }
+ mNavigationBarWindow = mCarNavigationBarController.getBottomWindow();
+ mLeftNavigationBarWindow = mCarNavigationBarController.getLeftWindow();
+ mRightNavigationBarWindow = mCarNavigationBarController.getRightWindow();
}
private void buildNavBarContent() {
- if (mShowBottom) {
- mNavigationBarView = mNavigationBarViewFactory.getBottomBar(mDeviceIsSetUpForUser);
+ mNavigationBarView = mCarNavigationBarController.getBottomBar(mDeviceIsSetUpForUser);
+ if (mNavigationBarView != null) {
mNavigationBarWindow.addView(mNavigationBarView);
- addTemperatureViewToController(mNavigationBarView);
}
- if (mShowLeft) {
- mLeftNavigationBarView = mNavigationBarViewFactory.getLeftBar(mDeviceIsSetUpForUser);
+ mLeftNavigationBarView = mCarNavigationBarController.getLeftBar(mDeviceIsSetUpForUser);
+ if (mLeftNavigationBarView != null) {
mLeftNavigationBarWindow.addView(mLeftNavigationBarView);
- addTemperatureViewToController(mLeftNavigationBarView);
}
- if (mShowRight) {
- mRightNavigationBarView = mNavigationBarViewFactory.getRightBar(mDeviceIsSetUpForUser);
+ mRightNavigationBarView = mCarNavigationBarController.getRightBar(mDeviceIsSetUpForUser);
+ if (mRightNavigationBarView != null) {
mRightNavigationBarWindow.addView(mRightNavigationBarView);
- // Add ability to toggle notification center.
- addTemperatureViewToController(mRightNavigationBarView);
- // Add ability to close notification center on touch.
- }
- }
-
- private void addTemperatureViewToController(View v) {
- if (v instanceof TemperatureView) {
- mHvacController.get().addHvacTextView((TemperatureView) v);
- } else if (v instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) v;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- addTemperatureViewToController(viewGroup.getChildAt(i));
- }
}
}
private void attachNavBarWindows() {
- if (mShowBottom && !mBottomNavBarVisible) {
+ if (mNavigationBarWindow != null && !mBottomNavBarVisible) {
mBottomNavBarVisible = true;
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -287,7 +238,7 @@
mWindowManager.addView(mNavigationBarWindow, lp);
}
- if (mShowLeft) {
+ if (mLeftNavigationBarWindow != null) {
int width = mContext.getResources().getDimensionPixelSize(
R.dimen.car_left_navigation_bar_width);
WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
@@ -304,7 +255,7 @@
leftlp.gravity = Gravity.LEFT;
mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
}
- if (mShowRight) {
+ if (mRightNavigationBarWindow != null) {
int width = mContext.getResources().getDimensionPixelSize(
R.dimen.car_right_navigation_bar_width);
WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
@@ -340,23 +291,7 @@
}
boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
- showBottomNavBarWindow(isKeyboardVisible);
- }
-
- private void showBottomNavBarWindow(boolean isKeyboardVisible) {
- if (!mShowBottom) {
- return;
- }
-
- // If keyboard is visible and bottom nav bar not visible, this is the correct state, so do
- // nothing. Same with if keyboard is not visible and bottom nav bar is visible.
- if (isKeyboardVisible ^ mBottomNavBarVisible) {
- return;
- }
-
- mNavigationBarViewFactory.getBottomWindow().setVisibility(
- isKeyboardVisible ? View.GONE : View.VISIBLE);
- mBottomNavBarVisible = !isKeyboardVisible;
+ mCarNavigationBarController.setBottomWindowVisibility(!isKeyboardVisible);
}
private void updateNavBarForKeyguardContent() {
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
new file mode 100644
index 0000000..f59f886
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.navigationbar.car;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.car.hvac.HvacController;
+import com.android.systemui.statusbar.car.hvac.TemperatureView;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
+/** A single class which controls the navigation bar views. */
+@Singleton
+public class CarNavigationBarController {
+
+ private final Context mContext;
+ private final NavigationBarViewFactory mNavigationBarViewFactory;
+ private final Lazy<HvacController> mHvacControllerLazy;
+
+ private boolean mShowBottom;
+ private boolean mShowLeft;
+ private boolean mShowRight;
+
+ private View.OnTouchListener mTopBarTouchListener;
+ private View.OnTouchListener mBottomBarTouchListener;
+ private View.OnTouchListener mLeftBarTouchListener;
+ private View.OnTouchListener mRightBarTouchListener;
+ private NotificationsShadeController mNotificationsShadeController;
+
+ private CarNavigationBarView mTopView;
+ private CarNavigationBarView mBottomView;
+ private CarNavigationBarView mLeftView;
+ private CarNavigationBarView mRightView;
+
+ @Inject
+ public CarNavigationBarController(Context context,
+ NavigationBarViewFactory navigationBarViewFactory,
+ Lazy<HvacController> hvacControllerLazy) {
+ mContext = context;
+ mNavigationBarViewFactory = navigationBarViewFactory;
+ mHvacControllerLazy = hvacControllerLazy;
+
+ // Read configuration.
+ mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
+ mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
+ mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
+ }
+
+ /** Connect to hvac service. */
+ public void connectToHvac() {
+ mHvacControllerLazy.get().connectToCarService();
+ }
+
+ /** Clean up hvac. */
+ public void removeAllFromHvac() {
+ mHvacControllerLazy.get().removeAllComponents();
+ }
+
+ /** Gets the bottom window if configured to do so. */
+ @Nullable
+ public ViewGroup getBottomWindow() {
+ return mShowBottom ? mNavigationBarViewFactory.getBottomWindow() : null;
+ }
+
+ /** Gets the left window if configured to do so. */
+ @Nullable
+ public ViewGroup getLeftWindow() {
+ return mShowLeft ? mNavigationBarViewFactory.getLeftWindow() : null;
+ }
+
+ /** Gets the right window if configured to do so. */
+ @Nullable
+ public ViewGroup getRightWindow() {
+ return mShowRight ? mNavigationBarViewFactory.getRightWindow() : null;
+ }
+
+ /** Toggles the bottom nav bar visibility. */
+ public boolean setBottomWindowVisibility(boolean isVisible) {
+ return setWindowVisibility(getBottomWindow(), isVisible);
+ }
+
+ /** Toggles the left nav bar visibility. */
+ public boolean setLeftWindowVisibility(boolean isVisible) {
+ return setWindowVisibility(getLeftWindow(), isVisible);
+ }
+
+ /** Toggles the right nav bar visibility. */
+ public boolean setRightWindowVisibility(boolean isVisible) {
+ return setWindowVisibility(getRightWindow(), isVisible);
+ }
+
+ private boolean setWindowVisibility(ViewGroup window, boolean isVisible) {
+ if (window == null) {
+ return false;
+ }
+
+ int newVisibility = isVisible ? View.VISIBLE : View.GONE;
+ if (window.getVisibility() == newVisibility) {
+ return false;
+ }
+
+ window.setVisibility(newVisibility);
+ return true;
+ }
+
+ /** Gets the top navigation bar with the appropriate listeners set. */
+ @NonNull
+ public CarNavigationBarView getTopBar(boolean isSetUp) {
+ mTopView = mNavigationBarViewFactory.getTopBar(isSetUp);
+ mTopView.setStatusBarWindowTouchListener(mTopBarTouchListener);
+ mTopView.setNotificationsPanelController(mNotificationsShadeController);
+ addTemperatureViewToController(mTopView);
+ return mTopView;
+ }
+
+ /** Gets the bottom navigation bar with the appropriate listeners set. */
+ @Nullable
+ public CarNavigationBarView getBottomBar(boolean isSetUp) {
+ if (!mShowBottom) {
+ return null;
+ }
+
+ mBottomView = mNavigationBarViewFactory.getBottomBar(isSetUp);
+ mBottomView.setStatusBarWindowTouchListener(mBottomBarTouchListener);
+ mBottomView.setNotificationsPanelController(mNotificationsShadeController);
+ addTemperatureViewToController(mBottomView);
+ return mBottomView;
+ }
+
+ /** Gets the left navigation bar with the appropriate listeners set. */
+ @Nullable
+ public CarNavigationBarView getLeftBar(boolean isSetUp) {
+ if (!mShowLeft) {
+ return null;
+ }
+
+ mLeftView = mNavigationBarViewFactory.getLeftBar(isSetUp);
+ mLeftView.setStatusBarWindowTouchListener(mLeftBarTouchListener);
+ mLeftView.setNotificationsPanelController(mNotificationsShadeController);
+ addTemperatureViewToController(mLeftView);
+ return mLeftView;
+ }
+
+ /** Gets the right navigation bar with the appropriate listeners set. */
+ @Nullable
+ public CarNavigationBarView getRightBar(boolean isSetUp) {
+ if (!mShowRight) {
+ return null;
+ }
+
+ mRightView = mNavigationBarViewFactory.getRightBar(isSetUp);
+ mRightView.setStatusBarWindowTouchListener(mRightBarTouchListener);
+ mRightView.setNotificationsPanelController(mNotificationsShadeController);
+ addTemperatureViewToController(mRightView);
+ return mRightView;
+ }
+
+ /** Sets a touch listener for the top navigation bar. */
+ public void registerTopBarTouchListener(View.OnTouchListener listener) {
+ mTopBarTouchListener = listener;
+ if (mTopView != null) {
+ mTopView.setStatusBarWindowTouchListener(mTopBarTouchListener);
+ }
+ }
+
+ /** Sets a touch listener for the bottom navigation bar. */
+ public void registerBottomBarTouchListener(View.OnTouchListener listener) {
+ mBottomBarTouchListener = listener;
+ if (mBottomView != null) {
+ mBottomView.setStatusBarWindowTouchListener(mBottomBarTouchListener);
+ }
+ }
+
+ /** Sets a touch listener for the left navigation bar. */
+ public void registerLeftBarTouchListener(View.OnTouchListener listener) {
+ mLeftBarTouchListener = listener;
+ if (mLeftView != null) {
+ mLeftView.setStatusBarWindowTouchListener(mLeftBarTouchListener);
+ }
+ }
+
+ /** Sets a touch listener for the right navigation bar. */
+ public void registerRightBarTouchListener(View.OnTouchListener listener) {
+ mRightBarTouchListener = listener;
+ if (mRightView != null) {
+ mRightView.setStatusBarWindowTouchListener(mRightBarTouchListener);
+ }
+ }
+
+ /** Sets a notification controller which toggles the notification panel. */
+ public void registerNotificationController(
+ NotificationsShadeController notificationsShadeController) {
+ mNotificationsShadeController = notificationsShadeController;
+ if (mTopView != null) {
+ mTopView.setNotificationsPanelController(mNotificationsShadeController);
+ }
+ if (mBottomView != null) {
+ mBottomView.setNotificationsPanelController(mNotificationsShadeController);
+ }
+ if (mLeftView != null) {
+ mLeftView.setNotificationsPanelController(mNotificationsShadeController);
+ }
+ if (mRightView != null) {
+ mRightView.setNotificationsPanelController(mNotificationsShadeController);
+ }
+ }
+
+ /** Interface for controlling the notifications shade. */
+ public interface NotificationsShadeController {
+ /** Toggles the visibility of the notifications shade. */
+ void togglePanel();
+ }
+
+ private void addTemperatureViewToController(View v) {
+ if (v instanceof TemperatureView) {
+ mHvacControllerLazy.get().addHvacTextView((TemperatureView) v);
+ } else if (v instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) v;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ addTemperatureViewToController(viewGroup.getChildAt(i));
+ }
+ }
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
index afb6954..24f8b74 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
@@ -24,7 +24,6 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
/**
@@ -36,7 +35,7 @@
public class CarNavigationBarView extends LinearLayout {
private View mNavButtons;
private CarNavigationButton mNotificationsButton;
- private CarStatusBar mCarStatusBar;
+ private CarNavigationBarController.NotificationsShadeController mNotificationsShadeController;
private Context mContext;
private View mLockScreenButtons;
// used to wire in open/close gestures for notifications
@@ -82,8 +81,9 @@
return super.onInterceptTouchEvent(ev);
}
- public void setStatusBar(CarStatusBar carStatusBar) {
- mCarStatusBar = carStatusBar;
+ public void setNotificationsPanelController(
+ CarNavigationBarController.NotificationsShadeController controller) {
+ mNotificationsShadeController = controller;
}
/**
@@ -104,7 +104,9 @@
}
protected void onNotificationsClick(View v) {
- mCarStatusBar.togglePanel();
+ if (mNotificationsShadeController != null) {
+ mNotificationsShadeController.togglePanel();
+ }
}
/**
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
index 707d80f..40823ab 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
@@ -85,6 +85,7 @@
super.onFinishInflate();
setScaleType(ImageView.ScaleType.CENTER);
setAlpha(mUnselectedAlpha);
+ setImageResource(mIconResourceId);
try {
if (mIntent != null) {
final Intent intent = Intent.parseUri(mIntent, Intent.URI_INTENT_SCHEME);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 52aaf4f..aebb62d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -76,8 +76,8 @@
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.navigationbar.car.CarFacetButtonController;
+import com.android.systemui.navigationbar.car.CarNavigationBarController;
import com.android.systemui.navigationbar.car.CarNavigationBarView;
-import com.android.systemui.navigationbar.car.NavigationBarViewFactory;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.car.CarQSFragment;
@@ -93,8 +93,6 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.car.hvac.HvacController;
-import com.android.systemui.statusbar.car.hvac.TemperatureView;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NewNotifPipeline;
@@ -174,14 +172,10 @@
private CarNavigationBarView mRightNavigationBarView;
private final Object mQueueLock = new Object();
- private boolean mShowLeft;
- private boolean mShowRight;
- private boolean mShowBottom;
- private final NavigationBarViewFactory mNavigationBarViewFactory;
+ private final CarNavigationBarController mCarNavigationBarController;
private CarFacetButtonController mCarFacetButtonController;
private DeviceProvisionedController mDeviceProvisionedController;
private boolean mDeviceIsSetUpForUser = true;
- private HvacController mHvacController;
private DrivingStateHelper mDrivingStateHelper;
private PowerManagerHelper mPowerManagerHelper;
private FlingAnimationUtils mFlingAnimationUtils;
@@ -309,7 +303,7 @@
DozeScrimController dozeScrimController,
/* Car Settings injected components. */
- NavigationBarViewFactory navigationBarViewFactory) {
+ CarNavigationBarController carNavigationBarController) {
super(
context,
featureFlags,
@@ -375,7 +369,7 @@
powerManager,
dozeScrimController);
mScrimController = scrimController;
- mNavigationBarViewFactory = navigationBarViewFactory;
+ mCarNavigationBarController = carNavigationBarController;
}
@Override
@@ -390,10 +384,6 @@
mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
mScreenLifecycle.addObserver(mScreenObserver);
- // Need to initialize HVAC controller before calling super.start - before system bars are
- // created.
- mHvacController = new HvacController(mContext);
-
super.start();
mNotificationPanel.setScrollingEnabled(true);
@@ -407,8 +397,6 @@
createBatteryController();
mCarBatteryController.startListening();
- mHvacController.connectToCarService();
-
mDeviceProvisionedController.addCallback(
new DeviceProvisionedController.DeviceProvisionedListener() {
@Override
@@ -445,9 +433,6 @@
* before and after the device is provisioned. . Also for change of density and font size.
*/
private void restartNavBars() {
- // remove and reattach all hvac components such that we don't keep a reference to unused
- // ui elements
- mHvacController.removeAllComponents();
mCarFacetButtonController.removeAll();
if (mNavigationBarWindow != null) {
@@ -466,17 +451,6 @@
mCarFacetButtonController.addAllFacetButtons(mStatusBarWindow);
}
- private void addTemperatureViewToController(View v) {
- if (v instanceof TemperatureView) {
- mHvacController.addHvacTextView((TemperatureView) v);
- } else if (v instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) v;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- addTemperatureViewToController(viewGroup.getChildAt(i));
- }
- }
- }
-
/**
* Allows for showing or hiding just the navigation bars. This is indented to be used when
* the full screen user selector is shown.
@@ -897,10 +871,6 @@
@Override
protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
- mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
- mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
- mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
-
buildNavBarWindows();
buildNavBarContent();
}
@@ -908,50 +878,36 @@
private void buildNavBarContent() {
buildTopBar();
- if (mShowBottom) {
- mNavigationBarView = mNavigationBarViewFactory.getBottomBar(mDeviceIsSetUpForUser);
- mNavigationBarView.setStatusBar(this);
- mNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
- }
+ mNavigationBarView = mCarNavigationBarController.getBottomBar(mDeviceIsSetUpForUser);
+ mCarNavigationBarController.registerBottomBarTouchListener(
+ mNavBarNotificationTouchListener);
- if (mShowLeft) {
- mLeftNavigationBarView = mNavigationBarViewFactory.getLeftBar(mDeviceIsSetUpForUser);
- mLeftNavigationBarView.setStatusBar(this);
- mLeftNavigationBarView.setStatusBarWindowTouchListener(
- mNavBarNotificationTouchListener);
- }
+ mLeftNavigationBarView = mCarNavigationBarController.getLeftBar(mDeviceIsSetUpForUser);
+ mCarNavigationBarController.registerLeftBarTouchListener(
+ mNavBarNotificationTouchListener);
- if (mShowRight) {
- mRightNavigationBarView = mNavigationBarViewFactory.getLeftBar(mDeviceIsSetUpForUser);
- mRightNavigationBarView.setStatusBar(this);
- mRightNavigationBarView.setStatusBarWindowTouchListener(
- mNavBarNotificationTouchListener);
- }
+ mRightNavigationBarView = mCarNavigationBarController.getLeftBar(mDeviceIsSetUpForUser);
+ mCarNavigationBarController.registerRightBarTouchListener(
+ mNavBarNotificationTouchListener);
+
+ mCarNavigationBarController.registerNotificationController(() -> togglePanel());
}
private void buildNavBarWindows() {
mTopNavigationBarContainer = mStatusBarWindow
.findViewById(R.id.car_top_navigation_bar_container);
- if (mShowBottom) {
- mNavigationBarWindow = mNavigationBarViewFactory.getBottomWindow();
- }
- if (mShowLeft) {
- mLeftNavigationBarWindow = mNavigationBarViewFactory.getLeftWindow();
- }
- if (mShowRight) {
- mRightNavigationBarWindow = mNavigationBarViewFactory.getRightWindow();
- }
+ mNavigationBarWindow = mCarNavigationBarController.getBottomWindow();
+ mLeftNavigationBarWindow = mCarNavigationBarController.getLeftWindow();
+ mRightNavigationBarWindow = mCarNavigationBarController.getRightWindow();
}
private void buildTopBar() {
mTopNavigationBarContainer.removeAllViews();
- mTopNavigationBarView = mNavigationBarViewFactory.getTopBar(mDeviceIsSetUpForUser);
+ mTopNavigationBarView = mCarNavigationBarController.getTopBar(mDeviceIsSetUpForUser);
+ mCarNavigationBarController.registerTopBarTouchListener(
+ mTopNavBarNotificationTouchListener);
mTopNavigationBarContainer.addView(mTopNavigationBarView);
-
- mTopNavigationBarView.setStatusBar(this);
- addTemperatureViewToController(mTopNavigationBarView);
- mTopNavigationBarView.setStatusBarWindowTouchListener(mTopNavBarNotificationTouchListener);
}
@Override
diff --git a/packages/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS
new file mode 100644
index 0000000..2054129
--- /dev/null
+++ b/packages/SettingsProvider/OWNERS
@@ -0,0 +1,3 @@
+hackbod@google.com
+svetoslavganov@google.com
+moltmann@google.com
diff --git a/packages/SystemUI/res/layout/home_controls.xml b/packages/SystemUI/res/layout/home_controls.xml
index bb971c2..b9a6a48 100644
--- a/packages/SystemUI/res/layout/home_controls.xml
+++ b/packages/SystemUI/res/layout/home_controls.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_controls_layout"
android:layout_width="match_parent"
@@ -8,6 +8,5 @@
android:visibility="gone"
android:padding="8dp"
android:layout_margin="5dp"
- android:background="?android:attr/colorBackgroundFloating"
- android:orientation="vertical">
-</LinearLayout>
+ android:background="?android:attr/colorBackgroundFloating">
+</FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
index af418f6..6949640 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
@@ -33,6 +33,7 @@
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -50,7 +51,6 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.MediaTransferManager;
/**
* Single media player for carousel in QSPanel
@@ -101,6 +101,12 @@
mToken = token;
mController = new MediaController(mContext, token);
MediaMetadata mMediaMetadata = mController.getMetadata();
+
+ if (mMediaMetadata == null) {
+ Log.e(TAG, "Media metadata was null");
+ return;
+ }
+
Notification.Builder builder = Notification.Builder.recoverBuilder(mContext, notif);
// Album art
@@ -151,18 +157,17 @@
// Album name
TextView albumName = headerView.findViewById(com.android.internal.R.id.header_text);
String albumString = mMediaMetadata.getString(MediaMetadata.METADATA_KEY_ALBUM);
- if (!albumString.isEmpty()) {
+ if (TextUtils.isEmpty(albumString)) {
+ albumName.setVisibility(View.GONE);
+ separator.setVisibility(View.GONE);
+ } else {
albumName.setText(albumString);
albumName.setTextColor(iconColor);
albumName.setVisibility(View.VISIBLE);
separator.setVisibility(View.VISIBLE);
- } else {
- albumName.setVisibility(View.GONE);
- separator.setVisibility(View.GONE);
}
// Transfer chip
- MediaTransferManager mediaTransferManager = new MediaTransferManager(mContext);
View transferBackgroundView = headerView.findViewById(
com.android.internal.R.id.media_seamless);
LinearLayout viewLayout = (LinearLayout) transferBackgroundView;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 2060059..b48814b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -166,6 +166,7 @@
mMediaCarousel = new LinearLayout(mContext);
mMediaCarousel.setOrientation(LinearLayout.HORIZONTAL);
mediaScrollView.addView(mMediaCarousel, lpCarousel);
+ mediaScrollView.setVisibility(View.GONE);
} else {
mMediaCarousel = null;
}
@@ -239,6 +240,7 @@
} else {
mMediaCarousel.addView(player.getView(), lp); // add at end
}
+ mMediaPlayers.add(player);
} else if (player.isPlaying()) {
// move it to the front
mMediaCarousel.removeView(player.getView());
@@ -248,7 +250,10 @@
Log.d(TAG, "setting player session");
player.setMediaSession(token, icon, iconColor, bgColor, actionsContainer,
notif.getNotification());
- mMediaPlayers.add(player);
+
+ if (mMediaPlayers.size() > 0) {
+ ((View) mMediaCarousel.getParent()).setVisibility(View.VISIBLE);
+ }
}
protected View getMediaPanel() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
index ae66cd5..3ec71ac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
@@ -84,6 +84,11 @@
mController = new MediaController(mContext, token);
MediaMetadata mMediaMetadata = mController.getMetadata();
+ if (mMediaMetadata == null) {
+ Log.e(TAG, "Media metadata was null");
+ return;
+ }
+
// Album art
addAlbumArtBackground(mMediaMetadata, bgColor);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 1c8e451..9a33c8c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -145,7 +145,7 @@
return mBluetoothTileProvider.get();
case "controls":
if (Settings.System.getInt(mHost.getContext().getContentResolver(),
- "qs_controls_tile_enabled", 0) == 1) {
+ "npv_plugin_flag", 0) == 3) {
return mControlsTileProvider.get();
} else return null;
case "cell":
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java
index 0a59618..39ae66e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java
@@ -22,11 +22,11 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.LinearLayout;
+import android.widget.FrameLayout;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.HomeControlsPlugin;
+import com.android.systemui.plugins.NPVPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -44,7 +44,7 @@
private ControlsDetailAdapter mDetailAdapter;
private final ActivityStarter mActivityStarter;
private PluginManager mPluginManager;
- private HomeControlsPlugin mPlugin;
+ private NPVPlugin mPlugin;
private Intent mHomeAppIntent;
@Inject
@@ -81,7 +81,7 @@
public void setDetailListening(boolean listening) {
if (mPlugin == null) return;
- mPlugin.setVisible(listening);
+ mPlugin.setListening(listening);
}
@Override
@@ -142,7 +142,7 @@
private class ControlsDetailAdapter implements DetailAdapter {
private View mDetailView;
- protected LinearLayout mHomeControlsLayout;
+ protected FrameLayout mHomeControlsLayout;
public CharSequence getTitle() {
return "Controls";
@@ -157,24 +157,30 @@
}
public View createDetailView(Context context, View convertView, final ViewGroup parent) {
- mHomeControlsLayout = (LinearLayout) LayoutInflater.from(context).inflate(
- R.layout.home_controls, parent, false);
+ if (convertView != null) return convertView;
+
+ mHomeControlsLayout = (FrameLayout) LayoutInflater.from(context).inflate(
+ R.layout.home_controls, parent, false);
mHomeControlsLayout.setVisibility(View.VISIBLE);
+ parent.addView(mHomeControlsLayout);
+
mPluginManager.addPluginListener(
- new PluginListener<HomeControlsPlugin>() {
+ new PluginListener<NPVPlugin>() {
@Override
- public void onPluginConnected(HomeControlsPlugin plugin,
+ public void onPluginConnected(NPVPlugin plugin,
Context pluginContext) {
mPlugin = plugin;
- mPlugin.sendParentGroup(mHomeControlsLayout);
- mPlugin.setVisible(true);
+ mPlugin.attachToRoot(mHomeControlsLayout);
+ mPlugin.setListening(true);
}
@Override
- public void onPluginDisconnected(HomeControlsPlugin plugin) {
+ public void onPluginDisconnected(NPVPlugin plugin) {
+ mPlugin.setListening(false);
+ mHomeControlsLayout.removeAllViews();
}
- }, HomeControlsPlugin.class, false);
+ }, NPVPlugin.class, false);
return mHomeControlsLayout;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index f284f73..53fbe5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
@@ -155,7 +156,8 @@
focusedStack.configuration.windowConfiguration
.getWindowingMode();
if (windowingMode == WINDOWING_MODE_FULLSCREEN
- || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
+ || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+ || windowingMode == WINDOWING_MODE_FREEFORM) {
checkAndPostForStack(focusedStack, notifs, noMan, pm);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index bd3d848..ffcbc40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -47,10 +47,12 @@
import java.lang.annotation.RetentionPolicy;
import javax.inject.Inject;
+import javax.inject.Singleton;
/**
* Controller which coordinates all the biometric unlocking actions with the UI.
*/
+@Singleton
public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
private static final String TAG = "BiometricUnlockCtrl";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index dd200da..7f31f3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -77,9 +77,12 @@
ExpandableView child = mCallback.getChildAtRawPosition(x, y);
mTouchingHeadsUpView = false;
if (child instanceof ExpandableNotificationRow) {
- mPickedChild = (ExpandableNotificationRow) child;
+ ExpandableNotificationRow pickedChild = (ExpandableNotificationRow) child;
mTouchingHeadsUpView = !mCallback.isExpanded()
- && mPickedChild.isHeadsUp() && mPickedChild.isPinned();
+ && pickedChild.isHeadsUp() && pickedChild.isPinned();
+ if (mTouchingHeadsUpView) {
+ mPickedChild = pickedChild;
+ }
} else if (child == null && !mCallback.isExpanded()) {
// We might touch above the visible heads up child, but then we still would
// like to capture it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 30fe68a..e00cfb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -55,7 +55,6 @@
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
-import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -243,7 +242,7 @@
private View mQsNavbarScrim;
protected NotificationsQuickSettingsContainer mNotificationContainerParent;
protected NotificationStackScrollLayout mNotificationStackScroller;
- protected LinearLayout mHomeControlsLayout;
+ protected FrameLayout mHomeControlsLayout;
private boolean mAnimateNextPositionUpdate;
private int mTrackingPointer;
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
similarity index 91%
rename from core/java/android/app/usage/UsageStatsManagerInternal.java
rename to services/core/java/android/app/usage/UsageStatsManagerInternal.java
index 024afe2..6641b5b 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -23,6 +23,8 @@
import android.os.UserHandle;
import android.os.UserManager;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
+
import java.util.List;
import java.util.Set;
@@ -153,35 +155,6 @@
*/
public abstract int[] getIdleUidsForUser(@UserIdInt int userId);
- /**
- * Sets up a listener for changes to packages being accessed.
- * @param listener A listener within the system process.
- */
- public abstract void addAppIdleStateChangeListener(
- AppIdleStateChangeListener listener);
-
- /**
- * Removes a listener that was previously added for package usage state changes.
- * @param listener The listener within the system process to remove.
- */
- public abstract void removeAppIdleStateChangeListener(
- AppIdleStateChangeListener listener);
-
- public static abstract class AppIdleStateChangeListener {
-
- /** Callback to inform listeners that the idle state has changed to a new bucket. */
- public abstract void onAppIdleStateChanged(String packageName, @UserIdInt int userId,
- boolean idle, int bucket, int reason);
-
- /**
- * Optional callback to inform the listener that the app has transitioned into
- * an active state due to user interaction.
- */
- public void onUserInteractionStarted(String packageName, @UserIdInt int userId) {
- // No-op by default
- }
- }
-
/** Backup/Restore API */
public abstract byte[] getBackupPayload(@UserIdInt int userId, String key);
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index b41e95f..ff0044f 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -99,6 +99,8 @@
import com.android.internal.util.LocalLog;
import com.android.internal.util.StatLogger;
import com.android.server.AppStateTracker.Listener;
+import com.android.server.usage.AppStandbyInternal;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
@@ -1599,7 +1601,9 @@
LocalServices.getService(DeviceIdleInternal.class);
mUsageStatsManagerInternal =
LocalServices.getService(UsageStatsManagerInternal.class);
- mUsageStatsManagerInternal.addAppIdleStateChangeListener(new AppStandbyTracker());
+ AppStandbyInternal appStandbyInternal =
+ LocalServices.getService(AppStandbyInternal.class);
+ appStandbyInternal.addListener(new AppStandbyTracker());
mAppStateTracker = LocalServices.getService(AppStateTracker.class);
mAppStateTracker.addListener(mForceAppStandbyListener);
@@ -4468,7 +4472,7 @@
* Tracking of app assignments to standby buckets
*/
private final class AppStandbyTracker extends
- UsageStatsManagerInternal.AppIdleStateChangeListener {
+ AppIdleStateChangeListener {
@Override
public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId,
boolean idle, int bucket, int reason) {
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index da760b6..5eff2c5 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -24,7 +24,6 @@
import android.app.IUidObserver;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -58,6 +57,8 @@
import com.android.internal.util.StatLogger;
import com.android.server.AppStateTrackerProto.ExemptedPackage;
import com.android.server.AppStateTrackerProto.RunAnyInBackgroundRestrictedPackages;
+import com.android.server.usage.AppStandbyInternal;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -89,7 +90,7 @@
IAppOpsService mAppOpsService;
PowerManagerInternal mPowerManagerInternal;
StandbyTracker mStandbyTracker;
- UsageStatsManagerInternal mUsageStatsManagerInternal;
+ AppStandbyInternal mAppStandbyInternal;
private final MyHandler mHandler;
@@ -420,8 +421,7 @@
mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
- mUsageStatsManagerInternal = Preconditions.checkNotNull(
- injectUsageStatsManagerInternal());
+ mAppStandbyInternal = Preconditions.checkNotNull(injectAppStandbyInternal());
mFlagsObserver = new FeatureFlagsObserver();
mFlagsObserver.register();
@@ -429,7 +429,7 @@
mForceAllAppStandbyForSmallBattery =
mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
mStandbyTracker = new StandbyTracker();
- mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
+ mAppStandbyInternal.addListener(mStandbyTracker);
try {
mIActivityManager.registerUidObserver(new UidObserver(),
@@ -494,8 +494,8 @@
}
@VisibleForTesting
- UsageStatsManagerInternal injectUsageStatsManagerInternal() {
- return LocalServices.getService(UsageStatsManagerInternal.class);
+ AppStandbyInternal injectAppStandbyInternal() {
+ return LocalServices.getService(AppStandbyInternal.class);
}
@VisibleForTesting
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/services/core/java/com/android/server/backup/SystemBackupAgent.java
similarity index 100%
rename from core/java/com/android/server/backup/SystemBackupAgent.java
rename to services/core/java/com/android/server/backup/SystemBackupAgent.java
diff --git a/core/java/com/android/server/backup/UsageStatsBackupHelper.java b/services/core/java/com/android/server/backup/UsageStatsBackupHelper.java
similarity index 100%
rename from core/java/com/android/server/backup/UsageStatsBackupHelper.java
rename to services/core/java/com/android/server/backup/UsageStatsBackupHelper.java
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 09be474..3b14d50 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -229,6 +229,8 @@
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
+import com.android.server.usage.AppStandbyInternal;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import libcore.io.IoUtils;
@@ -396,6 +398,7 @@
private NetworkStatsManagerInternal mNetworkStats;
private final INetworkManagementService mNetworkManager;
private UsageStatsManagerInternal mUsageStats;
+ private AppStandbyInternal mAppStandby;
private final Clock mClock;
private final UserManager mUserManager;
private final CarrierConfigManager mCarrierConfigManager;
@@ -734,6 +737,7 @@
}
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
+ mAppStandby = LocalServices.getService(AppStandbyInternal.class);
mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
synchronized (mUidRulesFirstLock) {
@@ -868,7 +872,7 @@
mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
new NetworkRequest.Builder().build(), mNetworkCallback);
- mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
+ mAppStandby.addListener(new NetPolicyAppIdleStateChangeListener());
// Listen for subscriber changes
mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
@@ -4375,9 +4379,7 @@
return newUidRules;
}
- private class AppIdleStateChangeListener
- extends UsageStatsManagerInternal.AppIdleStateChangeListener {
-
+ private class NetPolicyAppIdleStateChangeListener extends AppIdleStateChangeListener {
@Override
public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
int reason) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cd3343b..0fc1718 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -7826,6 +7826,7 @@
R.array.config_allowedManagedServicesOnLowRamDevices)) {
if (whitelisted.equals(pkg)) {
canUseManagedServices = true;
+ break;
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 7b7b8e6..9e7b805 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -85,6 +85,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.annotations.GuardedBy;
+import com.android.server.usage.AppStandbyInternal;
import org.junit.After;
import org.junit.Before;
@@ -108,7 +109,7 @@
private long mAppStandbyWindow;
private AlarmManagerService mService;
- private UsageStatsManagerInternal.AppIdleStateChangeListener mAppStandbyListener;
+ private AppStandbyInternal.AppIdleStateChangeListener mAppStandbyListener;
private AlarmManagerService.ChargingReceiver mChargingReceiver;
@Mock
private ContentResolver mMockResolver;
@@ -119,6 +120,8 @@
@Mock
private UsageStatsManagerInternal mUsageStatsManagerInternal;
@Mock
+ private AppStandbyInternal mAppStandbyInternal;
+ @Mock
private AppStateTracker mAppStateTracker;
@Mock
private AlarmManagerService.ClockReceiver mClockReceiver;
@@ -257,6 +260,8 @@
doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class));
doReturn(null)
.when(() -> LocalServices.getService(DeviceIdleInternal.class));
+ doReturn(mAppStandbyInternal).when(
+ () -> LocalServices.getService(AppStandbyInternal.class));
doReturn(mUsageStatsManagerInternal).when(
() -> LocalServices.getService(UsageStatsManagerInternal.class));
when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE),
@@ -289,9 +294,9 @@
assertEquals(0, mService.mConstants.MIN_FUTURITY);
assertEquals(0, mService.mConstants.MIN_INTERVAL);
mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW;
- ArgumentCaptor<UsageStatsManagerInternal.AppIdleStateChangeListener> captor =
- ArgumentCaptor.forClass(UsageStatsManagerInternal.AppIdleStateChangeListener.class);
- verify(mUsageStatsManagerInternal).addAppIdleStateChangeListener(captor.capture());
+ ArgumentCaptor<AppStandbyInternal.AppIdleStateChangeListener> captor =
+ ArgumentCaptor.forClass(AppStandbyInternal.AppIdleStateChangeListener.class);
+ verify(mAppStandbyInternal).addListener(captor.capture());
mAppStandbyListener = captor.getValue();
ArgumentCaptor<AlarmManagerService.ChargingReceiver> chargingReceiverCaptor =
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 80d1129..1f4656a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -45,7 +45,6 @@
import android.app.IUidObserver;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -70,6 +69,8 @@
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.server.AppStateTracker.Listener;
+import com.android.server.usage.AppStandbyInternal;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import org.junit.Before;
import org.junit.Test;
@@ -128,8 +129,8 @@
}
@Override
- UsageStatsManagerInternal injectUsageStatsManagerInternal() {
- return mMockUsageStatsManagerInternal;
+ AppStandbyInternal injectAppStandbyInternal() {
+ return mMockAppStandbyInternal;
}
@Override
@@ -175,7 +176,7 @@
private PowerManagerInternal mMockPowerManagerInternal;
@Mock
- private UsageStatsManagerInternal mMockUsageStatsManagerInternal;
+ private AppStandbyInternal mMockAppStandbyInternal;
private MockContentResolver mMockContentResolver;
@@ -271,7 +272,7 @@
verify(mMockContext).registerReceiver(
receiverCaptor.capture(), any(IntentFilter.class));
- verify(mMockUsageStatsManagerInternal).addAppIdleStateChangeListener(
+ verify(mMockAppStandbyInternal).addListener(
appIdleStateChangeListenerCaptor.capture());
mIUidObserver = uidObserverArgumentCaptor.getValue();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 5d03e151..6a80568 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -86,6 +86,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -180,8 +181,8 @@
}
}
- private UsageStatsManagerInternal.AppIdleStateChangeListener mStandbyChangeListener =
- new UsageStatsManagerInternal.AppIdleStateChangeListener() {
+ private AppIdleStateChangeListener mStandbyChangeListener =
+ new AppIdleStateChangeListener() {
@Override
public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
int bucket, int reason) {
@@ -253,6 +254,7 @@
null, mHandler);
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
+ publishLocalService(AppStandbyInternal.class, mAppStandby);
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
@@ -2029,17 +2031,6 @@
}
@Override
- public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) {
- mAppStandby.addListener(listener);
- }
-
- @Override
- public void removeAppIdleStateChangeListener(
- AppIdleStateChangeListener listener) {
- mAppStandby.removeListener(listener);
- }
-
- @Override
public byte[] getBackupPayload(int user, String key) {
synchronized (mLock) {
if (!mUserUnlockedStates.get(user)) {
diff --git a/services/usb/java/com/android/server/usb/UsbPermissionManager.java b/services/usb/java/com/android/server/usb/UsbPermissionManager.java
index ef9ee73..1e46f98 100644
--- a/services/usb/java/com/android/server/usb/UsbPermissionManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPermissionManager.java
@@ -20,14 +20,20 @@
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.UserInfo;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.UserHandle;
+import android.os.UserManager;
+import android.service.usb.UsbSettingsManagerProto;
import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.dump.DualDumpOutputStream;
+
+import java.util.List;
class UsbPermissionManager {
private static final String LOG_TAG = UsbPermissionManager.class.getSimpleName();
@@ -112,4 +118,18 @@
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
+ void dump(@NonNull DualDumpOutputStream dump, String idName, long id) {
+ long token = dump.start(idName, id);
+ UserManager userManager = mContext.getSystemService(UserManager.class);
+ synchronized (mPermissionsByUser) {
+ List<UserInfo> users = userManager.getUsers();
+ int numUsers = users.size();
+ for (int i = 0; i < numUsers; i++) {
+ getPermissionsForUser(users.get(i).id).dump(dump, "user_permissions",
+ UsbSettingsManagerProto.USER_SETTINGS);
+ }
+ }
+ dump.end(token);
+ }
+
}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index ce6f592..0493637 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -740,6 +740,8 @@
mSettingsManager.dump(dump, "settings_manager",
UsbServiceDumpProto.SETTINGS_MANAGER);
+ mPermissionManager.dump(dump, "permissions_manager",
+ UsbServiceDumpProto.PERMISSIONS_MANAGER);
dump.flush();
} else if ("set-port-roles".equals(args[0]) && args.length == 4) {
final String portId = args[1];
diff --git a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
index 0cb64a3..e700f19 100644
--- a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
+++ b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
@@ -36,9 +36,12 @@
import android.os.Environment;
import android.os.Process;
import android.os.UserHandle;
-import android.service.usb.UsbSettingsAccessoryPermissionProto;
-import android.service.usb.UsbSettingsDevicePermissionProto;
-import android.service.usb.UsbUserSettingsManagerProto;
+import android.service.usb.UsbAccessoryPermissionProto;
+import android.service.usb.UsbAccessoryPersistentPermissionProto;
+import android.service.usb.UsbDevicePermissionProto;
+import android.service.usb.UsbDevicePersistentPermissionProto;
+import android.service.usb.UsbUidPermissionProto;
+import android.service.usb.UsbUserPermissionsManagerProto;
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.Slog;
@@ -261,7 +264,7 @@
}
if (isChanged) {
- scheduleWritePermissionLocked();
+ scheduleWritePermissionsLocked();
}
}
}
@@ -288,7 +291,7 @@
}
if (isChanged) {
- scheduleWritePermissionLocked();
+ scheduleWritePermissionsLocked();
}
}
}
@@ -370,7 +373,7 @@
}
@GuardedBy("mLock")
- private void scheduleWritePermissionLocked() {
+ private void scheduleWritePermissionsLocked() {
if (mIsCopyPermissionsScheduled) {
return;
}
@@ -393,15 +396,18 @@
devices = new DeviceFilter[numDevices];
uidsForDevices = new int[numDevices][];
grantedValuesForDevices = new boolean[numDevices][];
- for (int i = 0; i < numDevices; i++) {
- devices[i] = new DeviceFilter(mDevicePersistentPermissionMap.keyAt(i));
- SparseBooleanArray permissions = mDevicePersistentPermissionMap.valueAt(i);
+ for (int deviceIdx = 0; deviceIdx < numDevices; deviceIdx++) {
+ devices[deviceIdx] =
+ new DeviceFilter(mDevicePersistentPermissionMap.keyAt(deviceIdx));
+ SparseBooleanArray permissions =
+ mDevicePersistentPermissionMap.valueAt(deviceIdx);
int numPermissions = permissions.size();
- uidsForDevices[i] = new int[numPermissions];
- grantedValuesForDevices[i] = new boolean[numPermissions];
- for (int j = 0; j < numPermissions; j++) {
- uidsForDevices[i][j] = permissions.keyAt(j);
- grantedValuesForDevices[i][j] = permissions.valueAt(j);
+ uidsForDevices[deviceIdx] = new int[numPermissions];
+ grantedValuesForDevices[deviceIdx] = new boolean[numPermissions];
+ for (int permissionIdx = 0; permissionIdx < numPermissions; permissionIdx++) {
+ uidsForDevices[deviceIdx][permissionIdx] = permissions.keyAt(permissionIdx);
+ grantedValuesForDevices[deviceIdx][permissionIdx] =
+ permissions.valueAt(permissionIdx);
}
}
@@ -409,16 +415,19 @@
accessories = new AccessoryFilter[numAccessories];
uidsForAccessories = new int[numAccessories][];
grantedValuesForAccessories = new boolean[numAccessories][];
- for (int i = 0; i < numAccessories; i++) {
- accessories[i] =
- new AccessoryFilter(mAccessoryPersistentPermissionMap.keyAt(i));
- SparseBooleanArray permissions = mAccessoryPersistentPermissionMap.valueAt(i);
+ for (int accessoryIdx = 0; accessoryIdx < numAccessories; accessoryIdx++) {
+ accessories[accessoryIdx] = new AccessoryFilter(
+ mAccessoryPersistentPermissionMap.keyAt(accessoryIdx));
+ SparseBooleanArray permissions =
+ mAccessoryPersistentPermissionMap.valueAt(accessoryIdx);
int numPermissions = permissions.size();
- uidsForAccessories[i] = new int[numPermissions];
- grantedValuesForAccessories[i] = new boolean[numPermissions];
- for (int j = 0; j < numPermissions; j++) {
- uidsForAccessories[i][j] = permissions.keyAt(j);
- grantedValuesForAccessories[i][j] = permissions.valueAt(j);
+ uidsForAccessories[accessoryIdx] = new int[numPermissions];
+ grantedValuesForAccessories[accessoryIdx] = new boolean[numPermissions];
+ for (int permissionIdx = 0; permissionIdx < numPermissions; permissionIdx++) {
+ uidsForAccessories[accessoryIdx][permissionIdx] =
+ permissions.keyAt(permissionIdx);
+ grantedValuesForAccessories[accessoryIdx][permissionIdx] =
+ permissions.valueAt(permissionIdx);
}
}
mIsCopyPermissionsScheduled = false;
@@ -477,22 +486,22 @@
* Creates UI dialog to request permission for the given package to access the device
* or accessory.
*
- * @param device The USB device attached
- * @param accessory The USB accessory attached
+ * @param device The USB device attached
+ * @param accessory The USB accessory attached
* @param canBeDefault Whether the calling pacakge can set as default handler
- * of the USB device or accessory
- * @param packageName The package name of the calling package
- * @param uid The uid of the calling package
- * @param userContext The context to start the UI dialog
- * @param pi PendingIntent for returning result
+ * of the USB device or accessory
+ * @param packageName The package name of the calling package
+ * @param uid The uid of the calling package
+ * @param userContext The context to start the UI dialog
+ * @param pi PendingIntent for returning result
*/
void requestPermissionDialog(@Nullable UsbDevice device,
- @Nullable UsbAccessory accessory,
- boolean canBeDefault,
- @NonNull String packageName,
- int uid,
- @NonNull Context userContext,
- @NonNull PendingIntent pi) {
+ @Nullable UsbAccessory accessory,
+ boolean canBeDefault,
+ @NonNull String packageName,
+ int uid,
+ @NonNull Context userContext,
+ @NonNull PendingIntent pi) {
long identity = Binder.clearCallingIdentity();
Intent intent = new Intent();
if (device != null) {
@@ -517,48 +526,96 @@
}
}
- void dump(@NonNull DualDumpOutputStream dump) {
+ void dump(@NonNull DualDumpOutputStream dump, String idName, long id) {
+ long token = dump.start(idName, id);
synchronized (mLock) {
- for (String deviceName : mDevicePermissionMap.keySet()) {
+ dump.write("user_id", UsbUserPermissionsManagerProto.USER_ID, mUser.getIdentifier());
+ int numMappings = mDevicePermissionMap.size();
+ for (int mappingsIdx = 0; mappingsIdx < numMappings; mappingsIdx++) {
+ String deviceName = mDevicePermissionMap.keyAt(mappingsIdx);
long devicePermissionToken = dump.start("device_permissions",
- UsbUserSettingsManagerProto.DEVICE_PERMISSIONS);
+ UsbUserPermissionsManagerProto.DEVICE_PERMISSIONS);
- dump.write("device_name", UsbSettingsDevicePermissionProto.DEVICE_NAME, deviceName);
+ dump.write("device_name", UsbDevicePermissionProto.DEVICE_NAME, deviceName);
- SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
- int count = uidList.size();
- for (int i = 0; i < count; i++) {
- dump.write("uids", UsbSettingsDevicePermissionProto.UIDS, uidList.keyAt(i));
+ SparseBooleanArray uidList = mDevicePermissionMap.valueAt(mappingsIdx);
+ int numUids = uidList.size();
+ for (int uidsIdx = 0; uidsIdx < numUids; uidsIdx++) {
+ dump.write("uids", UsbDevicePermissionProto.UIDS, uidList.keyAt(uidsIdx));
}
dump.end(devicePermissionToken);
}
- for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) {
+ numMappings = mAccessoryPermissionMap.size();
+ for (int mappingsIdx = 0; mappingsIdx < numMappings; ++mappingsIdx) {
+ UsbAccessory accessory = mAccessoryPermissionMap.keyAt(mappingsIdx);
long accessoryPermissionToken = dump.start("accessory_permissions",
- UsbUserSettingsManagerProto.ACCESSORY_PERMISSIONS);
+ UsbUserPermissionsManagerProto.ACCESSORY_PERMISSIONS);
dump.write("accessory_description",
- UsbSettingsAccessoryPermissionProto.ACCESSORY_DESCRIPTION,
+ UsbAccessoryPermissionProto.ACCESSORY_DESCRIPTION,
accessory.getDescription());
- SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
- int count = uidList.size();
- for (int i = 0; i < count; i++) {
- dump.write("uids", UsbSettingsAccessoryPermissionProto.UIDS, uidList.keyAt(i));
+ SparseBooleanArray uidList = mAccessoryPermissionMap.valueAt(mappingsIdx);
+ int numUids = uidList.size();
+ for (int uidsIdx = 0; uidsIdx < numUids; uidsIdx++) {
+ dump.write("uids", UsbAccessoryPermissionProto.UIDS, uidList.keyAt(uidsIdx));
}
dump.end(accessoryPermissionToken);
}
+
+ numMappings = mDevicePersistentPermissionMap.size();
+ for (int mappingsIdx = 0; mappingsIdx < numMappings; mappingsIdx++) {
+ DeviceFilter filter = mDevicePersistentPermissionMap.keyAt(mappingsIdx);
+ long devicePermissionToken = dump.start("device_persistent_permissions",
+ UsbUserPermissionsManagerProto.DEVICE_PERSISTENT_PERMISSIONS);
+ filter.dump(dump, "device",
+ UsbDevicePersistentPermissionProto.DEVICE_FILTER);
+ SparseBooleanArray permissions =
+ mDevicePersistentPermissionMap.valueAt(mappingsIdx);
+ int numPermissions = permissions.size();
+ for (int permissionsIdx = 0; permissionsIdx < numPermissions; permissionsIdx++) {
+ long uidPermissionToken = dump.start("uid_permission",
+ UsbDevicePersistentPermissionProto.PERMISSION_VALUES);
+ dump.write("uid", UsbUidPermissionProto.UID, permissions.keyAt(permissionsIdx));
+ dump.write("is_granted",
+ UsbUidPermissionProto.IS_GRANTED, permissions.valueAt(permissionsIdx));
+ dump.end(uidPermissionToken);
+ }
+ dump.end(devicePermissionToken);
+ }
+
+ numMappings = mAccessoryPersistentPermissionMap.size();
+ for (int mappingsIdx = 0; mappingsIdx < numMappings; mappingsIdx++) {
+ AccessoryFilter filter = mAccessoryPersistentPermissionMap.keyAt(mappingsIdx);
+ long accessoryPermissionToken = dump.start("accessory_persistent_permissions",
+ UsbUserPermissionsManagerProto.ACCESSORY_PERSISTENT_PERMISSIONS);
+ filter.dump(dump, "accessory",
+ UsbAccessoryPersistentPermissionProto.ACCESSORY_FILTER);
+ SparseBooleanArray permissions =
+ mAccessoryPersistentPermissionMap.valueAt(mappingsIdx);
+ int numPermissions = permissions.size();
+ for (int permissionsIdx = 0; permissionsIdx < numPermissions; permissionsIdx++) {
+ long uidPermissionToken = dump.start("uid_permission",
+ UsbAccessoryPersistentPermissionProto.PERMISSION_VALUES);
+ dump.write("uid", UsbUidPermissionProto.UID, permissions.keyAt(permissionsIdx));
+ dump.write("is_granted",
+ UsbUidPermissionProto.IS_GRANTED, permissions.valueAt(permissionsIdx));
+ dump.end(uidPermissionToken);
+ }
+ dump.end(accessoryPermissionToken);
+ }
}
+ dump.end(token);
}
/**
* Check for camera permission of the calling process.
*
* @param packageName Package name of the caller.
- * @param uid Linux uid of the calling process.
- *
+ * @param uid Linux uid of the calling process.
* @return True in case camera permission is available, False otherwise.
*/
private boolean isCameraPermissionGranted(String packageName, int uid) {
@@ -677,7 +734,7 @@
*
* @param device The device that needs to get scanned
* @return True in case a VIDEO device or interface is present,
- * False otherwise.
+ * False otherwise.
*/
private boolean isCameraDevicePresent(UsbDevice device) {
if (device.getDeviceClass() == UsbConstants.USB_CLASS_VIDEO) {
diff --git a/tests/Compatibility/Android.bp b/tests/Compatibility/Android.bp
index 4ca406e..7dc44fa 100644
--- a/tests/Compatibility/Android.bp
+++ b/tests/Compatibility/Android.bp
@@ -19,4 +19,7 @@
srcs: ["src/**/*.java"],
platform_apis: true,
certificate: "platform",
+ test_suites: [
+ "csuite"
+ ],
}
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 4ce4406..c08f9b0 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -95,7 +95,7 @@
],
}
-cc_library_shared {
+cc_library {
name: "libstatslog",
host_supported: true,
generated_sources: ["statslog.cpp"],
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 1337739..19be132 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -94,6 +94,8 @@
boolean disableNetwork(int netId, String packageName);
+ void allowAutojoin(int netId, boolean choice);
+
boolean startScan(String packageName);
List<ScanResult> getScanResults(String callingPackage);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 2afb14a..3bedddc 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -735,6 +735,14 @@
*/
public int userApproved = USER_UNSPECIFIED;
+ /**
+ * @hide
+ * Auto-join is allowed by user for this network.
+ * Default true.
+ */
+ @SystemApi
+ public boolean allowAutojoin = true;
+
/** The Below RSSI thresholds are used to configure AutoJoin
* - GOOD/LOW/BAD thresholds are used so as to calculate link score
* - UNWANTED_SOFT are used by the blacklisting logic so as to handle
@@ -2022,6 +2030,7 @@
if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier);
sbuf.append(" lcuid=" + lastConnectUid);
sbuf.append(" userApproved=" + userApprovedAsString(userApproved));
+ sbuf.append(" allowAutojoin=" + allowAutojoin);
sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected);
sbuf.append(" ");
@@ -2421,6 +2430,7 @@
numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
numAssociation = source.numAssociation;
userApproved = source.userApproved;
+ allowAutojoin = source.allowAutojoin;
numNoInternetAccessReports = source.numNoInternetAccessReports;
noInternetAccessExpected = source.noInternetAccessExpected;
creationTime = source.creationTime;
@@ -2496,6 +2506,7 @@
dest.writeInt(numScorerOverrideAndSwitchedNetwork);
dest.writeInt(numAssociation);
dest.writeInt(userApproved);
+ dest.writeBoolean(allowAutojoin);
dest.writeInt(numNoInternetAccessReports);
dest.writeInt(noInternetAccessExpected ? 1 : 0);
dest.writeInt(shared ? 1 : 0);
@@ -2571,6 +2582,7 @@
config.numScorerOverrideAndSwitchedNetwork = in.readInt();
config.numAssociation = in.readInt();
config.userApproved = in.readInt();
+ config.allowAutojoin = in.readBoolean();
config.numNoInternetAccessReports = in.readInt();
config.noInternetAccessExpected = in.readInt() != 0;
config.shared = in.readInt() != 0;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 11c2131..f626b0c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -3869,6 +3869,29 @@
}
/**
+ * Sets the user choice for allowing auto-join to a network.
+ * The updated choice will be made available through the updated config supplied by the
+ * CONFIGURED_NETWORKS_CHANGED broadcast.
+ *
+ * @param netId the id of the network to allow/disallow autojoin for.
+ * @param choice true to allow autojoin, false to disallow autojoin
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void allowAutojoin(int netId, boolean choice) {
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.allowAutojoin(netId, choice);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Disable ephemeral Network
*
* @param SSID, in the format of WifiConfiguration's SSID.
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 94fb5ae..5e6c107 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -168,6 +168,11 @@
}
@Override
+ public void allowAutojoin(int netId, boolean choice) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public boolean startScan(String packageName) {
throw new UnsupportedOperationException();
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index f8a0c8f..881dcbb 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -1489,6 +1489,16 @@
}
/**
+ * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)}
+ * @throws Exception
+ */
+ @Test
+ public void testAllowAutojoin() throws Exception {
+ mWifiManager.allowAutojoin(1, true);
+ verify(mWifiService).allowAutojoin(eq(1), eq(true));
+ }
+
+ /**
* Test behavior of {@link WifiManager#disconnect()}
* @throws Exception
*/