Merge changes from topic "fix_attributes_match"
* changes:
fix AudioAttributes matching rule in AudioProductStrategy
Revert "Revert "Mute haptic channels by default.""
diff --git a/api/current.txt b/api/current.txt
index f78dfde..9776a11 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11607,7 +11607,7 @@
method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(@NonNull android.content.Intent, int);
method @NonNull public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(@Nullable String, int, int);
method @NonNull public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(@NonNull String, int);
- method @Nullable public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(@NonNull android.content.Intent, int);
+ method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(@NonNull android.content.Intent, int);
method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], @NonNull android.content.Intent, int);
method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(@NonNull android.content.Intent, int);
method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(@NonNull android.content.Intent, int);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index dc4413f..cbb78bf 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -1406,7 +1406,7 @@
// Currently is last two bytes of a hash of a device level ID and
// the mac address of the bluetooth device that is connected.
// Deprecated: use obfuscated_id instead, this one is always 0 for Q+
- optional int32 OBSOLETE_obfuscated_id = 2 [deprecated = true];
+ optional int32 obfuscated_id = 2 [deprecated = true];
// The profile that is connected. Eg. GATT, A2DP, HEADSET.
// From android.bluetooth.BluetoothAdapter.java
// Default: 0 when not used
@@ -1417,7 +1417,7 @@
// Hash algorithm: HMAC-SHA256
// Size: 32 byte
// Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 4 [(android.os.statsd.log_mode) = MODE_BYTES];
+ optional bytes new_obfuscated_id = 4 [(android.os.statsd.log_mode) = MODE_BYTES];
}
/**
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index faa30f3..2e59b90 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -145,8 +145,7 @@
*/
public void createAndCacheNonBootclasspathSystemClassLoaders(SharedLibraryInfo[] libs) {
if (mSystemLibsCacheMap != null) {
- Log.wtf(TAG, "Already cached.");
- return;
+ throw new IllegalStateException("Already cached.");
}
mSystemLibsCacheMap = new HashMap<String, CachedClassLoader>();
@@ -159,7 +158,8 @@
/**
* Caches a single non-bootclasspath class loader.
*
- * All of this library's dependencies must have previously been cached.
+ * All of this library's dependencies must have previously been cached. Otherwise, an exception
+ * is thrown.
*/
private void createAndCacheNonBootclasspathSystemClassLoader(SharedLibraryInfo lib) {
String path = lib.getPath();
@@ -174,9 +174,8 @@
CachedClassLoader cached = mSystemLibsCacheMap.get(dependencyPath);
if (cached == null) {
- Log.e(TAG, "Failed to find dependency " + dependencyPath
- + " of cached library " + path);
- return;
+ throw new IllegalStateException("Failed to find dependency " + dependencyPath
+ + " of cachedlibrary " + path);
}
sharedLibraries.add(cached.loader);
@@ -189,8 +188,8 @@
null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/);
if (classLoader == null) {
- Log.e(TAG, "Failed to cache " + path);
- return;
+ // bad configuration or break in classloading code
+ throw new IllegalStateException("Failed to cache " + path);
}
CachedClassLoader cached = new CachedClassLoader();
@@ -215,7 +214,7 @@
*
* If there is an error or the cache is not available, this returns null.
*/
- private ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent,
+ public ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent,
String classLoaderName, List<ClassLoader> sharedLibraries) {
if (mSystemLibsCacheMap == null) {
return null;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f0539c49..025d8f9 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4423,7 +4423,7 @@
* {@link #resolveActivity}. If there are no matching activities, an
* empty list is returned.
*/
- @Nullable
+ @NonNull
public abstract List<ResolveInfo> queryIntentActivities(@NonNull Intent intent,
@ResolveInfoFlags int flags);
@@ -4444,7 +4444,7 @@
* empty list is returned.
* @hide
*/
- @Nullable
+ @NonNull
@UnsupportedAppUsage
public abstract List<ResolveInfo> queryIntentActivitiesAsUser(@NonNull Intent intent,
@ResolveInfoFlags int flags, @UserIdInt int userId);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 81abdea0..10fe52a 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -812,7 +812,10 @@
*
* @throws RuntimeException if starting preview fails; usually this would be
* because of a hardware or other low-level error, or because release()
- * has been called on this Camera instance.
+ * has been called on this Camera instance. The QCIF (176x144) exception
+ * mentioned in {@link Parameters#setPreviewSize setPreviewSize} and
+ * {@link Parameters#setPictureSize setPictureSize} can also cause this
+ * exception be thrown.
*/
public native final void startPreview();
@@ -2863,6 +2866,16 @@
* orientation should also be considered while setting picture size and
* thumbnail size.
*
+ * Exception on 176x144 (QCIF) resolution:
+ * Camera devices usually have a fixed capability for downscaling from
+ * larger resolution to smaller, and the QCIF resolution sometimes
+ * is not fully supported due to this limitation on devices with
+ * high-resolution image sensors. Therefore, trying to configure a QCIF
+ * preview size with any picture or video size larger than 1920x1080
+ * (either width or height) might not be supported, and
+ * {@link #setParameters(Camera.Parameters)} might throw a
+ * RuntimeException if it is not.
+ *
* @param width the width of the pictures, in pixels
* @param height the height of the pictures, in pixels
* @see #setDisplayOrientation(int)
@@ -2908,6 +2921,16 @@
* preview can be different from the resolution of the recorded video
* during video recording.</p>
*
+ * <p>Exception on 176x144 (QCIF) resolution:
+ * Camera devices usually have a fixed capability for downscaling from
+ * larger resolution to smaller, and the QCIF resolution sometimes
+ * is not fully supported due to this limitation on devices with
+ * high-resolution image sensors. Therefore, trying to configure a QCIF
+ * video resolution with any preview or picture size larger than
+ * 1920x1080 (either width or height) might not be supported, and
+ * {@link #setParameters(Camera.Parameters)} will throw a
+ * RuntimeException if it is not.</p>
+ *
* @return a list of Size object if camera has separate preview and
* video output; otherwise, null is returned.
* @see #getPreferredPreviewSizeForVideo()
@@ -3202,6 +3225,16 @@
* <p>Applications need to consider the display orientation. See {@link
* #setPreviewSize(int,int)} for reference.</p>
*
+ * <p>Exception on 176x144 (QCIF) resolution:
+ * Camera devices usually have a fixed capability for downscaling from
+ * larger resolution to smaller, and the QCIF resolution sometimes
+ * is not fully supported due to this limitation on devices with
+ * high-resolution image sensors. Therefore, trying to configure a QCIF
+ * picture size with any preview or video size larger than 1920x1080
+ * (either width or height) might not be supported, and
+ * {@link #setParameters(Camera.Parameters)} might throw a
+ * RuntimeException if it is not.</p>
+ *
* @param width the width for pictures, in pixels
* @param height the height for pictures, in pixels
* @see #setPreviewSize(int,int)
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 6a2d8d8..48588e6 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -2396,6 +2396,12 @@
* </table>
* <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} for additional
* mandatory stream configurations on a per-capability basis.</p>
+ * <p>Exception on 176x144 (QCIF) resolution: camera devices usually have a fixed capability for
+ * downscaling from larger resolution to smaller, and the QCIF resolution sometimes is not
+ * fully supported due to this limitation on devices with high-resolution image sensors.
+ * Therefore, trying to configure a QCIF resolution stream together with any other
+ * stream larger than 1920x1080 resolution (either width or height) might not be supported,
+ * and capture session creation will fail if it is not.</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
@@ -2592,6 +2598,12 @@
* ratio 4:3, and the JPEG encoder alignment requirement is 16, the maximum JPEG size will be
* 3264x2448.</li>
* </ul>
+ * <p>Exception on 176x144 (QCIF) resolution: camera devices usually have a fixed capability on
+ * downscaling from larger resolution to smaller ones, and the QCIF resolution can sometimes
+ * not be fully supported due to this limitation on devices with high-resolution image
+ * sensors. Therefore, trying to configure a QCIF resolution stream together with any other
+ * stream larger than 1920x1080 resolution (either width or height) might not be supported,
+ * and capture session creation will fail if it is not.</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
@@ -3580,7 +3592,7 @@
* <li><code>LEVEL_3</code> devices additionally support YUV reprocessing and RAW image capture, along
* with additional output stream configurations.</li>
* <li><code>EXTERNAL</code> devices are similar to <code>LIMITED</code> devices with exceptions like some sensor or
- * lens information not reorted or less stable framerates.</li>
+ * lens information not reported or less stable framerates.</li>
* </ul>
* <p>See the individual level enums for full descriptions of the supported capabilities. The
* {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} entry describes the device's capabilities at a
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 20fc53f..bac6522 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -449,6 +449,14 @@
* by calling {@link #isSessionConfigurationSupported} or attempting to create a session with
* such targets.</p>
*
+ * <p>Exception on 176x144 (QCIF) resolution:
+ * Camera devices usually have a fixed capability for downscaling from larger resolution to
+ * smaller, and the QCIF resolution sometimes is not fully supported due to this
+ * limitation on devices with high-resolution image sensors. Therefore, trying to configure a
+ * QCIF resolution stream together with any other stream larger than 1920x1080 resolution
+ * (either width or height) might not be supported, and capture session creation will fail if it
+ * is not.</p>
+ *
* @param outputs The new set of Surfaces that should be made available as
* targets for captured image data.
* @param callback The callback to notify about the status of the new capture session.
diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java
index 0c07a67..ce71db6 100644
--- a/core/java/android/hardware/display/ColorDisplayManager.java
+++ b/core/java/android/hardware/display/ColorDisplayManager.java
@@ -392,6 +392,26 @@
}
/**
+ * Enables or disables display white balance.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
+ public boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
+ return mManager.setDisplayWhiteBalanceEnabled(enabled);
+ }
+
+ /**
+ * Returns whether display white balance is currently enabled. Even if enabled, it may or may
+ * not be active, if another transform with higher priority is active.
+ *
+ * @hide
+ */
+ public boolean isDisplayWhiteBalanceEnabled() {
+ return mManager.isDisplayWhiteBalanceEnabled();
+ }
+
+ /**
* Returns {@code true} if Night Display is supported by the device.
*
* @hide
@@ -616,6 +636,22 @@
}
}
+ boolean isDisplayWhiteBalanceEnabled() {
+ try {
+ return mCdm.isDisplayWhiteBalanceEnabled();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
+ try {
+ return mCdm.setDisplayWhiteBalanceEnabled(enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
int getColorMode() {
try {
return mCdm.getColorMode();
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
index 88b59a6..7b1033d 100644
--- a/core/java/android/hardware/display/IColorDisplayManager.aidl
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -42,4 +42,7 @@
int getColorMode();
void setColorMode(int colorMode);
+
+ boolean isDisplayWhiteBalanceEnabled();
+ boolean setDisplayWhiteBalanceEnabled(boolean enabled);
}
\ No newline at end of file
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 3e8c334..6035f40 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -45,6 +45,7 @@
import android.util.Slog;
import com.android.internal.R;
+import com.android.internal.os.SomeArgs;
import java.util.List;
@@ -63,6 +64,8 @@
private static final int MSG_AUTHENTICATION_FAILED = 103;
private static final int MSG_ERROR = 104;
private static final int MSG_REMOVED = 105;
+ private static final int MSG_GET_FEATURE_COMPLETED = 106;
+ private static final int MSG_SET_FEATURE_COMPLETED = 107;
private IFaceService mService;
private final Context mContext;
@@ -70,6 +73,8 @@
private AuthenticationCallback mAuthenticationCallback;
private EnrollmentCallback mEnrollmentCallback;
private RemovalCallback mRemovalCallback;
+ private SetFeatureCallback mSetFeatureCallback;
+ private GetFeatureCallback mGetFeatureCallback;
private CryptoObject mCryptoObject;
private Face mRemovalFace;
private Handler mHandler;
@@ -112,6 +117,20 @@
public void onEnumerated(long deviceId, int faceId, int remaining) {
// TODO: Finish. Low priority since it's not used.
}
+
+ @Override
+ public void onFeatureSet(boolean success, int feature) {
+ mHandler.obtainMessage(MSG_SET_FEATURE_COMPLETED, feature, 0, success).sendToTarget();
+ }
+
+ @Override
+ public void onFeatureGet(boolean success, int feature, boolean value) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = success;
+ args.argi1 = feature;
+ args.arg2 = value;
+ mHandler.obtainMessage(MSG_GET_FEATURE_COMPLETED, args).sendToTarget();
+ }
};
/**
@@ -286,31 +305,31 @@
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public boolean setFeature(int feature, boolean enabled, byte[] token) {
+ public void setFeature(int feature, boolean enabled, byte[] token,
+ SetFeatureCallback callback) {
if (mService != null) {
try {
- return mService.setFeature(feature, enabled, token);
+ mSetFeatureCallback = callback;
+ mService.setFeature(feature, enabled, token, mServiceReceiver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- return false;
}
/**
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public boolean getFeature(int feature) {
- boolean result = true;
+ public void getFeature(int feature, GetFeatureCallback callback) {
if (mService != null) {
try {
- result = mService.getFeature(feature);
+ mGetFeatureCallback = callback;
+ mService.getFeature(feature, mServiceReceiver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- return result;
}
/**
@@ -874,6 +893,20 @@
}
}
+ /**
+ * @hide
+ */
+ public abstract static class SetFeatureCallback {
+ public abstract void onCompleted(boolean success, int feature);
+ }
+
+ /**
+ * @hide
+ */
+ public abstract static class GetFeatureCallback {
+ public abstract void onCompleted(boolean success, int feature, boolean value);
+ }
+
private class OnEnrollCancelListener implements OnCancelListener {
@Override
public void onCancel() {
@@ -926,9 +959,36 @@
case MSG_REMOVED:
sendRemovedResult((Face) msg.obj, msg.arg1 /* remaining */);
break;
+ case MSG_SET_FEATURE_COMPLETED:
+ sendSetFeatureCompleted((boolean) msg.obj /* success */,
+ msg.arg1 /* feature */);
+ break;
+ case MSG_GET_FEATURE_COMPLETED:
+ SomeArgs args = (SomeArgs) msg.obj;
+ sendGetFeatureCompleted((boolean) args.arg1 /* success */,
+ args.argi1 /* feature */,
+ (boolean) args.arg2 /* value */);
+ args.recycle();
+ break;
+ default:
+ Log.w(TAG, "Unknown message: " + msg.what);
}
}
- };
+ }
+
+ private void sendSetFeatureCompleted(boolean success, int feature) {
+ if (mSetFeatureCallback == null) {
+ return;
+ }
+ mSetFeatureCallback.onCompleted(success, feature);
+ }
+
+ private void sendGetFeatureCompleted(boolean success, int feature, boolean value) {
+ if (mGetFeatureCallback == null) {
+ return;
+ }
+ mGetFeatureCallback.onCompleted(success, feature, value);
+ }
private void sendRemovedResult(Face face, int remaining) {
if (mRemovalCallback == null) {
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 5043d4c..601be75 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -51,7 +51,7 @@
// Start face enrollment
void enroll(IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
- String opPackageName, in int [] disabledFeatures);
+ String opPackageName, in int [] disabledFeatures);
// Cancel enrollment in progress
void cancelEnrollment(IBinder token);
@@ -98,9 +98,10 @@
// Enumerate all faces
void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver);
- boolean setFeature(int feature, boolean enabled, in byte [] token);
+ void setFeature(int feature, boolean enabled, in byte [] token,
+ IFaceServiceReceiver receiver);
- boolean getFeature(int feature);
+ void getFeature(int feature, IFaceServiceReceiver receiver);
void userActivity();
}
diff --git a/core/java/android/hardware/face/IFaceServiceReceiver.aidl b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
index cec9fd8..2176902 100644
--- a/core/java/android/hardware/face/IFaceServiceReceiver.aidl
+++ b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
@@ -29,4 +29,6 @@
void onError(long deviceId, int error, int vendorCode);
void onRemoved(long deviceId, int faceId, int remaining);
void onEnumerated(long deviceId, int faceId, int remaining);
+ void onFeatureSet(boolean success, int feature);
+ void onFeatureGet(boolean success, int feature, boolean value);
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 00d522b..ecd16dd 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -266,8 +266,11 @@
* - Fixed bug in min learned capacity updating process.
* New in version 34:
* - Deprecated STATS_SINCE_UNPLUGGED and STATS_CURRENT.
+ * New in version 35:
+ * - Fixed bug that was not reporting high cellular tx power correctly
+ * - Added out of service and emergency service modes to data connection types
*/
- static final int CHECKIN_VERSION = 34;
+ static final int CHECKIN_VERSION = 35;
/**
* Old version, we hit 9 and ran out of room, need to remove.
@@ -2371,18 +2374,21 @@
*/
public abstract int getMobileRadioActiveUnknownCount(int which);
- public static final int DATA_CONNECTION_NONE = 0;
- public static final int DATA_CONNECTION_OTHER = TelephonyManager.MAX_NETWORK_TYPE + 1;
+ public static final int DATA_CONNECTION_OUT_OF_SERVICE = 0;
+ public static final int DATA_CONNECTION_EMERGENCY_SERVICE =
+ TelephonyManager.MAX_NETWORK_TYPE + 1;
+ public static final int DATA_CONNECTION_OTHER = DATA_CONNECTION_EMERGENCY_SERVICE + 1;
+
static final String[] DATA_CONNECTION_NAMES = {
- "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
+ "oos", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
"1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
"ehrpd", "hspap", "gsm", "td_scdma", "iwlan", "lte_ca", "nr",
- "other"
+ "emngcy", "other"
};
@UnsupportedAppUsage
- public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
+ public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER + 1;
/**
* Returns the time in microseconds that the phone has been running with
@@ -6564,6 +6570,10 @@
}
oldState = rec.states;
oldState2 = rec.states2;
+ // Clear High Tx Power Flag for volta positioning
+ if ((rec.states2 & HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG) != 0) {
+ rec.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
+ }
}
return item.toString();
@@ -7865,9 +7875,9 @@
// Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA)
for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) {
// Map OTHER to TelephonyManager.NETWORK_TYPE_UNKNOWN and mark NONE as a boolean.
- boolean isNone = (i == DATA_CONNECTION_NONE);
+ boolean isNone = (i == DATA_CONNECTION_OUT_OF_SERVICE);
int telephonyNetworkType = i;
- if (i == DATA_CONNECTION_OTHER) {
+ if (i == DATA_CONNECTION_OTHER || i == DATA_CONNECTION_EMERGENCY_SERVICE) {
telephonyNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
final long pdcToken = proto.start(SystemProto.DATA_CONNECTION);
diff --git a/core/java/android/util/HashedStringCache.java b/core/java/android/util/HashedStringCache.java
new file mode 100644
index 0000000..8ce8514
--- /dev/null
+++ b/core/java/android/util/HashedStringCache.java
@@ -0,0 +1,205 @@
+/*
+ * 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 android.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Environment;
+import android.os.storage.StorageManager;
+import android.text.TextUtils;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * HashedStringCache provides hashing functionality with an underlying LRUCache and expiring salt.
+ * Salt and expiration time are being stored under the tag passed in by the calling package --
+ * intended usage is the calling package name.
+ * TODO: Add unit tests b/129870147
+ * @hide
+ */
+public class HashedStringCache {
+ private static HashedStringCache sHashedStringCache = null;
+ private static final Charset UTF_8 = Charset.forName("UTF-8");
+ private static final int HASH_CACHE_SIZE = 100;
+ private static final int HASH_LENGTH = 8;
+ private static final String HASH_SALT = "_hash_salt";
+ private static final String HASH_SALT_DATE = "_hash_salt_date";
+ private static final String HASH_SALT_GEN = "_hash_salt_gen";
+ // For privacy we need to rotate the salt regularly
+ private static final long DAYS_TO_MILLIS = 1000 * 60 * 60 * 24;
+ private static final int MAX_SALT_DAYS = 100;
+ private final LruCache<String, String> mHashes;
+ private final SecureRandom mSecureRandom;
+ private final Object mPreferenceLock = new Object();
+ private final MessageDigest mDigester;
+ private byte[] mSalt;
+ private int mSaltGen;
+ private SharedPreferences mSharedPreferences;
+
+ private static final String TAG = "HashedStringCache";
+ private static final boolean DEBUG = false;
+
+ private HashedStringCache() {
+ mHashes = new LruCache<>(HASH_CACHE_SIZE);
+ mSecureRandom = new SecureRandom();
+ try {
+ mDigester = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException impossible) {
+ // this can't happen - MD5 is always present
+ throw new RuntimeException(impossible);
+ }
+ }
+
+ /**
+ * @return - instance of the HashedStringCache
+ * @hide
+ */
+ public static HashedStringCache getInstance() {
+ if (sHashedStringCache == null) {
+ sHashedStringCache = new HashedStringCache();
+ }
+ return sHashedStringCache;
+ }
+
+ /**
+ * Take the string and context and create a hash of the string. Trigger refresh on salt if salt
+ * is more than 7 days old
+ * @param context - callers context to retrieve SharedPreferences
+ * @param clearText - string that needs to be hashed
+ * @param tag - class name to use for storing values in shared preferences
+ * @param saltExpirationDays - number of days we may keep the same salt
+ * special value -1 will short-circuit and always return null.
+ * @return - HashResult containing the hashed string and the generation of the hash salt, null
+ * if clearText string is empty
+ *
+ * @hide
+ */
+ public HashResult hashString(Context context, String tag, String clearText,
+ int saltExpirationDays) {
+ if (TextUtils.isEmpty(clearText) || saltExpirationDays == -1) {
+ return null;
+ }
+
+ populateSaltValues(context, tag, saltExpirationDays);
+ String hashText = mHashes.get(clearText);
+ if (hashText != null) {
+ return new HashResult(hashText, mSaltGen);
+ }
+
+ mDigester.reset();
+ mDigester.update(mSalt);
+ mDigester.update(clearText.getBytes(UTF_8));
+ byte[] bytes = mDigester.digest();
+ int len = Math.min(HASH_LENGTH, bytes.length);
+ hashText = Base64.encodeToString(bytes, 0, len, Base64.NO_PADDING | Base64.NO_WRAP);
+ mHashes.put(clearText, hashText);
+
+ return new HashResult(hashText, mSaltGen);
+ }
+
+ /**
+ * Populates the mSharedPreferences and checks if there is a salt present and if it's older than
+ * 7 days
+ * @param tag - class name to use for storing values in shared preferences
+ * @param saltExpirationDays - number of days we may keep the same salt
+ * @param saltDate - the date retrieved from configuration
+ * @return - true if no salt or salt is older than 7 days
+ */
+ private boolean checkNeedsNewSalt(String tag, int saltExpirationDays, long saltDate) {
+ if (saltDate == 0 || saltExpirationDays < -1) {
+ return true;
+ }
+ if (saltExpirationDays > MAX_SALT_DAYS) {
+ saltExpirationDays = MAX_SALT_DAYS;
+ }
+ long now = System.currentTimeMillis();
+ long delta = now - saltDate;
+ // Check for delta < 0 to make sure we catch if someone puts their phone far in the
+ // future and then goes back to normal time.
+ return delta >= saltExpirationDays * DAYS_TO_MILLIS || delta < 0;
+ }
+
+ /**
+ * Populate the salt and saltGen member variables if they aren't already set / need refreshing.
+ * @param context - to get sharedPreferences
+ * @param tag - class name to use for storing values in shared preferences
+ * @param saltExpirationDays - number of days we may keep the same salt
+ */
+ private void populateSaltValues(Context context, String tag, int saltExpirationDays) {
+ synchronized (mPreferenceLock) {
+ // check if we need to refresh the salt
+ mSharedPreferences = getHashSharedPreferences(context);
+ long saltDate = mSharedPreferences.getLong(tag + HASH_SALT_DATE, 0);
+ boolean needsNewSalt = checkNeedsNewSalt(tag, saltExpirationDays, saltDate);
+ if (needsNewSalt) {
+ mHashes.evictAll();
+ }
+ if (mSalt == null || needsNewSalt) {
+ String saltString = mSharedPreferences.getString(tag + HASH_SALT, null);
+ mSaltGen = mSharedPreferences.getInt(tag + HASH_SALT_GEN, 0);
+ if (saltString == null || needsNewSalt) {
+ mSaltGen++;
+ byte[] saltBytes = new byte[16];
+ mSecureRandom.nextBytes(saltBytes);
+ saltString = Base64.encodeToString(saltBytes,
+ Base64.NO_PADDING | Base64.NO_WRAP);
+ mSharedPreferences.edit()
+ .putString(tag + HASH_SALT, saltString)
+ .putInt(tag + HASH_SALT_GEN, mSaltGen)
+ .putLong(tag + HASH_SALT_DATE, System.currentTimeMillis()).apply();
+ if (DEBUG) {
+ Log.d(TAG, "created a new salt: " + saltString);
+ }
+ }
+ mSalt = saltString.getBytes(UTF_8);
+ }
+ }
+ }
+
+ /**
+ * Android:ui doesn't have persistent preferences, so need to fall back on this hack originally
+ * from ChooserActivity.java
+ * @param context
+ * @return
+ */
+ private SharedPreferences getHashSharedPreferences(Context context) {
+ final File prefsFile = new File(new File(
+ Environment.getDataUserCePackageDirectory(
+ StorageManager.UUID_PRIVATE_INTERNAL,
+ context.getUserId(), context.getPackageName()),
+ "shared_prefs"),
+ "hashed_cache.xml");
+ return context.getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
+ }
+
+ /**
+ * Helper class to hold hashed string and salt generation.
+ */
+ public class HashResult {
+ public String hashedString;
+ public int saltGeneration;
+
+ public HashResult(String hString, int saltGen) {
+ hashedString = hString;
+ saltGeneration = saltGen;
+ }
+ }
+}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bd38327..c2aec6a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1746,7 +1746,7 @@
* what the other flags are.
* @hide
*/
- public static final int PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND = 0x00020000;
+ public static final int PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS = 0x00020000;
/**
* Flag to indicate that this window needs Sustained Performance Mode if
@@ -1877,8 +1877,8 @@
equals = PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
name = "LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"),
@ViewDebug.FlagToString(
- mask = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND,
- equals = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND,
+ mask = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS,
+ equals = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS,
name = "FORCE_DRAW_STATUS_BAR_BACKGROUND"),
@ViewDebug.FlagToString(
mask = PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a1d0cdc..d553c6c 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -74,6 +74,7 @@
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.DeviceConfig;
import android.provider.DocumentsContract;
import android.provider.Downloads;
import android.provider.OpenableColumns;
@@ -83,6 +84,7 @@
import android.service.chooser.IChooserTargetService;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.HashedStringCache;
import android.util.Log;
import android.util.Size;
import android.util.Slog;
@@ -106,6 +108,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ImageUtils;
@@ -170,6 +173,11 @@
private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
private static final int WATCHDOG_TIMEOUT_MILLIS = 3000;
+ private static final int DEFAULT_SALT_EXPIRATION_DAYS = 7;
+ private int mMaxHashSaltDays = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
+ DEFAULT_SALT_EXPIRATION_DAYS);
+
private Bundle mReplacementExtras;
private IntentSender mChosenComponentSender;
private IntentSender mRefinementIntentSender;
@@ -201,7 +209,8 @@
private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 4;
private static final int LIST_VIEW_UPDATE_MESSAGE = 5;
- private static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
+ @VisibleForTesting
+ public static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
private boolean mListViewDataChanged = false;
@@ -991,6 +1000,7 @@
// Lower values mean the ranking was better.
int cat = 0;
int value = which;
+ HashedStringCache.HashResult directTargetHashed = null;
switch (mChooserListAdapter.getPositionTargetType(which)) {
case ChooserListAdapter.TARGET_CALLER:
cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET;
@@ -998,6 +1008,17 @@
break;
case ChooserListAdapter.TARGET_SERVICE:
cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET;
+ value -= mChooserListAdapter.getCallerTargetCount();
+ // Log the package name + target name to answer the question if most users
+ // share to mostly the same person or to a bunch of different people.
+ ChooserTarget target =
+ mChooserListAdapter.mServiceTargets.get(value).getChooserTarget();
+ directTargetHashed = HashedStringCache.getInstance().hashString(
+ this,
+ TAG,
+ target.getComponentName().getPackageName()
+ + target.getTitle().toString(),
+ mMaxHashSaltDays);
break;
case ChooserListAdapter.TARGET_STANDARD:
cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET;
@@ -1007,6 +1028,15 @@
}
if (cat != 0) {
+ LogMaker targetLogMaker = new LogMaker(cat).setSubtype(value);
+ if (directTargetHashed != null) {
+ targetLogMaker.addTaggedData(
+ MetricsEvent.FIELD_HASHED_TARGET_NAME, directTargetHashed.hashedString);
+ targetLogMaker.addTaggedData(
+ MetricsEvent.FIELD_HASHED_TARGET_SALT_GEN,
+ directTargetHashed.saltGeneration);
+ }
+ getMetricsLogger().write(targetLogMaker);
MetricsLogger.action(this, cat, value);
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 114d31f..9f860e2 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -106,7 +106,7 @@
void notePhoneOn();
void notePhoneOff();
void notePhoneSignalStrength(in SignalStrength signalStrength);
- void notePhoneDataConnectionState(int dataType, boolean hasData);
+ void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType);
void notePhoneState(int phoneState);
void noteWifiOn();
void noteWifiOff();
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index fd74c04..495a5fb 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -95,5 +95,10 @@
public static final String COMPACT_MEDIA_SEEKBAR_ENABLED =
"compact_media_notification_seekbar_enabled";
+ /**
+ * (int) Maximum number of days to retain the salt for hashing direct share targets in logging
+ */
+ public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
+
private SystemUiDeviceConfigFlags() { }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 1fc7635..8f37d81 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -907,8 +907,6 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
protected StopwatchTimer mBluetoothScanTimer;
- boolean mIsCellularTxPowerHigh = false;
-
int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
long mMobileRadioActiveStartTime;
StopwatchTimer mMobileRadioActiveTimer;
@@ -5275,16 +5273,26 @@
}
@UnsupportedAppUsage
- public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
+ public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) {
// BatteryStats uses 0 to represent no network type.
// Telephony does not have a concept of no network type, and uses 0 to represent unknown.
// Unknown is included in DATA_CONNECTION_OTHER.
- int bin = DATA_CONNECTION_NONE;
+ int bin = DATA_CONNECTION_OUT_OF_SERVICE;
if (hasData) {
if (dataType > 0 && dataType <= TelephonyManager.MAX_NETWORK_TYPE) {
bin = dataType;
} else {
- bin = DATA_CONNECTION_OTHER;
+ switch (serviceType) {
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ bin = DATA_CONNECTION_OUT_OF_SERVICE;
+ break;
+ case ServiceState.STATE_EMERGENCY_ONLY:
+ bin = DATA_CONNECTION_EMERGENCY_SERVICE;
+ break;
+ default:
+ bin = DATA_CONNECTION_OTHER;
+ break;
+ }
}
}
if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
@@ -11198,19 +11206,9 @@
}
}
if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) {
- if (!mIsCellularTxPowerHigh) {
- mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mIsCellularTxPowerHigh = true;
- }
- return;
- }
- if (mIsCellularTxPowerHigh) {
- mHistoryCur.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
+ mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
addHistoryRecordLocked(elapsedRealtime, uptime);
- mIsCellularTxPowerHigh = false;
}
- return;
}
private final class BluetoothActivityInfoCache {
@@ -13670,7 +13668,6 @@
mCameraOnTimer.readSummaryFromParcelLocked(in);
mBluetoothScanNesting = 0;
mBluetoothScanTimer.readSummaryFromParcelLocked(in);
- mIsCellularTxPowerHigh = false;
int NRPMS = in.readInt();
if (NRPMS > 10000) {
@@ -14654,7 +14651,6 @@
mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in);
mBluetoothScanNesting = 0;
mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in);
- mIsCellularTxPowerHigh = false;
mDischargeUnplugLevel = in.readInt();
mDischargePlugLevel = in.readInt();
mDischargeCurrentLevel = in.readInt();
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 625814d..66a6329 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -38,7 +38,6 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
-
import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
import android.animation.Animator;
@@ -53,6 +52,7 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Insets;
import android.graphics.LinearGradient;
import android.graphics.Outline;
import android.graphics.Paint;
@@ -205,8 +205,8 @@
private final Interpolator mShowInterpolator;
private final Interpolator mHideInterpolator;
private final int mBarEnterExitDuration;
- final boolean mForceWindowDrawsStatusBarBackground;
- private final int mSemiTransparentStatusBarColor;
+ final boolean mForceWindowDrawsBarBackgrounds;
+ private final int mSemiTransparentBarColor;
private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
@@ -242,6 +242,8 @@
private boolean mWindowResizeCallbacksAdded = false;
private Drawable.Callback mLastBackgroundDrawableCb = null;
private BackdropFrameRenderer mBackdropFrameRenderer = null;
+ private Drawable mOriginalBackgroundDrawable;
+ private Drawable mLastOriginalBackgroundDrawable;
private Drawable mResizingBackgroundDrawable;
private Drawable mCaptionBackgroundDrawable;
private Drawable mUserCaptionBackgroundDrawable;
@@ -257,6 +259,8 @@
private final int mResizeShadowSize;
private final Paint mVerticalResizeShadowPaint = new Paint();
private final Paint mHorizontalResizeShadowPaint = new Paint();
+ private Insets mBackgroundInsets = Insets.NONE;
+ private Insets mLastBackgroundInsets = Insets.NONE;
DecorView(Context context, int featureId, PhoneWindow window,
WindowManager.LayoutParams params) {
@@ -270,10 +274,10 @@
mBarEnterExitDuration = context.getResources().getInteger(
R.integer.dock_enter_exit_duration);
- mForceWindowDrawsStatusBarBackground = context.getResources().getBoolean(
+ mForceWindowDrawsBarBackgrounds = context.getResources().getBoolean(
R.bool.config_forceWindowDrawsStatusBarBackground)
&& context.getApplicationInfo().targetSdkVersion >= N;
- mSemiTransparentStatusBarColor = context.getResources().getColor(
+ mSemiTransparentBarColor = context.getResources().getColor(
R.color.system_bar_background_semi_transparent, null /* theme */);
updateAvailableWidth();
@@ -948,8 +952,9 @@
}
public void setWindowBackground(Drawable drawable) {
- if (getBackground() != drawable) {
- setBackgroundDrawable(drawable);
+ if (mOriginalBackgroundDrawable != drawable) {
+ mOriginalBackgroundDrawable = drawable;
+ updateBackgroundDrawable();
if (drawable != null) {
mResizingBackgroundDrawable = enforceNonTranslucentBackground(drawable,
mWindow.isTranslucent() || mWindow.isShowingWallpaper());
@@ -1114,9 +1119,10 @@
boolean navBarToLeftEdge = isNavBarToLeftEdge(mLastBottomInset, mLastLeftInset);
int navBarSize = getNavBarSize(mLastBottomInset, mLastRightInset, mLastLeftInset);
updateColorViewInt(mNavigationColorViewState, sysUiVisibility,
- mWindow.mNavigationBarColor, mWindow.mNavigationBarDividerColor, navBarSize,
+ calculateNavigationBarColor(), mWindow.mNavigationBarDividerColor, navBarSize,
navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
- 0 /* sideInset */, animate && !disallowAnimate, false /* force */);
+ 0 /* sideInset */, animate && !disallowAnimate,
+ mForceWindowDrawsBarBackgrounds);
boolean statusBarNeedsRightInset = navBarToRightEdge
&& mNavigationColorViewState.present;
@@ -1128,24 +1134,34 @@
calculateStatusBarColor(), 0, mLastTopInset,
false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
animate && !disallowAnimate,
- mForceWindowDrawsStatusBarBackground);
+ mForceWindowDrawsBarBackgrounds);
}
- // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
- // to ensure that the rest of the view hierarchy doesn't notice it, unless they've
- // explicitly asked for it.
- boolean consumingNavBar =
- (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
+ // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS or
+ // mForceWindowDrawsBarBackgrounds, we still need to ensure that the rest of the view
+ // hierarchy doesn't notice it, unless they've explicitly asked for it.
+ //
+ // Note: We don't need to check for IN_SCREEN or INSET_DECOR because unlike the status bar,
+ // these flags wouldn't make the window draw behind the navigation bar, unless
+ // LAYOUT_HIDE_NAVIGATION was set.
+ boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
+ && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
- && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
+ && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
|| mLastShouldAlwaysConsumeSystemBars;
+ boolean consumingNavBar =
+ ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
+ && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
+ && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
+ || forceConsumingNavBar;
+
// If we didn't request fullscreen layout, but we still got it because of the
- // mForceWindowDrawsStatusBarBackground flag, also consume top inset.
+ // mForceWindowDrawsBarBackgrounds flag, also consume top inset.
boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
&& (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
&& (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
- && mForceWindowDrawsStatusBarBackground
+ && mForceWindowDrawsBarBackgrounds
&& mLastTopInset != 0
|| mLastShouldAlwaysConsumeSystemBars;
@@ -1176,21 +1192,63 @@
}
}
+ if (forceConsumingNavBar) {
+ mBackgroundInsets = Insets.of(mLastLeftInset, 0, mLastRightInset, mLastBottomInset);
+ } else {
+ mBackgroundInsets = Insets.NONE;
+ }
+ updateBackgroundDrawable();
+
if (insets != null) {
insets = insets.consumeStableInsets();
}
return insets;
}
- private int calculateStatusBarColor() {
- return calculateStatusBarColor(mWindow.getAttributes().flags,
- mSemiTransparentStatusBarColor, mWindow.mStatusBarColor);
+ /**
+ * Updates the background drawable, applying padding to it in case we {@link #mBackgroundInsets}
+ * are set.
+ */
+ private void updateBackgroundDrawable() {
+ if (mBackgroundInsets.equals(mLastBackgroundInsets)
+ && mLastOriginalBackgroundDrawable == mOriginalBackgroundDrawable) {
+ return;
+ }
+ if (mBackgroundInsets.equals(Insets.NONE)) {
+ setBackground(mOriginalBackgroundDrawable);
+ } else {
+ setBackground(new InsetDrawable(mOriginalBackgroundDrawable,
+ mBackgroundInsets.left, mBackgroundInsets.top,
+ mBackgroundInsets.right, mBackgroundInsets.bottom) {
+
+ /**
+ * Return inner padding so we don't apply the padding again in
+ * {@link DecorView#drawableChanged()}
+ */
+ @Override
+ public boolean getPadding(Rect padding) {
+ return getDrawable().getPadding(padding);
+ }
+ });
+ }
+ mLastBackgroundInsets = mBackgroundInsets;
+ mLastOriginalBackgroundDrawable = mOriginalBackgroundDrawable;
}
- public static int calculateStatusBarColor(int flags, int semiTransparentStatusBarColor,
- int statusBarColor) {
- return (flags & FLAG_TRANSLUCENT_STATUS) != 0 ? semiTransparentStatusBarColor
- : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? statusBarColor
+ private int calculateStatusBarColor() {
+ return calculateBarColor(mWindow.getAttributes().flags, FLAG_TRANSLUCENT_STATUS,
+ mSemiTransparentBarColor, mWindow.mStatusBarColor);
+ }
+
+ private int calculateNavigationBarColor() {
+ return calculateBarColor(mWindow.getAttributes().flags, FLAG_TRANSLUCENT_NAVIGATION,
+ mSemiTransparentBarColor, mWindow.mNavigationBarColor);
+ }
+
+ public static int calculateBarColor(int flags, int translucentFlag, int semiTransparentBarColor,
+ int barColor) {
+ return (flags & translucentFlag) != 0 ? semiTransparentBarColor
+ : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? barColor
: Color.BLACK;
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 890ee86..04559e4 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -31,7 +31,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
@@ -2469,8 +2469,8 @@
setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
}
- if (mDecor.mForceWindowDrawsStatusBarBackground) {
- params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+ if (mDecor.mForceWindowDrawsBarBackgrounds) {
+ params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
}
}
if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 000c044..0e31ab9 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -204,7 +204,6 @@
"android_content_res_Configuration.cpp",
"android_animation_PropertyValuesHolder.cpp",
"android_security_Scrypt.cpp",
- "com_android_internal_net_NetworkStatsFactory.cpp",
"com_android_internal_os_AtomicDirectory.cpp",
"com_android_internal_os_ClassLoaderFactory.cpp",
"com_android_internal_os_FuseAppLoop.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ccd0b66..967abce 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -227,7 +227,6 @@
extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
extern int register_android_security_Scrypt(JNIEnv *env);
extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
-extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
extern int register_com_android_internal_os_AtomicDirectory(JNIEnv *env);
extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
@@ -1569,7 +1568,6 @@
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_android_security_Scrypt),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
- REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
REG_JNI(register_com_android_internal_os_AtomicDirectory),
REG_JNI(register_com_android_internal_os_FuseAppLoop),
};
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index d029527..ace88f5 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2331,4 +2331,9 @@
// Open: Settings > app > bubble settings > confirmation dialog
DIALOG_APP_BUBBLE_SETTINGS = 1702;
+
+ // ACTION: Display white balance setting enabled or disabled.
+ // CATEGORY: SETTINGS
+ // OS: Q
+ ACTION_DISPLAY_WHITE_BALANCE_SETTING_CHANGED = 1703;
}
diff --git a/core/res/Android.bp b/core/res/Android.bp
index e66f1a2..4e60f8c 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -39,3 +39,12 @@
// PRODUCT-agnostic resource data like IDs and type definitions.
export_package_resources: true,
}
+
+// This logic can be removed once robolectric's transition to binary resources is complete
+filegroup {
+ name: "robolectric_framework_raw_res_files",
+ srcs: [
+ "assets/**/*",
+ "res/**/*",
+ ],
+}
diff --git a/core/res/res/drawable/perm_group_calendar.xml b/core/res/res/drawable/perm_group_calendar.xml
index 85a783e..4b46dd3 100644
--- a/core/res/res/drawable/perm_group_calendar.xml
+++ b/core/res/res/drawable/perm_group_calendar.xml
@@ -22,7 +22,8 @@
<path
android:fillColor="#000000"
- android:pathData="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99 .9 -1.99 2L3 19c0 1.1 .89 2 2
-2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z" />
+ android:pathData="M19 4h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99 0.9 -1.99 2L3 20c0 1.1 0.89 2 2 2h14c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm0 16H5V10h14v10zm-4.5-7c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5z" />
+ <path
+ android:pathData="M0 0h24v24H0V0z" />
</vector>
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ec2a6ae..21f5acb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1302,12 +1302,6 @@
<!-- Disable lockscreen rotation by default -->
<bool name="config_enableLockScreenRotation">false</bool>
- <!-- Enable lockscreen translucent decor by default -->
- <bool name="config_enableLockScreenTranslucentDecor">true</bool>
-
- <!-- Enable translucent decor by default -->
- <bool name="config_enableTranslucentDecor">true</bool>
-
<!-- Is the device capable of hot swapping an UICC Card -->
<bool name="config_hotswapCapable">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4b8a96c..6f3adfd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1434,7 +1434,7 @@
<string name="permdesc_mediaLocation">Allows the app to read locations from your media collection.</string>
<!-- Title shown when the system-provided biometric dialog is shown, asking the user to authenticate. [CHAR LIMIT=40] -->
- <string name="biometric_dialog_default_title">Application <xliff:g id="app" example="Gmail">%s</xliff:g> wants to authenticate.</string>
+ <string name="biometric_dialog_default_title">Verify it\u2018s you</string>
<!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] -->
<string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
<!-- Message shown when biometric authentication was canceled by the user [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3e23640..fb7be77 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1717,8 +1717,6 @@
<java-symbol type="bool" name="config_enableCarDockHomeLaunch" />
<java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
<java-symbol type="bool" name="config_enableLockScreenRotation" />
- <java-symbol type="bool" name="config_enableLockScreenTranslucentDecor" />
- <java-symbol type="bool" name="config_enableTranslucentDecor" />
<java-symbol type="bool" name="config_forceShowSystemBars" />
<java-symbol type="bool" name="config_lidControlsScreenLock" />
<java-symbol type="bool" name="config_lidControlsSleep" />
diff --git a/core/tests/BroadcastRadioTests/Android.bp b/core/tests/BroadcastRadioTests/Android.bp
new file mode 100644
index 0000000..0aebaaa
--- /dev/null
+++ b/core/tests/BroadcastRadioTests/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2017 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.
+
+android_test {
+ name: "BroadcastRadioTests",
+ privileged: true,
+ certificate: "platform",
+ // TODO(b/13282254): uncomment when b/13282254 is fixed
+ // sdk_version: "current"
+ platform_apis: true,
+ static_libs: [
+ "compatibility-device-util-axt",
+ "androidx.test.rules",
+ "testng",
+ ],
+ libs: ["android.test.base"],
+ srcs: ["src/**/*.java"],
+ dex_preopt: {
+ enabled: false,
+ },
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/core/tests/BroadcastRadioTests/Android.mk b/core/tests/BroadcastRadioTests/Android.mk
deleted file mode 100644
index faffc4b..0000000
--- a/core/tests/BroadcastRadioTests/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2017 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := BroadcastRadioTests
-
-LOCAL_PRIVILEGED_MODULE := true
-LOCAL_CERTIFICATE := platform
-LOCAL_MODULE_TAGS := tests
-# TODO(b/13282254): uncomment when b/13282254 is fixed
-# LOCAL_SDK_VERSION := current
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt androidx.test.rules testng
-
-LOCAL_JAVA_LIBRARIES := android.test.base
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_DEX_PREOPT := false
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/src/android/app/ApplicationLoadersTest.java b/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
new file mode 100644
index 0000000..4b9910c
--- /dev/null
+++ b/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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 android.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.content.pm.SharedLibraryInfo;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ApplicationLoadersTest {
+
+ // a library installed onto the device with no dependencies
+ private static final String LIB_A = "/system/framework/android.hidl.base-V1.0-java.jar";
+ // a library installed onto the device which only depends on A
+ private static final String LIB_DEP_A = "/system/framework/android.hidl.manager-V1.0-java.jar";
+
+ private static SharedLibraryInfo createLib(String zip) {
+ return new SharedLibraryInfo(
+ zip, null /*packageName*/, null /*codePaths*/, null /*name*/, 0 /*version*/,
+ SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
+ null /*dependentPackages*/, null /*dependencies*/);
+ }
+
+ @Test
+ public void testGetNonExistantLib() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
+ "/system/framework/nonexistantlib.jar", null, null, null));
+ }
+
+ @Test
+ public void testCacheExistantLib() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ SharedLibraryInfo libA = createLib(LIB_A);
+
+ loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
+
+ assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib(
+ LIB_A, null, null, null));
+ }
+
+ @Test
+ public void testNonNullParent() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ SharedLibraryInfo libA = createLib(LIB_A);
+
+ ClassLoader parent = ClassLoader.getSystemClassLoader();
+ assertNotEquals(null, parent);
+
+ loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
+
+ assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
+ LIB_A, parent, null, null));
+ }
+
+ @Test
+ public void testNonNullClassLoaderNamespace() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ SharedLibraryInfo libA = createLib(LIB_A);
+
+ loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
+
+ assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
+ LIB_A, null, "other classloader", null));
+ }
+
+ @Test
+ public void testDifferentSharedLibraries() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ SharedLibraryInfo libA = createLib(LIB_A);
+
+ // any other existant lib
+ ClassLoader dep = ClassLoader.getSystemClassLoader();
+ ArrayList<ClassLoader> sharedLibraries = new ArrayList<>();
+ sharedLibraries.add(dep);
+
+ loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
+
+ assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
+ LIB_A, null, null, sharedLibraries));
+ }
+
+ @Test
+ public void testDependentLibs() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ SharedLibraryInfo libA = createLib(LIB_A);
+ SharedLibraryInfo libB = createLib(LIB_DEP_A);
+ libB.addDependency(libA);
+
+ loaders.createAndCacheNonBootclasspathSystemClassLoaders(
+ new SharedLibraryInfo[]{libA, libB});
+
+ ClassLoader loadA = loaders.getCachedNonBootclasspathSystemLib(
+ LIB_A, null, null, null);
+ assertNotEquals(null, loadA);
+
+ ArrayList<ClassLoader> sharedLibraries = new ArrayList<>();
+ sharedLibraries.add(loadA);
+
+ assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib(
+ LIB_DEP_A, null, null, sharedLibraries));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testDependentLibsWrongOrder() {
+ ApplicationLoaders loaders = new ApplicationLoaders();
+ SharedLibraryInfo libA = createLib(LIB_A);
+ SharedLibraryInfo libB = createLib(LIB_DEP_A);
+ libB.addDependency(libA);
+
+ loaders.createAndCacheNonBootclasspathSystemClassLoaders(
+ new SharedLibraryInfo[]{libB, libA});
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 185fa07..00b4a22 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -39,6 +39,7 @@
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
@@ -47,8 +48,10 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.net.Uri;
+import android.service.chooser.ChooserTarget;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -735,6 +738,120 @@
onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
}
+ // This test is too long and too slow and should not be taken as an example for future tests.
+ // This is necessary because it tests that multiple calls result in the same result but
+ // normally a test this long should be broken into smaller tests testing individual components.
+ @Test
+ public void testDirectTargetSelectionLogging() throws InterruptedException {
+ Intent sendIntent = createSendTextIntent();
+ // We need app targets for direct targets to get displayed
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+ // Set up resources
+ MetricsLogger mockLogger = sOverrides.metricsLogger;
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ // Create direct share target
+ List<ChooserTarget> serviceTargets = createDirectShareTargets(1);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+
+ // Start activity
+ final ChooserWrapperActivity activity = mActivityRule
+ .launchActivity(Intent.createChooser(sendIntent, null));
+
+ // Insert the direct share target
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(
+ () -> activity.getAdapter().addServiceResults(
+ activity.createTestDisplayResolveInfo(sendIntent,
+ ri,
+ "testLabel",
+ "testInfo",
+ sendIntent),
+ serviceTargets,
+ false)
+ );
+ // Thread.sleep shouldn't be a thing in an integration test but it's
+ // necessary here because of the way the code is structured
+ // TODO: restructure the tests b/129870719
+ Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+
+ assertThat("Chooser should have 3 targets (2apps, 1 direct)",
+ activity.getAdapter().getCount(), is(3));
+ assertThat("Chooser should have exactly one selectable direct target",
+ activity.getAdapter().getSelectableServiceTargetCount(), is(1));
+ assertThat("The resolver info must match the resolver info used to create the target",
+ activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
+
+ // Click on the direct target
+ String name = serviceTargets.get(0).getTitle().toString();
+ onView(withText(name))
+ .perform(click());
+ waitForIdle();
+
+ // Currently we're seeing 3 invocations
+ // 1. ChooserActivity.onCreate()
+ // 2. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
+ // 3. ChooserActivity.startSelected -- which is the one we're after
+ verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
+ assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
+ is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
+ String hashedName = (String) logMakerCaptor
+ .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_HASHED_TARGET_NAME);
+ assertThat("Hash is not predictable but must be obfuscated",
+ hashedName, is(not(name)));
+
+ // Running the same again to check if the hashed name is the same as before.
+
+ Intent sendIntent2 = createSendTextIntent();
+
+ // Start activity
+ final ChooserWrapperActivity activity2 = mActivityRule
+ .launchActivity(Intent.createChooser(sendIntent2, null));
+ waitForIdle();
+
+ // Insert the direct share target
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(
+ () -> activity2.getAdapter().addServiceResults(
+ activity2.createTestDisplayResolveInfo(sendIntent,
+ ri,
+ "testLabel",
+ "testInfo",
+ sendIntent),
+ serviceTargets,
+ false)
+ );
+ // Thread.sleep shouldn't be a thing in an integration test but it's
+ // necessary here because of the way the code is structured
+ // TODO: restructure the tests b/129870719
+ Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+
+ assertThat("Chooser should have 3 targets (2apps, 1 direct)",
+ activity2.getAdapter().getCount(), is(3));
+ assertThat("Chooser should have exactly one selectable direct target",
+ activity2.getAdapter().getSelectableServiceTargetCount(), is(1));
+ assertThat("The resolver info must match the resolver info used to create the target",
+ activity2.getAdapter().getItem(0).getResolveInfo(), is(ri));
+
+ // Click on the direct target
+ onView(withText(name))
+ .perform(click());
+ waitForIdle();
+
+ // Currently we're seeing 6 invocations (3 from above, doubled up)
+ // 4. ChooserActivity.onCreate()
+ // 5. ChooserActivity$ChooserRowAdapter.createContentPreviewView()
+ // 6. ChooserActivity.startSelected -- which is the one we're after
+ verify(mockLogger, Mockito.times(6)).write(logMakerCaptor.capture());
+ assertThat(logMakerCaptor.getAllValues().get(5).getCategory(),
+ is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET));
+ String hashedName2 = (String) logMakerCaptor
+ .getAllValues().get(5).getTaggedData(MetricsEvent.FIELD_HASHED_TARGET_NAME);
+ assertThat("Hashing the same name should result in the same hashed value",
+ hashedName2, is(hashedName));
+ }
+
private Intent createSendTextIntent() {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@@ -798,6 +915,23 @@
return infoList;
}
+ private List<ChooserTarget> createDirectShareTargets(int numberOfResults) {
+ Icon icon = Icon.createWithBitmap(createBitmap());
+ String testTitle = "testTitle";
+ List<ChooserTarget> targets = new ArrayList<>();
+ for (int i = 0; i < numberOfResults; i++) {
+ ComponentName componentName = ResolverDataProvider.createComponentName(i);
+ ChooserTarget tempTarget = new ChooserTarget(
+ testTitle + i,
+ icon,
+ (float) (1 - ((i + 1) / 10.0)),
+ componentName,
+ null);
+ targets.add(tempTarget);
+ }
+ return targets;
+ }
+
private void waitForIdle() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 5e71129..44e56ea 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -21,7 +21,9 @@
import android.app.usage.UsageStatsManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -121,6 +123,11 @@
return super.isWorkProfile();
}
+ public DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri,
+ CharSequence pLabel, CharSequence pInfo, Intent pOrigIntent) {
+ return new DisplayResolveInfo(originalIntent, pri, pLabel, pInfo, pOrigIntent);
+ }
+
/**
* We cannot directly mock the activity created since instrumentation creates it.
* <p>
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index 9a95fdf..92125c9 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -253,8 +253,10 @@
pAsset = new _FileAsset;
result = pAsset->openChunk(NULL, fd, offset, length);
- if (result != NO_ERROR)
+ if (result != NO_ERROR) {
+ delete pAsset;
return NULL;
+ }
pAsset->mAccessMode = mode;
return pAsset;
@@ -273,8 +275,10 @@
pAsset = new _CompressedAsset;
result = pAsset->openChunk(fd, offset, compressionMethod,
uncompressedLen, compressedLen);
- if (result != NO_ERROR)
+ if (result != NO_ERROR) {
+ delete pAsset;
return NULL;
+ }
pAsset->mAccessMode = mode;
return pAsset;
@@ -328,8 +332,10 @@
pAsset = new _CompressedAsset;
result = pAsset->openChunk(dataMap, uncompressedLen);
- if (result != NO_ERROR)
+ if (result != NO_ERROR) {
+ delete pAsset;
return NULL;
+ }
pAsset->mAccessMode = mode;
return pAsset;
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index f1903a5..87b1467 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -1,3 +1,5 @@
set noparent
toddke@google.com
-rtmitchell@google.com
\ No newline at end of file
+rtmitchell@google.com
+
+per-file CursorWindow.cpp=omakoto@google.com
diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp
index 0535af3..d0f419c 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/tests/Android.bp
@@ -42,6 +42,7 @@
"libbinder",
"libbinderthreadstate",
"libc++",
+ "libcgrouprc",
"libcrypto",
"libcutils",
"libdexfile",
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
index 239b1d4..eff02d2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -173,6 +173,7 @@
}
override fun draw(c: Canvas) {
+ c.saveLayer(null, null)
unifiedPath.reset()
levelPath.reset()
levelRect.set(fillRect)
@@ -243,6 +244,7 @@
// And draw the plus sign on top of the fill
c.drawPath(scaledPlus, errorPaint)
}
+ c.restore()
}
private fun batteryColorForLevel(level: Int): Int {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index fc84332..8f24e79 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -14,7 +14,9 @@
package com.android.systemui.plugins.statusbar;
+import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.Point;
import android.service.notification.StatusBarNotification;
import android.view.MotionEvent;
import android.view.View;
@@ -84,6 +86,38 @@
public void setMenuItems(ArrayList<MenuItem> items);
+ /**
+ * If this returns {@code true}, then the menu row will bind and fade in the notification guts
+ * view for the menu item it holds.
+ *
+ * @see #menuItemToExposeOnSnap()
+ * @return whether or not to immediately expose the notification guts
+ */
+ default boolean shouldShowGutsOnSnapOpen() {
+ return false;
+ }
+
+ /**
+ * When #shouldShowGutsOnExpose is true, this method must return the menu item to expose on
+ * #onSnapOpen. Otherwise we will fall back to the default behavior of fading in the menu row
+ *
+ * @return the {@link MenuItem} containing the NotificationGuts that should be exposed
+ */
+ @Nullable
+ default MenuItem menuItemToExposeOnSnap() {
+ return null;
+ }
+
+ /**
+ * Get the origin for the circular reveal animation when expanding the notification guts. Only
+ * used when #shouldShowGutsOnSnapOpen is true
+ * @return the x,y coordinates for the start of the animation
+ */
+ @Nullable
+ default Point getRevealAnimationOrigin() {
+ return new Point(0, 0);
+ }
+
public void setMenuClickListener(OnMenuEventListener listener);
public void setAppName(String appName);
diff --git a/packages/SystemUI/res-keyguard/values/alias.xml b/packages/SystemUI/res-keyguard/values/alias.xml
index 1c63c79..6d49b1f 100644
--- a/packages/SystemUI/res-keyguard/values/alias.xml
+++ b/packages/SystemUI/res-keyguard/values/alias.xml
@@ -28,9 +28,6 @@
<!-- Alias used to reference framework configuration for screen rotation. -->
<item type="bool" name="config_enableLockScreenRotation">@*android:bool/config_enableLockScreenRotation</item>
- <!-- Alias used to reference framework configuration for translucent decor. -->
- <item type="bool" name="config_enableLockScreenTranslucentDecor">@*android:bool/config_enableLockScreenTranslucentDecor</item>
-
<!-- Alias used to reference framework activity duration. -->
<item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
index c8f0a24..9b6ccae 100644
--- a/packages/SystemUI/res/layout/contextual.xml
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -37,16 +37,10 @@
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:id="@+id/ime_switcher"
+ <include layout="@layout/ime_switcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_weight="0"
- android:scaleType="center"
android:visibility="invisible"
- android:contentDescription="@string/accessibility_ime_switch_button"
- android:paddingStart="@dimen/navigation_key_padding"
- android:paddingEnd="@dimen/navigation_key_padding"
/>
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/rotate_suggestion"
diff --git a/packages/SystemUI/res/layout/home_handle.xml b/packages/SystemUI/res/layout/home_handle.xml
index d950f39..7c5db10 100644
--- a/packages/SystemUI/res/layout/home_handle.xml
+++ b/packages/SystemUI/res/layout/home_handle.xml
@@ -21,5 +21,7 @@
android:layout_width="@dimen/navigation_home_handle_width"
android:layout_height="match_parent"
android:layout_weight="0"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
/>
diff --git a/packages/SystemUI/res/layout/ime_switcher.xml b/packages/SystemUI/res/layout/ime_switcher.xml
new file mode 100644
index 0000000..7710b25
--- /dev/null
+++ b/packages/SystemUI/res/layout/ime_switcher.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<com.android.systemui.statusbar.policy.KeyButtonView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/ime_switcher"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:contentDescription="@string/accessibility_ime_switch_button"
+ android:scaleType="center"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 8a3a0b1..24374e8 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -35,13 +35,13 @@
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
/>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:id="@+id/ime_switcher"
+ <include layout="@layout/ime_switcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="invisible"
- android:contentDescription="@string/accessibility_ime_switch_button"
android:scaleType="centerInside"
+ android:visibility="invisible"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
/>
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/rotate_suggestion"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b0afe75..ce04638 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -330,7 +330,7 @@
<!-- Nav bar button default ordering/layout -->
<string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
<string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string>
- <string name="config_navBarLayoutHandle" translatable="false">";home_handle;"</string>
+ <string name="config_navBarLayoutHandle" translatable="false">back[1.7WC];home_handle;ime_switcher[1.7WC]</string>
<bool name="quick_settings_show_full_alarm">false</bool>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 8ebe1ae..c1bf4d4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -20,6 +20,8 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
@@ -60,6 +62,7 @@
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.keyguard.KeyguardSliceProvider;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
@@ -70,6 +73,9 @@
import java.util.HashMap;
import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* View visible under the clock on the lock screen and AoD.
*/
@@ -80,6 +86,8 @@
public static final int DEFAULT_ANIM_DURATION = 550;
private final HashMap<View, PendingIntent> mClickActions;
+ private final ActivityStarter mActivityStarter;
+ private final ConfigurationController mConfigurationController;
private Uri mKeyguardSliceUri;
@VisibleForTesting
TextView mTitle;
@@ -99,16 +107,10 @@
private final int mRowWithHeaderPadding;
private final int mRowPadding;
- public KeyguardSliceView(Context context) {
- this(context, null, 0);
- }
-
- public KeyguardSliceView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public KeyguardSliceView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
+ @Inject
+ public KeyguardSliceView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+ ActivityStarter activityStarter, ConfigurationController configurationController) {
+ super(context, attrs);
TunerService tunerService = Dependency.get(TunerService.class);
tunerService.addTunable(this, Settings.Secure.KEYGUARD_SLICE_URI);
@@ -117,6 +119,8 @@
mRowPadding = context.getResources().getDimensionPixelSize(R.dimen.subtitle_clock_padding);
mRowWithHeaderPadding = context.getResources()
.getDimensionPixelSize(R.dimen.header_subtitle_padding);
+ mActivityStarter = activityStarter;
+ mConfigurationController = configurationController;
LayoutTransition transition = new LayoutTransition();
transition.setStagger(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION / 2);
@@ -137,6 +141,7 @@
mRow = findViewById(R.id.row);
mTextColor = Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor);
mIconSize = (int) mContext.getResources().getDimension(R.dimen.widget_icon_size);
+ mTitle.setOnClickListener(this);
}
@Override
@@ -146,7 +151,7 @@
mDisplayId = getDisplay().getDisplayId();
// Make sure we always have the most current slice
mLiveData.observeForever(this);
- Dependency.get(ConfigurationController.class).addCallback(this);
+ mConfigurationController.addCallback(this);
}
@Override
@@ -157,7 +162,7 @@
if (mDisplayId == DEFAULT_DISPLAY) {
mLiveData.removeObserver(this);
}
- Dependency.get(ConfigurationController.class).removeCallback(this);
+ mConfigurationController.removeCallback(this);
}
/**
@@ -179,6 +184,7 @@
Trace.endSection();
return;
}
+ mClickActions.clear();
ListContent lc = new ListContent(getContext(), mSlice);
SliceContent headerContent = lc.getHeader();
@@ -201,9 +207,12 @@
SliceItem mainTitle = header.getTitleItem();
CharSequence title = mainTitle != null ? mainTitle.getText() : null;
mTitle.setText(title);
+ if (header.getPrimaryAction() != null
+ && header.getPrimaryAction().getAction() != null) {
+ mClickActions.put(mTitle, header.getPrimaryAction().getAction());
+ }
}
- mClickActions.clear();
final int subItemsCount = subItems.size();
final int blendedColor = getTextColor();
final int startIndex = mHasHeader ? 1 : 0; // First item is header; skip it
@@ -289,11 +298,7 @@
public void onClick(View v) {
final PendingIntent action = mClickActions.get(v);
if (action != null) {
- try {
- action.send();
- } catch (PendingIntent.CanceledException e) {
- Log.i(TAG, "Pending intent cancelled, nothing to launch", e);
- }
+ mActivityStarter.startPendingIntentDismissingKeyguard(action);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 62b0542..de64cf8 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -176,10 +176,6 @@
setClipChildren(false);
setClipToPadding(false);
Dependency.get(ConfigurationController.class).observe(viewAttachLifecycle(this), this);
-
- // Needed for PorderDuff.Mode.CLEAR operations to work properly, but redraws don't happen
- // enough to justify a hardware layer.
- setLayerType(LAYER_TYPE_SOFTWARE, null);
}
private void setupLayoutTransition() {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 60e6083..f7ecfd7 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -265,7 +265,9 @@
public boolean onInterceptTouchEvent(final MotionEvent ev) {
if (mCurrView instanceof ExpandableNotificationRow) {
NotificationMenuRowPlugin nmr = ((ExpandableNotificationRow) mCurrView).getProvider();
- mMenuRowIntercepting = nmr.onInterceptTouchEvent(mCurrView, ev);
+ if (nmr != null) {
+ mMenuRowIntercepting = nmr.onInterceptTouchEvent(mCurrView, ev);
+ }
}
final int action = ev.getAction();
@@ -487,6 +489,7 @@
mSnappingChild = false;
if (!wasCancelled) {
updateSwipeProgressFromOffset(animView, canBeDismissed);
+ onChildSnappedBack(animView, targetLeft);
mCallback.onChildSnappedBack(animView, targetLeft);
}
}
@@ -500,6 +503,13 @@
}
/**
+ * Give the swipe helper itself a chance to do something on snap back so NSSL doesn't have
+ * to tell us what to do
+ */
+ protected void onChildSnappedBack(View animView, float targetLeft) {
+ }
+
+ /**
* Called to update the snap back animation.
*/
protected void prepareSnapBackAnimation(View view, Animator anim) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index de4605b..d850dbc 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -64,6 +64,8 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.util.Collections;
+import java.util.List;
/**
* Renders bubbles in a stack and handles animating expanded and collapsed states.
@@ -164,6 +166,8 @@
int[] mTempLoc = new int[2];
RectF mTempRect = new RectF();
+ private final List<Rect> mSystemGestureExclusionRects = Collections.singletonList(new Rect());
+
private ViewTreeObserver.OnPreDrawListener mViewUpdater =
new ViewTreeObserver.OnPreDrawListener() {
@Override
@@ -175,6 +179,9 @@
}
};
+ private ViewTreeObserver.OnDrawListener mSystemGestureExcludeUpdater =
+ this::updateSystemGestureExcludeRects;
+
private ViewClippingUtil.ClippingParameters mClippingParameters =
new ViewClippingUtil.ClippingParameters() {
@@ -361,6 +368,19 @@
return false;
}
+ private void updateSystemGestureExcludeRects() {
+ // Exclude the region occupied by the first BubbleView in the stack
+ Rect excludeZone = mSystemGestureExclusionRects.get(0);
+ if (mBubbleContainer.getChildCount() > 0) {
+ View firstBubble = mBubbleContainer.getChildAt(0);
+ excludeZone.set(firstBubble.getLeft(), firstBubble.getTop(), firstBubble.getRight(),
+ firstBubble.getBottom());
+ } else {
+ excludeZone.setEmpty();
+ }
+ mBubbleContainer.setSystemGestureExclusionRects(mSystemGestureExclusionRects);
+ }
+
/**
* Updates the visibility of the 'dot' indicating an update on the bubble.
* @param key the {@link NotificationEntry#key} associated with the bubble.
@@ -669,12 +689,17 @@
updateExpandedBubble();
applyCurrentState();
+ // This must be a separate OnDrawListener since it should be called for every draw.
+ getViewTreeObserver().addOnDrawListener(mSystemGestureExcludeUpdater);
+
mIsExpansionAnimating = true;
Runnable updateAfter = () -> {
applyCurrentState();
mIsExpansionAnimating = false;
requestUpdate();
+ getViewTreeObserver().removeOnDrawListener(mSystemGestureExcludeUpdater);
+ updateSystemGestureExcludeRects();
};
if (shouldExpand) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d287b92..efdcd05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1147,10 +1147,13 @@
@Override
public void onPluginConnected(NotificationMenuRowPlugin plugin, Context pluginContext) {
- boolean existed = mMenuRow.getMenuView() != null;
+ boolean existed = mMenuRow != null && mMenuRow.getMenuView() != null;
if (existed) {
removeView(mMenuRow.getMenuView());
}
+ if (plugin == null) {
+ return;
+ }
mMenuRow = plugin;
if (mMenuRow.shouldUseDefaultMenuItems()) {
ArrayList<MenuItem> items = new ArrayList<>();
@@ -1173,7 +1176,18 @@
}
}
+ /**
+ * Get a handle to a NotificationMenuRowPlugin whose menu view has been added to our hierarchy,
+ * or null if there is no menu row
+ *
+ * @return a {@link NotificationMenuRowPlugin}, or null
+ */
+ @Nullable
public NotificationMenuRowPlugin createMenu() {
+ if (mMenuRow == null) {
+ return null;
+ }
+
if (mMenuRow.getMenuView() == null) {
mMenuRow.createMenu(this, mStatusBarNotification);
mMenuRow.setAppName(mAppName);
@@ -1184,6 +1198,7 @@
return mMenuRow;
}
+ @Nullable
public NotificationMenuRowPlugin getProvider() {
return mMenuRow;
}
@@ -1211,7 +1226,7 @@
mGuts.setVisibility(oldGuts.getVisibility());
addView(mGuts, index);
}
- View oldMenu = mMenuRow.getMenuView();
+ View oldMenu = mMenuRow == null ? null : mMenuRow.getMenuView();
if (oldMenu != null) {
int menuIndex = indexOfChild(oldMenu);
removeView(oldMenu);
@@ -1230,7 +1245,7 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
- if (mMenuRow.getMenuView() != null) {
+ if (mMenuRow != null && mMenuRow.getMenuView() != null) {
mMenuRow.onConfigurationChanged();
}
}
@@ -1728,7 +1743,11 @@
public void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) {
mOnAppOpsClickListener = v -> {
createMenu();
- MenuItem menuItem = getProvider().getAppOpsMenuItem(mContext);
+ NotificationMenuRowPlugin provider = getProvider();
+ if (provider == null) {
+ return;
+ }
+ MenuItem menuItem = provider.getAppOpsMenuItem(mContext);
if (menuItem != null) {
l.onClick(this, v.getWidth() / 2, v.getHeight() / 2, menuItem);
}
@@ -1790,7 +1809,11 @@
public void doLongClickCallback(int x, int y) {
createMenu();
- MenuItem menuItem = getProvider().getLongpressMenuItem(mContext);
+ NotificationMenuRowPlugin provider = getProvider();
+ MenuItem menuItem = null;
+ if (provider != null) {
+ menuItem = provider.getLongpressMenuItem(mContext);
+ }
doLongClickCallback(x, y, menuItem);
}
@@ -1844,7 +1867,9 @@
getEntry().expandedIcon.setScrollX(0);
}
- mMenuRow.resetMenu();
+ if (mMenuRow != null) {
+ mMenuRow.resetMenu();
+ }
}
void onGutsOpened() {
@@ -1921,7 +1946,7 @@
getEntry().expandedIcon.setScrollX((int) -translationX);
}
- if (mMenuRow.getMenuView() != null) {
+ if (mMenuRow != null && mMenuRow.getMenuView() != null) {
mMenuRow.onParentTranslationUpdate(translationX);
}
}
@@ -1973,7 +1998,9 @@
mNotificationTranslationFinished = true;
}
if (!cancelled && leftTarget == 0) {
- mMenuRow.resetMenu();
+ if (mMenuRow != null) {
+ mMenuRow.resetMenu();
+ }
mTranslateAnim = null;
}
}
@@ -1982,7 +2009,7 @@
return translateAnim;
}
- public void inflateGuts() {
+ void ensureGutsInflated() {
if (mGuts == null) {
mGutsStub.inflate();
}
@@ -2438,7 +2465,7 @@
if (intrinsicBefore != getIntrinsicHeight() && intrinsicBefore != 0) {
notifyHeightChanged(true /* needsAnimation */);
}
- if (mMenuRow.getMenuView() != null) {
+ if (mMenuRow != null && mMenuRow.getMenuView() != null) {
mMenuRow.onParentHeightUpdate();
}
updateContentShiftHeight();
@@ -2641,7 +2668,7 @@
public long performRemoveAnimation(long duration, long delay, float translationDirection,
boolean isHeadsUpAnimation, float endLocation, Runnable onFinishedRunnable,
AnimatorListenerAdapter animationListener) {
- if (mMenuRow.isMenuVisible()) {
+ if (mMenuRow != null && mMenuRow.isMenuVisible()) {
Animator anim = getTranslateViewAnimator(0f, null /* listener */);
if (anim != null) {
anim.addListener(new AnimatorListenerAdapter() {
@@ -2712,7 +2739,7 @@
if (mGuts != null) {
mGuts.setActualHeight(height);
}
- if (mMenuRow.getMenuView() != null) {
+ if (mMenuRow != null && mMenuRow.getMenuView() != null) {
mMenuRow.onParentHeightUpdate();
}
}
@@ -2977,8 +3004,10 @@
default:
if (action == R.id.action_snooze) {
NotificationMenuRowPlugin provider = getProvider();
- if (provider == null) {
+ if (provider == null && mMenuRow != null) {
provider = createMenu();
+ } else {
+ return false;
}
MenuItem snoozeMenu = provider.getSnoozeMenuItem(getContext());
if (snoozeMenu != null) {
@@ -3109,7 +3138,9 @@
/** Sets whether dismiss gestures are right-to-left (instead of left-to-right). */
public void setDismissRtl(boolean dismissRtl) {
- mMenuRow.setDismissRtl(dismissRtl);
+ if (mMenuRow != null) {
+ mMenuRow.setDismissRtl(dismissRtl);
+ }
}
private static class NotificationViewState extends ExpandableViewState {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
index fbe9c5d..4700baa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
@@ -114,7 +114,7 @@
public void onHeightChanged(NotificationGuts guts);
}
- interface OnSettingsClickListener {
+ private interface OnSettingsClickListener {
void onClick(View v, int appUid);
}
@@ -271,6 +271,8 @@
double horz = Math.max(getWidth() - x, x);
double vert = Math.max(getHeight() - y, y);
float r = (float) Math.hypot(horz, vert);
+ // Make sure we'll be visible after the circular reveal
+ setAlpha(1f);
// Circular reveal originating at (x, y)
Animator a = ViewAnimationUtils.createCircularReveal(this, x, y, 0, r);
a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 69e6120..faa7898 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -165,8 +165,8 @@
}
}
- public boolean bindGuts(final ExpandableNotificationRow row) {
- row.inflateGuts();
+ private boolean bindGuts(final ExpandableNotificationRow row) {
+ row.ensureGutsInflated();
return bindGuts(row, mGutsMenuItem);
}
@@ -386,7 +386,7 @@
return false;
}
- row.inflateGuts();
+ row.ensureGutsInflated();
NotificationGuts guts = row.getGuts();
mNotificationGutsExposed = guts;
if (!bindGuts(row, menuItem)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index d83a158..ef7d20c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -25,6 +25,7 @@
import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
@@ -79,6 +80,7 @@
private OnMenuEventListener mMenuListener;
private boolean mDismissRtl;
private boolean mIsForeground;
+ private final boolean mIsUsingNewInterruptionModel;
private ValueAnimator mFadeAnimator;
private boolean mAnimating;
@@ -116,6 +118,7 @@
mHandler = new Handler(Looper.getMainLooper());
mLeftMenuItems = new ArrayList<>();
mRightMenuItems = new ArrayList<>();
+ mIsUsingNewInterruptionModel = NotificationUtils.useNewInterruptionModel(mContext);
}
@Override
@@ -252,13 +255,13 @@
mSnoozeItem = createSnoozeItem(mContext);
}
mAppOpsItem = createAppOpsItem(mContext);
- if (NotificationUtils.useNewInterruptionModel(mContext)) {
+ if (mIsUsingNewInterruptionModel) {
mInfoItem = createInfoItem(mContext, !mParent.getEntry().isHighPriority());
} else {
mInfoItem = createInfoItem(mContext);
}
- if (!NotificationUtils.useNewInterruptionModel(mContext)) {
+ if (!mIsUsingNewInterruptionModel) {
if (!isForeground) {
mRightMenuItems.add(mSnoozeItem);
}
@@ -268,10 +271,6 @@
} else {
ArrayList<MenuItem> menuItems = mDismissRtl ? mLeftMenuItems : mRightMenuItems;
menuItems.add(mInfoItem);
- menuItems.add(mAppOpsItem);
- if (!isForeground) {
- menuItems.add(mSnoozeItem);
- }
}
populateMenuViews();
@@ -617,6 +616,29 @@
// TODO -- handle / allow custom menu items!
}
+ @Override
+ public boolean shouldShowGutsOnSnapOpen() {
+ return mIsUsingNewInterruptionModel;
+ }
+
+ @Override
+ public MenuItem menuItemToExposeOnSnap() {
+ return mIsUsingNewInterruptionModel ? mInfoItem : null;
+ }
+
+ @Override
+ public Point getRevealAnimationOrigin() {
+ View v = mInfoItem.getMenuView();
+ int menuX = v.getLeft() + v.getPaddingLeft() + (v.getWidth() / 2);
+ int menuY = v.getTop() + v.getPaddingTop() + (v.getHeight() / 2);
+ if (isMenuOnLeft()) {
+ return new Point(menuX, menuY);
+ } else {
+ menuX = mParent.getRight() - menuX;
+ return new Point(menuX, menuY);
+ }
+ }
+
static MenuItem createSnoozeItem(Context context) {
Resources res = context.getResources();
NotificationSnooze content = (NotificationSnooze) LayoutInflater.from(context)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index bbb17c2..d11eab7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -38,6 +38,7 @@
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
@@ -1691,8 +1692,10 @@
ExpandableNotificationRow child = entry.getRow();
boolean animate = mIsExpanded || isPinnedHeadsUp(child);
// If the child is showing the notification menu snap to that
- float targetLeft = child.getProvider().isMenuVisible() ? child.getTranslation() : 0;
- mSwipeHelper.snapChildIfNeeded(child, animate, targetLeft);
+ if (child.getProvider() != null) {
+ float targetLeft = child.getProvider().isMenuVisible() ? child.getTranslation() : 0;
+ mSwipeHelper.snapChildIfNeeded(child, animate, targetLeft);
+ }
}
@Override
@@ -6143,8 +6146,24 @@
.setCategory(MetricsEvent.ACTION_REVEAL_GEAR)
.setType(MetricsEvent.TYPE_ACTION));
mHeadsUpManager.setMenuShown(notificationRow.getEntry(), true);
+ mSwipeHelper.onMenuShown(row);
+
+ // Check to see if we want to go directly to the notfication guts
+ NotificationMenuRowPlugin provider = notificationRow.getProvider();
+ if (provider.shouldShowGutsOnSnapOpen()) {
+ MenuItem item = provider.menuItemToExposeOnSnap();
+ if (item != null) {
+ Point origin = provider.getRevealAnimationOrigin();
+ mGutsManager.openGuts(row, origin.x, origin.y, item);
+ } else {
+ Log.e(TAG, "Provider has shouldShowGutsOnSnapOpen, but provided no "
+ + "menu item in menuItemtoExposeOnSnap. Skipping.");
+ }
+
+ // Close the menu row since we went directly to the guts
+ resetExposedMenuView(false, true);
+ }
}
- mSwipeHelper.onMenuShown(row);
}
};
@@ -6275,11 +6294,6 @@
mAmbientState.onDragFinished(animView);
updateContinuousShadowDrawing();
updateContinuousBackgroundDrawing();
- NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
- if (menuRow != null && targetLeft == 0) {
- menuRow.resetMenu();
- mSwipeHelper.clearCurrentMenuRow();
- }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 478427c..4569b66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -93,7 +93,17 @@
protected Handler getHandler() { return mHandler; }
@VisibleForTesting
- protected Runnable getFalsingCheck() { return mFalsingCheck; };
+ protected Runnable getFalsingCheck() {
+ return mFalsingCheck;
+ }
+
+ @Override
+ protected void onChildSnappedBack(View animView, float targetLeft) {
+ if (mCurrMenuRow != null && targetLeft == 0) {
+ mCurrMenuRow.resetMenu();
+ clearCurrentMenuRow();
+ }
+ }
@Override
public void onDownUpdate(View currView, MotionEvent ev) {
@@ -117,8 +127,10 @@
protected void initializeRow(ExpandableNotificationRow row) {
if (row.getEntry().hasFinishedInitialization()) {
mCurrMenuRow = row.createMenu();
- mCurrMenuRow.setMenuClickListener(mMenuListener);
- mCurrMenuRow.onTouchStart();
+ if (mCurrMenuRow != null) {
+ mCurrMenuRow.setMenuClickListener(mMenuListener);
+ mCurrMenuRow.onTouchStart();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
index 5dded52..541c142 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
@@ -51,6 +51,9 @@
* Reload the drawable from resource id, should reapply the previous dark intensity.
*/
public void updateIcon() {
+ if (getCurrentView() == null || !getCurrentView().isAttachedToWindow()) {
+ return;
+ }
final KeyButtonDrawable currentDrawable = getImageDrawable();
KeyButtonDrawable drawable = getNewDrawable();
if (currentDrawable != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
index 38df17a..02b660f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
@@ -112,23 +112,24 @@
* their icons for their buttons.
*/
public void updateIcons() {
- if (getCurrentView() == null || !getCurrentView().isAttachedToWindow()) {
- return;
- }
for (ButtonData data : mButtonData) {
data.button.updateIcon();
}
}
public void dump(PrintWriter pw) {
+ View view = getCurrentView();
pw.println("ContextualButtonGroup {");
pw.println(" getVisibleContextButton(): " + getVisibleContextButton());
pw.println(" isVisible(): " + isVisible());
+ pw.println(" attached(): " + (view != null && view.isAttachedToWindow()));
pw.println(" mButtonData [ ");
for (int i = mButtonData.size() - 1; i >= 0; --i) {
final ButtonData data = mButtonData.get(i);
+ view = data.button.getCurrentView();
pw.println(" " + i + ": markedVisible=" + data.markedVisible
+ " visible=" + data.button.getVisibility()
+ + " attached=" + (view != null && view.isAttachedToWindow())
+ " alpha=" + data.button.getAlpha());
}
pw.println(" ]");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 27394d9..6ebd6b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -263,8 +263,7 @@
return STATE_BIOMETRICS_ERROR;
} else if (mUnlockMethodCache.canSkipBouncer()) {
return STATE_LOCK_OPEN;
- } else if (mUnlockMethodCache.isFaceUnlockRunning()
- || updateMonitor.isFaceDetectionRunning()) {
+ } else if (updateMonitor.isFaceDetectionRunning()) {
return STATE_SCANNING_FACE;
} else {
return STATE_LOCKED;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 3dcadf1..6729f9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -202,7 +202,9 @@
@Override
public void onBackButtonAlphaChanged(float alpha, boolean animate) {
final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
- if (QuickStepContract.isGesturalMode(getContext())) {
+ final boolean useAltBack =
+ (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+ if (QuickStepContract.isGesturalMode(getContext()) && !useAltBack) {
// If property was changed to hide/show back button, going home will trigger
// launcher to to change the back button alpha to reflect property change
backButton.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 26aa617..a522ed1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -68,6 +68,7 @@
public static final String LEFT = "left";
public static final String RIGHT = "right";
public static final String CONTEXTUAL = "contextual";
+ public static final String IME_SWITCHER = "ime_switcher";
public static final String GRAVITY_SEPARATOR = ";";
public static final String BUTTON_SEPARATOR = ",";
@@ -164,17 +165,21 @@
@Override
public void onTuningChanged(String key, String newValue) {
if (NAV_BAR_VIEWS.equals(key)) {
- if (!Objects.equals(mCurrentLayout, newValue)) {
- mUsingCustomLayout = newValue != null;
- clearViews();
- inflateLayout(newValue);
- }
+ setNavigationBarLayout(newValue);
} else if (NAV_BAR_LEFT.equals(key) || NAV_BAR_RIGHT.equals(key)) {
clearViews();
inflateLayout(mCurrentLayout);
}
}
+ public void setNavigationBarLayout(String layoutValue) {
+ if (!Objects.equals(mCurrentLayout, layoutValue)) {
+ mUsingCustomLayout = layoutValue != null;
+ clearViews();
+ inflateLayout(layoutValue);
+ }
+ }
+
public void onLikelyDefaultLayoutChange() {
// Don't override custom layouts
if (mUsingCustomLayout) return;
@@ -401,6 +406,8 @@
v = inflater.inflate(R.layout.contextual, parent, false);
} else if (HOME_HANDLE.equals(button)) {
v = inflater.inflate(R.layout.home_handle, parent, false);
+ } else if (IME_SWITCHER.equals(button)) {
+ v = inflater.inflate(R.layout.ime_switcher, parent, false);
} else if (button.startsWith(KEY)) {
String uri = extractImage(button);
int code = extractKeycode(button);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 7abdbd0..e2a63cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -21,7 +21,6 @@
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS;
import android.animation.LayoutTransition;
import android.animation.LayoutTransition.TransitionListener;
@@ -35,6 +34,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ParceledListSlice;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Point;
@@ -48,6 +48,8 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
+import android.view.IPinnedStackController;
+import android.view.IPinnedStackListener;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
@@ -133,6 +135,7 @@
private boolean mUseCarModeUi = false;
private boolean mInCarMode = false;
private boolean mDockedStackExists;
+ private boolean mImeVisible;
private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
private final ContextualButtonGroup mContextualButtonGroup;
@@ -234,6 +237,45 @@
}
};
+ private final IPinnedStackListener.Stub mImeChangedListener = new IPinnedStackListener.Stub() {
+ @Override
+ public void onListenerRegistered(IPinnedStackController controller) {
+ }
+
+ @Override
+ public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+ post(() -> {
+ // TODO remove this and do below when mNavigationIconHints changes
+ if (imeVisible) {
+ getBackButton().setVisibility(VISIBLE);
+ reloadNavIcons();
+ } else {
+ getImeSwitchButton().setVisibility(GONE);
+ }
+ mImeVisible = imeVisible;
+ updateWindowTouchable();
+ });
+ }
+
+ @Override
+ public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+ }
+
+ @Override
+ public void onMinimizedStateChanged(boolean isMinimized) {
+ }
+
+ @Override
+ public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
+ Rect animatingBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment,
+ int displayRotation) {
+ }
+
+ @Override
+ public void onActionsChanged(ParceledListSlice actions) {
+ }
+ };
+
private BroadcastReceiver mOverlaysChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -472,6 +514,11 @@
return;
}
+ if (QuickStepContract.isGesturalMode(getContext())) {
+ drawable.setRotation(degrees);
+ return;
+ }
+
// Animate the back button's rotation to the new degrees and only in portrait move up the
// back button to line up with the other buttons
float targetY = !mOverviewProxyService.shouldShowSwipeUpUI() && !mIsVertical && useAltBack
@@ -574,8 +621,8 @@
// Always disable recents when alternate car mode UI is active and for secondary displays.
boolean disableRecent = isRecentsButtonDisabled();
- boolean disableBack = QuickStepContract.isGesturalMode(getContext())
- || (((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack);
+ boolean disableBack = !useAltBack && (QuickStepContract.isGesturalMode(getContext())
+ || ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0));
// When screen pinning, don't hide back and home when connected service or back and
// recents buttons when disconnected from launcher service in screen pinning mode,
@@ -715,6 +762,11 @@
setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery);
}
+ public void updateWindowTouchable() {
+ boolean touchable = mImeVisible || !QuickStepContract.isGesturalMode(getContext());
+ setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !touchable);
+ }
+
private void setWindowFlag(int flags, boolean enable) {
final ViewGroup navbarView = ((ViewGroup) getParent());
if (navbarView == null) {
@@ -734,7 +786,7 @@
}
private void onOverlaysChanged() {
- mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, null);
+ mNavigationInflaterView.setNavigationBarLayout(null);
// Color adaption is tied with showing home handle, only avaliable if visible
if (QuickStepContract.isGesturalMode(getContext())) {
@@ -1062,6 +1114,15 @@
filter.addDataScheme("package");
getContext().registerReceiver(mOverlaysChangedReceiver, filter);
mEdgeBackGestureHandler.onNavBarAttached();
+
+ if (QuickStepContract.isGesturalMode(getContext())) {
+ try {
+ WindowManagerWrapper.getInstance().addPinnedStackListener(mImeChangedListener);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register pinned stack listener", e);
+ }
+ }
+ updateWindowTouchable();
}
@Override
@@ -1078,6 +1139,8 @@
getContext().unregisterReceiver(mOverlaysChangedReceiver);
mEdgeBackGestureHandler.onNavBarDetached();
+
+ WindowManagerWrapper.getInstance().removePinnedStackListener(mImeChangedListener);
}
private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index bdd76c8..44c82c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -43,7 +43,6 @@
/** Whether the unlock method is currently insecure (insecure method or trusted environment) */
private boolean mCanSkipBouncer;
private boolean mTrustManaged;
- private boolean mFaceUnlockRunning;
private boolean mTrusted;
private UnlockMethodCache(Context ctx) {
@@ -93,16 +92,13 @@
boolean canSkipBouncer = !secure || mKeyguardUpdateMonitor.getUserCanSkipBouncer(user);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
- boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
- && trustManaged;
boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
- trustManaged != mTrustManaged || faceUnlockRunning != mFaceUnlockRunning;
+ trustManaged != mTrustManaged;
if (changed || updateAlways) {
mSecure = secure;
mCanSkipBouncer = canSkipBouncer;
mTrusted = trusted;
mTrustManaged = trustManaged;
- mFaceUnlockRunning = faceUnlockRunning;
notifyListeners();
}
Trace.endSection();
@@ -171,10 +167,6 @@
return mTrustManaged;
}
- public boolean isFaceUnlockRunning() {
- return mFaceUnlockRunning;
- }
-
public static interface OnUnlockMethodChangedListener {
void onUnlockMethodStateChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index 7705e4e..376c328 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -24,6 +24,7 @@
import android.view.View;
import com.android.keyguard.KeyguardClockSwitch;
+import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.qs.QSCarrierGroup;
import com.android.systemui.qs.QSFooterImpl;
@@ -136,6 +137,11 @@
* Creates the KeyguardClockSwitch.
*/
KeyguardClockSwitch createKeyguardClockSwitch();
+
+ /**
+ * Creates the KeyguardSliceView.
+ */
+ KeyguardSliceView createKeyguardSliceView();
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 190ce75..b3accbc 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -27,8 +27,10 @@
import androidx.slice.SliceSpecs;
import androidx.slice.builders.ListBuilder;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.KeyguardSliceProvider;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Assert;
import org.junit.Before;
@@ -49,7 +51,11 @@
@Before
public void setUp() throws Exception {
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
- mKeyguardSliceView = (KeyguardSliceView) LayoutInflater.from(getContext())
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater layoutInflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
+ mKeyguardSliceView = (KeyguardSliceView) layoutInflater
.inflate(R.layout.keyguard_status_area, null);
mSliceUri = Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI);
SliceProvider.setSpecs(new HashSet<>(Collections.singletonList(SliceSpecs.LIST)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 8380192..5f0839d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -186,7 +186,7 @@
when(row.getWindowToken()).thenReturn(new Binder());
when(row.getGuts()).thenReturn(guts);
- doNothing().when(row).inflateGuts();
+ doNothing().when(row).ensureGutsInflated();
NotificationEntry realEntry = realRow.getEntry();
NotificationEntry entry = spy(realEntry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index e6389c4..c62a802 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -14,6 +14,8 @@
package com.android.systemui.statusbar.notification.row;
+import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -26,6 +28,7 @@
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
+import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -39,6 +42,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.utils.leaks.LeakCheckedTest;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,6 +65,13 @@
when(mRow.getEntry()).thenReturn(entry);
}
+ @After
+ public void tearDown() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
+ }
+
+
@Test
public void testAttachDetach() {
NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
@@ -89,6 +100,9 @@
@Test
public void testNoAppOpsInSlowSwipe() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
+
NotificationMenuRow row = new NotificationMenuRow(mContext);
row.createMenu(mRow, null);
@@ -98,6 +112,19 @@
}
@Test
+ public void testNoAppOpsInSlowSwipe_newInterruptionModel() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+
+ NotificationMenuRow row = new NotificationMenuRow(mContext);
+ row.createMenu(mRow, null);
+
+ ViewGroup container = (ViewGroup) row.getMenuView();
+ // in the new interruption model there is only the blocking item
+ assertEquals(1, container.getChildCount());
+ }
+
+ @Test
public void testIsSnappedAndOnSameSide() {
NotificationMenuRow row = Mockito.spy(new NotificationMenuRow((mContext)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
index 6293b06..e3c081e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
@@ -36,6 +36,7 @@
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -173,6 +174,7 @@
}
@Test
+ @Ignore("b/112934365")
public void testUpdateIconsDarkIntensity() throws Exception {
final int unusedColor = 0;
final Drawable d = mock(Drawable.class);
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
index 23d2e7b..704ff2e 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -31,6 +31,6 @@
<bool name="config_navBarTapThrough">true</bool>
<!-- Controls the size of the back gesture inset. -->
- <dimen name="config_backGestureInset">48dp</dimen>
+ <dimen name="config_backGestureInset">20dp</dimen>
</resources>
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index ce39a70..a88ae9e 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7162,6 +7162,19 @@
// Open: Settings > app > bubble settings > confirmation dialog
DIALOG_APP_BUBBLE_SETTINGS = 1702;
+ // ACTION: Display white balance setting enabled or disabled.
+ // CATEGORY: SETTINGS
+ // OS: Q
+ ACTION_DISPLAY_WHITE_BALANCE_SETTING_CHANGED = 1703;
+
+ // Action: ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET
+ // Direct share target hashed with rotating salt
+ FIELD_HASHED_TARGET_NAME = 1704;
+
+ // Action: ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET
+ // Salt generation for the above hashed direct share target
+ FIELD_HASHED_TARGET_SALT_GEN = 1705;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 99bbcf8..7a1697f 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -18,16 +18,23 @@
import android.content.Context;
import android.content.pm.PackageManager;
+import android.gsi.GsiInstallParams;
import android.gsi.GsiProgress;
import android.gsi.IGsiService;
+import android.os.Environment;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.image.IDynamicSystemService;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
import android.util.Slog;
+import java.io.File;
+
/**
* DynamicSystemService implements IDynamicSystemService. It provides permission check before
* passing requests to gsid
@@ -36,7 +43,7 @@
private static final String TAG = "DynamicSystemService";
private static final String NO_SERVICE_ERROR = "no gsiservice";
private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
-
+ private static final String PATH_DEFAULT = "/data/gsi";
private Context mContext;
private volatile IGsiService mGsiService;
@@ -100,7 +107,32 @@
@Override
public boolean startInstallation(long systemSize, long userdataSize) throws RemoteException {
- return getGsiService().startGsiInstall(systemSize, userdataSize, true) == 0;
+ // priority from high to low: sysprop -> sdcard -> /data
+ String path = SystemProperties.get("os.aot.path");
+ if (path.isEmpty()) {
+ final int userId = UserHandle.myUserId();
+ final StorageVolume[] volumes =
+ StorageManager.getVolumeList(userId, StorageManager.FLAG_FOR_WRITE);
+ for (StorageVolume volume : volumes) {
+ if (volume.isEmulated()) continue;
+ if (!volume.isRemovable()) continue;
+ if (!Environment.MEDIA_MOUNTED.equals(volume.getState())) continue;
+ File sdCard = volume.getPathFile();
+ if (sdCard.isDirectory()) {
+ path = sdCard.getPath();
+ break;
+ }
+ }
+ if (path.isEmpty()) {
+ path = PATH_DEFAULT;
+ }
+ Slog.i(TAG, "startInstallation -> " + path);
+ }
+ GsiInstallParams installParams = new GsiInstallParams();
+ installParams.installDir = path;
+ installParams.gsiSize = systemSize;
+ installParams.userdataSize = userdataSize;
+ return getGsiService().beginGsiInstall(installParams) == 0;
}
@Override
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index d1ae284..3dc8af1 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -89,10 +89,10 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
-import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.HexDump;
import com.android.internal.util.Preconditions;
+import com.android.server.net.NetworkStatsFactory;
import com.google.android.collect.Maps;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index f86ba27..ae3324c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -720,10 +720,10 @@
}
}
- public void notePhoneDataConnectionState(int dataType, boolean hasData) {
+ public void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
+ mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType);
}
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 516844d..a64eacb 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -19,7 +19,6 @@
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.Manifest.permission.USE_FINGERPRINT;
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
@@ -576,30 +575,9 @@
if (useDefaultTitle) {
checkInternalPermission();
// Set the default title if necessary
- try {
- final List<ActivityManager.RunningAppProcessInfo> procs =
- ActivityManager.getService().getRunningAppProcesses();
- for (int i = 0; i < procs.size(); i++) {
- final ActivityManager.RunningAppProcessInfo info = procs.get(i);
- if (info.uid == callingUid
- && info.importance == IMPORTANCE_FOREGROUND) {
- PackageManager pm = getContext().getPackageManager();
- final CharSequence label = pm.getApplicationLabel(
- pm.getApplicationInfo(info.processName,
- PackageManager.GET_META_DATA));
- final String title = getContext()
- .getString(R.string.biometric_dialog_default_title, label);
- if (TextUtils.isEmpty(
- bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) {
- bundle.putCharSequence(BiometricPrompt.KEY_TITLE, title);
- }
- break;
- }
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception", e);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.e(TAG, "Name not found", e);
+ if (TextUtils.isEmpty(bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) {
+ bundle.putCharSequence(BiometricPrompt.KEY_TITLE,
+ getContext().getString(R.string.biometric_dialog_default_title));
}
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index d8e7b7d..c4855c3 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -1045,10 +1045,15 @@
}
} else {
currentClient.stop(initiatedByClient);
+
+ // Only post the reset runnable for non-cleanup clients. Cleanup clients should
+ // never be forcibly stopped since they ensure synchronization between HAL and
+ // framework. Thus, we should instead just start the pending client once cleanup
+ // finishes instead of using the reset runnable.
+ mHandler.removeCallbacks(mResetClientState);
+ mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
}
mPendingClient = newClient;
- mHandler.removeCallbacks(mResetClientState);
- mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
} else if (newClient != null) {
// For BiometricPrompt clients, do not start until
// <Biometric>Service#startPreparedClient is called. BiometricService waits until all
@@ -1225,6 +1230,7 @@
} else {
clearEnumerateState();
if (mPendingClient != null) {
+ Slog.d(getTag(), "Enumerate finished, starting pending client");
startClient(mPendingClient, false /* initiatedByClient */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 5e4bf33..c573bbb 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -397,61 +397,62 @@
}
@Override
- public boolean setFeature(int feature, boolean enabled, final byte[] token) {
+ public void setFeature(int feature, boolean enabled, final byte[] token,
+ IFaceServiceReceiver receiver) {
checkPermission(MANAGE_BIOMETRIC);
- if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
- Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
- return false;
- }
-
- final ArrayList<Byte> byteToken = new ArrayList<>();
- for (int i = 0; i < token.length; i++) {
- byteToken.add(token[i]);
- }
-
- // TODO: Support multiple faces
- final int faceId = getFirstTemplateForUser(mCurrentUserId);
-
- if (mDaemon != null) {
- try {
- return mDaemon.setFeature(feature, enabled, byteToken, faceId) == Status.OK;
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled,
- e);
+ mHandler.post(() -> {
+ if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+ Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
+ return;
}
- }
- return false;
+
+ final ArrayList<Byte> byteToken = new ArrayList<>();
+ for (int i = 0; i < token.length; i++) {
+ byteToken.add(token[i]);
+ }
+
+ // TODO: Support multiple faces
+ final int faceId = getFirstTemplateForUser(mCurrentUserId);
+
+ if (mDaemon != null) {
+ try {
+ final int result = mDaemon.setFeature(feature, enabled, byteToken, faceId);
+ receiver.onFeatureSet(result == Status.OK, feature);
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "Unable to set feature: " + feature
+ + " to enabled:" + enabled, e);
+ }
+ }
+ });
+
}
@Override
- public boolean getFeature(int feature) {
+ public void getFeature(int feature, IFaceServiceReceiver receiver) {
checkPermission(MANAGE_BIOMETRIC);
- // This should ideally return tri-state, but the user isn't shown settings unless
- // they are enrolled so it's fine for now.
- if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
- Slog.e(TAG, "No enrolled biometrics while getting feature: " + feature);
- return false;
- }
-
- // TODO: Support multiple faces
- final int faceId = getFirstTemplateForUser(mCurrentUserId);
-
- if (mDaemon != null) {
- try {
- OptionalBool result = mDaemon.getFeature(feature, faceId);
- if (result.status == Status.OK) {
- return result.value;
- } else {
- // Same tri-state comment applies here.
- return false;
- }
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to getRequireAttention", e);
+ mHandler.post(() -> {
+ // This should ideally return tri-state, but the user isn't shown settings unless
+ // they are enrolled so it's fine for now.
+ if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+ Slog.e(TAG, "No enrolled biometrics while getting feature: " + feature);
+ return;
}
- }
- return false;
+
+ // TODO: Support multiple faces
+ final int faceId = getFirstTemplateForUser(mCurrentUserId);
+
+ if (mDaemon != null) {
+ try {
+ OptionalBool result = mDaemon.getFeature(feature, faceId);
+ receiver.onFeatureGet(result.status == Status.OK, feature, result.value);
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "Unable to getRequireAttention", e);
+ }
+ }
+ });
+
}
@Override
diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
index 227ab23..4990ea1 100644
--- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java
+++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
@@ -91,7 +91,8 @@
if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
networkType, visible ? "" : "not "));
try {
- mBatteryStats.notePhoneDataConnectionState(networkType, visible);
+ mBatteryStats.notePhoneDataConnectionState(networkType, visible,
+ mServiceState.getState());
} catch (RemoteException e) {
Log.w(TAG, "Error noting data connection state", e);
}
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index da1360d..b6946023 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -469,7 +469,10 @@
*/
@VisibleForTesting
void sendPackagePermissionsToNetd(SparseIntArray netdPermissionsAppIds) {
-
+ if (mNetd == null) {
+ Log.e(TAG, "Failed to get the netd service");
+ return;
+ }
ArrayList<Integer> allPermissionAppIds = new ArrayList<>();
ArrayList<Integer> internetPermissionAppIds = new ArrayList<>();
ArrayList<Integer> updateStatsPermissionAppIds = new ArrayList<>();
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index e2ea42e..5fb67dd 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -572,9 +572,6 @@
public void onSwitchUser(@UserIdInt int newUserId) {
handleSettingsChange(true /* userSwitch */);
mBrightnessTracker.onSwitchUser(newUserId);
- if (mDisplayWhiteBalanceSettings != null) {
- mDisplayWhiteBalanceSettings.onSwitchUser();
- }
}
public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 4f81c03..9590f81 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -105,10 +105,12 @@
*/
private static final long TRANSITION_DURATION = 3000L;
- private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0;
- private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1;
- private static final int MSG_APPLY_GLOBAL_SATURATION = 2;
- private static final int MSG_APPLY_DISPLAY_WHITE_BALANCE = 3;
+ private static final int MSG_USER_CHANGED = 0;
+ private static final int MSG_SET_UP = 1;
+ private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 2;
+ private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 3;
+ private static final int MSG_APPLY_GLOBAL_SATURATION = 4;
+ private static final int MSG_APPLY_DISPLAY_WHITE_BALANCE = 5;
/**
* Return value if a setting has not been set.
@@ -186,7 +188,7 @@
// Register listeners now that boot is complete.
if (mCurrentUser != UserHandle.USER_NULL && mUserSetupObserver == null) {
- setUp();
+ mHandler.sendEmptyMessage(MSG_SET_UP);
}
}
}
@@ -196,7 +198,9 @@
super.onStartUser(userHandle);
if (mCurrentUser == UserHandle.USER_NULL) {
- onUserChanged(userHandle);
+ final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
+ message.arg1 = userHandle;
+ mHandler.sendMessage(message);
}
}
@@ -204,7 +208,9 @@
public void onSwitchUser(int userHandle) {
super.onSwitchUser(userHandle);
- onUserChanged(userHandle);
+ final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
+ message.arg1 = userHandle;
+ mHandler.sendMessage(message);
}
@Override
@@ -212,7 +218,9 @@
super.onStopUser(userHandle);
if (mCurrentUser == userHandle) {
- onUserChanged(UserHandle.USER_NULL);
+ final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
+ message.arg1 = UserHandle.USER_NULL;
+ mHandler.sendMessage(message);
}
}
@@ -262,7 +270,7 @@
// Listen for external changes to any of the settings.
if (mContentObserver == null) {
- mContentObserver = new ContentObserver(new Handler(DisplayThread.get().getLooper())) {
+ mContentObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
@@ -467,6 +475,9 @@
* Apply the accessibility daltonizer transform based on the settings value.
*/
private void onAccessibilityDaltonizerChanged() {
+ if (mCurrentUser == UserHandle.USER_NULL) {
+ return;
+ }
final boolean enabled = Secure.getIntForUser(getContext().getContentResolver(),
Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, mCurrentUser) != 0;
final int daltonizerMode = enabled ? Secure.getIntForUser(getContext().getContentResolver(),
@@ -490,6 +501,9 @@
* Apply the accessibility inversion transform based on the settings value.
*/
private void onAccessibilityInversionChanged() {
+ if (mCurrentUser == UserHandle.USER_NULL) {
+ return;
+ }
final boolean enabled = Secure.getIntForUser(getContext().getContentResolver(),
Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mCurrentUser) != 0;
final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
@@ -596,7 +610,19 @@
}
}
+ private boolean setDisplayWhiteBalanceSettingEnabled(boolean enabled) {
+ if (mCurrentUser == UserHandle.USER_NULL) {
+ return false;
+ }
+ return Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.DISPLAY_WHITE_BALANCE_ENABLED,
+ enabled ? 1 : 0, mCurrentUser);
+ }
+
private boolean isDisplayWhiteBalanceSettingEnabled() {
+ if (mCurrentUser == UserHandle.USER_NULL) {
+ return false;
+ }
return Secure.getIntForUser(getContext().getContentResolver(),
Secure.DISPLAY_WHITE_BALANCE_ENABLED, 0, mCurrentUser) == 1;
}
@@ -648,6 +674,9 @@
}
private int getNightDisplayAutoModeRawInternal() {
+ if (mCurrentUser == UserHandle.USER_NULL) {
+ return NOT_SET;
+ }
return Secure
.getIntForUser(getContext().getContentResolver(), Secure.NIGHT_DISPLAY_AUTO_MODE,
NOT_SET, mCurrentUser);
@@ -1214,6 +1243,13 @@
}
/**
+ * Returns whether Display white balance is currently enabled.
+ */
+ public boolean isDisplayWhiteBalanceEnabled() {
+ return isDisplayWhiteBalanceSettingEnabled();
+ }
+
+ /**
* Adds a {@link WeakReference<ColorTransformController>} for a newly started activity, and
* invokes {@link ColorTransformController#applyAppSaturation(float[], float[])} if needed.
*/
@@ -1233,7 +1269,7 @@
* Notify that the display white balance status has changed, either due to preemption by
* another transform or the feature being turned off.
*/
- void onDisplayWhiteBalanceStatusChanged(boolean enabled);
+ void onDisplayWhiteBalanceStatusChanged(boolean activated);
}
private final class TintHandler extends Handler {
@@ -1245,6 +1281,12 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case MSG_USER_CHANGED:
+ onUserChanged(msg.arg1);
+ break;
+ case MSG_SET_UP:
+ setUp();
+ break;
case MSG_APPLY_GLOBAL_SATURATION:
mGlobalSaturationTintController.setMatrix(msg.arg1);
applyTint(mGlobalSaturationTintController, false);
@@ -1500,6 +1542,29 @@
}
@Override
+ public boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
+ getContext().enforceCallingOrSelfPermission(
+ Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
+ "Permission required to set night display activated");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return setDisplayWhiteBalanceSettingEnabled(enabled);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public boolean isDisplayWhiteBalanceEnabled() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return isDisplayWhiteBalanceSettingEnabled();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
return;
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceSettings.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceSettings.java
index 1b7251c..6e78894 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceSettings.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceSettings.java
@@ -18,13 +18,9 @@
import android.annotation.NonNull;
import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.UserHandle;
-import android.provider.Settings.Secure;
import android.util.Slog;
import com.android.internal.util.Preconditions;
@@ -46,22 +42,19 @@
protected static final String TAG = "DisplayWhiteBalanceSettings";
protected boolean mLoggingEnabled;
- private static final String SETTING_URI = Secure.DISPLAY_WHITE_BALANCE_ENABLED;
- private static final int SETTING_DEFAULT = 0;
- private static final int SETTING_ENABLED = 1;
-
private static final int MSG_SET_ACTIVE = 1;
private final Context mContext;
private final Handler mHandler;
- private final SettingsObserver mSettingsObserver;
+
+ private final ColorDisplayServiceInternal mCdsi;
// To decouple the DisplayPowerController from the DisplayWhiteBalanceSettings, the DPC
// implements Callbacks and passes itself to the DWBS so it can call back into it without
// knowing about it.
private Callbacks mCallbacks;
- private int mSetting;
+ private boolean mEnabled;
private boolean mActive;
/**
@@ -79,18 +72,12 @@
mLoggingEnabled = false;
mContext = context;
mHandler = new DisplayWhiteBalanceSettingsHandler(handler.getLooper());
- mSettingsObserver = new SettingsObserver(mHandler);
- mSetting = getSetting();
- mActive = false;
mCallbacks = null;
- mContext.getContentResolver().registerContentObserver(
- Secure.getUriFor(SETTING_URI), false /* notifyForDescendants */, mSettingsObserver,
- UserHandle.USER_ALL);
-
- ColorDisplayServiceInternal cds =
- LocalServices.getService(ColorDisplayServiceInternal.class);
- cds.setDisplayWhiteBalanceListener(this);
+ mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class);
+ setEnabled(mCdsi.isDisplayWhiteBalanceEnabled());
+ final boolean isActive = mCdsi.setDisplayWhiteBalanceListener(this);
+ setActive(isActive);
}
/**
@@ -99,7 +86,7 @@
* @param callbacks
* The object to call back to.
*
- * @return Whether the method suceeded or not.
+ * @return Whether the method succeeded or not.
*/
public boolean setCallbacks(Callbacks callbacks) {
if (mCallbacks == callbacks) {
@@ -131,14 +118,7 @@
* @return Whether display white-balance is enabled.
*/
public boolean isEnabled() {
- return (mSetting == SETTING_ENABLED) && mActive;
- }
-
- /**
- * Re-evaluate state after switching to a new user.
- */
- public void onSwitchUser() {
- handleSettingChange();
+ return mEnabled && mActive;
}
/**
@@ -152,15 +132,14 @@
writer.println(" mLoggingEnabled=" + mLoggingEnabled);
writer.println(" mContext=" + mContext);
writer.println(" mHandler=" + mHandler);
- writer.println(" mSettingsObserver=" + mSettingsObserver);
- writer.println(" mSetting=" + mSetting);
+ writer.println(" mEnabled=" + mEnabled);
writer.println(" mActive=" + mActive);
writer.println(" mCallbacks=" + mCallbacks);
}
@Override
- public void onDisplayWhiteBalanceStatusChanged(boolean active) {
- Message msg = mHandler.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, 0);
+ public void onDisplayWhiteBalanceStatusChanged(boolean activated) {
+ Message msg = mHandler.obtainMessage(MSG_SET_ACTIVE, activated ? 1 : 0, 0);
msg.sendToTarget();
}
@@ -169,20 +148,14 @@
Preconditions.checkNotNull(handler, "handler must not be null");
}
- private int getSetting() {
- return Secure.getIntForUser(mContext.getContentResolver(), SETTING_URI, SETTING_DEFAULT,
- UserHandle.USER_CURRENT);
- }
-
- private void handleSettingChange() {
- final int setting = getSetting();
- if (mSetting == setting) {
+ private void setEnabled(boolean enabled) {
+ if (mEnabled == enabled) {
return;
}
if (mLoggingEnabled) {
- Slog.d(TAG, "Setting: " + setting);
+ Slog.d(TAG, "Setting: " + enabled);
}
- mSetting = setting;
+ mEnabled = enabled;
if (mCallbacks != null) {
mCallbacks.updateWhiteBalance();
}
@@ -201,17 +174,6 @@
}
}
- private final class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- handleSettingChange();
- }
- }
-
private final class DisplayWhiteBalanceSettingsHandler extends Handler {
DisplayWhiteBalanceSettingsHandler(Looper looper) {
super(looper, null, true /* async */);
@@ -222,6 +184,7 @@
switch (msg.what) {
case MSG_SET_ACTIVE:
setActive(msg.arg1 != 0);
+ setEnabled(mCdsi.isDisplayWhiteBalanceEnabled());
break;
}
}
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
similarity index 99%
rename from core/java/com/android/internal/net/NetworkStatsFactory.java
rename to services/core/java/com/android/server/net/NetworkStatsFactory.java
index f848346..af299cf 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.net;
+package com.android.server.net;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.TAG_ALL;
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 205ddb0..1559911 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -130,7 +130,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e62714e..78aa5a0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4700,6 +4700,11 @@
if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
continue;
}
+
+ if (ps.pkg.isSystem()) {
+ continue;
+ }
+
if (packagesToDelete == null) {
packagesToDelete = new ArrayList<>();
}
@@ -5149,7 +5154,7 @@
continue;
}
- if (!ps.getUserState().get(userId).isAvailable(flags)) {
+ if (!ps.readUserState(userId).isAvailable(flags)) {
continue;
}
@@ -6980,8 +6985,7 @@
}
final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
if (ps == null
- || ps.getUserState().get(userId) == null
- || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
+ || !ps.readUserState(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
return result;
}
final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b64abdb..10ae782 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -224,6 +224,7 @@
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
+import android.view.inputmethod.InputMethodSystemProperty;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -6436,6 +6437,10 @@
*/
@Override
public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
+ // Update display configuration for IME process only when Single-client IME window
+ // moving to another display.
+ if (!InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) return;
+
if (pid == MY_PID || pid < 0) {
if (DEBUG_CONFIGURATION) {
Slog.w(TAG,
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index bbb857f..6ae7720 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -49,7 +49,7 @@
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
@@ -211,7 +211,6 @@
private final boolean mCarDockEnablesAccelerometer;
private final boolean mDeskDockEnablesAccelerometer;
- private final boolean mTranslucentDecorEnabled;
private final AccessibilityManager mAccessibilityManager;
private final ImmersiveModeConfirmation mImmersiveModeConfirmation;
private final ScreenshotHelper mScreenshotHelper;
@@ -434,7 +433,6 @@
final Resources r = mContext.getResources();
mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
- mTranslucentDecorEnabled = r.getBoolean(R.bool.config_enableTranslucentDecor);
mForceShowSystemBarsFromExternal = r.getBoolean(R.bool.config_forceShowSystemBars);
mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
@@ -1287,14 +1285,12 @@
private static int getImpliedSysUiFlagsForLayout(LayoutParams attrs) {
int impliedFlags = 0;
- if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
- impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
- }
- final boolean forceWindowDrawsStatusBarBackground =
- (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+ final boolean forceWindowDrawsBarBackgrounds =
+ (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0
+ && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT;
if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
- || forceWindowDrawsStatusBarBackground
- && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT) {
+ || forceWindowDrawsBarBackgrounds) {
+ impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
}
return impliedFlags;
@@ -1396,9 +1392,6 @@
navTranslucent &= !immersiveSticky; // transient trumps translucent
boolean isKeyguardShowing = isStatusBarKeyguard()
&& !mService.mPolicy.isKeyguardOccluded();
- if (!isKeyguardShowing) {
- navTranslucent &= areTranslucentBarsAllowed();
- }
boolean statusBarForcesShowingNavigation = !isKeyguardShowing && mStatusBar != null
&& (mStatusBar.getAttrs().privateFlags
& PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
@@ -1560,9 +1553,6 @@
boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
boolean statusBarTranslucent = (sysui
& (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0;
- if (!isKeyguardShowing) {
- statusBarTranslucent &= areTranslucentBarsAllowed();
- }
// If the status bar is hidden, we don't want to cause windows behind it to scroll.
if (mStatusBar.isVisibleLw() && !statusBarTransient) {
@@ -1915,13 +1905,14 @@
&& (fl & FLAG_FULLSCREEN) == 0
&& (fl & FLAG_TRANSLUCENT_STATUS) == 0
&& (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
- && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) {
+ && (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) {
// Ensure policy decor includes status bar
dcf.top = displayFrames.mStable.top;
}
if ((fl & FLAG_TRANSLUCENT_NAVIGATION) == 0
&& (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
- && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
+ && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
+ && (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) {
// Ensure policy decor includes navigation bar
dcf.bottom = displayFrames.mStable.bottom;
dcf.right = displayFrames.mStable.right;
@@ -3148,6 +3139,8 @@
drawsStatusBarBackground(vis, mTopFullscreenOpaqueWindowState);
final boolean dockedDrawsStatusBarBackground =
drawsStatusBarBackground(dockedVis, mTopDockedOpaqueWindowState);
+ final boolean fullscreenDrawsNavBarBackground =
+ drawsNavigationBarBackground(vis, mTopFullscreenOpaqueWindowState);
// prevent status bar interaction from clearing certain flags
int type = win.getAttrs().type;
@@ -3167,12 +3160,12 @@
if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) {
vis |= View.STATUS_BAR_TRANSPARENT;
vis &= ~View.STATUS_BAR_TRANSLUCENT;
- } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar)
- || forceOpaqueStatusBar) {
+ } else if (forceOpaqueStatusBar) {
vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT);
}
- vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing);
+ vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing,
+ fullscreenDrawsNavBarBackground);
// update status bar
boolean immersiveSticky =
@@ -3256,8 +3249,9 @@
return vis;
}
- private boolean drawsStatusBarBackground(int vis, WindowState win) {
- if (!mStatusBarController.isTransparentAllowed(win)) {
+ private boolean drawsBarBackground(int vis, WindowState win, BarController controller,
+ int translucentFlag) {
+ if (!controller.isTransparentAllowed(win)) {
return false;
}
if (win == null) {
@@ -3267,9 +3261,17 @@
final boolean drawsSystemBars =
(win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
final boolean forceDrawsSystemBars =
- (win.getAttrs().privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+ (win.getAttrs().privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
- return forceDrawsSystemBars || drawsSystemBars && (vis & View.STATUS_BAR_TRANSLUCENT) == 0;
+ return forceDrawsSystemBars || drawsSystemBars && (vis & translucentFlag) == 0;
+ }
+
+ private boolean drawsStatusBarBackground(int vis, WindowState win) {
+ return drawsBarBackground(vis, win, mStatusBarController, FLAG_TRANSLUCENT_STATUS);
+ }
+
+ private boolean drawsNavigationBarBackground(int vis, WindowState win) {
+ return drawsBarBackground(vis, win, mNavigationBarController, FLAG_TRANSLUCENT_NAVIGATION);
}
/**
@@ -3277,10 +3279,13 @@
* on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
*/
private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
- boolean freeformStackVisible, boolean isDockedDividerResizing) {
+ boolean freeformStackVisible, boolean isDockedDividerResizing,
+ boolean fullscreenDrawsBackground) {
if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
visibility = setNavBarOpaqueFlag(visibility);
+ } else if (fullscreenDrawsBackground) {
+ visibility = setNavBarTransparentFlag(visibility);
}
} else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
if (isDockedDividerResizing) {
@@ -3292,9 +3297,6 @@
}
}
- if (!areTranslucentBarsAllowed()) {
- visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT;
- }
return visibility;
}
@@ -3307,6 +3309,11 @@
return visibility | View.NAVIGATION_BAR_TRANSLUCENT;
}
+ private int setNavBarTransparentFlag(int visibility) {
+ visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT;
+ return visibility | View.NAVIGATION_BAR_TRANSPARENT;
+ }
+
private void clearClearableFlagsLw() {
int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
if (newVal != mResettingSystemUiFlags) {
@@ -3338,16 +3345,6 @@
return (systemUiFlags & disableNavigationBar) == disableNavigationBar;
}
- /**
- * @return whether the navigation or status bar can be made translucent
- *
- * This should return true unless touch exploration is not enabled or
- * R.boolean.config_enableTranslucentDecor is false.
- */
- private boolean areTranslucentBarsAllowed() {
- return mTranslucentDecorEnabled;
- }
-
boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
int newRotation) {
// For the upside down rotation we don't rotate seamlessly as the navigation
diff --git a/services/core/java/com/android/server/wm/NavigationBarExperiments.java b/services/core/java/com/android/server/wm/NavigationBarExperiments.java
index b74fb45..bb3ff5e 100644
--- a/services/core/java/com/android/server/wm/NavigationBarExperiments.java
+++ b/services/core/java/com/android/server/wm/NavigationBarExperiments.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
@@ -91,7 +90,7 @@
* @param w the window that is being offset by experiment
*/
public void offsetWindowFramesForNavBar(int navPosition, WindowState w) {
- if (w.getAttrs().type != TYPE_INPUT_METHOD && w.getActivityType() != ACTIVITY_TYPE_HOME) {
+ if (w.getAttrs().type != TYPE_INPUT_METHOD) {
return;
}
@@ -102,6 +101,7 @@
int navHeight = getNavigationBarFrameHeight() - getNavigationBarHeight();
if (navHeight > 0) {
cf.bottom -= navHeight;
+ windowFrames.mStableFrame.bottom -= navHeight;
}
break;
case NAV_BAR_LEFT:
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index dafed9e..39b5662 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -29,8 +29,10 @@
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
@@ -104,7 +106,7 @@
| FLAG_SCALED
| FLAG_SECURE;
- private static final int PRIVATE_FLAG_INHERITS = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+ private static final int PRIVATE_FLAG_INHERITS = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM;
private static final int MSG_REPORT_DRAW = 0;
@@ -493,10 +495,12 @@
mWindowPrivateFlags = windowPrivateFlags;
mSysUiVis = sysUiVis;
final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
- mStatusBarColor = DecorView.calculateStatusBarColor(windowFlags,
- context.getColor(R.color.system_bar_background_semi_transparent),
- statusBarColor);
- mNavigationBarColor = navigationBarColor;
+ final int semiTransparent = context.getColor(
+ R.color.system_bar_background_semi_transparent);
+ mStatusBarColor = DecorView.calculateBarColor(windowFlags, FLAG_TRANSLUCENT_STATUS,
+ semiTransparent, statusBarColor);
+ mNavigationBarColor = DecorView.calculateBarColor(windowFlags,
+ FLAG_TRANSLUCENT_NAVIGATION, semiTransparent, navigationBarColor);
mStatusBarPaint.setColor(mStatusBarColor);
mNavigationBarPaint.setColor(navigationBarColor);
}
@@ -507,10 +511,10 @@
}
int getStatusBarColorViewHeight() {
- final boolean forceStatusBarBackground =
- (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+ final boolean forceBarBackground =
+ (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
- mSysUiVis, mStatusBarColor, mWindowFlags, forceStatusBarBackground)) {
+ mSysUiVis, mStatusBarColor, mWindowFlags, forceBarBackground)) {
return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
} else {
return 0;
@@ -518,8 +522,10 @@
}
private boolean isNavigationBarColorViewVisible() {
+ final boolean forceBarBackground =
+ (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
return NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
- mSysUiVis, mNavigationBarColor, mWindowFlags, false /* force */);
+ mSysUiVis, mNavigationBarColor, mWindowFlags, forceBarBackground);
}
void drawDecors(Canvas c, @Nullable Rect alreadyDrawnFrame) {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index a7423ea..e1318af 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -52,6 +52,7 @@
"com_android_server_GraphicsStatsService.cpp",
"com_android_server_am_AppCompactor.cpp",
"onload.cpp",
+ ":lib_networkStatsFactory_native",
],
include_dirs: [
@@ -151,3 +152,10 @@
}
}
}
+
+filegroup {
+ name: "lib_networkStatsFactory_native",
+ srcs: [
+ "com_android_server_net_NetworkStatsFactory.cpp",
+ ],
+}
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
similarity index 87%
rename from core/jni/com_android_internal_net_NetworkStatsFactory.cpp
rename to services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
index 8259ffc..9cd743b 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
@@ -21,9 +21,9 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include <core_jni_helpers.h>
#include <jni.h>
+#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativehelper/ScopedPrimitiveArray.h>
@@ -333,29 +333,27 @@
(void*) readNetworkStatsDev },
};
-int register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) {
- int err = RegisterMethodsOrDie(env,
- "com/android/internal/net/NetworkStatsFactory", gMethods,
+int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
+ int err = jniRegisterNativeMethods(env, "com/android/server/net/NetworkStatsFactory", gMethods,
NELEM(gMethods));
+ gStringClass = env->FindClass("java/lang/String");
+ gStringClass = static_cast<jclass>(env->NewGlobalRef(gStringClass));
- gStringClass = FindClassOrDie(env, "java/lang/String");
- gStringClass = MakeGlobalRefOrDie(env, gStringClass);
-
- jclass clazz = FindClassOrDie(env, "android/net/NetworkStats");
- gNetworkStatsClassInfo.size = GetFieldIDOrDie(env, clazz, "size", "I");
- gNetworkStatsClassInfo.capacity = GetFieldIDOrDie(env, clazz, "capacity", "I");
- gNetworkStatsClassInfo.iface = GetFieldIDOrDie(env, clazz, "iface", "[Ljava/lang/String;");
- gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I");
- gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I");
- gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
- gNetworkStatsClassInfo.metered = GetFieldIDOrDie(env, clazz, "metered", "[I");
- gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
- gNetworkStatsClassInfo.defaultNetwork = GetFieldIDOrDie(env, clazz, "defaultNetwork", "[I");
- gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
- gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");
- gNetworkStatsClassInfo.txBytes = GetFieldIDOrDie(env, clazz, "txBytes", "[J");
- gNetworkStatsClassInfo.txPackets = GetFieldIDOrDie(env, clazz, "txPackets", "[J");
- gNetworkStatsClassInfo.operations = GetFieldIDOrDie(env, clazz, "operations", "[J");
+ jclass clazz = env->FindClass("android/net/NetworkStats");
+ gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I");
+ gNetworkStatsClassInfo.capacity = env->GetFieldID(clazz, "capacity", "I");
+ gNetworkStatsClassInfo.iface = env->GetFieldID(clazz, "iface", "[Ljava/lang/String;");
+ gNetworkStatsClassInfo.uid = env->GetFieldID(clazz, "uid", "[I");
+ gNetworkStatsClassInfo.set = env->GetFieldID(clazz, "set", "[I");
+ gNetworkStatsClassInfo.tag = env->GetFieldID(clazz, "tag", "[I");
+ gNetworkStatsClassInfo.metered = env->GetFieldID(clazz, "metered", "[I");
+ gNetworkStatsClassInfo.roaming = env->GetFieldID(clazz, "roaming", "[I");
+ gNetworkStatsClassInfo.defaultNetwork = env->GetFieldID(clazz, "defaultNetwork", "[I");
+ gNetworkStatsClassInfo.rxBytes = env->GetFieldID(clazz, "rxBytes", "[J");
+ gNetworkStatsClassInfo.rxPackets = env->GetFieldID(clazz, "rxPackets", "[J");
+ gNetworkStatsClassInfo.txBytes = env->GetFieldID(clazz, "txBytes", "[J");
+ gNetworkStatsClassInfo.txPackets = env->GetFieldID(clazz, "txPackets", "[J");
+ gNetworkStatsClassInfo.operations = env->GetFieldID(clazz, "operations", "[J");
return err;
}
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 2cfaebf..cce96ff 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -52,6 +52,7 @@
int register_android_server_SyntheticPasswordManager(JNIEnv* env);
int register_android_server_GraphicsStatsService(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
+int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
int register_android_server_security_VerityUtils(JNIEnv* env);
int register_android_server_am_AppCompactor(JNIEnv* env);
@@ -100,6 +101,7 @@
register_android_server_SyntheticPasswordManager(env);
register_android_server_GraphicsStatsService(env);
register_android_hardware_display_DisplayViewport(env);
+ register_android_server_net_NetworkStatsFactory(env);
register_android_server_net_NetworkStatsService(env);
register_android_server_security_VerityUtils(env);
register_android_server_am_AppCompactor(env);
diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
index 9685ff6..22978a2 100644
--- a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
@@ -30,12 +30,15 @@
/** Converts this OnBlobRetrievedListener to a parcelable object */
@NonNull
- static IOnBlobRetrievedListener toAIDL(final OnBlobRetrievedListener listener) {
+ static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) {
return new IOnBlobRetrievedListener.Stub() {
@Override
public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key,
final String name, final Blob blob) {
- listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+ }
}
};
}
diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
index 80209c5..9e7c1c8 100644
--- a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
@@ -30,12 +30,15 @@
/** Converts this OnL2KeyResponseListener to a parcelable object */
@NonNull
- static IOnL2KeyResponseListener toAIDL(final OnL2KeyResponseListener listener) {
+ static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) {
return new IOnL2KeyResponseListener.Stub() {
@Override
public void onL2KeyResponse(final StatusParcelable statusParcelable,
final String l2Key) {
- listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+ }
}
};
}
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
index f0f6f40..59da268 100644
--- a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -31,15 +31,18 @@
/** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */
@NonNull
static IOnNetworkAttributesRetrievedListener toAIDL(
- final OnNetworkAttributesRetrievedListener listener) {
+ @NonNull final OnNetworkAttributesRetrievedListener listener) {
return new IOnNetworkAttributesRetrievedListener.Stub() {
@Override
public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable,
final String l2Key,
final NetworkAttributesParcelable networkAttributesParcelable) {
- listener.onNetworkAttributesRetrieved(
- new Status(statusParcelable), l2Key,
- new NetworkAttributes(networkAttributesParcelable));
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onNetworkAttributesRetrieved(
+ new Status(statusParcelable), l2Key,
+ new NetworkAttributes(networkAttributesParcelable));
+ }
}
};
}
diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
index ba1e0e6..0154fd2 100644
--- a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
@@ -30,14 +30,18 @@
/** Converts this OnSameL3NetworkResponseListener to a parcelable object */
@NonNull
- static IOnSameL3NetworkResponseListener toAIDL(final OnSameL3NetworkResponseListener listener) {
+ static IOnSameL3NetworkResponseListener toAIDL(
+ @NonNull final OnSameL3NetworkResponseListener listener) {
return new IOnSameL3NetworkResponseListener.Stub() {
@Override
public void onSameL3NetworkResponse(final StatusParcelable statusParcelable,
final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) {
- listener.onSameL3NetworkResponse(
- new Status(statusParcelable),
- new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onSameL3NetworkResponse(
+ new Status(statusParcelable),
+ new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+ }
}
};
}
diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
index 0de1666..824b7b0 100644
--- a/services/net/java/android/net/ipmemorystore/OnStatusListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
@@ -17,6 +17,7 @@
package android.net.ipmemorystore;
import android.annotation.NonNull;
+import android.annotation.Nullable;
/**
* A listener for the IpMemoryStore to return a status to a client.
@@ -30,11 +31,13 @@
/** Converts this OnStatusListener to a parcelable object */
@NonNull
- static IOnStatusListener toAIDL(final OnStatusListener listener) {
+ static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) {
return new IOnStatusListener.Stub() {
@Override
public void onComplete(final StatusParcelable statusParcelable) {
- listener.onComplete(new Status(statusParcelable));
+ if (null != listener) {
+ listener.onComplete(new Status(statusParcelable));
+ }
}
};
}
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 46d0761..231025c 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -484,9 +484,6 @@
private void waitForHandlerToComplete(Handler handler, long waitTimeMs)
throws InterruptedException {
- if (!handler.hasMessagesOrCallbacks()) { // if nothing queued, do not wait.
- return;
- }
final Object lock = new Object();
synchronized (lock) {
handler.post(() -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 03969da..e90f094 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -27,7 +27,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -142,20 +142,20 @@
}
@Test
- public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
+ public void layoutWindowLw_appWontDrawBars_forceStatusAndNav() throws Exception {
synchronized (mWm.mGlobalLock) {
mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+ mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index bdd01e2..fb82ca6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5267,6 +5267,18 @@
* Use this method when no subscriptions are available on the SIM and the operation must be
* performed using the physical slot index.
*
+ * This operation wraps two APDU instructions:
+ * <ul>
+ * <li>MANAGE CHANNEL to open a logical channel</li>
+ * <li>SELECT the given {@code AID} using the given {@code p2}</li>
+ * </ul>
+ *
+ * Per Open Mobile API Specification v3.2 section 6.2.7.h, only p2 values of 0x00, 0x04, 0x08,
+ * and 0x0C are guaranteed to be supported.
+ *
+ * If the SELECT command's status word is not '9000', '62xx', or '63xx', the status word will be
+ * considered an error and the channel shall not be opened.
+ *
* Input parameters equivalent to TS 27.007 AT+CCHO command.
*
* <p>Requires Permission:
@@ -5298,6 +5310,18 @@
/**
* Opens a logical channel to the ICC card.
*
+ * This operation wraps two APDU instructions:
+ * <ul>
+ * <li>MANAGE CHANNEL to open a logical channel</li>
+ * <li>SELECT the given {@code AID} using the given {@code p2}</li>
+ * </ul>
+ *
+ * Per Open Mobile API Specification v3.2 section 6.2.7.h, only p2 values of 0x00, 0x04, 0x08,
+ * and 0x0C are guaranteed to be supported.
+ *
+ * If the SELECT command's status word is not '9000', '62xx', or '63xx', the status word will be
+ * considered an error and the channel shall not be opened.
+ *
* Input parameters equivalent to TS 27.007 AT+CCHO command.
*
* <p>Requires Permission:
@@ -5315,6 +5339,18 @@
/**
* Opens a logical channel to the ICC card.
*
+ * This operation wraps two APDU instructions:
+ * <ul>
+ * <li>MANAGE CHANNEL to open a logical channel</li>
+ * <li>SELECT the given {@code AID} using the given {@code p2}</li>
+ * </ul>
+ *
+ * Per Open Mobile API Specification v3.2 section 6.2.7.h, only p2 values of 0x00, 0x04, 0x08,
+ * and 0x0C are guaranteed to be supported.
+ *
+ * If the SELECT command's status word is not '9000', '62xx', or '63xx', the status word will be
+ * considered an error and the channel shall not be opened.
+ *
* Input parameters equivalent to TS 27.007 AT+CCHO command.
*
* <p>Requires Permission:
diff --git a/tests/benchmarks/Android.bp b/tests/benchmarks/Android.bp
new file mode 100644
index 0000000..f16ddb9
--- /dev/null
+++ b/tests/benchmarks/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 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.
+
+// build framework base core benchmarks
+// ============================================================
+
+java_library {
+ name: "networkStatsFactory-benchmarks",
+ installable: true,
+
+ srcs: ["src/**/*.java"],
+
+ libs: [
+ "caliper-api-target",
+ "services.core",
+ ],
+
+}
diff --git a/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java b/tests/benchmarks/src/com/android/server/net/NetworkStatsFactoryBenchmark.java
similarity index 95%
rename from core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
rename to tests/benchmarks/src/com/android/server/net/NetworkStatsFactoryBenchmark.java
index c213464..ef014f0 100644
--- a/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
+++ b/tests/benchmarks/src/com/android/server/net/NetworkStatsFactoryBenchmark.java
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package com.android.internal.net;
+package com.android.server.net;
import android.net.NetworkStats;
import android.os.SystemClock;
+import com.android.server.net.NetworkStatsFactory;
import com.google.caliper.AfterExperiment;
import com.google.caliper.BeforeExperiment;
import java.io.File;
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index c62d85e..70b4089 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -1,11 +1,8 @@
//########################################################################
// Build FrameworksNetTests package
//########################################################################
-
-android_test {
- name: "FrameworksNetTests",
- // Include all test java files.
- srcs: ["java/**/*.java"],
+java_defaults {
+ name: "FrameworksNetTests-jni-defaults",
static_libs: [
"frameworks-base-testutils",
"framework-protos",
@@ -20,6 +17,53 @@
"android.test.base",
"android.test.mock",
],
+ jni_libs: [
+ "ld-android",
+ "libartbase",
+ "libbacktrace",
+ "libbase",
+ "libbinder",
+ "libbinderthreadstate",
+ "libbpf",
+ "libbpf_android",
+ "libc++",
+ "libcgrouprc",
+ "libcrypto",
+ "libcutils",
+ "libdexfile",
+ "libdl_android",
+ "libhidl-gen-utils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libjsoncpp",
+ "liblog",
+ "liblzma",
+ "libnativehelper",
+ "libnetdbpf",
+ "libnetdutils",
+ "libpackagelistparser",
+ "libpcre2",
+ "libprocessgroup",
+ "libselinux",
+ "libui",
+ "libutils",
+ "libvintf",
+ "libvndksupport",
+ "libtinyxml2",
+ "libunwindstack",
+ "libutilscallstack",
+ "libziparchive",
+ "libz",
+ "netd_aidl_interface-cpp",
+ "libnetworkstatsfactorytestjni",
+ ],
+}
+
+android_test {
+ name: "FrameworksNetTests",
+ defaults: ["FrameworksNetTests-jni-defaults"],
+ srcs: ["java/**/*.java"],
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/tests/net/java/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
index b6038ab..8b2b4e3 100644
--- a/tests/net/java/android/net/netlink/InetDiagSocketTest.java
+++ b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
@@ -189,7 +189,6 @@
udp.close();
}
- @Test
public void testGetConnectionOwnerUid() throws Exception {
checkGetConnectionOwnerUid("::", null);
checkGetConnectionOwnerUid("::", "::");
diff --git a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
similarity index 96%
rename from tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
rename to tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
index 4ec4fdd..95bc7d9 100644
--- a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.net;
+package com.android.server.net;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.METERED_NO;
@@ -70,6 +70,10 @@
IoUtils.deleteContents(mTestProc);
}
+ // The libandroid_servers which have the native method is not available to
+ // applications. So in order to have a test support native library, the native code
+ // related to networkStatsFactory is compiled to a minimal native library and loaded here.
+ System.loadLibrary("networkstatsfactorytestjni");
mFactory = new NetworkStatsFactory(mTestProc, false);
}
diff --git a/tests/net/jni/Android.bp b/tests/net/jni/Android.bp
new file mode 100644
index 0000000..9225ffb
--- /dev/null
+++ b/tests/net/jni/Android.bp
@@ -0,0 +1,23 @@
+cc_library_shared {
+ name: "libnetworkstatsfactorytestjni",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wthread-safety",
+ ],
+
+ srcs: [
+ ":lib_networkStatsFactory_native",
+ "test_onload.cpp",
+ ],
+
+ shared_libs: [
+ "libbpf_android",
+ "liblog",
+ "libnativehelper",
+ "libnetdbpf",
+ "libnetdutils",
+ ],
+}
diff --git a/tests/net/jni/test_onload.cpp b/tests/net/jni/test_onload.cpp
new file mode 100644
index 0000000..5194ddb
--- /dev/null
+++ b/tests/net/jni/test_onload.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/*
+ * this is a mini native libaray for NetworkStatsFactoryTest to run properly. It
+ * load all the native method related to NetworkStatsFactory when test run
+ */
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+namespace android {
+int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
+};
+
+using namespace android;
+
+extern "C" 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("GetEnv failed!");
+ return result;
+ }
+ ALOG_ASSERT(env, "Could not retrieve the env!");
+ register_android_server_net_NetworkStatsFactory(env);
+ return JNI_VERSION_1_4;
+}