Merge "Build android.test.* with java_sdk_library"
diff --git a/Android.bp b/Android.bp
index 87f50af..7658fb2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1480,7 +1480,7 @@
installable: false,
metalava_enabled: true,
metalava_annotations_enabled: true,
- metalava_previous_api: ":public-api-for-metalava-annotations",
+ metalava_previous_api: ":last-released-public-api",
metalava_merge_annotations_dirs: [
"metalava-manual",
"ojluni-annotated-stubs",
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 528c4df..0e0a8c7 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -177,7 +177,7 @@
Landroid/app/INotificationManager;->cancelAllNotifications(Ljava/lang/String;I)V
Landroid/app/INotificationManager;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;II)V
Landroid/app/INotificationManager;->cancelToast(Ljava/lang/String;Landroid/app/ITransientNotification;)V
-Landroid/app/INotificationManager;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;I)V
+Landroid/app/INotificationManager;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;II)V
Landroid/app/INotificationManager;->getActiveNotifications(Ljava/lang/String;)[Landroid/service/notification/StatusBarNotification;
Landroid/app/INotificationManager;->getHistoricalNotifications(Ljava/lang/String;I)[Landroid/service/notification/StatusBarNotification;
Landroid/app/INotificationManager;->getZenMode()I
@@ -1986,11 +1986,6 @@
Landroid/R$styleable;->Window_windowBackground:I
Landroid/R$styleable;->Window_windowFrame:I
Landroid/security/Credentials;->convertToPem([Ljava/security/cert/Certificate;)[B
-Landroid/security/Credentials;->getInstance()Landroid/security/Credentials;
-Landroid/security/Credentials;->install(Landroid/content/Context;Ljava/lang/String;[B)V
-Landroid/security/Credentials;->install(Landroid/content/Context;Ljava/security/KeyPair;)V
-Landroid/security/Credentials;->unlock(Landroid/content/Context;)V
-Landroid/security/GateKeeper;->getSecureUserId()J
Landroid/security/IKeyChainService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeyChainService;
Landroid/security/IKeyChainService;->requestPrivateKey(Ljava/lang/String;)Ljava/lang/String;
Landroid/security/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeystoreService;
@@ -2009,36 +2004,6 @@
Landroid/security/IKeystoreService;->sign(Ljava/lang/String;[B)[B
Landroid/security/IKeystoreService;->ungrant(Ljava/lang/String;I)I
Landroid/security/IKeystoreService;->verify(Ljava/lang/String;[B[B)I
-Landroid/security/keymaster/ExportResult;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/security/keymaster/KeyCharacteristics;-><init>()V
-Landroid/security/keymaster/KeyCharacteristics;->readFromParcel(Landroid/os/Parcel;)V
-Landroid/security/keymaster/KeymasterArguments;-><init>()V
-Landroid/security/keymaster/KeymasterArguments;->addEnum(II)V
-Landroid/security/keymaster/KeymasterArguments;->addUnsignedInt(IJ)V
-Landroid/security/keymaster/KeymasterArguments;->addUnsignedLong(ILjava/math/BigInteger;)V
-Landroid/security/keymaster/KeymasterArguments;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/security/keymaster/KeymasterArguments;->readFromParcel(Landroid/os/Parcel;)V
-Landroid/security/keymaster/KeymasterBlob;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/security/keymaster/OperationResult;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/security/KeyStore$State;->LOCKED:Landroid/security/KeyStore$State;
-Landroid/security/KeyStore$State;->UNLOCKED:Landroid/security/KeyStore$State;
-Landroid/security/keystore/AndroidKeyStoreProvider;->getKeyStoreOperationHandle(Ljava/lang/Object;)J
-Landroid/security/keystore/KeyGenParameterSpec;->getUid()I
-Landroid/security/keystore/KeyGenParameterSpec;->isUniqueIdIncluded()Z
-Landroid/security/KeyStore;->delete(Ljava/lang/String;)Z
-Landroid/security/KeyStore;->get(Ljava/lang/String;)[B
-Landroid/security/KeyStore;->getApplicationContext()Landroid/content/Context;
-Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
-Landroid/security/KeyStore;->getKeyStoreException(I)Landroid/security/KeyStoreException;
-Landroid/security/KeyStore;->isEmpty()Z
-Landroid/security/KeyStore;->NO_ERROR:I
-Landroid/security/KeyStore;->reset()Z
-Landroid/security/KeyStore;->state()Landroid/security/KeyStore$State;
-Landroid/security/KeyStore;->state(I)Landroid/security/KeyStore$State;
-Landroid/security/KeyStore;->unlock(Ljava/lang/String;)Z
-Landroid/security/KeystoreArguments;-><init>([[B)V
-Landroid/security/KeystoreArguments;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/security/net/config/RootTrustManager;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
Landroid/service/carrier/ICarrierMessagingCallback$Stub;-><init>()V
Landroid/service/carrier/ICarrierMessagingService;->filterSms(Landroid/service/carrier/MessagePdu;Ljava/lang/String;IILandroid/service/carrier/ICarrierMessagingCallback;)V
Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
diff --git a/config/hiddenapi-p-light-greylist.txt b/config/hiddenapi-p-light-greylist.txt
index e360879..e26a4c7 100644
--- a/config/hiddenapi-p-light-greylist.txt
+++ b/config/hiddenapi-p-light-greylist.txt
@@ -534,7 +534,7 @@
Landroid/app/INotificationManager;->cancelAllNotifications(Ljava/lang/String;I)V
Landroid/app/INotificationManager;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;II)V
Landroid/app/INotificationManager;->cancelToast(Ljava/lang/String;Landroid/app/ITransientNotification;)V
-Landroid/app/INotificationManager;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;I)V
+Landroid/app/INotificationManager;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;II)V
Landroid/app/IProcessObserver$Stub;-><init>()V
Landroid/app/ISearchManager$Stub$Proxy;->getGlobalSearchActivity()Landroid/content/ComponentName;
Landroid/app/ISearchManager$Stub$Proxy;->getWebSearchActivity()Landroid/content/ComponentName;
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index cd12710..3171e3e 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -43,7 +43,7 @@
void cancelAllNotifications(String pkg, int userId);
void clearData(String pkg, int uid, boolean fromApp);
- void enqueueToast(String pkg, ITransientNotification callback, int duration);
+ void enqueueToast(String pkg, ITransientNotification callback, int duration, int displayId);
void cancelToast(String pkg, ITransientNotification callback);
void finishToken(String pkg, ITransientNotification callback);
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 1275a85..caa99d5 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -819,11 +819,11 @@
* camera in the list of supported camera devices.</p>
* <p>This capability requires the camera device to support the following:</p>
* <ul>
- * <li>This camera device must list the following static metadata entries in {@link android.hardware.camera2.CameraCharacteristics }:<ul>
- * <li>android.logicalMultiCamera.physicalIds</li>
- * <li>{@link CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE android.logicalMultiCamera.sensorSyncType}</li>
- * </ul>
- * </li>
+ * <li>The IDs of underlying physical cameras are returned via
+ * {@link android.hardware.camera2.CameraCharacteristics#getPhysicalCameraIds }.</li>
+ * <li>This camera device must list static metadata
+ * {@link CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE android.logicalMultiCamera.sensorSyncType} in
+ * {@link android.hardware.camera2.CameraCharacteristics }.</li>
* <li>The underlying physical cameras' static metadata must list the following entries,
* so that the application can correlate pixels from the physical streams:<ul>
* <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference}</li>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d09c416..7980af1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7247,6 +7247,14 @@
private static final Validator DOZE_DOUBLE_TAP_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
/**
+ * Whether the device should pulse on reach gesture.
+ * @hide
+ */
+ public static final String DOZE_REACH_GESTURE = "doze_reach_gesture";
+
+ private static final Validator DOZE_REACH_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* The current night mode that has been selected by the user. Owned
* and controlled by UiModeManagerService. Constants are as per
* UiModeManager.
@@ -8148,6 +8156,7 @@
DOZE_ALWAYS_ON,
DOZE_PICK_UP_GESTURE,
DOZE_DOUBLE_TAP_GESTURE,
+ DOZE_REACH_GESTURE,
NFC_PAYMENT_DEFAULT_COMPONENT,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
FACE_UNLOCK_KEYGUARD_ENABLED,
@@ -8291,6 +8300,7 @@
VALIDATORS.put(DOZE_ALWAYS_ON, DOZE_ALWAYS_ON_VALIDATOR);
VALIDATORS.put(DOZE_PICK_UP_GESTURE, DOZE_PICK_UP_GESTURE_VALIDATOR);
VALIDATORS.put(DOZE_DOUBLE_TAP_GESTURE, DOZE_DOUBLE_TAP_GESTURE_VALIDATOR);
+ VALIDATORS.put(DOZE_REACH_GESTURE, DOZE_REACH_GESTURE_VALIDATOR);
VALIDATORS.put(NFC_PAYMENT_DEFAULT_COMPONENT, NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR);
VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
diff --git a/core/java/android/security/KeystoreArguments.java b/core/java/android/security/KeystoreArguments.java
index 16054e5..7d85ca7 100644
--- a/core/java/android/security/KeystoreArguments.java
+++ b/core/java/android/security/KeystoreArguments.java
@@ -16,6 +16,7 @@
package android.security;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,6 +28,7 @@
public class KeystoreArguments implements Parcelable {
public byte[][] args;
+ @UnsupportedAppUsage
public static final Parcelable.Creator<KeystoreArguments> CREATOR = new
Parcelable.Creator<KeystoreArguments>() {
public KeystoreArguments createFromParcel(Parcel in) {
@@ -41,6 +43,7 @@
args = null;
}
+ @UnsupportedAppUsage
public KeystoreArguments(byte[][] args) {
this.args = args;
}
diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java
index 2b3ccbc..c104671 100644
--- a/core/java/android/security/keymaster/ExportResult.java
+++ b/core/java/android/security/keymaster/ExportResult.java
@@ -16,6 +16,7 @@
package android.security.keymaster;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,6 +28,7 @@
public final int resultCode;
public final byte[] exportData;
+ @UnsupportedAppUsage
public static final Parcelable.Creator<ExportResult> CREATOR = new
Parcelable.Creator<ExportResult>() {
public ExportResult createFromParcel(Parcel in) {
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index 89300d1..555863e 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -16,6 +16,7 @@
package android.security.keymaster;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -44,6 +45,7 @@
}
};
+ @UnsupportedAppUsage
public KeyCharacteristics() {}
protected KeyCharacteristics(Parcel in) {
@@ -61,6 +63,7 @@
hwEnforced.writeToParcel(out, flags);
}
+ @UnsupportedAppUsage
public void readFromParcel(Parcel in) {
swEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index e862252..5aa0f91 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -16,6 +16,7 @@
package android.security.keymaster;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,6 +41,7 @@
private List<KeymasterArgument> mArguments;
+ @UnsupportedAppUsage
public static final Parcelable.Creator<KeymasterArguments> CREATOR = new
Parcelable.Creator<KeymasterArguments>() {
@Override
@@ -53,6 +55,7 @@
}
};
+ @UnsupportedAppUsage
public KeymasterArguments() {
mArguments = new ArrayList<KeymasterArgument>();
}
@@ -66,6 +69,7 @@
*
* @throws IllegalArgumentException if {@code tag} is not an enum tag.
*/
+ @UnsupportedAppUsage
public void addEnum(int tag, int value) {
int tagType = KeymasterDefs.getTagType(tag);
if ((tagType != KeymasterDefs.KM_ENUM) && (tagType != KeymasterDefs.KM_ENUM_REP)) {
@@ -137,6 +141,7 @@
* @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag or if
* {@code value} is outside of the permitted range [0; 2^32).
*/
+ @UnsupportedAppUsage
public void addUnsignedInt(int tag, long value) {
int tagType = KeymasterDefs.getTagType(tag);
if ((tagType != KeymasterDefs.KM_UINT) && (tagType != KeymasterDefs.KM_UINT_REP)) {
@@ -173,6 +178,7 @@
* @throws IllegalArgumentException if {@code tag} is not an unsigned 64-bit long tag or if
* {@code value} is outside of the permitted range [0; 2^64).
*/
+ @UnsupportedAppUsage
public void addUnsignedLong(int tag, BigInteger value) {
int tagType = KeymasterDefs.getTagType(tag);
if ((tagType != KeymasterDefs.KM_ULONG) && (tagType != KeymasterDefs.KM_ULONG_REP)) {
@@ -358,6 +364,7 @@
out.writeTypedList(mArguments);
}
+ @UnsupportedAppUsage
public void readFromParcel(Parcel in) {
in.readTypedList(mArguments, KeymasterArgument.CREATOR);
}
diff --git a/core/java/android/security/keymaster/KeymasterBlob.java b/core/java/android/security/keymaster/KeymasterBlob.java
index cd36870..0659a22 100644
--- a/core/java/android/security/keymaster/KeymasterBlob.java
+++ b/core/java/android/security/keymaster/KeymasterBlob.java
@@ -16,6 +16,7 @@
package android.security.keymaster;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,6 +29,7 @@
public KeymasterBlob(byte[] blob) {
this.blob = blob;
}
+ @UnsupportedAppUsage
public static final Parcelable.Creator<KeymasterBlob> CREATOR = new
Parcelable.Creator<KeymasterBlob>() {
public KeymasterBlob createFromParcel(Parcel in) {
diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java
index 4c962ec..2943211 100644
--- a/core/java/android/security/keymaster/OperationResult.java
+++ b/core/java/android/security/keymaster/OperationResult.java
@@ -16,6 +16,7 @@
package android.security.keymaster;
+import android.annotation.UnsupportedAppUsage;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,6 +34,7 @@
public final byte[] output;
public final KeymasterArguments outParams;
+ @UnsupportedAppUsage
public static final Parcelable.Creator<OperationResult> CREATOR = new
Parcelable.Creator<OperationResult>() {
@Override
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index 2a30f11..d8936d9 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -21,6 +21,7 @@
import java.security.cert.X509Certificate;
import java.util.List;
+import android.annotation.UnsupportedAppUsage;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
@@ -121,6 +122,7 @@
* This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
* modify without modifying those callers.
*/
+ @UnsupportedAppUsage
public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
String hostname) throws CertificateException {
if (hostname == null && mConfig.hasPerDomainConfigs()) {
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index bbdf15c..d1de498 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1247,7 +1247,10 @@
private int[] mRules = new int[VERB_COUNT];
private int[] mInitialRules = new int[VERB_COUNT];
- private int mLeft, mTop, mRight, mBottom;
+ private int mLeft;
+ private int mTop;
+ private int mRight;
+ private int mBottom;
/**
* Whether this view had any relative rules modified following the most
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5cadbe4..3941d6a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -421,7 +421,9 @@
private Editable.Factory mEditableFactory = Editable.Factory.getInstance();
private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance();
- private float mShadowRadius, mShadowDx, mShadowDy;
+ private float mShadowRadius;
+ private float mShadowDx;
+ private float mShadowDy;
private int mShadowColor;
private boolean mPreDrawRegistered;
@@ -717,8 +719,10 @@
private Scroller mScroller;
private TextPaint mTempTextPaint;
- private BoringLayout.Metrics mBoring, mHintBoring;
- private BoringLayout mSavedLayout, mSavedHintLayout;
+ private BoringLayout.Metrics mBoring;
+ private BoringLayout.Metrics mHintBoring;
+ private BoringLayout mSavedLayout;
+ private BoringLayout mSavedHintLayout;
private TextDirectionHeuristic mTextDir;
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index d74a60e..f6071d8 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -133,9 +133,10 @@
String pkg = mContext.getOpPackageName();
TN tn = mTN;
tn.mNextView = mNextView;
+ final int displayId = mContext.getDisplay().getDisplayId();
try {
- service.enqueueToast(pkg, tn, mDuration);
+ service.enqueueToast(pkg, tn, mDuration, displayId);
} catch (RemoteException e) {
// Empty
}
@@ -354,7 +355,8 @@
final Handler mHandler;
int mGravity;
- int mX, mY;
+ int mX;
+ int mY;
float mHorizontalMargin;
float mVerticalMargin;
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index c21159e..8728367 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -66,6 +66,15 @@
return !TextUtils.isEmpty(doubleTapSensorType());
}
+ public boolean reachGestureEnabled(int user) {
+ return boolSettingDefaultOn(Settings.Secure.DOZE_REACH_GESTURE, user)
+ && reachGestureAvailable();
+ }
+
+ public boolean reachGestureAvailable() {
+ return !TextUtils.isEmpty(reachSensorType());
+ }
+
public String doubleTapSensorType() {
return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
}
@@ -74,6 +83,10 @@
return mContext.getResources().getString(R.string.config_dozeLongPressSensorType);
}
+ public String reachSensorType() {
+ return mContext.getResources().getString(R.string.config_dozeReachSensorType);
+ }
+
public boolean pulseOnLongPressEnabled(int user) {
return pulseOnLongPressAvailable() && boolSettingDefaultOff(
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user);
diff --git a/core/res/res/values-mcc214-mnc01/config.xml b/core/res/res/values-mcc214-mnc01/config.xml
index 24150a7..41e24d7 100644
--- a/core/res/res/values-mcc214-mnc01/config.xml
+++ b/core/res/res/values-mcc214-mnc01/config.xml
@@ -40,4 +40,7 @@
<item>INTERNET,airtelnet.es,,,vodafone,vodafone,,,,,214,01,1,DUN</item>
</string-array>
+ <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+ <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
</resources>
diff --git a/core/res/res/values-mcc222-mnc10/config.xml b/core/res/res/values-mcc222-mnc10/config.xml
index c819de2..0085a1b 100644
--- a/core/res/res/values-mcc222-mnc10/config.xml
+++ b/core/res/res/values-mcc222-mnc10/config.xml
@@ -28,4 +28,8 @@
<string-array translatable="false" name="config_tether_apndata">
<item>Tethering Internet,web.omnitel.it,,,,,,,,,222,10,,DUN</item>
</string-array>
+
+ <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+ <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
</resources>
diff --git a/core/res/res/values-mcc234-mnc15/config.xml b/core/res/res/values-mcc234-mnc15/config.xml
new file mode 100644
index 0000000..84e779d
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc15/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+ <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc234-mnc91/config.xml b/core/res/res/values-mcc234-mnc91/config.xml
new file mode 100644
index 0000000..84e779d
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc91/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+ <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc262-mnc02/config.xml b/core/res/res/values-mcc262-mnc02/config.xml
new file mode 100644
index 0000000..84e779d
--- /dev/null
+++ b/core/res/res/values-mcc262-mnc02/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+ <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
+</resources>
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 688040b..351f8ea 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -19,12 +19,12 @@
<resources>
<!-- The primary text color if the text is on top of a dark background.
This is also affects colorized notifications with dark backgrounds. -->
- <color name="notification_primary_text_color_dark">#dadada</color>
+ <color name="notification_primary_text_color_dark">#ddffffff</color>
<!-- The secondary text color if the text is on top of a dark background. -->
- <color name="notification_secondary_text_color_dark">#dadada</color>
+ <color name="notification_secondary_text_color_dark">#ddffffff</color>
- <color name="notification_default_color_dark">#dadada</color>
+ <color name="notification_default_color_dark">#ddffffff</color>
<!-- The background color of a notification card. -->
<color name="notification_material_background_color">@*android:color/material_grey_900</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c8343e2..b15c9c5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2105,6 +2105,9 @@
<!-- Type of the long press sensor. Empty if long press is not supported. -->
<string name="config_dozeLongPressSensorType" translatable="false"></string>
+ <!-- Type of the reach sensor. Empty if reach is not supported. -->
+ <string name="config_dozeReachSensorType" translatable="false"></string>
+
<!-- Control whether the always on display mode is available. This should only be enabled on
devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
states. -->
@@ -2356,6 +2359,9 @@
<!-- Whether safe headphone volume is enabled or not (country specific). -->
<bool name="config_safe_media_volume_enabled">true</bool>
+ <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+ <bool name="config_safe_media_disable_on_volume_up">true</bool>
+
<!-- Set to true if the wifi display supports compositing content stored
in gralloc protected buffers. For this to be true, there must exist
a protected hardware path for surface flinger to composite and send
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5e1109e..2271baa 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -309,6 +309,7 @@
<java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" />
<java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
<java-symbol type="bool" name="config_safe_media_volume_enabled" />
+ <java-symbol type="bool" name="config_safe_media_disable_on_volume_up" />
<java-symbol type="bool" name="config_camera_sound_forced" />
<java-symbol type="bool" name="config_dontPreferApn" />
<java-symbol type="bool" name="config_restartRadioAfterProvisioning" />
@@ -3261,6 +3262,7 @@
<java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
<java-symbol type="string" name="config_dozeLongPressSensorType" />
+ <java-symbol type="string" name="config_dozeReachSensorType" />
<java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
<java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index f6587d3..616a8d6 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -126,6 +126,7 @@
<privapp-permissions package="com.android.omadm.service">
<permission name="android.permission.CHANGE_CONFIGURATION"/>
<permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+ <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.WRITE_APN_SETTINGS"/>
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 57db20b..7216a22 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -16,6 +16,7 @@
package android.security;
+import android.annotation.UnsupportedAppUsage;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -172,6 +173,7 @@
private static Credentials singleton;
+ @UnsupportedAppUsage
public static Credentials getInstance() {
if (singleton == null) {
singleton = new Credentials();
@@ -179,6 +181,7 @@
return singleton;
}
+ @UnsupportedAppUsage
public void unlock(Context context) {
try {
Intent intent = new Intent(UNLOCK_ACTION);
@@ -197,6 +200,7 @@
}
}
+ @UnsupportedAppUsage
public void install(Context context, KeyPair pair) {
try {
Intent intent = KeyChain.createInstallIntent();
@@ -208,6 +212,7 @@
}
}
+ @UnsupportedAppUsage
public void install(Context context, String type, byte[] value) {
try {
Intent intent = KeyChain.createInstallIntent();
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 03df5de..a50ff79 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -16,6 +16,7 @@
package android.security;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -42,6 +43,7 @@
return service;
}
+ @UnsupportedAppUsage
public static long getSecureUserId() throws IllegalStateException {
try {
return getService().getSecureUserId(UserHandle.myUserId());
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 4f4ca3f..0a4ac8c 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,6 +16,7 @@
package android.security;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.Application;
@@ -57,6 +58,7 @@
private static final String TAG = "KeyStore";
// ResponseCodes - see system/security/keystore/include/keystore/keystore.h
+ @UnsupportedAppUsage
public static final int NO_ERROR = 1;
public static final int LOCKED = 2;
public static final int UNINITIALIZED = 3;
@@ -129,7 +131,9 @@
// States
public enum State {
+ @UnsupportedAppUsage
UNLOCKED,
+ @UnsupportedAppUsage
LOCKED,
UNINITIALIZED
};
@@ -146,6 +150,7 @@
mContext = getApplicationContext();
}
+ @UnsupportedAppUsage
public static Context getApplicationContext() {
Application application = ActivityThread.currentApplication();
if (application == null) {
@@ -155,6 +160,7 @@
return application;
}
+ @UnsupportedAppUsage
public static KeyStore getInstance() {
IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
.getService("android.security.keystore"));
@@ -168,6 +174,7 @@
return mToken;
}
+ @UnsupportedAppUsage
public State state(int userId) {
final int ret;
try {
@@ -185,6 +192,7 @@
}
}
+ @UnsupportedAppUsage
public State state() {
return state(UserHandle.myUserId());
}
@@ -197,6 +205,7 @@
return get(key, uid, false);
}
+ @UnsupportedAppUsage
public byte[] get(String key) {
return get(key, UID_SELF);
}
@@ -247,6 +256,7 @@
}
}
+ @UnsupportedAppUsage
public boolean delete(String key) {
return delete(key, UID_SELF);
}
@@ -283,6 +293,7 @@
return list(prefix, UID_SELF);
}
+ @UnsupportedAppUsage
public boolean reset() {
try {
return mBinder.reset() == NO_ERROR;
@@ -333,6 +344,7 @@
}
}
+ @UnsupportedAppUsage
public boolean unlock(String password) {
return unlock(UserHandle.getUserId(Process.myUid()), password);
}
@@ -349,6 +361,7 @@
}
}
+ @UnsupportedAppUsage
public boolean isEmpty() {
return isEmpty(UserHandle.myUserId());
}
@@ -818,6 +831,7 @@
* Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
* code.
*/
+ @UnsupportedAppUsage
public static KeyStoreException getKeyStoreException(int errorCode) {
if (errorCode > 0) {
// KeyStore layer error
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index c048e82..c7c9ee4 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -17,6 +17,7 @@
package android.security.keystore;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.security.KeyStore;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
@@ -156,6 +157,7 @@
* by AndroidKeyStore provider.
* @throws IllegalStateException if the provided primitive is not initialized.
*/
+ @UnsupportedAppUsage
public static long getKeyStoreOperationHandle(Object cryptoPrimitive) {
if (cryptoPrimitive == null) {
throw new NullPointerException();
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 89d370f..c4df274 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
import android.security.GateKeeper;
@@ -371,6 +372,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public int getUid() {
return mUid;
}
@@ -645,6 +647,7 @@
*
* Returns {@code true} if the attestation certificate will contain a unique ID field.
*/
+ @UnsupportedAppUsage
public boolean isUniqueIdIncluded() {
return mUniqueIdIncluded;
}
diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java
index 332e360..59c9b82 100644
--- a/media/java/android/media/EncoderCapabilities.java
+++ b/media/java/android/media/EncoderCapabilities.java
@@ -42,11 +42,15 @@
*/
static public class VideoEncoderCap {
// These are not modifiable externally, thus are public accessible
- public final int mCodec; // @see android.media.MediaRecorder.VideoEncoder
- public final int mMinBitRate, mMaxBitRate; // min and max bit rate (bps)
- public final int mMinFrameRate, mMaxFrameRate; // min and max frame rate (fps)
- public final int mMinFrameWidth, mMaxFrameWidth; // min and max frame width (pixel)
- public final int mMinFrameHeight, mMaxFrameHeight; // minn and max frame height (pixel)
+ public final int mCodec; // @see android.media.MediaRecorder.VideoEncoder
+ public final int mMinBitRate; // min bit rate (bps)
+ public final int mMaxBitRate; // max bit rate (bps)
+ public final int mMinFrameRate; // min frame rate (fps)
+ public final int mMaxFrameRate; // max frame rate (fps)
+ public final int mMinFrameWidth; // min frame width (pixel)
+ public final int mMaxFrameWidth; // max frame width (pixel)
+ public final int mMinFrameHeight; // min frame height (pixel)
+ public final int mMaxFrameHeight; // max frame height (pixel)
// Private constructor called by JNI
private VideoEncoderCap(int codec,
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
new file mode 100644
index 0000000..36ef04a
--- /dev/null
+++ b/packages/CarSystemUI/Android.bp
@@ -0,0 +1,76 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+android_app {
+ name: "CarSystemUI",
+
+ srcs: [
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ],
+
+ static_libs: [
+ "SystemUI-core",
+ "SystemUIPluginLib",
+ "SystemUISharedLib",
+ "SettingsLib",
+ "androidx.car_car",
+ "androidx.legacy_legacy-support-v4",
+ "androidx.recyclerview_recyclerview",
+ "androidx.preference_preference",
+ "androidx.appcompat_appcompat",
+ "androidx.mediarouter_mediarouter",
+ "androidx.palette_palette",
+ "androidx.legacy_legacy-preference-v14",
+ "androidx.leanback_leanback",
+ "androidx.slice_slice-core",
+ "androidx.slice_slice-view",
+ "androidx.slice_slice-builders",
+ "androidx.arch.core_core-runtime",
+ "androidx.lifecycle_lifecycle-extensions",
+ "SystemUI-tags",
+ "SystemUI-proto",
+ ],
+
+ libs: [
+ "telephony-common",
+ "android.car",
+ ],
+
+ manifest: "AndroidManifest.xml",
+
+ owner: "google",
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+
+ optimize: {
+ proguard_flags_files: [
+ "proguard.flags",
+ ],
+ },
+ resource_dirs: [
+ "res",
+ ],
+
+
+ dxflags: ["--multi-dex"],
+
+ aaptflags: [
+ "--extra-packages",
+ "com.android.keyguard",
+ ],
+
+}
diff --git a/packages/CarSystemUI/Android.mk b/packages/CarSystemUI/Android.mk
deleted file mode 100644
index 0d40b7f..0000000
--- a/packages/CarSystemUI/Android.mk
+++ /dev/null
@@ -1,86 +0,0 @@
-# LOCAL_PATH is not the current directory of this file.
-# If you need the local path, use CAR_SYSUI_PATH.
-# This tweak ensures that the resource overlay that is device-specific still works
-# which requires that LOCAL_PATH match the original path (which must be frameworks/base/packages/SystemUI).
-#
-# For clarity, we also define SYSTEM_UI_AOSP_PATH to frameworks/base/packages/SystemUI and refer to that
-SYSTEM_UI_AOSP_PATH := frameworks/base/packages/SystemUI
-SYSTEM_UI_CAR_PATH := frameworks/base/packages/CarSystemUI
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := optional
-
-# The same as SYSTEM_UI_AOSP_PATH but based on the value of LOCAL_PATH which is
-# frameworks/base/packages/CarSystemUI.
-RELATIVE_SYSTEM_UI_AOSP_PATH := ../../../../$(SYSTEM_UI_AOSP_PATH)
-
-
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-Iaidl-files-under, src) \
- $(call all-java-files-under, $(RELATIVE_SYSTEM_UI_AOSP_PATH)/src) \
- $(call all-Iaidl-files-under, $(RELATIVE_SYSTEM_UI_AOSP_PATH)/src)
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- SystemUIPluginLib \
- SystemUISharedLib \
- androidx.car_car \
- androidx.legacy_legacy-support-v4 \
- androidx.recyclerview_recyclerview \
- androidx.preference_preference \
- androidx.appcompat_appcompat \
- androidx.mediarouter_mediarouter \
- androidx.palette_palette \
- androidx.legacy_legacy-preference-v14 \
- androidx.leanback_leanback \
- androidx.slice_slice-core \
- androidx.slice_slice-view \
- androidx.slice_slice-builders \
- androidx.arch.core_core-runtime \
- androidx.lifecycle_lifecycle-extensions \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- SystemUI-tags \
- SystemUI-proto
-
-LOCAL_JAVA_LIBRARIES := telephony-common \
- android.car
-
-LOCAL_FULL_LIBS_MANIFEST_FILES := $(SYSTEM_UI_AOSP_PATH)/AndroidManifest.xml
-LOCAL_MANIFEST_FILE := AndroidManifest.xml
-
-LOCAL_MODULE_OWNER := google
-LOCAL_PACKAGE_NAME := CarSystemUI
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_PROGUARD_FLAG_FILES := $(RELATIVE_SYSTEM_UI_AOSP_PATH)/proguard.flags \
- proguard.flags
-
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res \
- $(SYSTEM_UI_AOSP_PATH)/res-keyguard \
- $(SYSTEM_UI_AOSP_PATH)/res
-
-ifneq ($(INCREMENTAL_BUILDS),)
- LOCAL_PROGUARD_ENABLED := disabled
- LOCAL_JACK_ENABLED := incremental
-endif
-
-LOCAL_DX_FLAGS := --multi-dex
-LOCAL_JACK_FLAGS := --multi-dex native
-
-include frameworks/base/packages/SettingsLib/common.mk
-
-LOCAL_OVERRIDES_PACKAGES := SystemUI
-
-LOCAL_AAPT_FLAGS := --extra-packages com.android.keyguard
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under, $(SYSTEM_UI_CAR_PATH))
diff --git a/packages/CarSystemUI/proguard.flags b/packages/CarSystemUI/proguard.flags
index ceb037c..a81c7e0 100644
--- a/packages/CarSystemUI/proguard.flags
+++ b/packages/CarSystemUI/proguard.flags
@@ -1 +1,3 @@
-keep class com.android.systemui.CarSystemUIFactory
+
+-include ../SystemUI/proguard.flags
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
new file mode 100644
index 0000000..4791517
--- /dev/null
+++ b/packages/SettingsLib/Android.bp
@@ -0,0 +1,25 @@
+android_library {
+
+ name: "SettingsLib",
+
+ libs: [
+ "androidx.annotation_annotation",
+ "androidx.legacy_legacy-support-v4",
+ "androidx.recyclerview_recyclerview",
+ "androidx.preference_preference",
+ "androidx.appcompat_appcompat",
+ "androidx.lifecycle_lifecycle-runtime",
+ ],
+
+ // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
+ // LOCAL_SHARED_JAVA_LIBRARIES := androidx.lifecycle_lifecycle-common
+
+ resource_dirs: ["res"],
+
+ srcs: ["src/**/*.java"],
+
+ min_sdk_version: "21",
+
+}
+
+// For the test package.
diff --git a/packages/SettingsLib/Android.mk b/packages/SettingsLib/Android.mk
deleted file mode 100644
index 96012c1..0000000
--- a/packages/SettingsLib/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_AAPT2_ONLY := true
-
-LOCAL_MODULE := SettingsLib
-
-LOCAL_JAVA_LIBRARIES := \
- androidx.annotation_annotation
-
-LOCAL_SHARED_ANDROID_LIBRARIES := \
- androidx.legacy_legacy-support-v4 \
- androidx.recyclerview_recyclerview \
- androidx.preference_preference \
- androidx.appcompat_appcompat \
- androidx.lifecycle_lifecycle-runtime
-
-LOCAL_SHARED_JAVA_LIBRARIES := \
- androidx.lifecycle_lifecycle-common
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_JAR_EXCLUDE_FILES := none
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MIN_SDK_VERSION := 21
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# For the test package.
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 2af406d..b523ae2 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -449,7 +449,6 @@
<string name="alarm_template_far" msgid="3779172822607461675">"<xliff:g id="WHEN">%1$s</xliff:g> વાગ્યે"</string>
<string name="zen_mode_duration_settings_title" msgid="229547412251222757">"અવધિ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"દર વખતે પૂછો"</string>
- <!-- no translation found for zen_mode_forever (2704305038191592967) -->
- <skip />
+ <string name="zen_mode_forever" msgid="2704305038191592967">"તમે બંધ ન કરો ત્યાં સુધી"</string>
<string name="time_unit_just_now" msgid="6363336622778342422">"હમણાં જ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ff1f4f3..63c88cd 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -449,7 +449,6 @@
<string name="alarm_template_far" msgid="3779172822607461675">"<xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ"</string>
<string name="zen_mode_duration_settings_title" msgid="229547412251222757">"ਮਿਆਦ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"ਹਰ ਵਾਰ ਪੁੱਛੋ"</string>
- <!-- no translation found for zen_mode_forever (2704305038191592967) -->
- <skip />
+ <string name="zen_mode_forever" msgid="2704305038191592967">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਬੰਦ ਨਹੀਂ ਕਰਦੇ"</string>
<string name="time_unit_just_now" msgid="6363336622778342422">"ਹੁਣੇ ਹੀ"</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 1ce4484..a710410 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -42,7 +42,6 @@
private BluetoothA2dp mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
static final ParcelUuid[] SINK_UUIDS = {
@@ -71,7 +70,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "A2dpProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(A2dpProfile.this, BluetoothProfile.STATE_CONNECTED);
device.refresh();
@@ -94,14 +93,12 @@
return BluetoothProfile.A2DP;
}
- A2dpProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ A2dpProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
mContext = context;
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new A2dpServiceListener(),
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new A2dpServiceListener(),
BluetoothProfile.A2DP);
}
@@ -123,20 +120,6 @@
public boolean connect(BluetoothDevice device) {
if (mService == null) return false;
- int max_connected_devices = mLocalAdapter.getMaxConnectedAudioDevices();
- if (max_connected_devices == 1) {
- // Original behavior: disconnect currently connected device
- List<BluetoothDevice> sinks = getConnectedDevices();
- if (sinks != null) {
- for (BluetoothDevice sink : sinks) {
- if (sink.equals(device)) {
- Log.w(TAG, "Connecting to device " + device + " : disconnect skipped");
- continue;
- }
- mService.disconnect(sink);
- }
- }
- }
return mService.connect(device);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 6a4aa0a..0c4e02b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -38,7 +38,6 @@
private BluetoothA2dpSink mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
static final ParcelUuid[] SRC_UUIDS = {
@@ -67,7 +66,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "A2dpSinkProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(A2dpSinkProfile.this, BluetoothProfile.STATE_CONNECTED);
device.refresh();
@@ -90,13 +89,11 @@
return BluetoothProfile.A2DP_SINK;
}
- A2dpSinkProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ A2dpSinkProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new A2dpSinkServiceListener(),
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new A2dpSinkServiceListener(),
BluetoothProfile.A2DP_SINK);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index a3f3b59..466d02b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -150,7 +150,7 @@
for (BluetoothDevice device : bondedDevices) {
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice == null) {
- cachedDevice = mDeviceManager.addDevice(mLocalAdapter, device);
+ cachedDevice = mDeviceManager.addDevice(device);
dispatchDeviceAdded(cachedDevice);
deviceAdded = true;
}
@@ -282,7 +282,7 @@
// Skip for now, there's a bluez problem and we are not getting uuids even for 2.1.
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice == null) {
- cachedDevice = mDeviceManager.addDevice(mLocalAdapter, device);
+ cachedDevice = mDeviceManager.addDevice(device);
Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
+ cachedDevice);
}
@@ -348,8 +348,7 @@
if (cachedDevice == null) {
Log.w(TAG, "Got bonding state changed for " + device +
", but we have no record of that device.");
-
- cachedDevice = mDeviceManager.addDevice(mLocalAdapter, device);
+ cachedDevice = mDeviceManager.addDevice(device);
dispatchDeviceAdded(cachedDevice);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b0ff9e3..5ecbe80 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -48,7 +48,7 @@
private static final String TAG = "CachedBluetoothDevice";
private final Context mContext;
- private final LocalBluetoothAdapter mLocalAdapter;
+ private final BluetoothAdapter mLocalAdapter;
private final LocalBluetoothProfileManager mProfileManager;
private final BluetoothDevice mDevice;
//TODO: consider remove, BluetoothDevice.getName() is already cached
@@ -143,7 +143,7 @@
Log.d(TAG, "onProfileStateChanged: profile " + profile +
" newProfileState " + newProfileState);
}
- if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_TURNING_OFF)
+ if (mLocalAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF)
{
if (BluetoothUtils.D) {
Log.d(TAG, " BT Turninig Off...Profile conn state change ignored...");
@@ -179,11 +179,10 @@
}
CachedBluetoothDevice(Context context,
- LocalBluetoothAdapter adapter,
LocalBluetoothProfileManager profileManager,
BluetoothDevice device) {
mContext = context;
- mLocalAdapter = adapter;
+ mLocalAdapter = BluetoothAdapter.getDefaultAdapter();
mProfileManager = profileManager;
mDevice = device;
mProfileConnectionState = new HashMap<LocalBluetoothProfile, Integer>();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 475ece8..f8543fc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -107,10 +107,10 @@
* @param device the address of the new Bluetooth device
* @return the newly created CachedBluetoothDevice object
*/
- public CachedBluetoothDevice addDevice(LocalBluetoothAdapter adapter, BluetoothDevice device) {
+ public CachedBluetoothDevice addDevice(BluetoothDevice device) {
LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
- CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, adapter,
- profileManager, device);
+ CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, profileManager,
+ device);
if (profileManager.getHearingAidProfile() != null
&& profileManager.getHearingAidProfile().getHiSyncId(newDevice.getDevice())
!= BluetoothHearingAid.HI_SYNC_ID_INVALID) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index e284382..99f550b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -41,7 +41,6 @@
private BluetoothHeadset mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
private final LocalBluetoothProfileManager mProfileManager;
@@ -70,7 +69,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "HeadsetProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(HeadsetProfile.this,
BluetoothProfile.STATE_CONNECTED);
@@ -97,13 +96,11 @@
return BluetoothProfile.HEADSET;
}
- HeadsetProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ HeadsetProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new HeadsetServiceListener(),
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new HeadsetServiceListener(),
BluetoothProfile.HEADSET);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index a0cf105..6eaa620 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -38,7 +38,6 @@
private BluetoothHearingAid mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
static final String NAME = "HearingAid";
@@ -64,7 +63,7 @@
if (V) {
Log.d(TAG, "HearingAidProfile found new device: " + nextDevice);
}
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(HearingAidProfile.this,
BluetoothProfile.STATE_CONNECTED);
@@ -92,15 +91,13 @@
return BluetoothProfile.HEARING_AID;
}
- HearingAidProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ HearingAidProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
mContext = context;
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new HearingAidServiceListener(),
- BluetoothProfile.HEARING_AID);
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
+ new HearingAidServiceListener(), BluetoothProfile.HEARING_AID);
}
public boolean isConnectable() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index b8c72fb..4b4db75 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -41,7 +41,6 @@
private BluetoothHeadsetClient mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
static final ParcelUuid[] SRC_UUIDS = {
@@ -71,7 +70,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "HfpClient profile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(
HfpClientProfile.this, BluetoothProfile.STATE_CONNECTED);
@@ -97,14 +96,12 @@
return BluetoothProfile.HEADSET_CLIENT;
}
- HfpClientProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ HfpClientProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new HfpClientServiceListener(),
- BluetoothProfile.HEADSET_CLIENT);
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
+ new HfpClientServiceListener(), BluetoothProfile.HEADSET_CLIENT);
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
index f9da109..8c4bff5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
@@ -39,7 +39,6 @@
private static final int PREFERRED_VALUE = -1;
private static final boolean DEBUG = true;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
private final LocalBluetoothProfileManager mProfileManager;
static final String NAME = "HID DEVICE";
@@ -47,14 +46,12 @@
private BluetoothHidDevice mService;
private boolean mIsProfileReady;
- HidDeviceProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ HidDeviceProfile(Context context,CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- adapter.getProfileProxy(context, new HidDeviceServiceListener(),
- BluetoothProfile.HID_DEVICE);
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
+ new HidDeviceServiceListener(), BluetoothProfile.HID_DEVICE);
}
// These callbacks run on the main thread.
@@ -73,7 +70,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "HidProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
Log.d(TAG, "Connection status changed: " + device);
device.onProfileStateChanged(HidDeviceProfile.this,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index c5ba58c..701ef00 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -38,7 +38,6 @@
private BluetoothHidHost mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
private final LocalBluetoothProfileManager mProfileManager;
@@ -62,7 +61,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "HidProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(HidProfile.this, BluetoothProfile.STATE_CONNECTED);
device.refresh();
@@ -85,13 +84,12 @@
return BluetoothProfile.HID_HOST;
}
- HidProfile(Context context, LocalBluetoothAdapter adapter,
+ HidProfile(Context context,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- adapter.getProfileProxy(context, new HidHostServiceListener(),
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new HidHostServiceListener(),
BluetoothProfile.HID_HOST);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
index 5e7f6d4..8f40ab4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
@@ -249,10 +249,6 @@
return mAdapter.getRemoteDevice(address);
}
- public int getMaxConnectedAudioDevices() {
- return mAdapter.getMaxConnectedAudioDevices();
- }
-
public List<Integer> getSupportedProfiles() {
return mAdapter.getSupportedProfiles();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 3ebbf7e..8bb8210 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -18,6 +18,7 @@
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothA2dpSink;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadsetClient;
@@ -79,7 +80,6 @@
}
private final Context mContext;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
private final BluetoothEventManager mEventManager;
@@ -111,14 +111,13 @@
BluetoothEventManager eventManager) {
mContext = context;
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mEventManager = eventManager;
mUsePbapPce = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
// MAP Client is typically used in the same situations as PBAP Client
mUseMapClient = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
// pass this reference to adapter and event manager (circular dependency)
- mLocalAdapter.setProfileManager(this);
+ adapter.setProfileManager(this);
updateLocalProfiles();
if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
@@ -128,26 +127,26 @@
* create profile instance according to bluetooth supported profile list
*/
void updateLocalProfiles() {
- List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
+ List<Integer> supportedList = BluetoothAdapter.getDefaultAdapter().getSupportedProfiles();
if (CollectionUtils.isEmpty(supportedList)) {
if(DEBUG) Log.d(TAG, "supportedList is null");
return;
}
if (mA2dpProfile == null && supportedList.contains(BluetoothProfile.A2DP)) {
if(DEBUG) Log.d(TAG, "Adding local A2DP profile");
- mA2dpProfile = new A2dpProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mA2dpProfile = new A2dpProfile(mContext, mDeviceManager, this);
addProfile(mA2dpProfile, A2dpProfile.NAME,
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
}
if (mA2dpSinkProfile == null && supportedList.contains(BluetoothProfile.A2DP_SINK)) {
if(DEBUG) Log.d(TAG, "Adding local A2DP SINK profile");
- mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mA2dpSinkProfile = new A2dpSinkProfile(mContext, mDeviceManager, this);
addProfile(mA2dpSinkProfile, A2dpSinkProfile.NAME,
BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);
}
if (mHeadsetProfile == null && supportedList.contains(BluetoothProfile.HEADSET)) {
if (DEBUG) Log.d(TAG, "Adding local HEADSET profile");
- mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mHeadsetProfile = new HeadsetProfile(mContext, mDeviceManager, this);
addHeadsetProfile(mHeadsetProfile, HeadsetProfile.NAME,
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED,
@@ -155,7 +154,7 @@
}
if (mHfpClientProfile == null && supportedList.contains(BluetoothProfile.HEADSET_CLIENT)) {
if(DEBUG) Log.d(TAG, "Adding local HfpClient profile");
- mHfpClientProfile = new HfpClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mHfpClientProfile = new HfpClientProfile(mContext, mDeviceManager, this);
addHeadsetProfile(mHfpClientProfile, HfpClientProfile.NAME,
BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED,
BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED,
@@ -165,13 +164,13 @@
if (mMapClientProfile == null && supportedList.contains(BluetoothProfile.MAP_CLIENT)) {
if(DEBUG) Log.d(TAG, "Adding local MAP CLIENT profile");
mMapClientProfile =
- new MapClientProfile(mContext, mLocalAdapter, mDeviceManager,this);
+ new MapClientProfile(mContext, mDeviceManager,this);
addProfile(mMapClientProfile, MapClientProfile.NAME,
BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
}
} else if (mMapProfile == null && supportedList.contains(BluetoothProfile.MAP)) {
if(DEBUG) Log.d(TAG, "Adding local MAP profile");
- mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mMapProfile = new MapProfile(mContext, mDeviceManager, this);
addProfile(mMapProfile, MapProfile.NAME, BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
}
if (mOppProfile == null && supportedList.contains(BluetoothProfile.OPP)) {
@@ -182,26 +181,26 @@
}
if (mHearingAidProfile == null && supportedList.contains(BluetoothProfile.HEARING_AID)) {
if(DEBUG) Log.d(TAG, "Adding local Hearing Aid profile");
- mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
+ mHearingAidProfile = new HearingAidProfile(mContext, mDeviceManager,
this);
addProfile(mHearingAidProfile, HearingAidProfile.NAME,
BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
}
if (mHidProfile == null && supportedList.contains(BluetoothProfile.HID_HOST)) {
if(DEBUG) Log.d(TAG, "Adding local HID_HOST profile");
- mHidProfile = new HidProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mHidProfile = new HidProfile(mContext, mDeviceManager, this);
addProfile(mHidProfile, HidProfile.NAME,
BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED);
}
if (mHidDeviceProfile == null && supportedList.contains(BluetoothProfile.HID_DEVICE)) {
if(DEBUG) Log.d(TAG, "Adding local HID_DEVICE profile");
- mHidDeviceProfile = new HidDeviceProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ mHidDeviceProfile = new HidDeviceProfile(mContext, mDeviceManager, this);
addProfile(mHidDeviceProfile, HidDeviceProfile.NAME,
BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED);
}
if (mPanProfile == null && supportedList.contains(BluetoothProfile.PAN)) {
if(DEBUG) Log.d(TAG, "Adding local PAN profile");
- mPanProfile = new PanProfile(mContext, mLocalAdapter);
+ mPanProfile = new PanProfile(mContext);
addPanProfile(mPanProfile, PanProfile.NAME,
BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
}
@@ -214,8 +213,7 @@
if (mUsePbapPce && mPbapClientProfile == null && supportedList.contains(
BluetoothProfile.PBAP_CLIENT)) {
if(DEBUG) Log.d(TAG, "Adding local PBAP Client profile");
- mPbapClientProfile = new PbapClientProfile(mContext, mLocalAdapter, mDeviceManager,
- this);
+ mPbapClientProfile = new PbapClientProfile(mContext, mDeviceManager,this);
addProfile(mPbapClientProfile, PbapClientProfile.NAME,
BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
}
@@ -271,7 +269,7 @@
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice == null) {
Log.w(TAG, "StateChangedHandler found new device: " + device);
- cachedDevice = mDeviceManager.addDevice(mLocalAdapter, device);
+ cachedDevice = mDeviceManager.addDevice(device);
}
onReceiveInternal(intent, cachedDevice);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
index 63af24c..7d334eb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -41,7 +41,6 @@
private BluetoothMapClient mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
private final LocalBluetoothProfileManager mProfileManager;
@@ -71,7 +70,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "MapProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(MapClientProfile.this,
BluetoothProfile.STATE_CONNECTED);
@@ -99,14 +98,12 @@
return BluetoothProfile.MAP_CLIENT;
}
- MapClientProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ MapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new MapClientServiceListener(),
- BluetoothProfile.MAP_CLIENT);
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
+ new MapClientServiceListener(), BluetoothProfile.MAP_CLIENT);
}
public boolean isConnectable() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index 2c63d50..689669f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -41,7 +41,6 @@
private BluetoothMap mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
private final LocalBluetoothProfileManager mProfileManager;
@@ -70,7 +69,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "MapProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(MapProfile.this,
BluetoothProfile.STATE_CONNECTED);
@@ -98,13 +97,11 @@
return BluetoothProfile.MAP;
}
- MapProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ MapProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new MapServiceListener(),
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new MapServiceListener(),
BluetoothProfile.MAP);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index e204d03..02afe8d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -38,7 +38,6 @@
private BluetoothPan mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
// Tethering direction for each device
private final HashMap<BluetoothDevice, Integer> mDeviceRoleMap =
@@ -74,9 +73,8 @@
return BluetoothProfile.PAN;
}
- PanProfile(Context context, LocalBluetoothAdapter adapter) {
- mLocalAdapter = adapter;
- mLocalAdapter.getProfileProxy(context, new PanServiceListener(),
+ PanProfile(Context context) {
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new PanServiceListener(),
BluetoothProfile.PAN);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index d34ad30..ad3506f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -39,7 +39,6 @@
private BluetoothPbapClient mService;
private boolean mIsProfileReady;
- private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
static final ParcelUuid[] SRC_UUIDS = {
@@ -69,7 +68,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "PbapClientProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(PbapClientProfile.this, BluetoothProfile.STATE_CONNECTED);
device.refresh();
@@ -105,14 +104,12 @@
return BluetoothProfile.PBAP_CLIENT;
}
- PbapClientProfile(Context context, LocalBluetoothAdapter adapter,
- CachedBluetoothDeviceManager deviceManager,
+ PbapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
- mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mProfileManager = profileManager;
- mLocalAdapter.getProfileProxy(context, new PbapClientServiceListener(),
- BluetoothProfile.PBAP_CLIENT);
+ BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
+ new PbapClientServiceListener(), BluetoothProfile.PBAP_CLIENT);
}
public boolean isConnectable() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
index f1d73ed..f0e259e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
@@ -69,7 +69,7 @@
// we may add a new device here, but generally this should not happen
if (device == null) {
Log.w(TAG, "SapProfile found new device: " + nextDevice);
- device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
+ device = mDeviceManager.addDevice(nextDevice);
}
device.onProfileStateChanged(SapProfile.this,
BluetoothProfile.STATE_CONNECTED);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index b2ab45c..29831a8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -19,11 +19,11 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCodecConfig;
import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
@@ -33,21 +33,23 @@
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class A2dpProfileTest {
@Mock
Context mContext;
@Mock
- LocalBluetoothAdapter mAdapter;
- @Mock
CachedBluetoothDeviceManager mDeviceManager;
@Mock
LocalBluetoothProfileManager mProfileManager;
@@ -58,20 +60,14 @@
BluetoothProfile.ServiceListener mServiceListener;
A2dpProfile mProfile;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
-
- // Capture the A2dpServiceListener our A2dpProfile will pass during its constructor, so that
- // we can call its onServiceConnected method and get it to use our mock BluetoothA2dp
- // object.
- doAnswer((invocation) -> {
- mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1];
- return null;
- }).when(mAdapter).getProfileProxy(any(Context.class), any(), eq(BluetoothProfile.A2DP));
-
- mProfile = new A2dpProfile(mContext, mAdapter, mDeviceManager, mProfileManager);
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ mProfile = new A2dpProfile(mContext, mDeviceManager, mProfileManager);
+ mServiceListener = mShadowBluetoothAdapter.getServiceListener();
mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index b33e9c3..2d34f23 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -21,7 +21,6 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
@@ -59,8 +58,6 @@
private final BluetoothClass DEVICE_CLASS_2 =
new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
@Mock
- private LocalBluetoothAdapter mLocalAdapter;
- @Mock
private LocalBluetoothProfileManager mLocalProfileManager;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
@@ -110,18 +107,17 @@
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
- when(mLocalAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
when(mHfpProfile.isProfileReady()).thenReturn(true);
when(mA2dpProfile.isProfileReady()).thenReturn(true);
when(mPanProfile.isProfileReady()).thenReturn(true);
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
mCachedDevice1 = spy(
- new CachedBluetoothDevice(mContext, mLocalAdapter, mLocalProfileManager, mDevice1));
+ new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
mCachedDevice2 = spy(
- new CachedBluetoothDevice(mContext, mLocalAdapter, mLocalProfileManager, mDevice2));
+ new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
mCachedDevice3 = spy(
- new CachedBluetoothDevice(mContext, mLocalAdapter, mLocalProfileManager, mDevice3));
+ new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3));
}
/**
@@ -129,11 +125,9 @@
*/
@Test
public void testAddDevice_validCachedDevices_devicesAdded() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
@@ -149,8 +143,7 @@
*/
@Test
public void testGetName_validCachedDevice_nameFound() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
assertThat(mCachedDeviceManager.getName(mDevice1)).isEqualTo(DEVICE_ALIAS_1);
}
@@ -160,8 +153,7 @@
*/
@Test
public void testOnDeviceNameUpdated_validName_nameUpdated() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1);
@@ -176,11 +168,9 @@
*/
@Test
public void testClearNonBondedDevices_bondedAndNonBondedDevices_nonBondedDevicesCleared() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
@@ -231,11 +221,9 @@
*/
@Test
public void testOnHiSyncIdChanged_sameHiSyncId_populateInDifferentLists() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
// Since both devices do not have hiSyncId, they should be added in mCachedDevices.
@@ -266,11 +254,9 @@
*/
@Test
public void testOnHiSyncIdChanged_sameHiSyncIdAndOneConnected_chooseConnectedDevice() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
@@ -303,11 +289,9 @@
*/
@Test
public void testOnHiSyncIdChanged_differentHiSyncId_populateInSameList() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
// Since both devices do not have hiSyncId, they should be added in mCachedDevices.
@@ -339,8 +323,7 @@
*/
@Test
public void testOnProfileConnectionStateChanged_singleDeviceConnected_visible() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
@@ -377,11 +360,9 @@
*/
@Test
public void testOnProfileConnectionStateChanged_twoDevicesConnected_oneDeviceVisible() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
@@ -431,11 +412,9 @@
*/
@Test
public void testOnProfileConnectionStateChanged_twoDevicesDisconnected_oneDeviceVisible() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
@@ -486,11 +465,9 @@
*/
@Test
public void testOnDeviceUnpaired_bothHearingAidsPaired_removesItsPairFromList() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
cachedDevice1.setHiSyncId(HISYNCID1);
@@ -518,14 +495,11 @@
*/
@Test
public void testOnDeviceUnpaired_bothHearingAidsNotPaired_doesNotRemoveAnyDeviceFromList() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
- CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice3);
+ CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mDevice3);
assertThat(cachedDevice2).isNotNull();
cachedDevice1.setHiSyncId(HISYNCID1);
@@ -570,8 +544,7 @@
doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice2);
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
// The first hearing aid device should be populated in mCachedDevice and
// mCachedDevicesMapForHearingAids.
@@ -581,8 +554,7 @@
assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
.contains(cachedDevice1);
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
// The second hearing aid device should be populated in mHearingAidDevicesNotAddedInCache.
assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
@@ -599,8 +571,7 @@
.getHearingAidProfile();
doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
doAnswer((invocation) -> HISYNCID2).when(mHearingAidProfile).getHiSyncId(mDevice2);
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
// The first hearing aid device should be populated in mCachedDevice and
// mCachedDevicesMapForHearingAids.
@@ -610,8 +581,7 @@
assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
.contains(cachedDevice1);
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
// The second hearing aid device should also be populated in mCachedDevice
// and mCachedDevicesMapForHearingAids as its not a pair of the first one.
@@ -680,8 +650,7 @@
*/
@Test
public void testOnBtClassChanged_validBtClass_classChanged() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
assertThat(cachedDevice1.getBtClass()).isEqualTo(DEVICE_CLASS_1);
@@ -696,8 +665,7 @@
*/
@Test
public void testOnDeviceDisappeared_deviceBondedUnbonded_unbondedDeviceDisappeared() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
@@ -712,11 +680,9 @@
*/
@Test
public void testOnActiveDeviceChanged_connectedDevices_activeDeviceChanged() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
@@ -777,11 +743,9 @@
*/
@Test
public void testOnActiveDeviceChanged_withA2dpAndHearingAid() {
- CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice1);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
assertThat(cachedDevice1).isNotNull();
- CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
- mDevice2);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
assertThat(cachedDevice2).isNotNull();
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index c39fb85..034574f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -26,7 +26,6 @@
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
@@ -49,8 +48,6 @@
private final static String DEVICE_ADDRESS = "AA:BB:CC:DD:EE:FF";
private final static String DEVICE_ALIAS_NEW = "TestAliasNew";
@Mock
- private LocalBluetoothAdapter mAdapter;
- @Mock
private LocalBluetoothProfileManager mProfileManager;
@Mock
private HeadsetProfile mHfpProfile;
@@ -73,13 +70,11 @@
mContext = RuntimeEnvironment.application;
mShadowAudioManager = shadowOf(mContext.getSystemService(AudioManager.class));
when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
- when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
when(mHfpProfile.isProfileReady()).thenReturn(true);
when(mA2dpProfile.isProfileReady()).thenReturn(true);
when(mPanProfile.isProfileReady()).thenReturn(true);
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
- mCachedDevice = spy(
- new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice));
+ mCachedDevice = spy(new CachedBluetoothDevice(mContext, mProfileManager, mDevice));
doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel();
}
@@ -477,7 +472,7 @@
when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);
when(mDevice.getName()).thenReturn(DEVICE_NAME);
CachedBluetoothDevice cachedBluetoothDevice =
- new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice);
+ new CachedBluetoothDevice(mContext, mProfileManager, mDevice);
// Verify alias is returned on getName
assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS);
// Verify device is visible
@@ -487,7 +482,7 @@
@Test
public void testDeviceName_testNameNotAvailable() {
CachedBluetoothDevice cachedBluetoothDevice =
- new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice);
+ new CachedBluetoothDevice(mContext, mProfileManager, mDevice);
// Verify device address is returned on getName
assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ADDRESS);
// Verify device is not visible
@@ -504,7 +499,7 @@
}).when(mDevice).setAlias(anyString());
when(mDevice.getName()).thenReturn(DEVICE_NAME);
CachedBluetoothDevice cachedBluetoothDevice =
- new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice);
+ new CachedBluetoothDevice(mContext, mProfileManager, mDevice);
// Verify alias is returned on getName
assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS);
// Verify null name does not get set
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java
index bc8be4d..c0a1f0c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java
@@ -2,18 +2,17 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
import org.junit.Test;
@@ -21,13 +20,14 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class HeadsetProfileTest {
@Mock
- private LocalBluetoothAdapter mAdapter;
- @Mock
private CachedBluetoothDeviceManager mDeviceManager;
@Mock
private LocalBluetoothProfileManager mProfileManager;
@@ -39,19 +39,18 @@
private BluetoothDevice mBluetoothDevice;
private BluetoothProfile.ServiceListener mServiceListener;
private HeadsetProfile mProfile;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Context context = spy(RuntimeEnvironment.application);
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- doAnswer((invocation) -> {
- mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1];
- return null;
- }).when(mAdapter).getProfileProxy(any(Context.class), any(), eq(BluetoothProfile.HEADSET));
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
- mProfile = new HeadsetProfile(context, mAdapter, mDeviceManager, mProfileManager);
+ mProfile = new HeadsetProfile(context, mDeviceManager, mProfileManager);
+ mServiceListener = mShadowBluetoothAdapter.getServiceListener();
mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mService);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index af66f7a..f223176 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -38,6 +38,7 @@
import android.os.ParcelUuid;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
import org.junit.Test;
@@ -45,34 +46,38 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
import java.util.List;
@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class LocalBluetoothProfileManagerTest {
@Mock
private CachedBluetoothDeviceManager mDeviceManager;
@Mock
private BluetoothEventManager mEventManager;
@Mock
- private LocalBluetoothAdapter mAdapter;
- @Mock
private BluetoothDevice mDevice;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
private Context mContext;
- private LocalBluetoothProfileManager mProfileManager;
private Intent mIntent;
+ private LocalBluetoothAdapter mLocalBluetoothAdapter;
+ private LocalBluetoothProfileManager mProfileManager;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- mEventManager = spy(new BluetoothEventManager(mAdapter,
- mDeviceManager, mContext));
- when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+ mLocalBluetoothAdapter = LocalBluetoothAdapter.getInstance();
+ mEventManager = spy(new BluetoothEventManager(mLocalBluetoothAdapter, mDeviceManager,
+ mContext));
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
when(mDeviceManager.findDevice(mDevice)).thenReturn(mCachedBluetoothDevice);
}
@@ -81,12 +86,10 @@
*/
@Test
public void constructor_initiateHidAndHidDeviceProfile() {
- when(mAdapter.getSupportedProfiles()).thenReturn(
- generateList(new int[] {BluetoothProfile.HID_HOST}));
- when(mAdapter.getSupportedProfiles()).thenReturn(
- generateList(new int[] {BluetoothProfile.HID_HOST, BluetoothProfile.HID_DEVICE}));
- mProfileManager =
- new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
+ new int[] {BluetoothProfile.HID_HOST, BluetoothProfile.HID_DEVICE}));
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
assertThat(mProfileManager.getHidProfile()).isNotNull();
assertThat(mProfileManager.getHidDeviceProfile()).isNotNull();
@@ -97,12 +100,12 @@
*/
@Test
public void updateLocalProfiles_addA2dpToLocalProfiles() {
- mProfileManager =
- new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
assertThat(mProfileManager.getA2dpProfile()).isNull();
assertThat(mProfileManager.getHeadsetProfile()).isNull();
- when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
new int[] {BluetoothProfile.A2DP}));
mProfileManager.updateLocalProfiles();
@@ -115,10 +118,10 @@
*/
@Test
public void updateProfiles_addHidProfileForRemoteDevice() {
- when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
new int[] {BluetoothProfile.HID_HOST}));
- mProfileManager =
- new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
ParcelUuid[] uuids = new ParcelUuid[]{BluetoothUuid.Hid};
ParcelUuid[] localUuids = new ParcelUuid[]{};
List<LocalBluetoothProfile> profiles = new ArrayList<>();
@@ -138,10 +141,10 @@
*/
@Test
public void stateChangedHandler_receiveA2dpConnectionStateChanged_shouldDispatchCallback() {
- when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
new int[] {BluetoothProfile.A2DP}));
- mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
- mEventManager);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
// Refer to BluetoothControllerImpl, it will call setReceiverHandler after
// LocalBluetoothProfileManager created.
mEventManager.setReceiverHandler(null);
@@ -162,10 +165,10 @@
*/
@Test
public void stateChangedHandler_receiveHeadsetConnectionStateChanged_shouldDispatchCallback() {
- when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
new int[] {BluetoothProfile.HEADSET}));
- mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
- mEventManager);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
// Refer to BluetoothControllerImpl, it will call setReceiverHandler after
// LocalBluetoothProfileManager created.
mEventManager.setReceiverHandler(null);
@@ -186,12 +189,10 @@
*/
@Test
public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldDispatchCallback() {
- ArrayList<Integer> supportProfiles = new ArrayList<>();
- supportProfiles.add(BluetoothProfile.HEARING_AID);
- when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles);
- when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.HearingAid});
- mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
- mEventManager);
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
+ new int[] {BluetoothProfile.HEARING_AID}));
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
// Refer to BluetoothControllerImpl, it will call setReceiverHandler after
// LocalBluetoothProfileManager created.
mEventManager.setReceiverHandler(null);
@@ -212,10 +213,10 @@
*/
@Test
public void stateChangedHandler_receivePanConnectionStateChanged_shouldNotDispatchCallback() {
- when(mAdapter.getSupportedProfiles()).thenReturn(
- generateList(new int[] {BluetoothProfile.PAN}));
- mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
- mEventManager);
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
+ new int[] {BluetoothProfile.PAN}));
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
// Refer to BluetoothControllerImpl, it will call setReceiverHandler after
// LocalBluetoothProfileManager created.
mEventManager.setReceiverHandler(null);
@@ -237,9 +238,9 @@
@Test
public void stateChangedHandler_receivePanConnectionStateChangedWithoutProfile_shouldNotRefresh
() {
- when(mAdapter.getSupportedProfiles()).thenReturn(null);
- mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
- mEventManager);
+ mShadowBluetoothAdapter.setSupportedProfiles(null);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
// Refer to BluetoothControllerImpl, it will call setReceiverHandler after
// LocalBluetoothProfileManager created.
mEventManager.setReceiverHandler(null);
@@ -259,10 +260,10 @@
*/
@Test
public void stateChangedHandler_receivePanConnectionStateChangedWithProfile_shouldRefresh() {
- when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
+ mShadowBluetoothAdapter.setSupportedProfiles(generateList(
new int[] {BluetoothProfile.PAN}));
- mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
- mEventManager);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter,
+ mDeviceManager, mEventManager);
// Refer to BluetoothControllerImpl, it will call setReceiverHandler after
// LocalBluetoothProfileManager created.
mEventManager.setReceiverHandler(null);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
new file mode 100644
index 0000000..9b8c230
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.testutils.shadow;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+import java.util.List;
+
+@Implements(value = BluetoothAdapter.class, inheritImplementationMethods = true)
+public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter {
+
+ private List<Integer> mSupportedProfiles;
+ private BluetoothProfile.ServiceListener mServiceListener;
+
+ @Implementation
+ public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
+ int profile) {
+ mServiceListener = listener;
+ return true;
+ }
+
+ public BluetoothProfile.ServiceListener getServiceListener() {
+ return mServiceListener;
+ }
+
+ @Implementation
+ public List<Integer> getSupportedProfiles() {
+ return mSupportedProfiles;
+ }
+
+ public void setSupportedProfiles(List<Integer> supportedProfiles) {
+ mSupportedProfiles = supportedProfiles;
+ }
+}
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
new file mode 100644
index 0000000..c9ba268
--- /dev/null
+++ b/packages/SystemUI/Android.bp
@@ -0,0 +1,101 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_library {
+ name: "SystemUI-proto",
+
+ srcs: ["src/**/*.proto"],
+
+ proto: {
+ type: "nano",
+ },
+}
+
+java_library {
+ name: "SystemUI-tags",
+ srcs: ["src/com/android/systemui/EventLogTags.logtags"],
+}
+
+android_library {
+ name: "SystemUI-core",
+ srcs: [
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ],
+ resource_dirs: [
+ "res-keyguard",
+ "res",
+ ],
+ static_libs: [
+ "SystemUIPluginLib",
+ "SystemUISharedLib",
+ "SettingsLib",
+ "androidx.car_car",
+ "androidx.legacy_legacy-support-v4",
+ "androidx.recyclerview_recyclerview",
+ "androidx.preference_preference",
+ "androidx.appcompat_appcompat",
+ "androidx.mediarouter_mediarouter",
+ "androidx.palette_palette",
+ "androidx.legacy_legacy-preference-v14",
+ "androidx.leanback_leanback",
+ "androidx.slice_slice-core",
+ "androidx.slice_slice-view",
+ "androidx.slice_slice-builders",
+ "androidx.arch.core_core-runtime",
+ "androidx.lifecycle_lifecycle-extensions",
+ "SystemUI-tags",
+ "SystemUI-proto",
+ ],
+ manifest: "AndroidManifest.xml",
+
+ libs: [
+ "telephony-common",
+ "android.car",
+ ],
+
+ aaptflags: [
+ "--extra-packages",
+ "com.android.keyguard",
+ ],
+}
+
+android_app {
+ name: "SystemUI",
+ static_libs: [
+ "SystemUI-core",
+ ],
+
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+
+ optimize: {
+ proguard_flags_files: ["proguard.flags"],
+ },
+
+ libs: [
+ "telephony-common",
+ "android.car",
+ ],
+
+ dxflags: ["--multi-dex"],
+ aaptflags: [
+ "--extra-packages",
+ "com.android.keyguard",
+ ],
+
+}
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
deleted file mode 100644
index 920e3b6a..0000000
--- a/packages/SystemUI/Android.mk
+++ /dev/null
@@ -1,82 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := SystemUI-proto
-
-LOCAL_SRC_FILES := $(call all-proto-files-under,src)
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := SystemUI-tags
-
-LOCAL_SRC_FILES := src/com/android/systemui/EventLogTags.logtags
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# ------------------
-
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := optional
-
-RELATIVE_FINGERPRINT_PATH := ../../core/java/android/hardware/fingerprint
-
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-Iaidl-files-under, src) \
- $(call all-Iaidl-files-under, $(RELATIVE_FINGERPRINT_PATH))
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- SystemUIPluginLib \
- SystemUISharedLib \
- androidx.car_car \
- androidx.legacy_legacy-support-v4 \
- androidx.recyclerview_recyclerview \
- androidx.preference_preference \
- androidx.appcompat_appcompat \
- androidx.mediarouter_mediarouter \
- androidx.palette_palette \
- androidx.legacy_legacy-preference-v14 \
- androidx.leanback_leanback \
- androidx.slice_slice-core \
- androidx.slice_slice-view \
- androidx.slice_slice-builders \
- androidx.arch.core_core-runtime \
- androidx.lifecycle_lifecycle-extensions \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- SystemUI-tags \
- SystemUI-proto
-
-LOCAL_JAVA_LIBRARIES := telephony-common \
- android.car
-
-LOCAL_PACKAGE_NAME := SystemUI
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res-keyguard $(LOCAL_PATH)/res
-
-ifneq ($(INCREMENTAL_BUILDS),)
- LOCAL_PROGUARD_ENABLED := disabled
- LOCAL_JACK_ENABLED := incremental
- LOCAL_DX_FLAGS := --multi-dex
- LOCAL_JACK_FLAGS := --multi-dex native
-endif
-
-include frameworks/base/packages/SettingsLib/common.mk
-
-LOCAL_AAPT_FLAGS := --extra-packages com.android.keyguard
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
new file mode 100644
index 0000000..b38059d
--- /dev/null
+++ b/packages/SystemUI/plugin/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 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.
+
+java_library {
+
+ name: "SystemUIPluginLib",
+
+ srcs: ["src/**/*.java"],
+
+
+}
+
+android_app {
+
+ // Dummy to generate .toc files.
+ name: "PluginDummyLib",
+ platform_apis: true,
+ srcs: ["src/**/*.java"],
+
+ libs: ["SystemUIPluginLib"],
+
+ optimize: {
+ enabled: false,
+ },
+
+}
diff --git a/packages/SystemUI/plugin/Android.mk b/packages/SystemUI/plugin/Android.mk
deleted file mode 100644
index 8634684..0000000
--- a/packages/SystemUI/plugin/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2016 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_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := SystemUIPluginLib
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_JAR_EXCLUDE_FILES := none
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-
-# Dummy to generate .toc files.
-LOCAL_PACKAGE_NAME := PluginDummyLib
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := SystemUIPluginLib
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/plugin/ExamplePlugin/Android.bp b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
new file mode 100644
index 0000000..a0eaf14
--- /dev/null
+++ b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
@@ -0,0 +1,14 @@
+android_app {
+
+ name: "ExamplePlugin",
+
+ libs: ["SystemUIPluginLib"],
+
+ certificate: "platform",
+ optimize: {
+ enabled: false,
+ },
+
+ srcs: ["src/**/*.java"],
+
+}
diff --git a/packages/SystemUI/plugin/ExamplePlugin/Android.mk b/packages/SystemUI/plugin/ExamplePlugin/Android.mk
deleted file mode 100644
index 4c82c75..0000000
--- a/packages/SystemUI/plugin/ExamplePlugin/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_PACKAGE_NAME := ExamplePlugin
-
-LOCAL_JAVA_LIBRARIES := SystemUIPluginLib
-
-LOCAL_CERTIFICATE := platform
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 61f7fe8..bf4374a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -43,7 +43,7 @@
boolean isAvailable();
void setTileSpec(String tileSpec);
- void clearState();
+ @Deprecated default void clearState() {}
void refreshState();
void addCallback(Callback callback);
diff --git a/packages/SystemUI/res-keyguard/values/alias.xml b/packages/SystemUI/res-keyguard/values/alias.xml
index f06b450..1c63c79 100644
--- a/packages/SystemUI/res-keyguard/values/alias.xml
+++ b/packages/SystemUI/res-keyguard/values/alias.xml
@@ -25,9 +25,6 @@
<!-- Alias used to reference framework "OK" string in keyguard. -->
<item type="string" name="ok">@*android:string/ok</item>
- <!-- Alias used to reference framework "OK" string in keyguard. -->
- <item type="string" name="system_ui_date_pattern">@*android:string/system_ui_date_pattern</item>
-
<!-- Alias used to reference framework configuration for screen rotation. -->
<item type="bool" name="config_enableLockScreenRotation">@*android:bool/config_enableLockScreenRotation</item>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
index a960af7..da23937 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
@@ -14,13 +14,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval"
- android:useLevel="false">
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
- <solid android:color="?attr/singleToneColor" />
-
- <size
- android:height="14dp"
- android:width="14dp" />
-</shape>
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M 14 7 C 17.8659932488 7 21 10.1340067512 21 14 C 21 17.8659932488 17.8659932488 21 14 21 C 10.1340067512 21 7 17.8659932488 7 14 C 7 10.1340067512 10.1340067512 7 14 7 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 915fc6e..9a64c60 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1929,23 +1929,17 @@
<!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_add_tile_label"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g>. Double tap to add.</string>
- <!-- Accessibility description of a place to drop a tile while editing positions [CHAR LIMIT=NONE] -->
- <string name="accessibility_qs_edit_position_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>. Double tap to select.</string>
-
<!-- Accessibility description of option to move QS tile [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_move_tile">Move <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g></string>
<!-- Accessibility description of option to remove QS tile [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_remove_tile">Remove <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g></string>
- <!-- Accessibility action when QS tile is added [CHAR LIMIT=NONE] -->
- <string name="accessibility_qs_edit_tile_added"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> is added to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
+ <!-- Accessibility action when QS tile is to be added [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_add">Add <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
- <!-- Accessibility action when QS tile is removed [CHAR LIMIT=NONE] -->
- <string name="accessibility_qs_edit_tile_removed"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> is removed</string>
-
- <!-- Accessibility action when QS tile is moved [CHAR LIMIT=NONE] -->
- <string name="accessibility_qs_edit_tile_moved"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> moved to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
+ <!-- Accessibility action when QS tile is to be moved [CHAR LIMIT=NONE] -->
+ <string name="accessibility_qs_edit_tile_move">Move <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
<!-- Accessibility label for window when QS editing is happening [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_quick_settings_edit">Quick settings editor.</string>
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
new file mode 100644
index 0000000..0fb1200
--- /dev/null
+++ b/packages/SystemUI/shared/Android.bp
@@ -0,0 +1,40 @@
+// 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_library {
+
+ name: "SystemUISharedLib",
+ srcs: [
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ],
+
+}
+
+android_app {
+
+ name: "SysUISharedLib",
+ platform_apis: true,
+ srcs: [
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ],
+
+ static_libs: ["SystemUISharedLib"],
+
+ optimize: {
+ enabled: false,
+ },
+
+}
diff --git a/packages/SystemUI/shared/Android.mk b/packages/SystemUI/shared/Android.mk
deleted file mode 100644
index f20df0c..0000000
--- a/packages/SystemUI/shared/Android.mk
+++ /dev/null
@@ -1,43 +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_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := SystemUISharedLib
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-under, src)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_JAR_EXCLUDE_FILES := none
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := SysUISharedLib
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := SystemUISharedLib
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/SystemUI/shared/tests/Android.mk b/packages/SystemUI/shared/tests/Android.mk
index 4e7cbbf..02774c9 100644
--- a/packages/SystemUI/shared/tests/Android.mk
+++ b/packages/SystemUI/shared/tests/Android.mk
@@ -30,10 +30,10 @@
LOCAL_COMPATIBILITY_SUITE := device-tests
# Add local path sources as well as shared lib sources
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(call all-java-files-under, ../src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
+ SystemUISharedLib \
metrics-helper-lib \
android-support-test \
mockito-target-inline-minus-junit4 \
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index f4acc0c..b159b39 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -15,7 +15,6 @@
*/
package com.android.keyguard;
-import android.R.style;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.admin.DevicePolicyManager;
@@ -27,7 +26,6 @@
import android.util.Log;
import android.util.Slog;
import android.util.StatsLog;
-import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
@@ -212,7 +210,7 @@
if (messageId != 0) {
final String message = mContext.getString(messageId,
- KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(userId),
+ mLockPatternUtils.getCurrentFailedPasswordAttempts(userId),
timeoutInSeconds);
showDialog(null, message);
}
@@ -257,8 +255,8 @@
}
private void reportFailedUnlockAttempt(int userId, int timeoutMs) {
- final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
- final int failedAttempts = monitor.getFailedUnlockAttempts(userId) + 1; // +1 for this time
+ // +1 for this time
+ final int failedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(userId) + 1;
if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
@@ -292,7 +290,6 @@
showWipeDialog(failedAttempts, userType);
}
}
- monitor.reportFailedStrongAuthUnlockAttempt(userId);
mLockPatternUtils.reportFailedPasswordAttempt(userId);
if (timeoutMs > 0) {
mLockPatternUtils.reportPasswordLockout(timeoutMs, userId);
@@ -436,7 +433,6 @@
if (success) {
StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED,
StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__SUCCESS);
- monitor.clearFailedUnlockAttempts();
mLockPatternUtils.reportSuccessfulPasswordAttempt(userId);
} else {
StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 6517a9d..9603562 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -27,6 +27,7 @@
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Trace;
import android.provider.Settings;
import android.text.Layout;
import android.text.TextUtils;
@@ -148,6 +149,7 @@
}
private void showSlice() {
+ Trace.beginSection("KeyguardSliceView#showSlice");
if (mPulsing || mSlice == null) {
mTitle.setVisibility(GONE);
mRow.setVisibility(GONE);
@@ -236,6 +238,7 @@
if (mContentChangeListener != null) {
mContentChangeListener.run();
}
+ Trace.endSection();
}
public void setPulsing(boolean pulsing, boolean animate) {
@@ -383,8 +386,23 @@
}
public void refresh() {
- Slice slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
+ Slice slice;
+ Trace.beginSection("KeyguardSliceView#refresh");
+ // We can optimize performance and avoid binder calls when we know that we're bound
+ // to a Slice on the same process.
+ if (KeyguardSliceProvider.KEYGUARD_SLICE_URI.equals(mKeyguardSliceUri.toString())) {
+ KeyguardSliceProvider instance = KeyguardSliceProvider.getAttachedInstance();
+ if (instance != null) {
+ slice = instance.onBindSlice(mKeyguardSliceUri);
+ } else {
+ Log.w(TAG, "Keyguard slice not bound yet?");
+ slice = null;
+ }
+ } else {
+ slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
+ }
onChanged(slice);
+ Trace.endSection();
}
public static class Row extends LinearLayout {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index dfd6a18..3e534d1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -215,9 +215,6 @@
// Battery status
private BatteryStatus mBatteryStatus;
- // Password attempts
- private SparseIntArray mFailedAttempts = new SparseIntArray();
-
private final StrongAuthTracker mStrongAuthTracker;
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
@@ -2141,22 +2138,10 @@
return mDeviceProvisioned;
}
- public void clearFailedUnlockAttempts() {
- mFailedAttempts.delete(sCurrentUser);
- }
-
public ServiceState getServiceState(int subId) {
return mServiceStates.get(subId);
}
- public int getFailedUnlockAttempts(int userId) {
- return mFailedAttempts.get(userId, 0);
- }
-
- public void reportFailedStrongAuthUnlockAttempt(int userId) {
- mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
- }
-
public void clearBiometricRecognized() {
mUserFingerprintAuthenticated.clear();
mUserFaceAuthenticated.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 1cacdb5..51cc4a1 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -35,7 +35,7 @@
private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
- private static final int PULSE_REASONS = 6;
+ private static final int PULSE_REASONS = 7;
public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
@@ -44,6 +44,7 @@
public static final int PULSE_REASON_SENSOR_PICKUP = 3;
public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
+ public static final int PULSE_REASON_SENSOR_REACH = 6;
private static boolean sRegisterKeyguardCallback = true;
@@ -169,6 +170,11 @@
log("state " + state);
}
+ public static void traceReachWakeUp() {
+ if (!ENABLED) return;
+ log("reachWakeUp");
+ }
+
public static void traceProximityResult(Context context, boolean near, long millis,
int pulseReason) {
if (!ENABLED) return;
@@ -186,6 +192,7 @@
case PULSE_REASON_SENSOR_PICKUP: return "pickup";
case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
+ case PULSE_REASON_SENSOR_REACH: return "reach";
default: throw new IllegalArgumentException("bad reason: " + pulseReason);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 18dffa7..045a98c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -110,6 +110,13 @@
DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
true /* reports touch coordinates */,
true /* touchscreen */),
+ new TriggerSensor(
+ findSensorWithType(config.reachSensorType()),
+ Settings.Secure.DOZE_REACH_GESTURE,
+ true /* configured */,
+ DozeLog.PULSE_REASON_SENSOR_REACH,
+ false /* reports touch coordinates */,
+ false /* touchscreen */),
};
mProxSensor = new ProxSensor(policy);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 4391a44..73cbd7d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -128,6 +128,7 @@
boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
+ boolean isReach = pulseReason == DozeLog.PULSE_REASON_SENSOR_REACH;
if (isLongPress) {
requestPulse(pulseReason, sensorPerformedProxCheck);
@@ -140,7 +141,7 @@
if (isDoubleTap) {
mDozeHost.onDoubleTap(screenX, screenY);
mMachine.wakeUp();
- } else if (isPickup) {
+ } else if (isPickup || isReach) {
mMachine.wakeUp();
} else {
mDozeHost.extendPulse();
@@ -155,6 +156,8 @@
final boolean withinVibrationThreshold =
timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
DozeLog.tracePickupWakeUp(mContext, withinVibrationThreshold);
+ } else if (isReach) {
+ DozeLog.traceReachWakeUp();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index a42191c..76a1acc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -318,7 +318,7 @@
private CachedBluetoothDevice getCachedBluetoothDevice(BluetoothDevice d) {
CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(d);
if (cachedDevice == null) {
- cachedDevice = mCachedDeviceManager.addDevice(mLocalBluetoothAdapter, d);
+ cachedDevice = mCachedDeviceManager.addDevice(d);
}
return cachedDevice;
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index c96aa73..82b79ac 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -30,6 +30,7 @@
import android.icu.text.DisplayContext;
import android.net.Uri;
import android.os.Handler;
+import android.os.Trace;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
@@ -72,6 +73,8 @@
@VisibleForTesting
static final int ALARM_VISIBILITY_HOURS = 12;
+ private static KeyguardSliceProvider sInstance;
+
protected final Uri mSliceUri;
protected final Uri mDateUri;
protected final Uri mAlarmUri;
@@ -89,6 +92,7 @@
protected AlarmManager mAlarmManager;
protected ContentResolver mContentResolver;
private AlarmManager.AlarmClockInfo mNextAlarmInfo;
+ private PendingIntent mPendingIntent;
/**
* Receiver responsible for time ticking and updating the date format.
@@ -117,6 +121,10 @@
this(new Handler());
}
+ public static KeyguardSliceProvider getAttachedInstance() {
+ return KeyguardSliceProvider.sInstance;
+ }
+
@VisibleForTesting
KeyguardSliceProvider(Handler handler) {
mHandler = handler;
@@ -128,23 +136,24 @@
@Override
public Slice onBindSlice(Uri sliceUri) {
+ Trace.beginSection("KeyguardSliceProvider#onBindSlice");
ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText));
addNextAlarm(builder);
addZenMode(builder);
addPrimaryAction(builder);
- return builder.build();
+ Slice slice = builder.build();
+ Trace.endSection();
+ return slice;
}
protected void addPrimaryAction(ListBuilder builder) {
// Add simple action because API requires it; Keyguard handles presenting
// its own slices so this action + icon are actually never used.
- PendingIntent pi = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
IconCompat icon = IconCompat.createWithResource(getContext(),
R.drawable.ic_access_alarms_big);
- SliceAction action = SliceAction.createDeeplink(pi, icon,
+ SliceAction action = SliceAction.createDeeplink(mPendingIntent, icon,
ListBuilder.ICON_IMAGE, mLastText);
-
RowBuilder primaryActionRow = new RowBuilder(Uri.parse(KEYGUARD_ACTION_URI))
.setPrimaryAction(action);
builder.addRow(primaryActionRow);
@@ -154,7 +163,6 @@
if (TextUtils.isEmpty(mNextAlarm)) {
return;
}
-
IconCompat alarmIcon = IconCompat.createWithResource(getContext(),
R.drawable.ic_access_alarms_big);
RowBuilder alarmRowBuilder = new RowBuilder(mAlarmUri)
@@ -198,6 +206,8 @@
mZenModeController = new ZenModeControllerImpl(getContext(), mHandler);
mZenModeController.addCallback(this);
mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
+ mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
+ KeyguardSliceProvider.sInstance = this;
registerClockUpdate();
updateClock();
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4763fa9..4977ff7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1655,7 +1655,6 @@
resetKeyguardDonePendingLocked();
}
- mUpdateMonitor.clearFailedUnlockAttempts();
mUpdateMonitor.clearBiometricRecognized();
if (mGoingToSleep) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 0876a5d..3fc258b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -285,9 +285,6 @@
updatePageIndicator();
- for (TileRecord r : mRecords) {
- r.tile.clearState();
- }
if (mListening) {
refreshAllTiles();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 78e9f36..10b92f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -88,6 +88,7 @@
private Holder mCurrentDrag;
private int mAccessibilityAction = ACTION_NONE;
private int mAccessibilityFromIndex;
+ private CharSequence mAccessibilityFromLabel;
private QSTileHost mHost;
public TileAdapter(Context context) {
@@ -241,7 +242,8 @@
holder.mTileView.setVisibility(View.VISIBLE);
holder.mTileView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
holder.mTileView.setContentDescription(mContext.getString(
- R.string.accessibility_qs_edit_position_label, position + 1));
+ R.string.accessibility_qs_edit_tile_add, mAccessibilityFromLabel,
+ position + 1));
holder.mTileView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -270,9 +272,12 @@
if (position > mEditIndex) {
info.state.contentDescription = mContext.getString(
R.string.accessibility_qs_edit_add_tile_label, info.state.label);
- } else if (mAccessibilityAction != ACTION_NONE) {
+ } else if (mAccessibilityAction == ACTION_ADD) {
info.state.contentDescription = mContext.getString(
- R.string.accessibility_qs_edit_position_label, position + 1);
+ R.string.accessibility_qs_edit_tile_add, mAccessibilityFromLabel, position + 1);
+ } else if (mAccessibilityAction == ACTION_MOVE) {
+ info.state.contentDescription = mContext.getString(
+ R.string.accessibility_qs_edit_tile_move, mAccessibilityFromLabel, position + 1);
} else {
info.state.contentDescription = mContext.getString(
R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
@@ -351,6 +356,7 @@
private void startAccessibleAdd(int position) {
mAccessibilityFromIndex = position;
+ mAccessibilityFromLabel = mTiles.get(position).state.label;
mAccessibilityAction = ACTION_ADD;
// Add placeholder for last slot.
mTiles.add(mEditIndex++, null);
@@ -360,6 +366,7 @@
private void startAccessibleMove(int position) {
mAccessibilityFromIndex = position;
+ mAccessibilityFromLabel = mTiles.get(position).state.label;
mAccessibilityAction = ACTION_MOVE;
notifyDataSetChanged();
}
@@ -385,15 +392,11 @@
strip(mTiles.get(to)));
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD,
to);
- v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_added,
- fromLabel, (to + 1)));
} else {
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE_SPEC,
strip(mTiles.get(to)));
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE,
to);
- v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_moved,
- fromLabel, (to + 1)));
}
saveSpecs(mHost);
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 53a576d..591e9e0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -95,7 +95,6 @@
continue;
}
tile.setListening(this, true);
- tile.clearState();
tile.refreshState();
tile.setListening(this, false);
tile.setTileSpec(spec);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 6bc3bee..b6a776f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -211,10 +211,6 @@
mHandler.obtainMessage(H.REFRESH_STATE, arg).sendToTarget();
}
- public void clearState() {
- mHandler.sendEmptyMessage(H.CLEAR_STATE);
- }
-
public void userSwitch(int newUserId) {
mHandler.obtainMessage(H.USER_SWITCH, newUserId, 0).sendToTarget();
}
@@ -266,11 +262,6 @@
public abstract Intent getLongClickIntent();
- protected void handleClearState() {
- mTmpState = newTileState();
- mState = newTileState();
- }
-
protected void handleRefreshState(Object arg) {
handleUpdateState(mTmpState, arg);
final boolean changed = mTmpState.copyTo(mState);
@@ -409,11 +400,10 @@
private static final int TOGGLE_STATE_CHANGED = 8;
private static final int SCAN_STATE_CHANGED = 9;
private static final int DESTROY = 10;
- private static final int CLEAR_STATE = 11;
- private static final int REMOVE_CALLBACKS = 12;
- private static final int REMOVE_CALLBACK = 13;
- private static final int SET_LISTENING = 14;
- private static final int STALE = 15;
+ private static final int REMOVE_CALLBACKS = 11;
+ private static final int REMOVE_CALLBACK = 12;
+ private static final int SET_LISTENING = 13;
+ private static final int STALE = 14;
@VisibleForTesting
protected H(Looper looper) {
@@ -467,9 +457,6 @@
} else if (msg.what == DESTROY) {
name = "handleDestroy";
handleDestroy();
- } else if (msg.what == CLEAR_STATE) {
- name = "handleClearState";
- handleClearState();
} else if (msg.what == SET_LISTENING) {
name = "handleSetListeningInternal";
handleSetListeningInternal(msg.obj, msg.arg1 != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
index d7c4bbf..c97095e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
@@ -21,11 +21,13 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources.NotFoundException;
import android.media.AudioManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManager;
+
import com.android.systemui.statusbar.phone.SystemUIDialog;
abstract public class SafetyWarningDialog extends SystemUIDialog
@@ -40,12 +42,18 @@
private long mShowTime;
private boolean mNewVolumeUp;
+ private boolean mDisableOnVolumeUp;
public SafetyWarningDialog(Context context, AudioManager audioManager) {
super(context);
mContext = context;
mAudioManager = audioManager;
-
+ try {
+ mDisableOnVolumeUp = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_safe_media_disable_on_volume_up);
+ } catch (NotFoundException e) {
+ mDisableOnVolumeUp = true;
+ }
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
setShowForAllUsers(true);
setMessage(mContext.getString(com.android.internal.R.string.safe_media_volume_warning));
@@ -63,7 +71,8 @@
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && event.getRepeatCount() == 0) {
+ if (mDisableOnVolumeUp && keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ && event.getRepeatCount() == 0) {
mNewVolumeUp = true;
}
return super.onKeyDown(keyCode, event);
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index a4120c4..9ee5532 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -30,37 +30,17 @@
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(call all-Iaidl-files-under, src) \
- $(call all-java-files-under, ../src)
+ $(call all-Iaidl-files-under, src)
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
- frameworks/base/packages/SystemUI/res \
- frameworks/base/packages/SystemUI/res-keyguard \
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_STATIC_ANDROID_LIBRARIES := \
- SystemUIPluginLib \
- SystemUISharedLib \
- androidx.car_car \
- androidx.legacy_legacy-support-v4 \
- androidx.recyclerview_recyclerview \
- androidx.preference_preference \
- androidx.appcompat_appcompat \
- androidx.mediarouter_mediarouter \
- androidx.palette_palette \
- androidx.legacy_legacy-preference-v14 \
- androidx.leanback_leanback \
- androidx.slice_slice-core \
- androidx.slice_slice-view \
- androidx.slice_slice-builders \
- androidx.arch.core_core-runtime \
- androidx.lifecycle_lifecycle-extensions \
+ SystemUI-core
LOCAL_STATIC_JAVA_LIBRARIES := \
metrics-helper-lib \
android-support-test \
mockito-target-inline-minus-junit4 \
- SystemUI-proto \
- SystemUI-tags \
testables \
truth-prebuilt \
@@ -70,7 +50,6 @@
libdexmakerjvmtiagent \
libmultiplejvmtiagentsinterferenceagent
-
LOCAL_JAVA_LIBRARIES := \
android.test.runner \
telephony-common \
@@ -112,8 +91,6 @@
LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.systemui.*
LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := com.android.systemui.tests.*,$(jacoco_exclude)
-include frameworks/base/packages/SettingsLib/common.mk
-
ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
include $(BUILD_PACKAGE)
endif
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index f95027b..64f96da 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -15,6 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.android.systemui.tests">
@@ -72,6 +73,18 @@
android:authorities="${applicationId}.lifecycle-tests"
android:exported="false"
android:multiprocess="true" />
+ <provider android:name="com.android.systemui.keyguard.KeyguardSliceProvider"
+ android:authorities="com.android.systemui.test.keyguard.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+
+ <provider
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="com.android.systemui.test.fileprovider"
+ android:exported="false"
+ tools:replace="android:authorities"
+ android:grantUriPermissions="true" />
</application>
<instrumentation android:name="android.testing.TestableInstrumentation"
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index cc789e2..a20eece 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2219,6 +2219,7 @@
// 1: Gesture performed is Nudge
// 2: Gesture performed is Pickup
// 4: Gesture performed is Double Tap
+ // 6: Gesture performed is Reach
ACTION_AMBIENT_GESTURE = 411;
// ---- End N Constants, all N constants go above this line ----
@@ -6440,6 +6441,10 @@
// OS: Q
SETTINGS_WIFI_ADD_NETWORK = 1556;
+ // OPEN: Settings > System > Input & Gesture > Reach up gesture
+ // OS: Q
+ SETTINGS_GESTURE_REACH = 1557;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/art-profile b/services/art-profile
index cbc00ea..3c60eee 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -13303,7 +13303,7 @@
PLcom/android/server/notification/NotificationManagerService$10;->deleteNotificationChannel(Ljava/lang/String;Ljava/lang/String;)V
PLcom/android/server/notification/NotificationManagerService$10;->enforcePolicyAccess(ILjava/lang/String;)V
PLcom/android/server/notification/NotificationManagerService$10;->enforceSystemOrSystemUI(Ljava/lang/String;)V
-PLcom/android/server/notification/NotificationManagerService$10;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;I)V
+PLcom/android/server/notification/NotificationManagerService$10;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;II)V
PLcom/android/server/notification/NotificationManagerService$10;->finishToken(Ljava/lang/String;Landroid/app/ITransientNotification;)V
PLcom/android/server/notification/NotificationManagerService$10;->getAppActiveNotifications(Ljava/lang/String;I)Landroid/content/pm/ParceledListSlice;
PLcom/android/server/notification/NotificationManagerService$10;->getBackupPayload(I)[B
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 67abedc..628207c 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -705,9 +705,13 @@
final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
// Picture-in-picture mode changes also trigger a multi-window mode change as well, so
- // update that here in order
+ // update that here in order. Set the last reported MW state to the same as the PiP
+ // state since we haven't yet actually resized the task (these callbacks need to
+ // preceed the configuration change from the resiez.
+ // TODO(110009072): Once we move these callbacks to the client, remove all logic related
+ // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
mLastReportedPictureInPictureMode = inPictureInPictureMode;
- mLastReportedMultiWindowMode = inMultiWindowMode();
+ mLastReportedMultiWindowMode = inPictureInPictureMode;
final Configuration newConfig = task.computeNewOverrideConfigurationForBounds(
targetStackBounds, null);
schedulePictureInPictureModeChanged(newConfig);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b1b4c4f..f074319 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -628,15 +628,17 @@
final String pkg;
final ITransientNotification callback;
int duration;
+ int displayId;
Binder token;
ToastRecord(int pid, String pkg, ITransientNotification callback, int duration,
- Binder token) {
+ Binder token, int displayId) {
this.pid = pid;
this.pkg = pkg;
this.callback = callback;
this.duration = duration;
this.token = token;
+ this.displayId = displayId;
}
void update(int duration) {
@@ -1986,11 +1988,12 @@
// ============================================================================
@Override
- public void enqueueToast(String pkg, ITransientNotification callback, int duration)
+ public void enqueueToast(String pkg, ITransientNotification callback, int duration,
+ int displayId)
{
if (DBG) {
Slog.i(TAG, "enqueueToast pkg=" + pkg + " callback=" + callback
- + " duration=" + duration);
+ + " duration=" + duration + " displayId=" + displayId);
}
if (pkg == null || callback == null) {
@@ -2042,8 +2045,9 @@
}
Binder token = new Binder();
- mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY);
- record = new ToastRecord(callingPid, pkg, callback, duration, token);
+ mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, displayId);
+ record = new ToastRecord(callingPid, pkg, callback, duration, token,
+ displayId);
mToastQueue.add(record);
index = mToastQueue.size() - 1;
keepProcessAliveIfNeededLocked(callingPid);
@@ -2094,7 +2098,7 @@
int index = indexOfToastLocked(pkg, callback);
if (index >= 0) {
ToastRecord record = mToastQueue.get(index);
- finishTokenLocked(record.token);
+ finishTokenLocked(record.token, record.displayId);
} else {
Slog.w(TAG, "Toast already killed. pkg=" + pkg
+ " callback=" + callback);
@@ -5231,13 +5235,13 @@
ToastRecord lastToast = mToastQueue.remove(index);
mWindowManagerInternal.removeWindowToken(lastToast.token, false /* removeWindows */,
- DEFAULT_DISPLAY);
+ lastToast.displayId);
// We passed 'false' for 'removeWindows' so that the client has time to stop
// rendering (as hide above is a one-way message), otherwise we could crash
// a client which was actively using a surface made from the token. However
// we need to schedule a timeout to make sure the token is eventually killed
// one way or another.
- scheduleKillTokenTimeout(lastToast.token);
+ scheduleKillTokenTimeout(lastToast);
keepProcessAliveIfNeededLocked(record.pid);
if (mToastQueue.size() > 0) {
@@ -5248,14 +5252,13 @@
}
}
- void finishTokenLocked(IBinder t) {
+ void finishTokenLocked(IBinder t, int displayId) {
mHandler.removeCallbacksAndMessages(t);
// We pass 'true' for 'removeWindows' to let the WindowManager destroy any
// remaining surfaces as either the client has called finishToken indicating
// it has successfully removed the views, or the client has timed out
// at which point anything goes.
- mWindowManagerInternal.removeWindowToken(t, true /* removeWindows */,
- DEFAULT_DISPLAY);
+ mWindowManagerInternal.removeWindowToken(t, true /* removeWindows */, displayId);
}
@GuardedBy("mToastQueue")
@@ -5279,18 +5282,18 @@
}
@GuardedBy("mToastQueue")
- private void scheduleKillTokenTimeout(IBinder token)
+ private void scheduleKillTokenTimeout(ToastRecord r)
{
- mHandler.removeCallbacksAndMessages(token);
- Message m = Message.obtain(mHandler, MESSAGE_FINISH_TOKEN_TIMEOUT, token);
+ mHandler.removeCallbacksAndMessages(r);
+ Message m = Message.obtain(mHandler, MESSAGE_FINISH_TOKEN_TIMEOUT, r);
mHandler.sendMessageDelayed(m, FINISH_TOKEN_TIMEOUT);
}
- private void handleKillTokenTimeout(IBinder token)
+ private void handleKillTokenTimeout(ToastRecord record)
{
- if (DBG) Slog.d(TAG, "Kill Token Timeout token=" + token);
+ if (DBG) Slog.d(TAG, "Kill Token Timeout token=" + record.token);
synchronized (mToastQueue) {
- finishTokenLocked(token);
+ finishTokenLocked(record.token, record.displayId);
}
}
@@ -5484,7 +5487,7 @@
handleDurationReached((ToastRecord)msg.obj);
break;
case MESSAGE_FINISH_TOKEN_TIMEOUT:
- handleKillTokenTimeout((IBinder)msg.obj);
+ handleKillTokenTimeout((ToastRecord)msg.obj);
break;
case MESSAGE_SAVE_POLICY_FILE:
handleSavePolicyFile();
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index 71cee05..28cee7a 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -117,7 +117,8 @@
}
public boolean shouldIntercept(int zen, ZenModeConfig config, NotificationRecord record) {
- if (zen == ZEN_MODE_OFF) {
+ // Zen mode is ignored for critical notifications.
+ if (zen == ZEN_MODE_OFF || isCritical(record)) {
return false;
}
// Make an exception to policy for the notification saying that policy has changed
@@ -207,6 +208,19 @@
}
}
+ /**
+ * Check if the notification is too critical to be suppressed.
+ *
+ * @param record the record to test for criticality
+ * @return {@code true} if notification is considered critical
+ *
+ * @see CriticalNotificationExtractor for criteria
+ */
+ private boolean isCritical(NotificationRecord record) {
+ // 0 is the most critical
+ return record.getCriticality() < CriticalNotificationExtractor.NORMAL;
+ }
+
private static boolean shouldInterceptAudience(int source, NotificationRecord record) {
if (!audienceMatches(source, record.getContactAffinity())) {
ZenLog.traceIntercepted(record, "!audienceMatches");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 42d6c8e..e18d564 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1365,7 +1365,7 @@
// UID, otherwise we allow unlimited duration. When a UID looses focus we
// schedule hiding all of its toast windows.
if (type == TYPE_TOAST) {
- if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) {
+ if (!displayContent.canAddToastWindowForUid(callingUid)) {
Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 81ac6a4..664a837 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4579,10 +4579,12 @@
enforceFullCrossUsersPermission(userHandle);
synchronized (getLockObject()) {
if (!isCallerWithSystemUid()) {
- // This API can only be called by an active device admin,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(
- null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+ // This API can be called by an active device admin or by keyguard code.
+ if (mContext.checkCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+ != PackageManager.PERMISSION_GRANTED) {
+ getActiveAdminForCallerLocked(
+ null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+ }
}
DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, parent));
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 16cc8fd..348e201 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -65,6 +65,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SUSPEND_APPS"/>
<uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
+ <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
<!-- Uses API introduced in O (26) -->
<uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 5c449b3..7a96f4c 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -47,6 +47,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.pm.UserInfo;
@@ -111,6 +112,7 @@
@Mock private IAccountManagerResponse mMockAccountManagerResponse;
@Mock private IBinder mMockBinder;
@Mock private INotificationManager mMockNotificationManager;
+ @Mock private PackageManagerInternal mMockPackageManagerInternal;
@Captor private ArgumentCaptor<Intent> mIntentCaptor;
@Captor private ArgumentCaptor<Bundle> mBundleCaptor;
@@ -155,6 +157,9 @@
when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
mMockDevicePolicyManager);
when(mMockAccountManagerResponse.asBinder()).thenReturn(mMockBinder);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(true);
+ LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
Context realTestContext = getContext();
MyMockContext mockContext = new MyMockContext(realTestContext, mMockContext);
@@ -174,6 +179,7 @@
cdl.countDown();
});
cdl.await(1, TimeUnit.SECONDS);
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
super.tearDown();
}
@@ -607,6 +613,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -623,7 +631,7 @@
waitForLatch(latch);
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -789,6 +797,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -805,7 +815,7 @@
waitForLatch(latch);
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -1089,6 +1099,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -1103,7 +1115,7 @@
waitForLatch(latch);
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -1349,6 +1361,8 @@
unlockSystemUser();
when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
.thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
try {
mAms.removeAccountAsUser(
mMockAccountManagerResponse, // response
@@ -1685,6 +1699,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -1698,7 +1714,7 @@
waitForLatch(latch);
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -1956,6 +1972,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -1971,7 +1989,7 @@
waitForLatch(latch);
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -2094,6 +2112,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -2107,7 +2127,7 @@
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -2227,6 +2247,8 @@
any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
when(mMockPackageManager.checkSignatures(
anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
@@ -2242,7 +2264,7 @@
verify(mMockAccountManagerResponse, never()).onResult(any(Bundle.class));
verify(mMockAccountManagerResponse).onError(
- eq(AccountManager.ERROR_CODE_REMOTE_EXCEPTION), anyString());
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), anyString());
}
@SmallTest
@@ -2329,6 +2351,8 @@
unlockSystemUser();
when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
.thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
try {
mAms.editProperties(
mMockAccountManagerResponse, // response
@@ -2618,6 +2642,8 @@
PackageManager.PERMISSION_DENIED);
when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
.thenReturn(PackageManager.SIGNATURE_NO_MATCH);
+ when(mMockPackageManagerInternal.hasSignatureCapability(anyInt(), anyInt(), anyInt()))
+ .thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
Response response = new Response(latch, mMockAccountManagerResponse);
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
index fa7501d..72c22fd 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -25,6 +25,7 @@
import android.accounts.Account;
import android.content.Context;
import android.database.Cursor;
+import android.os.Build;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
@@ -86,6 +87,12 @@
@Test
public void testCeNotAvailableInitially() {
+ // If the CE database is not attached to the DE database then any calls that modify the CE
+ // database will result in a Log.wtf call that will crash this process on eng builds. To
+ // allow the test to run through to completion skip this test on eng builds.
+ if (Build.IS_ENG) {
+ return;
+ }
Account account = new Account("name", "example.com");
long id = mAccountsDb.insertCeAccount(account, "");
assertEquals("Insert into CE should fail until CE database is attached", -1, id);
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index b431af1..3f7c714 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -143,10 +143,10 @@
assertEquals(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, params[1]);
}
- @Test
/**
* Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted.
*/
+ @Test
public void testTaskChangeCallBacks() throws Exception {
final Object[] params = new Object[2];
final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
@@ -218,16 +218,17 @@
/**
* Starts the provided activity and returns the started instance.
*/
- private Activity startTestActivity(Class<?> activityClass) {
+ private TestActivity startTestActivity(Class<?> activityClass) throws InterruptedException {
final Context context = InstrumentationRegistry.getContext();
final ActivityMonitor monitor =
new ActivityMonitor(activityClass.getName(), null, false);
InstrumentationRegistry.getInstrumentation().addMonitor(monitor);
context.startActivity(new Intent(context, activityClass));
- final Activity activity = monitor.waitForActivityWithTimeout(1000);
+ final TestActivity activity = (TestActivity)monitor.waitForActivityWithTimeout(1000);
if (activity == null) {
throw new RuntimeException("Timed out waiting for Activity");
}
+ activity.waitForResumeStateChange(true);
return activity;
}
@@ -245,7 +246,43 @@
}catch (InterruptedException e) {}
}
- public static class ActivityA extends Activity {
+ public static class TestActivity extends Activity {
+ boolean mIsResumed = false;
+
+ @Override
+ protected void onPostResume() {
+ super.onPostResume();
+ synchronized (this) {
+ mIsResumed = true;
+ notifyAll();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ synchronized (this) {
+ mIsResumed = false;
+ notifyAll();
+ }
+ }
+
+ /**
+ * If isResumed is {@code true}, sleep the thread until the activity is resumed.
+ * if {@code false}, sleep the thread until the activity is paused.
+ */
+ public void waitForResumeStateChange(boolean isResumed) throws InterruptedException {
+ synchronized (this) {
+ if (mIsResumed == isResumed) {
+ return;
+ }
+ wait(5000);
+ }
+ assertTrue("The activity resume state change timed out", mIsResumed == isResumed);
+ }
+ }
+
+ public static class ActivityA extends TestActivity {
private boolean mActivityBLaunched = false;
@@ -261,7 +298,7 @@
}
}
- public static class ActivityB extends Activity {
+ public static class ActivityB extends TestActivity {
@Override
protected void onPostResume() {
@@ -274,7 +311,7 @@
}
}
- public static class ActivityRequestedOrientationChange extends Activity {
+ public static class ActivityRequestedOrientationChange extends TestActivity {
@Override
protected void onPostResume() {
super.onPostResume();
@@ -283,7 +320,7 @@
}
}
- public static class ActivityTaskDescriptionChange extends Activity {
+ public static class ActivityTaskDescriptionChange extends TestActivity {
@Override
protected void onPostResume() {
super.onPostResume();
@@ -292,7 +329,7 @@
}
}
- public static class ActivityTaskChangeCallbacks extends Activity {
+ public static class ActivityTaskChangeCallbacks extends TestActivity {
boolean onDetachedFromWindowCalled = false;
CountDownLatch onDetachedFromWindowCountDownLatch;
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
index 34831cd..7fb1278 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
@@ -15,7 +15,7 @@
import java.util.ArrayList;
import java.util.Arrays;
-public class MockWeaverService implements IWeaver {
+public class MockWeaverService extends IWeaver.Stub {
private static final int MAX_SLOTS = 8;
private static final int KEY_LENGTH = 256 / 8;
@@ -55,54 +55,4 @@
cb.onValues(WeaverStatus.FAILED, response);
}
}
-
- @Override
- public IHwBinder asBinder() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ArrayList<String> interfaceChain() throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String interfaceDescriptor() throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setHALInstrumentation() throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean linkToDeath(DeathRecipient recipient, long cookie) throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void ping() throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DebugInfo getDebugInfo() throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void notifySyspropsChanged() throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean unlinkToDeath(DeathRecipient recipient) throws RemoteException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ArrayList<byte[]> getHashChain() throws RemoteException {
- throw new UnsupportedOperationException();
- }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index c0bd7cc..d335450 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -171,4 +171,17 @@
assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_OFF, config, r));
}
+
+ @Test
+ public void testSuppressAnything_bypass_ZenModeOn() {
+ NotificationRecord r = getNotificationRecord();
+ r.setCriticality(CriticalNotificationExtractor.CRITICAL);
+ when(r.sbn.getPackageName()).thenReturn("bananas");
+ ZenModeConfig config = mock(ZenModeConfig.class);
+
+ assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, config, r));
+
+ r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW);
+ assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_NO_INTERRUPTIONS, config, r));
+ }
}
diff --git a/tests/testables/Android.bp b/tests/testables/Android.bp
new file mode 100644
index 0000000..f07f09d
--- /dev/null
+++ b/tests/testables/Android.bp
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+java_library {
+
+ name: "testables",
+ // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_MODULE_TAG
+ // LOCAL_MODULE_TAG := tests
+
+ srcs: ["src/**/*.java"],
+
+ libs: [
+ "android.test.runner",
+ "android.test.mock",
+ "android-support-test",
+ "mockito-target-inline-minus-junit4",
+ ],
+
+}
diff --git a/tests/testables/Android.mk b/tests/testables/Android.mk
deleted file mode 100644
index f3cbac0..0000000
--- a/tests/testables/Android.mk
+++ /dev/null
@@ -1,32 +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_MODULE := testables
-LOCAL_MODULE_TAG := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.mock \
- android-support-test \
- mockito-target-inline-minus-junit4
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index f064cb1..0a517ab 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -408,6 +408,41 @@
}
}
+void Debug::DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer) {
+ using namespace android;
+
+ if (pool->getError() == NO_INIT) {
+ printer->Print("String pool is unitialized.\n");
+ return;
+ } else if (pool->getError() != NO_ERROR) {
+ printer->Print("String pool is corrupt/invalid.\n");
+ return;
+ }
+
+ SortedVector<const void*> uniqueStrings;
+ const size_t N = pool->size();
+ for (size_t i=0; i<N; i++) {
+ size_t len;
+ if (pool->isUTF8()) {
+ uniqueStrings.add(pool->string8At(i, &len));
+ } else {
+ uniqueStrings.add(pool->stringAt(i, &len));
+ }
+ }
+
+ printer->Print(StringPrintf("String pool of %zd unique %s %s strings, %zd entries and %zd styles "
+ "using %zd bytes:\n", uniqueStrings.size(),
+ pool->isUTF8() ? "UTF-8" : "UTF-16",
+ pool->isSorted() ? "sorted" : "non-sorted", N, pool->styleCount(),
+ pool->bytes()));
+
+ const size_t NS = pool->size();
+ for (size_t s=0; s<NS; s++) {
+ String8 str = pool->string8ObjectAt(s);
+ printer->Print(StringPrintf("String #%zd : %s\n", s, str.string()));
+ }
+}
+
namespace {
class XmlPrinter : public xml::ConstVisitor {
diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h
index 382707e..a43197c 100644
--- a/tools/aapt2/Debug.h
+++ b/tools/aapt2/Debug.h
@@ -38,6 +38,7 @@
static void PrintStyleGraph(ResourceTable* table, const ResourceName& target_style);
static void DumpHex(const void* data, size_t len);
static void DumpXml(const xml::XmlResource& doc, text::Printer* printer);
+ static void DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer);
};
} // namespace aapt
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index b32766b..a73d56c 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -184,10 +184,7 @@
std::unique_ptr<io::IFileCollectionIterator> iterator = apk_->Iterator();
while (iterator->HasNext()) {
io::IFile* file = iterator->Next();
-
std::string path = file->GetSource().path;
- // The name of the path has the format "<zip-file-name>@<path-to-file>".
- path = path.substr(path.find('@') + 1);
// Skip resources that are not referenced if requested.
if (path.find("res/") == 0 && referenced_resources.find(path) == referenced_resources.end()) {
@@ -257,6 +254,53 @@
return true;
}
+std::unique_ptr<xml::XmlResource> LoadedApk::LoadXml(const std::string& file_path,
+ IDiagnostics* diag) {
+ io::IFile* file = apk_->FindFile(file_path);
+ if (file == nullptr) {
+ diag->Error(DiagMessage() << "failed to find file");
+ return nullptr;
+ }
+
+ std::unique_ptr<xml::XmlResource> doc;
+ if (format_ == ApkFormat::kProto) {
+ std::unique_ptr<io::InputStream> in = file->OpenInputStream();
+ if (!in) {
+ diag->Error(DiagMessage() << "failed to open file");
+ return nullptr;
+ }
+
+ io::ZeroCopyInputAdaptor adaptor(in.get());
+ pb::XmlNode pb_node;
+ if (!pb_node.ParseFromZeroCopyStream(&adaptor)) {
+ diag->Error(DiagMessage() << "failed to parse file as proto XML");
+ return nullptr;
+ }
+
+ std::string err;
+ doc = DeserializeXmlResourceFromPb(pb_node, &err);
+ if (!doc) {
+ diag->Error(DiagMessage() << "failed to deserialize proto XML: " << err);
+ return nullptr;
+ }
+ } else if (format_ == ApkFormat::kBinary) {
+ std::unique_ptr<io::IData> data = file->OpenAsData();
+ if (!data) {
+ diag->Error(DiagMessage() << "failed to open file");
+ return nullptr;
+ }
+
+ std::string err;
+ doc = xml::Inflate(data->data(), data->size(), &err);
+ if (!doc) {
+ diag->Error(DiagMessage() << "failed to parse file as binary XML: " << err);
+ return nullptr;
+ }
+ }
+
+ return doc;
+}
+
ApkFormat LoadedApk::DetermineApkFormat(io::IFileCollection* apk) {
if (apk->FindFile(kApkResourceTablePath) != nullptr) {
return ApkFormat::kBinary;
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index 41f879d..dcb085a 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -70,6 +70,10 @@
return apk_.get();
}
+ ApkFormat GetApkFormat() {
+ return format_;
+ }
+
const ResourceTable* GetResourceTable() const {
return table_.get();
}
@@ -106,6 +110,8 @@
const TableFlattenerOptions& options, FilterChain* filters,
IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
+ /** Loads the file as an xml document. */
+ std::unique_ptr<xml::XmlResource> LoadXml(const std::string& file_path, IDiagnostics* diag);
private:
DISALLOW_COPY_AND_ASSIGN(LoadedApk);
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 23903c9e..37013c0 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -71,7 +71,7 @@
explicit MainCommand(IDiagnostics* diagnostics) : Command("aapt2"), diagnostics_(diagnostics) {
AddOptionalSubcommand(util::make_unique<CompileCommand>(diagnostics));
AddOptionalSubcommand(util::make_unique<LinkCommand>(diagnostics));
- AddOptionalSubcommand(util::make_unique<DumpCommand>());
+ AddOptionalSubcommand(util::make_unique<DumpCommand>(diagnostics));
AddOptionalSubcommand(util::make_unique<DiffCommand>());
AddOptionalSubcommand(util::make_unique<OptimizeCommand>());
AddOptionalSubcommand(util::make_unique<ConvertCommand>());
diff --git a/tools/aapt2/Source.h b/tools/aapt2/Source.h
index 0f312d6..92934c3 100644
--- a/tools/aapt2/Source.h
+++ b/tools/aapt2/Source.h
@@ -31,12 +31,16 @@
struct Source {
std::string path;
Maybe<size_t> line;
+ Maybe<std::string> archive;
Source() = default;
inline Source(const android::StringPiece& path) : path(path.to_string()) { // NOLINT(implicit)
}
+ inline Source(const android::StringPiece& path, const android::StringPiece& archive)
+ : path(path.to_string()), archive(archive.to_string()) {}
+
inline Source(const android::StringPiece& path, size_t line)
: path(path.to_string()), line(line) {}
@@ -45,10 +49,14 @@
}
std::string to_string() const {
- if (line) {
- return ::android::base::StringPrintf("%s:%zd", path.c_str(), line.value());
+ std::string s = path;
+ if (archive) {
+ s = ::android::base::StringPrintf("%s@%s", archive.value().c_str(), s.c_str());
}
- return path;
+ if (line) {
+ s = ::android::base::StringPrintf("%s:%zd", s.c_str(), line.value());
+ }
+ return s;
}
};
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 2ba2cf7..62c19fb 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -41,8 +41,10 @@
#include "format/proto/ProtoSerialize.h"
#include "io/BigBufferStream.h"
#include "io/FileStream.h"
+#include "io/FileSystem.h"
#include "io/StringStream.h"
#include "io/Util.h"
+#include "io/ZipArchive.h"
#include "util/Files.h"
#include "util/Maybe.h"
#include "util/Util.h"
@@ -135,81 +137,20 @@
return name.str();
}
-static bool IsHidden(const StringPiece& filename) {
- return util::StartsWith(filename, ".");
-}
-
-// Walks the res directory structure, looking for resource files.
-static bool LoadInputFilesFromDir(IAaptContext* context, const CompileOptions& options,
- std::vector<ResourcePathData>* out_path_data) {
- const std::string& root_dir = options.res_dir.value();
- std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
- if (!d) {
- context->GetDiagnostics()->Error(DiagMessage(root_dir) << "failed to open directory: "
- << SystemErrorCodeToString(errno));
- return false;
- }
-
- while (struct dirent* entry = readdir(d.get())) {
- if (IsHidden(entry->d_name)) {
- continue;
- }
-
- std::string prefix_path = root_dir;
- file::AppendPath(&prefix_path, entry->d_name);
-
- if (file::GetFileType(prefix_path) != file::FileType::kDirectory) {
- continue;
- }
-
- std::unique_ptr<DIR, decltype(closedir)*> subdir(opendir(prefix_path.data()), closedir);
- if (!subdir) {
- context->GetDiagnostics()->Error(DiagMessage(prefix_path) << "failed to open directory: "
- << SystemErrorCodeToString(errno));
- return false;
- }
-
- while (struct dirent* leaf_entry = readdir(subdir.get())) {
- if (IsHidden(leaf_entry->d_name)) {
- continue;
- }
-
- std::string full_path = prefix_path;
- file::AppendPath(&full_path, leaf_entry->d_name);
-
- std::string err_str;
- Maybe<ResourcePathData> path_data = ExtractResourcePathData(full_path, &err_str);
- if (!path_data) {
- context->GetDiagnostics()->Error(DiagMessage(full_path) << err_str);
- return false;
- }
-
- out_path_data->push_back(std::move(path_data.value()));
- }
- }
-
- // File-system directory enumeration order is platform-dependent. Sort the result to remove any
- // inconsistencies between platforms.
- std::sort(
- out_path_data->begin(), out_path_data->end(),
- [](const ResourcePathData& a, const ResourcePathData& b) { return a.source < b.source; });
- return true;
-}
-
static bool CompileTable(IAaptContext* context, const CompileOptions& options,
- const ResourcePathData& path_data, IArchiveWriter* writer,
+ const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
ResourceTable table;
{
- FileInputStream fin(path_data.source.path);
- if (fin.HadError()) {
+ auto fin = file->OpenInputStream();
+ if (fin->HadError()) {
context->GetDiagnostics()->Error(DiagMessage(path_data.source)
- << "failed to open file: " << fin.GetError());
+ << "failed to open file: " << fin->GetError());
return false;
}
// Parse the values file from XML.
- xml::XmlPullParser xml_parser(&fin);
+ xml::XmlPullParser xml_parser(fin.get());
ResourceParserOptions parser_options;
parser_options.error_on_positional_arguments = !options.legacy_mode;
@@ -222,7 +163,7 @@
parser_options.visibility = options.visibility;
ResourceParser res_parser(context->GetDiagnostics(), &table, path_data.source, path_data.config,
- parser_options);
+ parser_options);
if (!res_parser.Parse(&xml_parser)) {
return false;
}
@@ -408,7 +349,7 @@
}
static bool CompileXml(IAaptContext* context, const CompileOptions& options,
- const ResourcePathData& path_data, IArchiveWriter* writer,
+ const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling XML");
@@ -416,18 +357,17 @@
std::unique_ptr<xml::XmlResource> xmlres;
{
- FileInputStream fin(path_data.source.path);
- if (fin.HadError()) {
+ auto fin = file->OpenInputStream();
+ if (fin->HadError()) {
context->GetDiagnostics()->Error(DiagMessage(path_data.source)
- << "failed to open file: " << fin.GetError());
+ << "failed to open file: " << fin->GetError());
return false;
}
- xmlres = xml::Inflate(&fin, context->GetDiagnostics(), path_data.source);
- }
-
- if (!xmlres) {
- return false;
+ xmlres = xml::Inflate(fin.get(), context->GetDiagnostics(), path_data.source);
+ if (!xmlres) {
+ return false;
+ }
}
xmlres->file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), path_data.name);
@@ -508,7 +448,7 @@
}
static bool CompilePng(IAaptContext* context, const CompileOptions& options,
- const ResourcePathData& path_data, IArchiveWriter* writer,
+ const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling PNG");
@@ -522,15 +462,17 @@
res_file.type = ResourceFile::Type::kPng;
{
- std::string content;
- if (!android::base::ReadFileToString(path_data.source.path, &content,
- true /*follow_symlinks*/)) {
- context->GetDiagnostics()->Error(DiagMessage(path_data.source)
- << "failed to open file: "
- << SystemErrorCodeToString(errno));
+ auto data = file->OpenAsData();
+ if (!data) {
+ context->GetDiagnostics()->Error(DiagMessage(path_data.source) << "failed to open file ");
return false;
}
+ // Read the file as a string
+ char buffer_2[data->size()];
+ memcpy(&buffer_2, data->data(), data->size());
+ StringPiece content(buffer_2, data->size());
+
BigBuffer crunched_png_buffer(4096);
io::BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer);
@@ -598,7 +540,7 @@
if (context->IsVerbose()) {
// For debugging only, use the legacy PNG cruncher and compare the resulting file sizes.
// This will help catch exotic cases where the new code may generate larger PNGs.
- std::stringstream legacy_stream(content);
+ std::stringstream legacy_stream(content.to_string());
BigBuffer legacy_buffer(4096);
Png png(context->GetDiagnostics());
if (!png.process(path_data.source, &legacy_stream, &legacy_buffer, {})) {
@@ -612,41 +554,31 @@
}
io::BigBufferInputStream buffer_in(&buffer);
- if (!WriteHeaderAndDataToWriter(output_path, res_file, &buffer_in, writer,
- context->GetDiagnostics())) {
- return false;
- }
- return true;
+ return WriteHeaderAndDataToWriter(output_path, res_file, &buffer_in, writer,
+ context->GetDiagnostics());
}
static bool CompileFile(IAaptContext* context, const CompileOptions& options,
- const ResourcePathData& path_data, IArchiveWriter* writer,
+ const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling file");
}
- BigBuffer buffer(256);
ResourceFile res_file;
res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), path_data.name);
res_file.config = path_data.config;
res_file.source = path_data.source;
res_file.type = ResourceFile::Type::kUnknown;
- std::string error_str;
- Maybe<android::FileMap> f = file::MmapPath(path_data.source.path, &error_str);
- if (!f) {
- context->GetDiagnostics()->Error(DiagMessage(path_data.source) << "failed to mmap file: "
- << error_str);
+ auto data = file->OpenAsData();
+ if (!data) {
+ context->GetDiagnostics()->Error(DiagMessage(path_data.source) << "failed to open file ");
return false;
}
- io::MmappedData mmapped_in(std::move(f.value()));
- if (!WriteHeaderAndDataToWriter(output_path, res_file, &mmapped_in, writer,
- context->GetDiagnostics())) {
- return false;
- }
- return true;
+ return WriteHeaderAndDataToWriter(output_path, res_file, data.get(), writer,
+ context->GetDiagnostics());
}
class CompileContext : public IAaptContext {
@@ -701,6 +633,79 @@
bool verbose_ = false;
};
+int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer,
+ CompileOptions& options) {
+ bool error = false;
+
+ // Iterate over the input files in a stable, platform-independent manner
+ auto file_iterator = inputs->Iterator();
+ while (file_iterator->HasNext()) {
+ auto file = file_iterator->Next();
+ std::string path = file->GetSource().path;
+
+ // Skip hidden input files
+ if (file::IsHidden(path)) {
+ continue;
+ }
+
+ if (!options.res_zip && !IsValidFile(context, path)) {
+ error = true;
+ continue;
+ }
+
+ // Extract resource type information from the full path
+ std::string err_str;
+ ResourcePathData path_data;
+ if (auto maybe_path_data = ExtractResourcePathData(path, &err_str)) {
+ path_data = maybe_path_data.value();
+ } else {
+ context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << err_str);
+ error = true;
+ continue;
+ }
+
+ // Determine how to compile the file based on its type.
+ auto compile_func = &CompileFile;
+ if (path_data.resource_dir == "values" && path_data.extension == "xml") {
+ compile_func = &CompileTable;
+ // We use a different extension (not necessary anymore, but avoids altering the existing
+ // build system logic).
+ path_data.extension = "arsc";
+
+ } else if (const ResourceType* type = ParseResourceType(path_data.resource_dir)) {
+ if (*type != ResourceType::kRaw) {
+ if (path_data.extension == "xml") {
+ compile_func = &CompileXml;
+ } else if ((!options.no_png_crunch && path_data.extension == "png")
+ || path_data.extension == "9.png") {
+ compile_func = &CompilePng;
+ }
+ }
+ } else {
+ context->GetDiagnostics()->Error(DiagMessage()
+ << "invalid file path '" << path_data.source << "'");
+ error = true;
+ continue;
+ }
+
+ // Treat periods as a reserved character that should not be present in a file name
+ // Legacy support for AAPT which did not reserve periods
+ if (compile_func != &CompileFile && !options.legacy_mode
+ && std::count(path_data.name.begin(), path_data.name.end(), '.') != 0) {
+ error = true;
+ context->GetDiagnostics()->Error(DiagMessage(file->GetSource())
+ << "file name cannot contain '.' other than for"
+ << " specifying the extension");
+ continue;
+ }
+
+ const std::string out_path = BuildIntermediateContainerFilename(path_data);
+ error |= !compile_func(context, options, path_data, file, output_writer, out_path);
+ }
+
+ return error ? 1 : 0;
+}
+
int CompileCommand::Action(const std::vector<std::string>& args) {
CompileContext context(diagnostic_);
context.SetVerbose(options_.verbose);
@@ -720,37 +725,55 @@
}
}
+ std::unique_ptr<io::IFileCollection> file_collection;
std::unique_ptr<IArchiveWriter> archive_writer;
- std::vector<ResourcePathData> input_data;
- if (options_.res_dir) {
+ // Collect the resources files to compile
+ if (options_.res_dir && options_.res_zip) {
+ context.GetDiagnostics()->Error(DiagMessage()
+ << "only one of --dir and --zip can be specified");
+ return 1;
+ } else if (options_.res_dir) {
if (!args.empty()) {
- // Can't have both files and a resource directory.
context.GetDiagnostics()->Error(DiagMessage() << "files given but --dir specified");
Usage(&std::cerr);
return 1;
}
- if (!LoadInputFilesFromDir(&context, options_, &input_data)) {
+ // Load the files from the res directory
+ std::string err;
+ file_collection = io::FileCollection::Create(options_.res_dir.value(), &err);
+ if (!file_collection) {
+ context.GetDiagnostics()->Error(DiagMessage(options_.res_dir.value()) << err);
return 1;
}
archive_writer = CreateZipFileArchiveWriter(context.GetDiagnostics(), options_.output_path);
+ } else if (options_.res_zip) {
+ if (!args.empty()) {
+ context.GetDiagnostics()->Error(DiagMessage() << "files given but --zip specified");
+ Usage(&std::cerr);
+ return 1;
+ }
+ // Load a zip file containing a res directory
+ std::string err;
+ file_collection = io::ZipFileCollection::Create(options_.res_zip.value(), &err);
+ if (!file_collection) {
+ context.GetDiagnostics()->Error(DiagMessage(options_.res_zip.value()) << err);
+ return 1;
+ }
+
+ archive_writer = CreateZipFileArchiveWriter(context.GetDiagnostics(), options_.output_path);
} else {
- input_data.reserve(args.size());
+ auto collection = util::make_unique<io::FileCollection>();
// Collect data from the path for each input file.
for (const std::string& arg : args) {
- std::string error_str;
- if (Maybe<ResourcePathData> path_data = ExtractResourcePathData(arg, &error_str)) {
- input_data.push_back(std::move(path_data.value()));
- } else {
- context.GetDiagnostics()->Error(DiagMessage() << error_str << " (" << arg << ")");
- return 1;
- }
+ collection->InsertFile(arg);
}
+ file_collection = std::move(collection);
archive_writer = CreateDirectoryArchiveWriter(context.GetDiagnostics(), options_.output_path);
}
@@ -758,57 +781,7 @@
return 1;
}
- bool error = false;
- for (ResourcePathData& path_data : input_data) {
- if (options_.verbose) {
- context.GetDiagnostics()->Note(DiagMessage(path_data.source) << "processing");
- }
-
- if (!IsValidFile(&context, path_data.source.path)) {
- error = true;
- continue;
- }
-
- // Determine how to compile the file based on its type.
- auto compile_func = &CompileFile;
- if (path_data.resource_dir == "values" && path_data.extension == "xml") {
- compile_func = &CompileTable;
- // We use a different extension (not necessary anymore, but avoids altering the existing
- // build system logic).
- path_data.extension = "arsc";
-
- } else if (const ResourceType* type = ParseResourceType(path_data.resource_dir)) {
- if (*type != ResourceType::kRaw) {
- if (path_data.extension == "xml") {
- compile_func = &CompileXml;
- } else if ((!options_.no_png_crunch && path_data.extension == "png")
- || path_data.extension == "9.png") {
- compile_func = &CompilePng;
- }
- }
- } else {
- context.GetDiagnostics()->Error(DiagMessage()
- << "invalid file path '" << path_data.source << "'");
- error = true;
- continue;
- }
-
- // Treat periods as a reserved character that should not be present in a file name
- // Legacy support for AAPT which did not reserve periods
- if (compile_func != &CompileFile && !options_.legacy_mode
- && std::count(path_data.name.begin(), path_data.name.end(), '.') != 0) {
- error = true;
- context.GetDiagnostics()->Error(DiagMessage() << "resource file '" << path_data.source.path
- << "' name cannot contain '.' other than for"
- << "specifying the extension");
- continue;
- }
-
- // Compile the file.
- const std::string out_path = BuildIntermediateContainerFilename(path_data);
- error |= !compile_func(&context, options_, path_data, archive_writer.get(), out_path);
- }
- return error ? 1 : 0;
+ return Compile(&context, file_collection.get(), archive_writer.get(), options_);
}
} // namespace aapt
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 4151952..c429d5f 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -18,7 +18,8 @@
#define AAPT2_COMPILE_H
#include "androidfw/StringPiece.h"
-
+#include "format/Archive.h"
+#include "process/IResourceTableConsumer.h"
#include "Command.h"
#include "Diagnostics.h"
#include "ResourceTable.h"
@@ -28,6 +29,7 @@
struct CompileOptions {
std::string output_path;
Maybe<std::string> res_dir;
+ Maybe<std::string> res_zip;
Maybe<std::string> generate_text_symbols_path;
Maybe<Visibility::Level> visibility;
bool pseudolocalize = false;
@@ -36,6 +38,7 @@
bool verbose = false;
};
+/** Parses flags and compiles resources to be used in linking. */
class CompileCommand : public Command {
public:
explicit CompileCommand(IDiagnostics* diagnostic) : Command("compile", "c"),
@@ -43,6 +46,8 @@
SetDescription("Compiles resources to be linked into an apk.");
AddRequiredFlag("-o", "Output path", &options_.output_path);
AddOptionalFlag("--dir", "Directory to scan for resources", &options_.res_dir);
+ AddOptionalFlag("--zip", "Zip file containing the res directory to scan for resources",
+ &options_.res_zip);
AddOptionalFlag("--output-text-symbols",
"Generates a text file containing the resource symbols in the\n"
"specified file", &options_.generate_text_symbols_path);
@@ -51,10 +56,10 @@
AddOptionalSwitch("--no-crunch", "Disables PNG processing", &options_.no_png_crunch);
AddOptionalSwitch("--legacy", "Treat errors that used to be valid in AAPT as warnings",
&options_.legacy_mode);
- AddOptionalSwitch("-v", "Enables verbose logging", &options_.verbose);
AddOptionalFlag("--visibility",
"Sets the visibility of the compiled resources to the specified\n"
"level. Accepted levels: public, private, default", &visibility_);
+ AddOptionalSwitch("-v", "Enables verbose logging", &options_.verbose);
}
int Action(const std::vector<std::string>& args) override;
@@ -65,6 +70,8 @@
Maybe<std::string> visibility_;
};
+int Compile(IAaptContext* context, io::IFileCollection* inputs,
+ IArchiveWriter* output_writer, CompileOptions& options);
}// namespace aapt
#endif //AAPT2_COMPILE_H
diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp
index d21addf..dd5198c 100644
--- a/tools/aapt2/cmd/Compile_test.cpp
+++ b/tools/aapt2/cmd/Compile_test.cpp
@@ -18,6 +18,7 @@
#include "android-base/file.h"
#include "io/StringStream.h"
+#include "io/ZipArchive.h"
#include "java/AnnotationProcessor.h"
#include "test/Test.h"
@@ -29,7 +30,6 @@
args.push_back(path);
args.push_back("-o");
args.push_back(outDir);
- args.push_back("-v");
if (legacy) {
args.push_back("--legacy");
}
@@ -94,4 +94,56 @@
ASSERT_EQ(remove(path5_out.c_str()), 0);
}
-}
\ No newline at end of file
+TEST(CompilerTest, DirInput) {
+ StdErrDiagnostics diag;
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ const std::string kResDir = android::base::Dirname(android::base::GetExecutablePath())
+ + "/integration-tests/CompileTest/DirInput/res";
+ const std::string kOutputFlata = android::base::Dirname(android::base::GetExecutablePath())
+ + "/integration-tests/CompileTest/DirInput/compiled.flata";
+ remove(kOutputFlata.c_str());
+
+ std::vector<android::StringPiece> args;
+ args.push_back("--dir");
+ args.push_back(kResDir);
+ args.push_back("-o");
+ args.push_back(kOutputFlata);
+ ASSERT_EQ(CompileCommand(&diag).Execute(args, &std::cerr), 0);
+
+ // Check for the presence of the compiled files
+ std::string err;
+ std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
+ ASSERT_NE(zip, nullptr) << err;
+ ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
+ ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
+ ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
+ ASSERT_EQ(remove(kOutputFlata.c_str()), 0);
+}
+
+TEST(CompilerTest, ZipInput) {
+ StdErrDiagnostics diag;
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ const std::string kResZip = android::base::Dirname(android::base::GetExecutablePath())
+ + "/integration-tests/CompileTest/ZipInput/res.zip";
+ const std::string kOutputFlata = android::base::Dirname(android::base::GetExecutablePath())
+ + "/integration-tests/CompileTest/ZipInput/compiled.flata";
+ remove(kOutputFlata.c_str());
+
+ std::vector<android::StringPiece> args;
+ args.push_back("--zip");
+ args.push_back(kResZip);
+ args.push_back("-o");
+ args.push_back(kOutputFlata);
+ ASSERT_EQ(CompileCommand(&diag).Execute(args, &std::cerr), 0);
+
+ // Check for the presence of the compiled files
+ std::string err;
+ std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
+ ASSERT_NE(zip, nullptr) << err;
+ ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
+ ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
+ ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
+ ASSERT_EQ(remove(kOutputFlata.c_str()), 0);
+}
+
+} // namespace aapt
\ No newline at end of file
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index d57eaa1..86b1f4c 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -105,10 +105,7 @@
std::unique_ptr<io::IFileCollectionIterator> iterator = apk->GetFileCollection()->Iterator();
while (iterator->HasNext()) {
io::IFile* file = iterator->Next();
-
std::string path = file->GetSource().path;
- // The name of the path has the format "<zip-file-name>@<path-to-file>".
- path = path.substr(path.find('@') + 1);
// Manifest, resource table and resources have already been taken care of.
if (path == kAndroidManifestPath ||
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 6e9c800..b4311c5 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -24,8 +24,11 @@
#include "Debug.h"
#include "Diagnostics.h"
+#include "LoadedApk.h"
+#include "Util.h"
#include "format/Container.h"
#include "format/binary/BinaryResourceParser.h"
+#include "format/binary/XmlFlattener.h"
#include "format/proto/ProtoDeserialize.h"
#include "io/FileStream.h"
#include "io/ZipArchive.h"
@@ -70,184 +73,6 @@
printer->Println(StringPrintf("Data: offset=%" PRIi64 " length=%zd", offset, len));
}
-static bool DumpXmlFile(IAaptContext* context, io::IFile* file, bool proto,
- text::Printer* printer) {
- std::unique_ptr<xml::XmlResource> doc;
- if (proto) {
- std::unique_ptr<io::InputStream> in = file->OpenInputStream();
- if (in == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage() << "failed to open file");
- return false;
- }
-
- io::ZeroCopyInputAdaptor adaptor(in.get());
- pb::XmlNode pb_node;
- if (!pb_node.ParseFromZeroCopyStream(&adaptor)) {
- context->GetDiagnostics()->Error(DiagMessage() << "failed to parse file as proto XML");
- return false;
- }
-
- std::string err;
- doc = DeserializeXmlResourceFromPb(pb_node, &err);
- if (doc == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage() << "failed to deserialize proto XML");
- return false;
- }
- printer->Println("Proto XML");
- } else {
- std::unique_ptr<io::IData> data = file->OpenAsData();
- if (data == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage() << "failed to open file");
- return false;
- }
-
- std::string err;
- doc = xml::Inflate(data->data(), data->size(), &err);
- if (doc == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage() << "failed to parse file as binary XML");
- return false;
- }
- printer->Println("Binary XML");
- }
-
- Debug::DumpXml(*doc, printer);
- return true;
-}
-
-static bool TryDumpFile(IAaptContext* context, const std::string& file_path,
- const DumpOptions& options) {
- // Use a smaller buffer so that there is less latency for dumping to stdout.
- constexpr size_t kStdOutBufferSize = 1024u;
- io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
- Printer printer(&fout);
-
- std::string err;
- std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(file_path, &err);
- if (zip) {
- ResourceTable table(/** validate_resources **/ false);
- bool proto = false;
- if (io::IFile* file = zip->FindFile("resources.pb")) {
- proto = true;
-
- std::unique_ptr<io::IData> data = file->OpenAsData();
- if (data == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage(file_path) << "failed to open resources.pb");
- return false;
- }
-
- pb::ResourceTable pb_table;
- if (!pb_table.ParseFromArray(data->data(), data->size())) {
- context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.pb");
- return false;
- }
-
- if (!DeserializeTableFromPb(pb_table, zip.get(), &table, &err)) {
- context->GetDiagnostics()->Error(DiagMessage(file_path)
- << "failed to parse table: " << err);
- return false;
- }
- } else if (io::IFile* file = zip->FindFile("resources.arsc")) {
- std::unique_ptr<io::IData> data = file->OpenAsData();
- if (!data) {
- context->GetDiagnostics()->Error(DiagMessage(file_path) << "failed to open resources.arsc");
- return false;
- }
-
- BinaryResourceParser parser(context->GetDiagnostics(), &table, Source(file_path),
- data->data(), data->size());
- if (!parser.Parse()) {
- return false;
- }
- }
-
- if (!options.file_to_dump_path) {
- if (proto) {
- printer.Println("Proto APK");
- } else {
- printer.Println("Binary APK");
- }
- Debug::PrintTable(table, options.print_options, &printer);
- return true;
- }
-
- io::IFile* file = zip->FindFile(options.file_to_dump_path.value());
- if (file == nullptr) {
- context->GetDiagnostics()->Error(DiagMessage(file_path)
- << "file '" << options.file_to_dump_path.value()
- << "' not found in APK");
- return false;
- }
- return DumpXmlFile(context, file, proto, &printer);
- }
-
- err.clear();
-
- io::FileInputStream input(file_path);
- if (input.HadError()) {
- context->GetDiagnostics()->Error(DiagMessage(file_path)
- << "failed to open file: " << input.GetError());
- return false;
- }
-
- // Try as a compiled file.
- ContainerReader reader(&input);
- if (reader.HadError()) {
- context->GetDiagnostics()->Error(DiagMessage(file_path)
- << "failed to read container: " << reader.GetError());
- return false;
- }
-
- printer.Println("AAPT2 Container (APC)");
- ContainerReaderEntry* entry;
- while ((entry = reader.Next()) != nullptr) {
- if (entry->Type() == ContainerEntryType::kResTable) {
- printer.Println("kResTable");
-
- pb::ResourceTable pb_table;
- if (!entry->GetResTable(&pb_table)) {
- context->GetDiagnostics()->Error(DiagMessage(file_path)
- << "failed to parse proto table: " << entry->GetError());
- continue;
- }
-
- ResourceTable table;
- err.clear();
- if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &err)) {
- context->GetDiagnostics()->Error(DiagMessage(file_path)
- << "failed to parse table: " << err);
- continue;
- }
-
- printer.Indent();
- Debug::PrintTable(table, options.print_options, &printer);
- printer.Undent();
- } else if (entry->Type() == ContainerEntryType::kResFile) {
- printer.Println("kResFile");
- pb::internal::CompiledFile pb_compiled_file;
- off64_t offset;
- size_t length;
- if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
- context->GetDiagnostics()->Error(
- DiagMessage(file_path) << "failed to parse compiled proto file: " << entry->GetError());
- continue;
- }
-
- ResourceFile file;
- std::string error;
- if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
- context->GetDiagnostics()->Warn(DiagMessage(file_path)
- << "failed to parse compiled file: " << error);
- continue;
- }
-
- printer.Indent();
- DumpCompiledFile(file, Source(file_path), offset, length, &printer);
- printer.Undent();
- }
- }
- return true;
-}
-
namespace {
class DumpContext : public IAaptContext {
@@ -299,17 +124,290 @@
} // namespace
-int DumpCommand::Action(const std::vector<std::string>& args) {
+// Use a smaller buffer so that there is less latency for dumping to stdout.
+constexpr size_t kStdOutBufferSize = 1024u;
+
+int DumpAPCCommand::Action(const std::vector<std::string>& args) {
DumpContext context;
- context.SetVerbose(verbose_);
- options_.print_options.show_sources = true;
- options_.print_options.show_values = !no_values_;
- for (const std::string& arg : args) {
- if (!TryDumpFile(&context, arg, options_)) {
- return 1;
+ DebugPrintTableOptions print_options;
+ print_options.show_sources = true;
+ print_options.show_values = !no_values_;
+
+ if (args.size() < 1) {
+ diag_->Error(DiagMessage() << "No dump container specified.");
+ return 1;
+ }
+
+ io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+ Printer printer(&fout);
+
+ for (auto container : args) {
+ io::FileInputStream input(container);
+ if (input.HadError()) {
+ context.GetDiagnostics()->Error(DiagMessage(container)
+ << "failed to open file: " << input.GetError());
+ return false;
+ }
+
+ // Try as a compiled file.
+ ContainerReader reader(&input);
+ if (reader.HadError()) {
+ context.GetDiagnostics()->Error(DiagMessage(container)
+ << "failed to read container: " << reader.GetError());
+ return false;
+ }
+
+ printer.Println("AAPT2 Container (APC)");
+ ContainerReaderEntry* entry;
+ std::string error;
+ while ((entry = reader.Next()) != nullptr) {
+ if (entry->Type() == ContainerEntryType::kResTable) {
+ printer.Println("kResTable");
+
+ pb::ResourceTable pb_table;
+ if (!entry->GetResTable(&pb_table)) {
+ context.GetDiagnostics()->Error(DiagMessage(container)
+ << "failed to parse proto table: "
+ << entry->GetError());
+ continue;
+ }
+
+ ResourceTable table;
+ error.clear();
+ if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
+ context.GetDiagnostics()->Error(DiagMessage(container)
+ << "failed to parse table: " << error);
+ continue;
+ }
+
+ printer.Indent();
+ Debug::PrintTable(table, print_options, &printer);
+ printer.Undent();
+ } else if (entry->Type() == ContainerEntryType::kResFile) {
+ printer.Println("kResFile");
+ pb::internal::CompiledFile pb_compiled_file;
+ off64_t offset;
+ size_t length;
+ if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
+ context.GetDiagnostics()->Error(
+ DiagMessage(container) << "failed to parse compiled proto file: "
+ << entry->GetError());
+ continue;
+ }
+
+ ResourceFile file;
+ if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
+ context.GetDiagnostics()->Warn(DiagMessage(container)
+ << "failed to parse compiled file: " << error);
+ continue;
+ }
+
+ printer.Indent();
+ DumpCompiledFile(file, Source(container), offset, length, &printer);
+ printer.Undent();
+ }
}
}
+
return 0;
}
+int DumpConfigsCommand::Action(const std::vector<std::string>& args) {
+ if (args.size() < 1) {
+ diag_->Error(DiagMessage() << "No dump apk specified.");
+ return 1;
+ }
+
+ auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
+ if (!loaded_apk) {
+ return 1;
+ }
+
+ io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+ Printer printer(&fout);
+
+ // Comparison function used to order configurations
+ auto compare = [](ConfigDescription c1, ConfigDescription c2) -> bool {
+ return c1.compare(c2) < 0;
+ };
+
+ // Insert the configurations into a set in order to keep every configuarion seen
+ std::set<ConfigDescription, decltype(compare)> configs(compare);
+ for (auto& package : loaded_apk->GetResourceTable()->packages) {
+ for (auto& type : package->types) {
+ for (auto& entry : type->entries) {
+ for (auto& value : entry->values) {
+ configs.insert(value->config);
+ }
+ }
+ }
+ }
+
+ // Print the configurations in order
+ for (auto& config : configs) {
+ printer.Print(StringPrintf("%s\n", config.to_string().data()));
+ }
+
+ return 0;
+}
+
+int DumpStringsCommand::Action(const std::vector<std::string>& args) {
+ DumpContext context;
+ if (args.size() < 1) {
+ diag_->Error(DiagMessage() << "No dump apk specified.");
+ return 1;
+ }
+
+ io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+ Printer printer(&fout);
+
+ for (auto apk : args) {
+ auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
+ if (!loaded_apk) {
+ return 1;
+ }
+
+ // Load the run-time xml string pool using the flattened data
+ BigBuffer buffer(4096);
+ StringPool::FlattenUtf8(&buffer, loaded_apk->GetResourceTable()->string_pool,
+ context.GetDiagnostics());
+ auto data = buffer.to_string();
+ android::ResStringPool pool(data.data(), data.size(), false);
+ Debug::DumpResStringPool(&pool, &printer);
+ }
+
+ return 0;
+}
+
+int DumpTableCommand::Action(const std::vector<std::string>& args) {
+ if (args.size() < 1) {
+ diag_->Error(DiagMessage() << "No dump apk specified.");
+ return 1;
+ }
+
+ io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+ Printer printer(&fout);
+
+ DebugPrintTableOptions print_options;
+ print_options.show_sources = true;
+ print_options.show_values = !no_values_;
+
+ for (auto apk : args) {
+ auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
+ if (!loaded_apk) {
+ return 1;
+ }
+
+ if (loaded_apk->GetApkFormat()) {
+ printer.Println("Proto APK");
+ } else {
+ printer.Println("Binary APK");
+ }
+
+ Debug::PrintTable(*loaded_apk->GetResourceTable(), print_options, &printer);
+ }
+
+ return 0;
+}
+
+int DumpXmlTreeCommand::Action(const std::vector<std::string>& args) {
+ if (args.size() < 1) {
+ diag_->Error(DiagMessage() << "No dump apk specified");
+ return 1;
+ }
+
+ auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
+ if (!loaded_apk) {
+ return 1;
+ }
+
+ io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+ Printer printer(&fout);
+
+ // Dump the xml tree of every passed in file
+ for (auto file : files_) {
+ auto xml = loaded_apk->LoadXml(file, diag_);
+ if (!xml) {
+ return 1;
+ }
+
+ Debug::DumpXml(*xml, &printer);
+ }
+
+ return 0;
+}
+
+int DumpXmlStringsCommand::Action(const std::vector<std::string>& args) {
+ DumpContext context;
+ if (args.size() < 1) {
+ diag_->Error(DiagMessage() << "No dump apk specified.");
+ return 1;
+ }
+
+ auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
+ if (!loaded_apk) {
+ return 1;
+ }
+
+ io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+ Printer printer(&fout);
+
+ // Dump the xml strings of every passed in file
+ for (auto xml_file : files_) {
+ android::ResXMLTree tree;
+
+ if (loaded_apk->GetApkFormat() == kProto) {
+ auto xml = loaded_apk->LoadXml(xml_file, diag_);
+ if (!xml) {
+ return 1;
+ }
+
+ // Flatten the xml document to get a binary representation of the proto xml file
+ BigBuffer buffer(4096);
+ XmlFlattenerOptions options = {};
+ options.keep_raw_values = true;
+ XmlFlattener flattener(&buffer, options);
+ if (!flattener.Consume(&context, xml.get())) {
+ return 1;
+ }
+
+ // Load the run-time xml tree using the flattened data
+ std::string data = buffer.to_string();
+ tree.setTo(data.data(), data.size(), /** copyData */ true);
+
+ } else if (loaded_apk->GetApkFormat() == kBinary) {
+ io::IFile* file = loaded_apk->GetFileCollection()->FindFile(xml_file);
+ if (!file) {
+ diag_->Error(DiagMessage(xml_file) << "file '" << xml_file << "' not found in APK");
+ return 1;
+ }
+
+ std::unique_ptr<io::IData> data = file->OpenAsData();
+ if (!data) {
+ diag_->Error(DiagMessage() << "failed to open file");
+ return 1;
+ }
+
+ // Load the run-time xml tree from the file data
+ tree.setTo(data->data(), data->size(), /** copyData */ true);
+ }
+
+ Debug::DumpResStringPool(&tree.getStrings(), &printer);
+ }
+
+ return 0;
+}
+
+/** Preform no action because a subcommand is required. */
+int DumpCommand::Action(const std::vector<std::string>& args) {
+ if (args.size() == 0) {
+ diag_->Error(DiagMessage() << "no subcommand specified");
+ } else {
+ diag_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'");
+ }
+
+ Usage(&std::cerr);
+ return 1;
+}
+
} // namespace aapt
diff --git a/tools/aapt2/cmd/Dump.h b/tools/aapt2/cmd/Dump.h
index 4893c8b..03a4fba 100644
--- a/tools/aapt2/cmd/Dump.h
+++ b/tools/aapt2/cmd/Dump.h
@@ -22,33 +22,117 @@
namespace aapt {
-struct DumpOptions {
- DebugPrintTableOptions print_options;
-
- // The path to a file within an APK to dump.
- Maybe<std::string> file_to_dump_path;
-};
-
-class DumpCommand : public Command {
+/** Command the contents of files generated from the compilation stage. */
+class DumpAPCCommand : public Command {
public:
- DumpCommand() : Command("dump", "d") {
- SetDescription("Prints resource and manifest information.");
+ explicit DumpAPCCommand(IDiagnostics* diag) : Command("apc"), diag_(diag) {
+ SetDescription("Print the contents of the AAPT2 Container (APC) generated fom compilation.");
AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
- &no_values_);
- AddOptionalFlag("--file", "Dumps the specified file from the APK passed as arg.",
- &options_.file_to_dump_path);
- AddOptionalSwitch("-v", "increase verbosity of output", &verbose_);
+ &no_values_);
+ AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
}
int Action(const std::vector<std::string>& args) override;
private:
- DumpOptions options_;
-
+ IDiagnostics* diag_;
bool verbose_ = false;
bool no_values_ = false;
};
+/** Prints every configuration used by a resource in an APK. */
+class DumpConfigsCommand : public Command {
+ public:
+ explicit DumpConfigsCommand(IDiagnostics* diag) : Command("configurations"), diag_(diag) {
+ SetDescription("Print every configuration used by a resource in the APK.");
+ }
+
+ int Action(const std::vector<std::string>& args) override;
+
+ private:
+ IDiagnostics* diag_;
+};
+
+/** Prints the contents of the resource table string pool in the APK. */
+class DumpStringsCommand : public Command {
+ public:
+ explicit DumpStringsCommand(IDiagnostics* diag) : Command("strings"), diag_(diag) {
+ SetDescription("Print the contents of the resource table string pool in the APK.");
+ }
+
+ int Action(const std::vector<std::string>& args) override;
+
+ private:
+ IDiagnostics* diag_;
+};
+
+/** Prints the contents of the resource table from the APK. */
+class DumpTableCommand : public Command {
+ public:
+ explicit DumpTableCommand(IDiagnostics* diag) : Command("resources"), diag_(diag) {
+ SetDescription("Print the contents of the resource table from the APK.");
+ AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
+ &no_values_);
+ AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
+ }
+
+ int Action(const std::vector<std::string>& args) override;
+
+ private:
+ IDiagnostics* diag_;
+ bool verbose_ = false;
+ bool no_values_ = false;
+};
+
+/** Prints the string pool of a compiled xml in an APK. */
+class DumpXmlStringsCommand : public Command {
+public:
+ explicit DumpXmlStringsCommand(IDiagnostics* diag) : Command("xmlstrings"), diag_(diag) {
+ SetDescription("Print the string pool of a compiled xml in an APK.");
+ AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
+ }
+
+ int Action(const std::vector<std::string>& args) override;
+
+private:
+ IDiagnostics* diag_;
+ std::vector<std::string> files_;
+};
+
+
+/** Prints the tree of a compiled xml in an APK. */
+class DumpXmlTreeCommand : public Command {
+ public:
+ explicit DumpXmlTreeCommand(IDiagnostics* diag) : Command("xmltree"), diag_(diag) {
+ SetDescription("Print the tree of a compiled xml in an APK.");
+ AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
+ }
+
+ int Action(const std::vector<std::string>& args) override;
+
+ private:
+ IDiagnostics* diag_;
+ std::vector<std::string> files_;
+};
+
+/** The default dump command. Preforms no action because a subcommand is required. */
+class DumpCommand : public Command {
+ public:
+ explicit DumpCommand(IDiagnostics* diag) : Command("dump", "d"), diag_(diag) {
+ AddOptionalSubcommand(util::make_unique<DumpAPCCommand>(diag_));
+ AddOptionalSubcommand(util::make_unique<DumpConfigsCommand>(diag_));
+ AddOptionalSubcommand(util::make_unique<DumpStringsCommand>(diag_));
+ AddOptionalSubcommand(util::make_unique<DumpTableCommand>(diag_));
+ AddOptionalSubcommand(util::make_unique<DumpXmlStringsCommand>(diag_));
+ AddOptionalSubcommand(util::make_unique<DumpXmlTreeCommand>(diag_));
+ }
+
+ int Action(const std::vector<std::string>& args) override;
+
+ private:
+ IDiagnostics* diag_;
+};
+
}// namespace aapt
#endif //AAPT2_DUMP_H
diff --git a/tools/aapt2/integration-tests/CompileTest/DirInput/res/drawable/image.png b/tools/aapt2/integration-tests/CompileTest/DirInput/res/drawable/image.png
new file mode 100644
index 0000000..1a3731b
--- /dev/null
+++ b/tools/aapt2/integration-tests/CompileTest/DirInput/res/drawable/image.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/CompileTest/DirInput/res/layout/layout.xml b/tools/aapt2/integration-tests/CompileTest/DirInput/res/layout/layout.xml
new file mode 100644
index 0000000..e5835ed
--- /dev/null
+++ b/tools/aapt2/integration-tests/CompileTest/DirInput/res/layout/layout.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
diff --git a/tools/aapt2/integration-tests/CompileTest/DirInput/res/values/values.xml b/tools/aapt2/integration-tests/CompileTest/DirInput/res/values/values.xml
new file mode 100644
index 0000000..62ab652
--- /dev/null
+++ b/tools/aapt2/integration-tests/CompileTest/DirInput/res/values/values.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+</resources>
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/CompileTest/ZipInput/res.zip b/tools/aapt2/integration-tests/CompileTest/ZipInput/res.zip
new file mode 100644
index 0000000..00e396d
--- /dev/null
+++ b/tools/aapt2/integration-tests/CompileTest/ZipInput/res.zip
Binary files differ
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
index 1387d22..16a20f4c 100644
--- a/tools/aapt2/io/FileSystem.cpp
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -16,6 +16,9 @@
#include "io/FileSystem.h"
+#include <dirent.h>
+
+#include "android-base/errors.h"
#include "androidfw/StringPiece.h"
#include "utils/FileMap.h"
@@ -26,6 +29,7 @@
#include "util/Util.h"
using ::android::StringPiece;
+using ::android::base::SystemErrorCodeToString;
namespace aapt {
namespace io {
@@ -64,6 +68,50 @@
return result;
}
+std::unique_ptr<FileCollection> FileCollection::Create(const android::StringPiece& root,
+ std::string* outError) {
+ std::unique_ptr<FileCollection> collection =
+ std::unique_ptr<FileCollection>(new FileCollection());
+
+ std::unique_ptr<DIR, decltype(closedir) *> d(opendir(root.data()), closedir);
+ if (!d) {
+ *outError = "failed to open directory: " + SystemErrorCodeToString(errno);
+ return nullptr;
+ }
+
+ while (struct dirent *entry = readdir(d.get())) {
+ std::string prefix_path = root.to_string();
+ file::AppendPath(&prefix_path, entry->d_name);
+
+ // The directory to iterate over looking for files
+ if (file::GetFileType(prefix_path) != file::FileType::kDirectory
+ || file::IsHidden(prefix_path)) {
+ continue;
+ }
+
+ std::unique_ptr<DIR, decltype(closedir)*> subdir(opendir(prefix_path.data()), closedir);
+ if (!subdir) {
+ *outError = "failed to open directory: " + SystemErrorCodeToString(errno);
+ return nullptr;
+ }
+
+ while (struct dirent* leaf_entry = readdir(subdir.get())) {
+ std::string full_path = prefix_path;
+ file::AppendPath(&full_path, leaf_entry->d_name);
+
+ // Do not add folders to the file collection
+ if (file::GetFileType(full_path) == file::FileType::kDirectory
+ || file::IsHidden(full_path)) {
+ continue;
+ }
+
+ collection->InsertFile(full_path);
+ }
+ }
+
+ return collection;
+}
+
IFile* FileCollection::InsertFile(const StringPiece& path) {
return (files_[path.to_string()] = util::make_unique<RegularFile>(Source(path))).get();
}
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
index 6be8807..fb6bf6e 100644
--- a/tools/aapt2/io/FileSystem.h
+++ b/tools/aapt2/io/FileSystem.h
@@ -59,6 +59,10 @@
public:
FileCollection() = default;
+ /** Creates a file collection containing all files contained in the specified root directory. */
+ static std::unique_ptr<FileCollection> Create(const android::StringPiece& path,
+ std::string* outError);
+
// Adds a file located at path. Returns the IFile representation of that file.
IFile* InsertFile(const android::StringPiece& path);
IFile* FindFile(const android::StringPiece& path) override;
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 269b6c5..8e6d713 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -20,6 +20,7 @@
#include "ziparchive/zip_archive.h"
#include "Source.h"
+#include "util/Files.h"
#include "util/Util.h"
using ::android::StringPiece;
@@ -121,9 +122,14 @@
std::string zip_entry_path =
std::string(reinterpret_cast<const char*>(zip_entry_name.name),
zip_entry_name.name_length);
- std::string nested_path = path.to_string() + "@" + zip_entry_path;
- std::unique_ptr<IFile> file =
- util::make_unique<ZipFile>(collection->handle_, zip_data, Source(nested_path));
+
+ // Do not add folders to the file collection
+ if (util::EndsWith(zip_entry_path, "/")) {
+ continue;
+ }
+
+ std::unique_ptr<IFile> file = util::make_unique<ZipFile>(collection->handle_, zip_data,
+ Source(zip_entry_path, path.to_string()));
collection->files_by_name_[zip_entry_path] = file.get();
collection->files_.push_back(std::move(file));
}
@@ -132,6 +138,7 @@
if (out_error) *out_error = ErrorCodeString(result);
return {};
}
+
return collection;
}
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index 5a8ff09..7cd023b 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -149,6 +149,10 @@
return {};
}
+bool IsHidden(const android::StringPiece& path) {
+ return util::StartsWith(GetFilename(path), ".");
+}
+
void AppendPath(std::string* base, StringPiece part) {
CHECK(base != nullptr);
const bool base_has_trailing_sep = (!base->empty() && *(base->end() - 1) == sDirSep);
diff --git a/tools/aapt2/util/Files.h b/tools/aapt2/util/Files.h
index b26e4fa..219e1a0 100644
--- a/tools/aapt2/util/Files.h
+++ b/tools/aapt2/util/Files.h
@@ -70,6 +70,9 @@
// of the path.
android::StringPiece GetExtension(const android::StringPiece& path);
+// Returns whether or not the name of the file or directory is a hidden file name
+bool IsHidden(const android::StringPiece& path);
+
// Converts a package name (com.android.app) to a path: com/android/app
std::string PackageToPath(const android::StringPiece& package);